--- module: devices.agent-scripts title: Agent Scripts tab: Claude order: 40 audience: dev --- > Act-without-guessing reference. Only confirmed facts (hiveops-devices source, 2026-07-01). ## Owner - **Service:** `hiveops-devices` (Spring Boot, port `8096`, DB `hiveiq_devices`). - Served under `/api/fleet/scripts` **but owned by devices, NOT hiveops-fleet.** - SPA: `hiveops-devices/frontend` → `components/Settings/AgentScripts.svelte`, `lib/api.ts` → `agentScriptAPI` on `devicesApi` (base `window.__APP_CONFIG__.apiUrl` else `http://localhost:8096`). ## Endpoints (all `hasAnyRole('MSP_ADMIN','BCOS_ADMIN')`) | Method | Path | Result | |--------|------|--------| | GET | `/api/fleet/scripts` | list; optional `?institutionKey=` | | POST | `/api/fleet/scripts` | 400 if name/content blank, else 201 | | PUT | `/api/fleet/scripts/{id}` | 404 if missing | | DELETE | `/api/fleet/scripts/{id}` | 204 (hard delete) | | POST | `/api/fleet/scripts/{id}/push` | **STUB → 200 + `[]`, does nothing** | ## Data - **Table:** `agent_scripts` (Flyway `V15`). Cols: `id`, `name` VARCHAR(200), `description` TEXT, `content` TEXT, `institution_key` VARCHAR(50), `created_at`, `updated_at`. Index: `idx_agent_scripts_institution_key`. - **Entity/Repo/Service/Controller:** `AgentScript` / `AgentScriptRepository` / `AgentScriptService` / `AgentScriptController` (pkg `com.hiveops.devices.*`). - Repo methods: `findAllByOrderByNameAsc`, `findByInstitutionKeyOrderByNameAsc`. ## Kafka / topics - **None.** This module produces/consumes nothing. ## Signed delivery (lives elsewhere, NOT wired here) - hiveops-fleet: `FleetTaskKind.UPDATE_SCRIPT` + `ScriptSigningService` (`SHA256withRSA`, key `script.signing.private-key` / env `SCRIPT_SIGNING_PRIVATE_KEY`). - agent: `com.hiveops.filemgmt.ProcessScriptUpdate` verifies `SHA256withRSA`, needs patch keys `scriptName` + `scriptContent` (base64) + `scriptSignature`. ## Gotchas - Devices Push button is a **no-op**; SPA still shows a success toast. Never treat a push as delivered. - Path says `fleet` but the backend is **devices** — route to `api.bcos.cloud/devices`, not `/fleet`. - Name extension check (`.cmd/.sh/.ps1`) is **client-side only**; backend accepts any non-blank name. - SPA `getAll()` never sends `institutionKey` → lists ALL institutions; `create()` never sends it → rows saved with `institution_key = NULL`. - Edit locks `name` (SPA sends only `{description, content}` on PUT). - Fleet signer writes patch key `signature` over raw `script`; agent reads `scriptSignature` + base64 `scriptContent` — key/format mismatch (see uncertainties). ## Do NOT - Do NOT claim scripts reach ATMs via this module's Push endpoint — it's a stub. - Do NOT look for a Kafka topic or `device_summary` mirror for scripts — none exist. - Do NOT expect institution scoping from the UI — it lists/creates unscoped. - Do NOT search hiveops-fleet for `/api/fleet/scripts` — that path is a devices controller. - Do NOT rely on backend name-extension validation.