Commit Graph

100 Commits

Author SHA1 Message Date
008d2bf30b spec: add SPEC-007 managed-agent installer builder
Dashboard "Build Installer" wizard for pre-labeled managed/persistent agents
(Name/Company/Site/Department/Device Type/Tag/Type) with Download / Copy URL /
Send Link, ScreenConnect-style. The embed-config build path already exists
(downloads.rs appends EmbeddedConfig GURUCONFIG blob; AgentDownloadParams takes
company/site/tags/api_key; agent reads it at config.rs:223) - missing is the UI,
department + device_type fields (EmbeddedConfig/AgentStatus/connect_machines),
name strategy, and Copy-URL/Send-Link actions. Labels persist at install time,
feeding SPEC-003/005/006. Embedded key should be revocable per-machine/site
(pairs with SPEC-004). Biggest open question: appending config after Authenticode
signing invalidates the signature. Requested by Mike 2026-05-30.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 16:24:56 -07:00
0eb38520ed spec: add SPEC-006 universal machine search
Single search box matching case-insensitive substring across ALL machine
attributes (OS, logged-on user, external/private IP, company, site, tag,
serial, MAC, client version, ...) server-side, ScreenConnect-style. Replaces
the dashboard's hostname/agent_id-only client filter (inadequate at ~900+
machines). pg_trgm GIN index over a concatenated searchable-text expression
(INET cast to text, tags via array_to_string); multi-term AND; optional
field-scoped syntax (os:/user:/ip:). Parameterized + fixed column allowlist
(no injection), admin-guarded, DoS-capped. Depends on SPEC-003 (attrs must be
persisted to be searchable); reuses SPEC-005 enriched payload. Requested by
Mike 2026-05-30.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 16:21:10 -07:00
cdc182f0fb spec: add SPEC-005 machines list view (dual indicators + rich rows)
ScreenConnect "Access"-list parity for the Operator Console machines list:
per-row dual Host/Guest connection indicators (Guest=agent is_online,
Host=viewer_count>0 with viewer names + durations) and rich inline metadata
(company, site, device type, tags, logged-on user + idle, client version in
red when outdated). Live Host/Guest state already exists on SessionInfo
(is_online, viewer_count, viewers); main work is enriching /api/machines with
that + SPEC-003 inventory and redesigning MachinesPage rows. Depends on
SPEC-003 (data), reads cleanest after SPEC-004 (dedup), dovetails SPEC-002
Phase 2. Company-tree nav split out as a P3 follow-up. Requested by Mike
2026-05-30.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 16:17:48 -07:00
f8bd4d1dab spec: SPEC-004 add stable machine-derived identity as the primary fix
Address duplicate registration at the source, not just via cleanup. Root
cause now grounded: agent_id is a random UUID (config.rs:90 generate_agent_id)
persisted only in the config file, so a portable/misconfigured execution
(the Pavon desktop launcher) regenerates a fresh id each launch, defeating
both the DB upsert (ON CONFLICT agent_id) and session-reuse dedupe. Add a
deterministic machine_uid (Windows MachineGuid-based, recomputable) keyed by
registration; reaping/supersede become defense-in-depth. Security: machine_uid
is identity not authorization and must be bound to the per-machine agent key
to prevent session/record hijack. Requested by Mike 2026-05-30.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 16:11:38 -07:00
ee900c6395 spec: add SPEC-004 session lifecycle reaping + operator removal
Stop orphaned managed sessions accumulating in the Operator Console and let
admins remove stale sessions/units individually and in bulk. Root cause
confirmed in code: the Sessions list is the in-memory SessionManager;
register_agent reconnect-reuse keys on a stable agent_id (session/mod.rs:169)
and persistent sessions are never reaped on disconnect (session/mod.rs:519-542),
so an agent reconnecting with a fresh agent_id leaves a new retained ghost
session each time (observed: 15 sessions/0 live, ~10 orphans for one machine
after a GuruConnect-client reconnect storm). Adds TTL sweep + same-machine
supersede, admin-gated audited purge + bulk endpoints, and dashboard
multi-select removal. Requested by Mike 2026-05-30.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 16:05:32 -07:00
abf499cb23 spec: add SPEC-003 full machine inventory in connection DB
Persist a complete per-machine device inventory on connect_machines
(OS+locale+install, CPU/RAM, mfr/model/serial, external WAN IP captured
server-side via trusted-proxy client_ip + private LAN IP + MAC, logged-on
user, idle, time zone, uptime, local-admin-present), refreshed each
AgentStatus and surfaced in the dashboard machine detail — ScreenConnect
"Guest Info" parity. Data layer for SPEC-002 Phase 2; closes the GC side
of the agent-IP gap (coord todo 7459428e). Requested by Mike 2026-05-30.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 15:48:09 -07:00
abc55abb0b fix(server): tolerate NULL connect_machines columns (tags decode bug)
Some checks failed
Build and Test / Build Server (Linux) (push) Failing after 3m37s
Build and Test / Build Agent (Windows) (push) Successful in 7m30s
Build and Test / Security Audit (push) Successful in 4m49s
Build and Test / Build Summary (push) Has been skipped
connect_machines.tags is text[] nullable with no default; the derived
FromRow decoded it as non-Option Vec<String>, so rows with NULL tags
threw "unexpected null" - breaking managed-session reconcile on startup
and the authed Machines list. Hit in production on the v2 cutover.

- Replace the derived FromRow on Machine with a manual impl that decodes
  every nullable-non-Option column as Option<T> with unwrap_or_default
  (tags, is_elevated, is_persistent, status, timestamps), fixing all six
  read sites at once. Public field types unchanged.
- migrations/007: backfill NULL tags to empty array, set DEFAULT '{}',
  set NOT NULL (no writer inserts NULL: upsert omits tags, metadata
  update binds a non-null array). Idempotent with the prod hot-patch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 15:17:12 -07:00
96b4fd7721 feat(dashboard): GuruConnect v2 Users admin view
Some checks failed
Build and Test / Build Server (Linux) (push) Failing after 4m43s
Build and Test / Build Agent (Windows) (push) Successful in 8m48s
Build and Test / Security Audit (push) Successful in 4m38s
Build and Test / Build Summary (push) Has been skipped
Admin-only user management: list, create, edit role/permissions/status,
reset password, and disable/delete, against the v2 users API.

- Admin-gated three ways: AdminRoute on /users (calm access-denied panel
  for non-admins, no redirect loop or data fetch), Sidebar hides the nav
  item, and every mutation relies on the server AdminUser 403 as the real
  authority. isAdmin is derived from the server-validated user, not the
  client token.
- Users table: role badge (admin/operator/viewer), permissions summary,
  enabled/disabled status, created, last-login. Sticky header, skeleton,
  empty/error states. Self row tagged "You".
- Create/edit use the real roles and permission strings
  (view/control/transfer/manage_users/manage_clients); admin permissions
  are server-implicit and shown locked. Passwords: typed or Web Crypto
  generated (rejection-sampled, copy-once reveal), type=password +
  autoComplete=new-password, cleared from state on open/close/success,
  never logged/persisted/in-URL; blank on edit means unchanged.
- Self-lockout guards: cannot disable, delete, or demote your own admin
  account (controls disabled + submit-handler checks, matched on the
  authoritative user id). Server mirrors self-disable/self-delete; the
  self-demotion guard is client-side (server todo filed).
- useUpdateUser sequences user-update then permissions-set; invalidates
  ["users"] on settled so the table reconciles after a partial failure,
  with an actionable message if only permissions failed.

Passed Code Review (no blockers after fixes) and local gates
(tsc/lint/build green). Completes the v2 dashboard view set.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 14:18:40 -07:00
664f33d5ab feat(dashboard): GuruConnect v2 Support Codes view
Some checks failed
Build and Test / Build Server (Linux) (push) Failing after 3m27s
Build and Test / Build Agent (Windows) (push) Successful in 7m11s
Build and Test / Security Audit (push) Successful in 4m32s
Build and Test / Build Summary (push) Has been skipped
Generate, list, and cancel attended-support codes (XXX-XXX-XXX), built
on the v2 codes API and existing UI primitives.

- Codes table: code in mono, status badge (pending+pulse/connected/
  completed/cancelled), bound client/machine, created-by, created
  (relative + absolute tooltip). Sticky header, skeleton load,
  actionable empty/error states.
- Generate opens a focused reveal modal showing the code large in
  JetBrains Mono with copy and a read-aloud instruction; the code is
  announced character-by-character for screen readers. Mint is ref-
  guarded so it creates exactly one code per open (no StrictMode dupe).
- Cancel via confirm dialog (POST /api/codes/:code/cancel), disabled for
  non-cancellable statuses; invalidates the codes query. List polls 7s.
- Shared API client now tolerates non-JSON 200 bodies, so the cancel
  endpoint's plain-text "Code cancelled" success no longer surfaces as a
  failure. Error-envelope handling unchanged.

Passed Code Review (no blockers after fixes) and local gates
(tsc/lint/build green).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:59:18 -07:00
67f3722b3c feat(server): serve dashboard SPA with deep-link fallback; remove v1 portal
Some checks failed
Build and Test / Build Server (Linux) (push) Failing after 3m26s
Build and Test / Build Agent (Windows) (push) Successful in 7m17s
Build and Test / Security Audit (push) Successful in 4m29s
Build and Test / Build Summary (push) Has been skipped
Axum now serves the v2 React/Vite dashboard SPA at / with a client-side
routing fallback, and the dead v1 HTML portal is removed (nothing was
live on the server to preserve).

- SPA served from server/static/app via ServeDir with a fallback to
  index.html, so deep links (/machines, /sessions) resolve to the SPA.
- /api/*rest and /ws/*rest return JSON 404 so unrouted API/WS paths never
  leak index.html to clients; real /api, /ws, /health, /metrics, and the
  /downloads nest keep precedence (matchit static-over-wildcard).
- Path-aware Cache-Control: hashed /assets immutable, index.html no-cache.
- Vite builds to server/static/app (base /); the artifact is gitignored
  and rebuilt at deploy time (npm ci && npm run build).
- Removed v1 portal files (login/dashboard/users/index/viewer .html) and
  their dead serve_* handlers; the SPA owns /, /login, /dashboard, /users.

Verified locally: server boots, / and deep links serve the SPA, unknown
/api path returns JSON 404 (not HTML), /health and /downloads intact.
cargo build + clippy -D warnings green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:44:13 -07:00
6ecb937eb6 feat(dashboard): GuruConnect v2 Sessions view (pass 2)
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 7m9s
Build and Test / Build Server (Linux) (push) Successful in 10m41s
Build and Test / Security Audit (push) Successful in 4m25s
Build and Test / Build Summary (push) Successful in 10s
Active-sessions table with consent-state badges, viewer-token Join,
and disconnect, built on the v2 session API and existing UI primitives.

- Sessions table: machine, mode (managed/attended), consent badge
  (granted/pending+pulse/denied/not_required), viewers, started,
  duration, status. Sticky header, skeleton load, empty/error states.
- Join action mints a session-scoped viewer token
  (POST /api/sessions/:id/viewer-token) and reveals it with the
  /ws/viewer relay URL and copy buttons. The static viewer.html is
  intentionally not targeted: it sends the raw login JWT, which the v2
  viewer plane rejects. In-dashboard web viewer ships in a later pass.
- Authz split mirrors the server mint gate: admin or control permission
  gets Control; view permission gets View only; neither hides the action.
  Server remains authoritative; the minted token carries the signed
  access claim.
- Disconnect via confirm dialog (DELETE /api/sessions/:id), invalidates
  the sessions query. List polls every 8s so consent transitions surface.

Passed Code Review (no blockers) and local gates (tsc/lint/build green).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:12:04 -07:00
43a9432b81 feat(dashboard): GuruConnect v2 operator console (pass 1)
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 6m56s
Build and Test / Build Server (Linux) (push) Successful in 10m15s
Build and Test / Security Audit (push) Successful in 4m12s
Build and Test / Build Summary (push) Successful in 10s
React + Vite + TypeScript SPA: scaffold, operations-terminal design
system, Bearer-token auth, and the Machines view.

- Design system: OKLCH-tinted dark theme (ink-slate + signal-cyan),
  Hanken Grotesk + JetBrains Mono, status-color language
  (online/offline/granted/pending/denied/not_required), motion with
  prefers-reduced-motion honored.
- Auth: token in sessionStorage via ref (never React state), protected
  routes, 401 session teardown, admin-gated per-agent-key UI.
- Machines view: data table (sticky header, keyboard-activated rows,
  skeleton loading, actionable empty/error states), non-blocking detail
  drawer, delete confirm, admin key management with copy-once reveal.
- UI primitives: Modal (focus trap + inert + portal + dialogStack),
  Drawer, Table, Badge/StatusDot, toast, states.
- Typed API client normalizing the two error-envelope shapes.

Passed Code Review (no blockers), impeccable critique-and-polish, and
local gates (tsc/lint/build green). Dev-only Vite proxy to :3002.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 12:51:11 -07:00
f9bdecbfdb feat(agent,server): v2 secure-session-core Task 7 - HW H.264 + negotiated raw fallback
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 6m57s
Build and Test / Build Server (Linux) (push) Successful in 10m23s
Build and Test / Security Audit (push) Successful in 4m15s
Build and Test / Build Summary (push) Successful in 9s
SPEC-002 Phase 1 Task 7 (the last), code-reviewed APPROVED, locally verified
(cargo fmt + clippy -D warnings exit 0 + cargo test --workspace 89 pass + build).

- Encoder trait + factory: RawEncoder (salvaged, UNCHANGED) and H264Encoder,
  selected by negotiation; factory falls back to raw on H.264 init failure.
- Negotiation: agent advertises supports_h264 (MFTEnumEx HW probe, cached) in
  AgentStatus; server picks the codec via select_video_codec(supports, prefer)
  and stamps StartStream.video_codec; agent re-guards on local HW. Policy
  constant DEFAULT_PREFER_H264 = false, so RAW is negotiated for every session
  today - H.264 stays dormant until live hardware validation (Task 8).
- MF H.264 encoder (h264.rs, FIRST-CUT / compile-verified-only): HW encoder MFT,
  BGRA->NV12 (color.rs, unit-tested), sync drain, fall-back-to-raw on any failure.
- Viewer H.264 decoder (decoder.rs, FIRST-CUT): MF decoder on a dedicated COM
  thread; drops+logs on failure, raw render path untouched.
- proto additive: VideoCodec enum, StartStream.video_codec=3,
  SessionResponse.video_codec=5, AgentStatus.supports_h264=11.
- Raw+Zstd path byte-for-byte unchanged; remains the guaranteed default/fallback.

Review confirmed unsafe impl Send for H264Encoder is sound (single-owned &mut on
the block_on thread; session future never spawned) and every MF failure degrades
to raw. H.264 is NOT claimed functional - compile/clippy/build-verified only;
live validation + force-IDR + the no-spawn-invariant doc are Task 8 go-live gates.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 10:35:04 -07:00
bb73ba667f feat(agent): v2 secure-session-core Task 6 - full key fidelity
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 7m1s
Build and Test / Build Server (Linux) (push) Successful in 11m32s
Build and Test / Security Audit (push) Successful in 4m31s
Build and Test / Build Summary (push) Successful in 11s
SPEC-002 Phase 1 Task 6, code-reviewed APPROVED (2 rounds), locally verified
(cargo fmt + clippy -D warnings exit 0 + cargo test --workspace 70 pass + build).

- Viewer WH_KEYBOARD_LL hook diverts system combos (Win/Win+R, Alt+Tab, Alt+Esc,
  Ctrl+Esc) to the remote as a full KeyEvent (vk + scan + is_extended + modifiers)
  and suppresses local handling - GATED on the viewer window having focus AND a
  "send system keys" toggle (default on; Pause/Break host-key), so it never bricks
  the technician's local keyboard when unfocused.
- Agent injection via SendInput KEYEVENTF_SCANCODE + correct KEYEVENTF_EXTENDEDKEY
  (right Ctrl/Alt, arrows, nav, Win, NumLock, numpad Divide) - layout-independent,
  extended-key-correct.
- Ctrl+Alt+Del completes through the SAS helper (SYSTEM SendSAS); installer sets
  the SoftwareSASGeneration policy; 3-tier fail-loud (no false success). SAS named
  pipe DACL tightened from NULL/Everyone to Authenticated Users.
- Modifier hygiene: viewer emits key-ups for held Ctrl/Alt/Shift/Win on focus loss
  / close so modifiers never stick on the remote.
- proto: KeyEvent.is_extended = 7 (additive; older agents derive the flag).

Closes Win+R / Ctrl+C-V / Ctrl+Alt+Del / arrows-vs-numpad fidelity. Live on-device
testing is plan Task 8.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 09:16:26 -07:00
d0de888dd1 style(agent): clear 77 pre-existing clippy -D warnings
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 6m53s
Build and Test / Build Server (Linux) (push) Successful in 10m59s
Build and Test / Security Audit (push) Successful in 4m31s
Build and Test / Build Summary (push) Successful in 10s
CI never ran clippy on the agent crate (the build-server clippy job is
Linux-only and can't compile the Windows agent; build-agent only runs cargo
build), so 77 clippy -D-warnings errors had accumulated. Behavior-preserving
cleanup, code-reviewed APPROVED, locally verified (cargo clippy --workspace
--all-targets --all-features -- -D warnings exits 0; cargo test --workspace =
57 passed).

- let _ = on Win32 resource-teardown BOOL returns (gdi.rs); fallible
  BitBlt/GetDIBits stay error-handled
- removed unused imports/vars; idiom fixes (div_ceil, is_null, transmute
  annotations, match collapsing, useless_conversion)
- #[allow(dead_code)] + comment on genuine Task-6/7 scaffolding (vk consts,
  SpecialKey emission, SAS mgmt API, modifier tracking, GDI frame-diff fields)
- Cargo.lock: cargo pruned ~147 stale transitive entries (no version changes)

Follow-up: add cargo clippy -D warnings to the build-agent CI job so the agent
crate stays clippy-clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 08:51:45 -07:00
fbf9e26f5a style(server,agent): fmt + clippy fixes for Task 5 (CI green)
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 7m29s
Build and Test / Build Server (Linux) (push) Successful in 12m9s
Build and Test / Security Audit (push) Successful in 5m23s
Build and Test / Build Summary (push) Successful in 11s
9082e11 compiles + passes all 50 server tests on the build host; only blocked
CI on cargo fmt (4 files) and one clippy -D dead-code denial:
- cargo fmt --all (relay/mod.rs, session/mod.rs, agent consent/mod.rs + session/mod.rs)
- #[cfg_attr(not(test), allow(dead_code))] on session::get_consent_state (a
  read accessor currently exercised only by tests)
No logic change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 07:59:29 -07:00
9082e11490 feat(server,agent): v2 secure-session-core Task 5 - attended consent
Some checks failed
Build and Test / Build Server (Linux) (push) Failing after 5m42s
Build and Test / Build Agent (Windows) (push) Successful in 8m22s
Build and Test / Security Audit (push) Successful in 5m12s
Build and Test / Build Summary (push) Has been skipped
SPEC-002 Phase 1 Task 5, code-reviewed APPROVED. An attended (support-code)
session is invisible and inert to the technician until the end user accepts a
consent prompt on their own machine.

- proto: ConsentRequest / ConsentResponse + ConsentAccessMode enum (oneof
  fields 80/81; no existing field renumbered).
- server: ConsentState on Session; attended -> Pending, managed -> NotRequired;
  join_session refuses viewers unless Granted/NotRequired (single chokepoint -
  StartStream only fires from join_session, so no frames or input flow pre-
  consent); run_consent_handshake sends ConsentRequest, 60s timeout, granted ->
  proceed, denied/timeout/disconnect -> teardown (end_session denied, machine
  offline, support code released). consent_state persisted; consent_requested/
  granted/denied audited.
- agent: Windows MessageBox (topmost/system-modal) on spawn_blocking; anything
  but an explicit Yes = deny; non-Windows build is a fail-closed stub.

Not cargo-check-verified locally (no toolchain). Server verified on the build
host; the Windows agent half is verified by CI build-agent (Pluto).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 07:44:09 -07:00
8cb0b5b16b style(server): cargo fmt for trusted-proxy IP extractor (CI green)
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 6m53s
Build and Test / Build Server (Linux) (push) Successful in 10m54s
Build and Test / Security Audit (push) Successful in 4m21s
Build and Test / Build Summary (push) Successful in 11s
5d5cd26 compiles + passes clippy -D warnings + all 45 tests on the build host;
only cargo fmt --check failed on one reflowed method chain in ip_extract.rs.
No logic change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 07:26:15 -07:00
5d5cd26572 fix(server): trusted-proxy client-IP extraction for rate-limit/audit keying
Some checks failed
Build and Test / Build Server (Linux) (push) Failing after 5m9s
Build and Test / Build Agent (Windows) (push) Successful in 7m38s
Build and Test / Security Audit (push) Successful in 4m59s
Build and Test / Build Summary (push) Has been skipped
Resolves coord todo 3c1f372a (Task-4 review SHOULD-FIX). Behind NPM-on-loopback,
ConnectInfo was 127.0.0.1 so the rate limiter + lockout bucketed every client
under one IP. New shared utils::ip_extract::client_ip() honors X-Real-IP /
X-Forwarded-For (rightmost-untrusted hop) ONLY when the TCP peer is a configured
trusted proxy (CONNECT_TRUSTED_PROXIES env, default loopback, fail-closed);
untrusted peers are keyed by their true peer IP (forged headers ignored). Wired
into the 3 rate-limit middleware, the validate_code lockout feed, and the agent/
viewer WS handlers so the limiter, lockout, and audit ip_address all key on the
real client consistently. 13 unit tests (spoof rejection, XFF walk, fail-safe
defaults). Code-reviewed APPROVED. Not cargo-check-verified locally (no toolchain);
build-host/CI verification follows.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 07:15:45 -07:00
21189423f2 fix(server): clippy fixes for Task 4 (CI green)
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 6m3s
Build and Test / Build Server (Linux) (push) Successful in 10m19s
Build and Test / Security Audit (push) Successful in 4m10s
Build and Test / Build Summary (push) Successful in 9s
Task 4 (bfcdbb5) compiles and passes all 32 tests on the build host; only
clippy -D warnings blocked CI. Fixed the two denials:
- rate_limit.rs: converted a dangling /// doc block (no documented item) to //
  to clear clippy::empty_line_after_doc_comments
- db/events.rs: #[allow(dead_code)] on CONNECTION_REJECTED_EXPIRED_CODE and
  _CANCELLED_CODE (not-yet-wired audit-event constants), matching the file's
  existing STREAMING_STOPPED pattern; TODO comments note the rejection-event wiring

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 21:17:23 -07:00
bfcdbb5379 feat(server): v2 secure-session-core Task 4 - rate limit + single-use codes
Some checks failed
Build and Test / Build Server (Linux) (push) Failing after 6m12s
Build and Test / Build Agent (Windows) (push) Successful in 6m43s
Build and Test / Security Audit (push) Successful in 4m23s
Build and Test / Build Summary (push) Has been skipped
SPEC-002 Phase 1 Task 4 (the final keystone task), code-reviewed APPROVED.
Closes the audit's reusable-code HIGH and rate-limiting-disabled HIGH.

- Rebuilt rate limiting as a self-contained in-memory per-IP limiter (replaces
  the non-compiling tower_governor; removed that dep). Fixed-window caps wired
  to login (8/min), change-password (5/min), code-validate (15/min) -> 429;
  per-IP lockout after 10 consecutive failed code validations (15-min cooldown).
- Single-use support codes: atomic consume on first agent bind (in-memory
  Pending->Connected under write lock + DB conditional UPDATE), rejecting a
  second presenter; validate/preview does not consume.
- Widened code format: XXX-XXX-XXX, 31-char unambiguous alphabet (no 0/O/1/I/L),
  CSPRNG + rejection sampling, ~44.6 bits (replaces 6-digit numeric); migration
  006 widens the code columns to TEXT.

Completes the keystone (Tasks 1-4): every audit CRITICAL + HIGH in the secure
auth/session core is now addressed. Known follow-up todos (not blocking): (1)
trusted-proxy client-IP extraction (NPM-on-loopback collapses clients to
127.0.0.1); (2) multi-instance fail-closed DB single-use gate. Not
cargo-check-verified locally - build-host/CI verification follows this commit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 21:04:54 -07:00
8a0193577b style(server): cargo fmt + clippy fixes for v2 keystone (CI green)
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 6m29s
Build and Test / Build Server (Linux) (push) Successful in 10m23s
Build and Test / Security Audit (push) Successful in 4m17s
Build and Test / Build Summary (push) Successful in 11s
The Task 2/3/authz commits failed CI at the first gate (cargo fmt --all
--check), which short-circuited before clippy/build/test ran. Verified on the
build host (172.16.3.30): the v2 server compiles and all 18 tests pass; only
3 cosmetic issues blocked CI, all fixed here:
- cargo fmt --all (whitespace, 3 files)
- clippy unused_imports: drop ViewerClaims from auth/mod.rs re-export
- clippy doc_overindented_list_items: de-indent one doc line in sessions.rs
Testing Agent confirmed fmt + clippy -D warnings + build --release + test are
all green with these applied. No logic changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 20:19:26 -07:00
a453e7984e feat(server): viewer-token view-only/control split - closes CRITICAL #1
Some checks failed
Build and Test / Build Server (Linux) (push) Failing after 3m20s
Build and Test / Build Agent (Windows) (push) Successful in 6m9s
Build and Test / Security Audit (push) Successful in 4m21s
Build and Test / Build Summary (push) Has been skipped
Authz-strength fix (coord todo c8916c89), code-reviewed APPROVED. Replaces the
weak "view" gate (held by every role) with a permission-tiered access mode
stamped inside the signed viewer token:
- mint: is_admin() || has_permission("control") -> CONTROL token; else
  has_permission("view") -> VIEW_ONLY token; else 403.
- enforce: the relay drops MouseEvent/KeyEvent/SpecialKey for a VIEW_ONLY token
  before forwarding (video still streams); CONTROL tokens forward under the
  Task-3 throttle. Mode is unforgeable (in the signature) and unbypassable
  (all other viewer->agent payloads hit the catch-all and are never forwarded).
A low-privilege viewer-role user can now at most watch, never control. New
ViewerAccess enum (view_only|control) on ViewerClaims; 3 unit tests.

Audit CRITICAL #1 now fully closed (mechanism in Task 3 + this authz strength).
Not cargo-check-verified locally (no toolchain) - the push triggers CI
(clippy -D warnings + build + test) which is the verification gate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 19:24:32 -07:00
0f258788f9 feat(server): v2 secure-session-core Task 3 - secure relay WS
Some checks failed
Build and Test / Build Server (Linux) (push) Failing after 4m3s
Build and Test / Build Agent (Windows) (push) Successful in 7m48s
Build and Test / Security Audit (push) Successful in 4m20s
Build and Test / Build Summary (push) Has been skipped
SPEC-002 Phase 1 Task 3 (specs/v2-secure-session-core), code-reviewed APPROVED.

- viewer_ws_handler: verify the session-scoped VIEWER token (validate_viewer_token
  sig+exp+purpose) + token_blacklist.is_revoked + session_id claim == requested
  session, before upgrade. Raw login JWTs no longer accepted on the viewer plane
  (closes audit CRITICAL #2; closes the *mechanism* of CRITICAL #1).
- mint_viewer_token: authz gate is_admin() || has_permission("view") -> 403.
- Agent identity binding: validate_agent_api_key returns AgentKeyAuth; a cak_-
  verified agent rebinds to the key's machine identity (fails closed if
  unresolvable), so a key for machine X cannot seize machine Y's session slot.
- Frame caps on both WS upgrades (agent 4 MiB, viewer 64 KiB) - closes WS-OOM HIGH.
- Viewer->agent input throttle (200 ev/s token bucket, bounded try_send) - closes
  input-injection MEDIUM.
- Startup managed-session reconcile clarified.

KNOWN FOLLOW-UPS (tracked todos): (1) authz STRENGTH - the "view" permission is
held by every default role incl. viewer, and a viewer token grants input control,
so the gate should be "control" or a VIEW_ONLY/CONTROL token split; CRITICAL #1 is
mechanism-closed, strength pending decision. (2) revoke minted viewer tokens on
logout (currently bounded only by 5-min TTL). Not cargo-check-verified (no toolchain
on the authoring host).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 19:13:03 -07:00
41691bfb2c feat(server): v2 secure-session-core Task 2 - auth rebuild
Some checks failed
Build and Test / Build Server (Linux) (push) Failing after 3m37s
Build and Test / Build Agent (Windows) (push) Successful in 6m37s
Build and Test / Security Audit (push) Successful in 4m10s
Build and Test / Build Summary (push) Has been skipped
SPEC-002 Phase 1 Task 2 (specs/v2-secure-session-core), code-reviewed APPROVED.

- DELETE the JWT-as-agent-key branch in relay validate_agent_api_key (audit
  CRITICAL): agent auth now = per-agent cak_ key (SHA-256 -> connect_agent_keys,
  revoked filtered) OR support code OR deprecated shared AGENT_API_KEY (warned).
  A user JWT can no longer authenticate an agent.
- auth/agent_keys.rs: cak_ gen (OsRng 256-bit) + SHA-256 hash + verify.
- auth/jwt.rs: ViewerClaims + create/validate_viewer_token (5-min TTL,
  purpose=viewer, session_id+tenant_id claims; non-interchangeable with login).
- Admin key issuance: POST/GET/DELETE /api/machines/:agent_id/keys.
- POST /api/sessions/:id/viewer-token mints a session-bound short-lived token.
- Migration 005: organization/site/tags on connect_machines (fixes the silent
  update_machine_metadata write, coord todo faf39fe0).

NOTE: viewer-token minting is gated by AuthenticatedUser only; the AUTHORIZATION
check (admin/permission gate) that closes audit CRITICAL #1 lands in Task 3 (the
viewer WS verification). The viewer WS path (relay/mod.rs:285) is untouched here.
Not cargo-check-verified (no toolchain on the authoring host) - self-reviewed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 18:57:12 -07:00
fef8111ff3 feat(server): v2 secure-session-core Task 1 - schema + per-agent keys
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 6m7s
Build and Test / Build Server (Linux) (push) Successful in 10m15s
Build and Test / Security Audit (push) Successful in 4m24s
Build and Test / Build Summary (push) Successful in 12s
SPEC-002 Phase 1 Task 1 (specs/v2-secure-session-core), code-reviewed APPROVED.

Migration 004 (idempotent, server-applied): tenants + seeded default tenant,
connect_agent_keys (hash-only, revocable, FK->connect_machines), nullable
tenant_id on all scoped tables (tenancy-ready, not tenant-yet), connect_sessions
is_managed/source/consent_state, connect_support_codes consumed_at. New db
modules agent_keys.rs (stores only key_hash) + tenancy.rs (DEFAULT_TENANT_ID,
Phase-4 switch point). Struct/query updates across machines/sessions/
support_codes/events/users. Runtime sqlx throughout (GC db layer already uses
it - no compile-time macros).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 18:33:26 -07:00
81e4b99a34 spec: add v2-secure-session-core shape spec
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 7m2s
Build and Test / Build Server (Linux) (push) Successful in 10m41s
Build and Test / Security Audit (push) Successful in 4m17s
Build and Test / Build Summary (push) Successful in 8s
Phase 1 of SPEC-002 (GuruConnect v2). Keystone-first plan: Tasks 1-4
rebuild the auth/session core that closes the 3 audit CRITICALs by design
(per-agent cak_ keys, plane separation, session-scoped viewer tokens,
blacklist+frame-caps+throttle on the relay WS, single-use rate-limited
support codes, tenancy-ready schema); Tasks 5-7 deliver attended consent,
native full key fidelity (WH_KEYBOARD_LL hook, scan-code injection, SAS
Ctrl+Alt+Del), and HW H.264 with raw+Zstd fallback. plan/shape/references/
standards.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 18:15:37 -07:00
5c60a105c0 docs(spec): add SPEC-002 GuruConnect v2 modernization architecture
Some checks failed
Build and Test / Build Agent (Windows) (push) Successful in 6m34s
Build and Test / Build Server (Linux) (push) Has started running
Build and Test / Security Audit (push) Has been cancelled
Build and Test / Build Summary (push) Has been cancelled
Ground-up v2 re-architecture decided 2026-05-29 (Mike), grounded in the
2026-05-29 audit + adopted GuruRMM design principles. Greenfield salvaging
proven Rust cores (DXGI/GDI capture, input injection, SAS helper, prost codec,
CI). Native-first full key fidelity (Win+R/Ctrl+Alt+Del) + bidirectional file
transfer (clipboard cut/paste + drag-and-drop) as headline differentiators;
WebRTC fallback only. Hardened single-tenant, tenancy-ready schema. Standalone-
first + /api/integration/v1 RMM contract. Closes all audit CRITICALs by design.
Open decisions resolved: in-place repo reset, H.264 default, WSS-first web
transport, widened support codes, clean v1 cutover (no client migration).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 18:08:23 -07:00
486debfc52 docs(audit): add inaugural gc-audit report 2026-05-29
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 6m14s
Build and Test / Build Server (Linux) (push) Successful in 10m29s
Build and Test / Security Audit (push) Successful in 4m12s
Build and Test / Build Summary (push) Successful in 10s
First /gc-audit run (also a dry run validating the skill). 7 passes.
4 CRITICAL (3 relay-plane auth failures: any-JWT session hijack,
viewer-WS blacklist bypass, JWT-accepted-as-agent-key; 1 functional:
dashboard protobuf.ts wire-incompatible). Plus deploy.yml stub leaving
prod 57 commits stale. Proposed roadmap/tech-debt deltas listed (not
yet applied, pending review).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 17:46:26 -07:00
ccc6ba9c02 ci: enforce clippy -D warnings and cargo audit as hard gates
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 12m18s
Build and Test / Build Server (Linux) (push) Successful in 14m11s
Build and Test / Security Audit (push) Successful in 5m32s
Build and Test / Build Summary (push) Successful in 9s
Flip both CI gates from informational to hard-fail (SPEC-001 quality gates):
- clippy: `-- -D warnings` on the server crate. Cleared the debt via clippy --fix
  (unused imports/style), targeted #[allow(dead_code)] on native-remote-control
  future API, and #[allow(clippy::too_many_arguments)] on 3 protocol-mirroring fns.
- cargo audit: hard-fail with documented per-ID --ignore flags (rsa RUSTSEC-2023-0071
  unfixable/unreachable in active tree; gtk-rs + glib Linux-only tray backend not
  compiled into the Windows agent; proc-macro-error build-time). New advisories fail.
- Move [profile.release] to the workspace root (it was silently ignored in the server
  member), activating lto/codegen-units/strip.

No behavioral changes. Reviewed and gates verified passing on the build host.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 00:18:50 +00:00
guruconnect-ci
6e7e7c0ccb chore: release v0.2.2 [skip ci] v0.2.2 2026-05-29 18:41:21 +00:00
5727ccf39e fix: drop broken jsign --info verify step in release
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 5m9s
Build and Test / Build Server (Linux) (push) Successful in 9m23s
Build and Test / Security Audit (push) Successful in 4m19s
Build and Test / Build Summary (push) Successful in 15s
jsign 7.1 signs guruconnect.exe successfully via Azure Trusted Signing, but the separate
verify step called `jsign --info` (not a real jsign subcommand) and wrongly failed the job.
jsign's non-zero exit under `set -euo pipefail` already gates signing fail-closed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 11:27:08 -07:00
guruconnect-ci
e80ffe4f9e chore: release v0.2.1 [skip ci] 2026-05-29 18:18:59 +00:00
e7f38ce2a0 fix: use jsign 7.1 for Azure Trusted Signing
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 5m4s
Build and Test / Build Server (Linux) (push) Successful in 8m38s
Build and Test / Security Audit (push) Successful in 4m14s
Build and Test / Build Summary (push) Successful in 18s
jsign 6.0 lacks the TRUSTEDSIGNING keystore type (only AZUREKEYVAULT); Azure Trusted
Signing support requires jsign >= 7.0. 7.1 matches /usr/share/jsign on the build host.
Fixes the release sign-and-publish step.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 11:05:34 -07:00
guruconnect-ci
520569937c chore: release v0.2.0 [skip ci] 2026-05-29 17:56:38 +00:00
4ddced1b9b ci: fix native Windows agent build, audit, lockfile; drop redundant test.yml
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 4m51s
Build and Test / Build Server (Linux) (push) Successful in 9m1s
Build and Test / Security Audit (push) Successful in 4m18s
Build and Test / Build Summary (push) Successful in 9s
- Windows agent jobs (build-and-test + release): set PROTOC env + add protoc to PATH
  (prost-build needs it; the runner did not inherit the machine env), and fix the artifact
  path to the workspace-root target/ (Cargo workspace, not agent/target/).
- Commit root Cargo.lock (was missing) -> fixes `cargo audit` (Couldn't load Cargo.lock) and
  makes builds reproducible.
- Security audit is now a single workspace-root `cargo audit`, informational (warn-only) like
  clippy; re-tighten in the GC re-spec.
- Remove test.yml: redundant with build-and-test and broken (`no library targets` — server is
  a binary crate).

Native MSVC agent build verified on the Pluto runner (4m20s, clean compile).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 10:22:13 -07:00
39e9ac4b75 ci: add workflow_dispatch trigger to build-and-test
Some checks failed
Build and Test / Build Server (Linux) (push) Successful in 7m49s
Build and Test / Build Agent (Windows) (push) Failing after 13m6s
Build and Test / Security Audit (push) Failing after 4m17s
Build and Test / Build Summary (push) Has been skipped
Run Tests / Test Server (push) Failing after 2m39s
Run Tests / Test Agent (push) Failing after 2m34s
Run Tests / Code Coverage (push) Failing after 6m1s
Run Tests / Lint and Format Check (push) Failing after 2m12s
Allow manual re-runs of the CI gate without a dummy commit (useful while
provisioning the Pluto windows-msvc runner). Also re-triggers the run.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 09:48:08 -07:00
8a47332b39 ci: build Windows agent natively on Pluto runner (drop mingw cross-compile)
Some checks failed
Build and Test / Build Agent (Windows) (push) Failing after 7m29s
Build and Test / Build Server (Linux) (push) Successful in 10m2s
Build and Test / Security Audit (push) Failing after 4m39s
Build and Test / Build Summary (push) Has been skipped
Run Tests / Test Server (push) Has started running
Run Tests / Test Agent (push) Has been cancelled
Run Tests / Code Coverage (push) Has been cancelled
Run Tests / Lint and Format Check (push) Has been cancelled
The build-agent job (build-and-test.yml) and a new build-agent-windows job (release.yml)
now run on the windows-msvc Gitea Actions runner on Pluto, building native
x86_64-pc-windows-msvc with crt-static. release.yml hands the unsigned guruconnect.exe to
the Linux job, which signs it with Azure Trusted Signing (jsign). Removes the fragile
mingw/GNU cross-compile. Reviewed by Code Review Agent (approve-with-nits).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 09:32:12 -07:00
cd88facaf0 ci: make clippy informational (warn-only) until GC re-spec
Some checks failed
Build and Test / Build Server (Linux) (push) Successful in 7m33s
Build and Test / Build Agent (Windows) (push) Failing after 6m5s
Build and Test / Security Audit (push) Failing after 4m39s
Build and Test / Build Summary (push) Has been skipped
Run Tests / Test Server (push) Failing after 3m1s
Run Tests / Test Agent (push) Failing after 2m23s
Run Tests / Code Coverage (push) Failing after 6m33s
Run Tests / Lint and Format Check (push) Failing after 2m24s
The pre-spec server has ~65 clippy lints (no compile errors), mostly dead-code
for API the native-remote-control integration will wire. Keep clippy running for
visibility but stop gating on it; fmt stays strict. Re-tighten to -D warnings
during the GC re-spec.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 08:37:44 -07:00
b2f9cbc089 ci: force linux target for build-server clippy/test
Some checks failed
Build and Test / Build Server (Linux) (push) Failing after 4m6s
Build and Test / Build Agent (Windows) (push) Failing after 7m4s
Build and Test / Security Audit (push) Failing after 5m1s
Build and Test / Build Summary (push) Has been skipped
Run Tests / Test Server (push) Failing after 3m11s
Run Tests / Test Agent (push) Failing after 2m39s
Run Tests / Code Coverage (push) Has started running
Run Tests / Lint and Format Check (push) Has been cancelled
.cargo/config.toml defaults to x86_64-pc-windows-msvc for local Windows dev,
which made the CI clippy/test steps (no explicit --target) try to compile for
an uninstalled cross target (E0463 can't find crate for core). Set
CARGO_BUILD_TARGET=x86_64-unknown-linux-gnu for the build-server job.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 08:09:44 -07:00
1c5c1e78e7 style: cargo fmt --all — make codebase rustfmt-clean
Some checks failed
Build and Test / Build Server (Linux) (push) Failing after 2m59s
Build and Test / Build Agent (Windows) (push) Has started running
Build and Test / Security Audit (push) Has been cancelled
Build and Test / Build Summary (push) Has been cancelled
Run Tests / Test Server (push) Has been cancelled
Run Tests / Test Agent (push) Has been cancelled
Run Tests / Code Coverage (push) Has been cancelled
Run Tests / Lint and Format Check (push) Has been cancelled
First run of the build-and-test CI gate (cargo fmt --all -- --check) surfaced
pre-existing formatting drift across the agent and server crates. Apply rustfmt
across the workspace so the codebase meets its own CI gate. Pure formatting; no
logic changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 15:02:12 +00:00
f2e0456f8d ci: gate release workflow to manual dispatch
Some checks failed
Build and Test / Build Server (Linux) (push) Failing after 6m22s
Build and Test / Build Agent (Windows) (push) Failing after 6m29s
Build and Test / Security Audit (push) Has started running
Build and Test / Build Summary (push) Has been cancelled
Run Tests / Test Server (push) Has been cancelled
Run Tests / Test Agent (push) Has been cancelled
Run Tests / Code Coverage (push) Has been cancelled
Run Tests / Lint and Format Check (push) Has been cancelled
Release builds (auto-versioning + Azure Trusted Signing + Gitea release) no longer
run on every push to main; trigger deliberately via workflow_dispatch. build-and-test.yml
remains the automatic PR/push CI gate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 07:27:17 -07:00
60519be28a feat: operational tooling — signing, versioning, changelog, roadmap (SPEC-001)
Establish GuruConnect's release engineering and project tracking (SPEC-001):
- docs/ scaffold: FEATURE_ROADMAP, ARCHITECTURE_DECISIONS (ADR-001 standalone+contract,
  ADR-002 Gitea Actions + Azure Trusted Signing), docs/specs/SPEC-001, CHANGELOG.
- .gitea/workflows/release.yml: conventional-commit auto-versioning, git-cliff changelog,
  Windows agent build, Azure Trusted Signing via jsign (reusing the shared ACG cert profile),
  Gitea release via REST API. build-and-test.yml is the PR/push gate; deploy.yml de-duplicated.
- server: GET /api/changelog/:component/:version (latest + by-version), path-traversal hardened.
- cliff.toml; server/.env.example documents CHANGELOG_DIR.

Reviewed (Code Review Agent): axum route-conflict blocker fixed; CHANGELOG ordering, toolchain
target, breaking-change parsing, empty-changelog fallback addressed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 07:19:29 -07:00
e3e95f8fa7 chore: sync repository to current working state
Some checks failed
Build and Test / Build Server (Linux) (push) Has been cancelled
Build and Test / Build Agent (Windows) (push) Has been cancelled
Build and Test / Security Audit (push) Has been cancelled
Build and Test / Build Summary (push) Has been cancelled
Run Tests / Test Server (push) Has been cancelled
Run Tests / Test Agent (push) Has been cancelled
Run Tests / Code Coverage (push) Has been cancelled
Run Tests / Lint and Format Check (push) Has been cancelled
Brings azcomputerguru/guru-connect up to the authoritative working copy that
had been maintained in the claudetools monorepo: Phase 1 security and
infrastructure (middleware, metrics, utils, token blacklist, deployment
scripts, security audits) plus the native-remote-control integration spec.
Preserves the repo .gitignore, .cargo, and server/static/downloads.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 06:15:29 -07:00
5b7cf5fb07 ci: add Gitea Actions workflows and deployment automation
Some checks failed
Build and Test / Build Server (Linux) (push) Has been cancelled
Build and Test / Build Agent (Windows) (push) Has been cancelled
Build and Test / Security Audit (push) Has been cancelled
Build and Test / Build Summary (push) Has been cancelled
Run Tests / Test Server (push) Has been cancelled
Run Tests / Test Agent (push) Has been cancelled
Run Tests / Code Coverage (push) Has been cancelled
Run Tests / Lint and Format Check (push) Has been cancelled
- Add build-and-test workflow for automated builds
- Add deploy workflow for production deployments
- Add test workflow for comprehensive testing
- Add deployment automation script with rollback
- Add version tagging automation
- Add Gitea Actions runner installation script

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-18 15:48:20 +00:00
3292ca4275 Fix auth token localStorage key consistency
- Dashboard, viewer, and native viewer all now use guruconnect_token
- Fixed loadMachines() to include Authorization header
2026-01-01 19:18:07 +00:00
22f592dd27 Add organization/site/tags support for machine grouping
- Added organization, site, tags columns to connect_machines table
- Agent now sends org/site/tags from embedded config in AgentStatus
- Server stores org/site/tags metadata in database
- Enables grouping machines by client/site/tag in dashboard
2026-01-01 10:40:11 -07:00
5a82637a04 Add magic bytes deployment system for agent modes
- Agent config: Added EmbeddedConfig struct and RunMode enum for
  filename-based mode detection (Viewer, TempSupport, PermanentAgent)
- Agent main: Updated to detect run mode from filename or embedded config
- Server: Added /api/download/* endpoints for generating configured binaries
  - /api/download/viewer - Downloads GuruConnect-Viewer.exe
  - /api/download/support?code=123456 - Downloads GuruConnect-123456.exe
  - /api/download/agent?company=X&site=Y - Downloads with embedded config
- Dashboard: Updated Build tab with Quick Downloads and Permanent Agent Builder
- Included base agent binary in static/downloads

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 11:13:16 -07:00
0387295401 Fix viewer-only installs registering as agents
Previously, any installation with the protocol handler registered
would default to running as an agent. This caused admin/technician
machines (viewer-only) to appear in the sessions list.

Changes:
- Add Config::has_agent_config() to check for explicit agent config
- Only run as agent when: explicit 'agent' command, support code
  provided, OR agent config file exists
- Viewer-only installs (protocol handler but no config) now exit
  silently when launched without arguments

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 10:10:10 -07:00
4e5328fe4a Implement robust auto-update system for GuruConnect agent
Features:
- Agent checks for updates periodically (hourly) during idle
- Admin can trigger immediate updates via dashboard "Update Agent" button
- Silent updates with in-place binary replacement (no reboot required)
- SHA-256 checksum verification before installation
- Semantic version comparison

Server changes:
- New releases table for tracking available versions
- GET /api/version endpoint for agent polling (unauthenticated)
- POST /api/machines/:id/update endpoint for admin push updates
- Release management API (/api/releases CRUD)
- Track agent_version in machine status

Agent changes:
- New update.rs module with download/verify/install/restart logic
- Handle ADMIN_UPDATE WebSocket command for push updates
- --post-update flag for cleanup after successful update
- Periodic update check in idle loop (persistent agents only)
- agent_version included in AgentStatus messages

Dashboard changes:
- Version display in machine detail panel
- "Update Agent" button for each connected machine

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 09:31:23 -07:00