Commit Graph

283 Commits

Author SHA1 Message Date
Nyk 5c873a0d2c fix(openapi): add GET /api/frameworks to spec
Fixes API contract parity check in CI.
2026-03-21 22:35:41 +07:00
Nyk 9cac9eb362 chore: merge main, resolve migration conflict
Renumber spawn_history → 044, dispatch_attempts → 045 to follow
043_hash_session_tokens from main.
2026-03-21 22:33:26 +07:00
Nyk bf87864a96 fix: CI typecheck error + standalone bind address
- Fix TS2339 in mcp-server.spec.ts (content.task access on string type)
- Default HOSTNAME=0.0.0.0 in start-standalone.sh for external access

Fixes #465, unblocks docker-publish workflow (#464)
2026-03-21 22:29:44 +07:00
Nyk 2d171ad464 fix: task routing stuck issues + k8s agent visibility
- Add stale task watchdog (requeueStaleTasks) to scheduler — detects
  in_progress tasks with offline agents and requeues or fails them
- Fix Aegis rejection loop: rejected tasks now requeue to 'assigned'
  instead of staying in 'in_progress', with max 3 retries before failing
- Track dispatch_attempts on tasks (migration 044) to prevent infinite
  retry loops — tasks fail after 5 dispatch attempts
- Include error_message and reason in SSE event broadcasts so UI can
  show why a task reverted
- Atomic task queue claim: replace SELECT-then-UPDATE race with single
  UPDATE...RETURNING statement
- Gateway agent auto-registration: POST/PUT /api/gateways accepts
  optional 'agents' array to upsert agents (k8s sidecar support)
- Document k8s sidecar deployment in docs/deployment.md

Fixes: tasks stuck in assigned, Aegis rejection loops, agents invisible
in k8s sidecar deployments
2026-03-21 22:21:33 +07:00
Nyk dd7d663a36 feat: add framework template adapters 2026-03-21 22:21:18 +07:00
Nyk b8c121ebea fix(test): relax sessions list exit code assertion 2026-03-21 22:04:11 +07:00
Nyk a7ef6a0de5 fix(openapi): complete parity burn-down — 0 ignored entries remaining
Add OpenAPI specs for all 56 previously-ignored API operations:

Methods added to existing paths (15):
- backup (GET, DELETE), agents/sync, cleanup, integrations (PUT, DELETE),
  logs (POST), memory (DELETE), notifications (PUT, DELETE, deliver),
  pipelines/run, spawn, standup, super/provision-jobs/{id}

New paths (41 operations across 28 paths):
- agents/evals, agents/optimize, channels, claude-tasks, gateways/discover,
  gateways/health/history, github/sync, gnap, hermes (+ memory, tasks),
  index, local/agents-doc, local/flight-deck, local/terminal,
  memory/context, memory/graph, memory/health, memory/links, memory/process,
  nodes, projects/{id}/agents, schedule-parse, security-audit, security-scan
  (+ agent, fix), super/os-users, system-monitor, auth/google/disconnect,
  releases/update

Parity ignore list is now empty (was 66 entries at branch start).
Route coverage: 240/241 (only untracked GET /api/frameworks remains).
2026-03-21 21:58:29 +07:00
Nyk f12aac13c3 feat: platform hardening — spawn history, auth warnings, security docs
FR-D1: Add least-privilege auth guidance to SECURITY-HARDENING.md
  - Agent-scoped keys vs global API key comparison
  - Auth hierarchy table (scoped key > global key > session > proxy)
  - CLI examples for creating scoped keys
  - Monitoring guidance for global key usage

FR-D2: Log security event when global admin API key is used
  - Emits 'global_api_key_used' event to audit trail
  - Hints toward agent-scoped keys for least-privilege

FR-D3: Add durable spawn history persistence
  - New migration 043_spawn_history with indexed table
  - spawn-history.ts with recordSpawnStart/Finish, getSpawnHistory,
    getSpawnStats functions
  - Replaces log-scraping fallback with DB-backed tracking

FR-D4: Document rate-limit backend strategy
  - Current in-memory Map approach documented
  - Pluggable backend plan for multi-instance (Redis, SQLite WAL)
  - Per-agent rate limiter details documented

Also fixes MCP test type annotation (content: string → any).
2026-03-21 21:52:12 +07:00
Nyk 06cfb3d9db feat(tui): add terminal dashboard for Mission Control
Zero-dependency TUI using raw ANSI escape codes. Shows:
- System health status with connection indicator
- Agents panel (sorted by status, with last heartbeat)
- Tasks panel (recent tasks with status and assignee)
- Token costs summary (24h)

Keyboard controls:
- r: refresh now
- a: focus agents panel
- t: focus tasks panel
- w: wake first sleeping agent
- q/Esc: quit

Auto-refreshes every 5s (configurable with --refresh flag).
Uses same profile/auth system as CLI and MCP server.

Run with: pnpm mc:tui
2026-03-21 21:46:45 +07:00
Nyk a9d9005bac docs: add agent control interfaces section to CLAUDE.md 2026-03-21 21:41:36 +07:00
Nyk 7994aa6c6c fix(openapi): burn down 7 parity mismatches (66 → 59 ignored)
Add OpenAPI specs for 7 routes that the CLI/MCP server depend on:

- DELETE /api/agents/{id}/memory — agent memory clear
- GET /api/tokens/by-agent — per-agent cost breakdown
- POST /api/tokens/rotate — API key rotation
- POST /api/agents/register — agent self-registration
- PATCH /api/auth/me — self-service profile update
- GET /api/tasks/outcomes — task outcome analytics
- GET /api/tasks/regression — regression comparison metrics

Remove corresponding entries from the parity ignore list.
2026-03-21 21:35:27 +07:00
Nyk 5cd515105e test: add CLI and MCP server integration tests (38 new e2e tests)
CLI tests cover:
- Help/usage output and exit codes
- Unknown group/action handling
- Missing required flag validation
- Status health/overview
- Agent list, get, heartbeat lifecycle
- Agent memory set/get
- Agent attribution
- Task list, queue polling, comments add/list
- Sessions, tokens, skills, cron, connect list
- Raw passthrough

MCP server tests cover:
- Protocol: initialize handshake, tools/list, ping, unknown method
- Tool schema validation (all 35 tools have name, description, schema)
- Unknown tool error handling
- mc_health and mc_dashboard
- Agent tools: list, heartbeat, write/read/clear memory
- Task tools: list, poll queue, create, add comment, list comments
- Token stats, skills list, cron list

Total e2e: 472 → 510 (all passing)
2026-03-21 21:14:59 +07:00
Nyk b8e04864cd chore: chmod +x CLI and MCP server scripts 2026-03-21 20:10:18 +07:00
Nyk 59f7f0d720 feat(mcp): add Mission Control MCP server for agent-native tool access
Zero-dependency MCP server (stdio transport, JSON-RPC 2.0) that wraps
the Mission Control REST API as 35 MCP tools. Agents can add it with:

  claude mcp add mission-control -- node scripts/mc-mcp-server.cjs

Tools cover the full agent workflow:
- Agent lifecycle: list, get, heartbeat, wake, diagnostics, attribution
- Memory & Soul: read/write/clear working memory, read/write SOUL,
  list/retrieve SOUL templates
- Tasks: CRUD, queue polling, broadcast, comments (list/add)
- Sessions: list, control, continue, transcript
- Connections: list, register
- Tokens & Costs: stats, agent-costs, costs-by-agent
- Skills: list, read content
- Cron: list jobs
- Status: health, dashboard, overview

Auth uses the same profile system as the CLI (~/.mission-control/profiles/)
or MC_URL/MC_API_KEY/MC_COOKIE environment variables.

Also adds `mc` and `mc:mcp` package.json scripts.
2026-03-21 19:42:58 +07:00
Nyk f2747b5330 feat(cli): v2 rewrite with full command coverage and lazy evaluation
- Fix eager required() evaluation bug (route map was evaluated at parse
  time, causing unrelated commands to crash on missing flags)
- Refactor to lazy command handler pattern (functions only execute when
  their group+action matches)
- Add compound subcommands: agents memory get|set|clear, agents soul
  get|set|templates, tasks comments list|add
- Add missing PRD commands: agents attribution, tasks broadcast,
  sessions transcript, tokens agent-costs/task-costs/trends/export/rotate,
  status health/overview/dashboard/gateway/models/capabilities,
  export audit/tasks/activities/pipelines
- Add proper SSE streaming for events watch (NDJSON in --json mode,
  human-readable otherwise, graceful Ctrl+C shutdown)
- Add optional() helper for flags with defaults
- Update docs/cli-agent-control.md with full v2 command reference
2026-03-21 19:30:28 +07:00
nyk dbf9ab1423
Merge pull request #463 from builderz-labs/fix/open-issues-458-461
fix: debug panel gateway routes and Docker file permissions (#461, #458)
2026-03-21 18:52:24 +07:00
Nyk 9a4c7c7b3c fix: update debug panel gateway routes and Docker file permissions (#461, #458)
- Debug panel now probes both legacy (/api/status, /api/health) and current
  OpenClaw routes (/healthz, /health, /ready) with automatic fallback.
  Returns probedPath in response so admins know which route succeeded.
- POST proxy allowlist updated to include current gateway health routes.
- Path validation relaxed from /api/ prefix to / prefix (health routes
  don't use /api/).
- Dockerfile: chmod 755 entrypoint (was +x/711, shell needs read permission)
  and chmod -R a+rX on public/ and src/ for nextjs user access.
2026-03-21 18:51:40 +07:00
nyk 311c7b06ab
Merge pull request #462 from builderz-labs/fix/security-audit-hardening
fix: security hardening from audit
2026-03-21 18:47:07 +07:00
Nyk afa8e9dacb fix: security hardening from audit (closes #460)
- Hash session tokens (SHA-256) before storing in DB; migration for existing tokens
- Enforce 12-char password minimum on self-service change (was 8, creation was 12)
- Increase scrypt cost N=16384→65536 with progressive rehash on login
- Add MC_PROXY_AUTH_TRUSTED_IPS to restrict proxy auth header spoofing
- Enable HSTS by default in production (opt-out via MC_DISABLE_HSTS=1)
- Restrict debug endpoint to allowlisted gateway API paths (SSRF prevention)
- Default session cookie secure=true in production
- Gate MC_DISABLE_RATE_LIMIT on NODE_ENV !== 'production'
- Remove password value from insecure-default log warning
- chmod 600 generated secrets file in Docker entrypoint
2026-03-21 18:45:48 +07:00
Nyk 7b104952cc chore(api): tranche C parity burn-down and CLI integration scaffolding 2026-03-20 23:53:02 +07:00
nyk 69e89a97a1
fix: add timeout/retry for setup status check (#457)
- add bounded timeout+retry helper for /api/setup checks
- show actionable setup error state with Retry button
- avoid blank-screen fallback when setup status check fails
- add unit tests for retry helper

Fixes #456
2026-03-19 23:59:02 +07:00
danielaustralia1 465cd96107
feat: add system monitor panel (btop-style) (#455)
* feat: add system monitor panel with live CPU, memory, disk, and GPU metrics

New btop-inspired monitoring page in the OBSERVE sidebar group.
Polls /api/system-monitor every 2s and renders rolling Recharts area
charts for CPU/memory/GPU and progress bars for disk usage.

* feat: add network I/O monitoring to system monitor panel

Add live network throughput (rx/tx bytes/sec) as a dual area chart.
API returns cumulative byte counters per interface (stateless), frontend
computes rates from deltas between 2s polls. Supports Linux (/proc/net/dev)
and macOS (netstat -ib).

* feat: add top processes list to system monitor

Shows top 8 processes by CPU usage in a compact table with CPU%, Mem%,
and RSS columns. Color-codes high usage values. Uses ps on both Linux
and macOS with fallback for platforms without --sort support.

* fix: normalize process CPU% to 0-100 and filter out ps itself

CPU% from ps is per-core (e.g. 200% on 4 cores), now divided by core
count to show total system percentage. Also filters out the ps command
that briefly appears while collecting process data.

---------

Co-authored-by: Dan <github@bookkept.com.au>
2026-03-19 22:40:55 +07:00
danielaustralia1 8431992866
fix: sync agent live statuses from gateway sessions during scheduled sync (#454)
Closes #450

Co-authored-by: Dan <github@bookkept.com.au>
2026-03-19 20:48:28 +07:00
danielaustralia1 f872aac504
feat: add hide/unhide agents from UI (#453)
Add ability to hide agents from the dashboard without deleting them.
Hidden agents still receive heartbeats and exist in the DB — they are
purely hidden from the default UI view.

- Migration 042: adds `hidden` column to agents table
- API: POST/DELETE /api/agents/[id]/hide to toggle visibility
- GET /api/agents filters hidden by default, ?show_hidden=true to include
- UI: "Show hidden" toggle in panel header, Hide/Unhide button on cards

Co-authored-by: Dan <github@bookkept.com.au>
2026-03-19 20:48:25 +07:00
danielaustralia1 51a51a0ba2
fix: enable vertical scrolling on tasks board columns (#452)
Add min-h-0 to the kanban board flex container and its column children
so that overflow-y-auto on column bodies can actually trigger. Without
this, flexbox min-height:auto causes containers to grow unbounded
instead of constraining height and enabling scroll.

Fixes #376

Co-authored-by: Dan <github@bookkept.com.au>
2026-03-19 20:48:15 +07:00
Nyk 4ddb4d0268 chore: release v2.0.1 2026-03-18 20:48:26 +07:00
nyk 8517d5e896
fix: support gateway defaults for spawn and Docker Hub publish
- make /api/spawn compatible with gateway-managed default models
- add regression coverage for gateway dashboard registration
- publish official multi-arch images to Docker Hub when configured
2026-03-18 19:36:04 +07:00
nyk fc4384bba9
feat: add awaiting_owner task status detection (#428)
Add awaiting_owner column to task board with keyword-based detection
for tasks requiring human action. Tasks matching keywords like
"waiting for", "needs human", "approval needed" are automatically
placed in a dedicated column with orange styling.

Supersedes #397
2026-03-17 13:52:37 +07:00
nyk d0cd8701c7
feat: add Dunk It button animation with CSS transitions (#427)
Add a CSS-only Dunk It button to task cards with a 4-phase state
machine (idle, success, error, dismissing). Uses inline CSS
transitions for animations with no external dependencies.

Supersedes #373
2026-03-17 13:52:34 +07:00
nyk 2f2531f3d1
feat: discover and display per-agent workspace skill roots (#426)
Dynamically scan workspace-* directories under the openclaw state dir
to discover per-agent skill roots. Display them in the Skills Hub with
agent-specific labels and violet badge styling.

Closes #412
Supersedes #413
2026-03-17 13:52:27 +07:00
nyk 4671946e97
fix: remove CSP nonce from style-src to unblock reagraph canvas (#425)
Replace style-src nonce directive with unsafe-inline to support
reagraph's runtime <style> injection. Add style-src-elem and
style-src-attr directives for CSP Level 3 compliance. Extend
fitNodesInView retries from 2 to 4 for more reliable canvas sizing.

Closes #414
Supersedes #415
2026-03-17 13:52:09 +07:00
nyk 00a22a2e24
fix: use CSPRNG for password generation in install.ps1 (#424)
Replace Get-Random (System.Random, clock-seeded) with RandomNumberGenerator in Get-RandomPassword to match the CSPRNG already used by Get-RandomHex.
2026-03-17 12:54:55 +07:00
Lucas Wiessel a4fefc882e
feat: add Windows PowerShell installer (#423)
Adds install.ps1 — a PowerShell port of install.sh for Windows users. Supports local and Docker deployment modes with secure credential generation, standalone server setup, and OpenClaw fleet checks. Adds Windows install section to README.
2026-03-17 12:51:10 +07:00
Brixyy ff53415014
fix(i18n): add missing logViewer, pipeline, debug namespaces (#420)
Adds 70 missing translation keys across 3 namespaces (logViewer, pipeline, debug) to messages/en.json. These namespaces are referenced by existing components but were absent, causing raw keys to render.\n\nFixes #416
2026-03-17 12:43:19 +07:00
Jonathan Gill ccf3f3fb01
fix(i18n): add missing agentDetail translation keys (#409)
Adds all missing agentDetail.* keys to messages/en.json — role, model, status, stats, action buttons, sandbox config, SOUL/identity/memory editor, sub-agent/tool/workspace management.
2026-03-16 22:24:42 +07:00
Brixyy b908c40ba5
fix: add workspace skill root to skill-sync.ts (#411)
Fixes #410 — getSkillRoots() in skill-sync.ts was not updated when #408 added workspace support to route.ts, causing the scheduler sync to never populate workspace skills (always showing 0).
2026-03-16 22:24:31 +07:00
nyk 6f1237704a
feat: add workspace skill root and root-based filtering to Skills Hub (#408)
- Add `workspace` skill root (~/.openclaw/workspace/skills) for
  workspace-local skill discovery alongside the existing 5 roots
- Make group cards clickable to filter the installed skills list by root
- Add `workspace` as valid target for skill creation and registry install
- Add `showAllRoots` i18n key to all 10 locale files

Closes #364
2026-03-16 12:37:51 +07:00
nyk 17bf0761f5
fix: migrate clawdbot CLI calls to gateway RPC and improve session labels (#407)
Replace all `runClawdbot(['-c', ...])` invocations with
`callOpenClawGateway()` RPC calls in session control, spawn, and delete
routes. This eliminates the deprecated CLI dependency and uses the
structured gateway protocol instead.

Also add `formatSessionLabel()` helper and `useAgentSessions()` hook to
task-board-panel for better session dropdown display labels.

Closes #401, closes #406
2026-03-16 12:18:12 +07:00
nyk 85b4184aa9
feat: GNAP sync engine for git-native task persistence (#396)
Implements Phase 1 of GNAP (Git-Native Agent Protocol) integration:
- SQLite stays primary, GNAP repo is an optional sync target
- Push task create/update/delete to .gnap/tasks/{id}.json with git commits
- Status/priority mapping between MC and GNAP formats
- Management API at /api/gnap (status, init, manual sync)
- GNAP badge in task board header with click-to-sync
- 15 unit tests covering mapping, init, push, remove, pull, and status

Enable with GNAP_ENABLED=true in .env. Follows the same fire-and-forget
pattern as the existing GitHub sync engine.

Closes #374
Supersedes #389
2026-03-16 12:07:39 +07:00
nyk d87307a4f8
feat: hybrid mode — show gateway + local sessions simultaneously (#392)
Always merge both gateway and local (Claude Code, Codex, Hermes) sessions
in the sessions API instead of gating on `include_local`. The conversation
list now renders all sources unconditionally, using each session's `source`
field for display logic rather than the global `dashboardMode`.

- Add `localSessionsAvailable` store flag, set from capabilities `claudeHome`
- Remove `include_local` query param and early-return in sessions API
- Remove source-based filter and `dashboardMode` branching in conversation list
- Show both gateway and local active/recent groups when data exists
2026-03-16 12:05:41 +07:00
HonzysClawdbot 301ee9cdd8
fix(gateway): probe /api/health instead of root URL (#394)
* fix(gateway): probe /api/health instead of root URL for health checks (#390)

The server-side gateway health probe was fetching the root URL (/)
which returns HTTP 400 on OpenClaw 2026.3.13 gateways. The gateway
exposes a dedicated /api/health endpoint that returns 200 with status
info.

The WebSocket ping RPC 'unknown method' issue is already handled —
websocket.ts detects the INVALID_REQUEST and falls back to passive
heartbeat mode. The actual bug was this HTTP probe hitting the wrong
endpoint.

Fixes #390

* fix(gateway): ensure gateways table exists before health probe

The gateways table is created lazily by the gateways API (ensureTable).
The health route was querying it directly without CREATE IF NOT EXISTS,
causing SqliteError: no such table: gateways in fresh databases (E2E tests,
Docker first-boot).

Add ensureGatewaysTable() inline to mirror the pattern in route.ts.

* fix: update health-utils test to match /api/health probe path

The test file has its own copy of buildGatewayProbeUrl — update it to
append /api/health instead of / to match the route.ts change.

---------

Co-authored-by: Nyk <0xnykcd@googlemail.com>
2026-03-16 11:55:56 +07:00
HonzysClawdbot 0acf7daf32
feat: task assignment session targeting (#399)
* feat: add task session targeting - dispatch tasks to specific agent sessions (#395)

When assigning a task to an agent, users can now optionally select an
existing session to dispatch the task to instead of creating a new one.

Changes:
- task-dispatch.ts: When target_session is set in task metadata, use
  gateway chat.send to dispatch to that specific session instead of
  creating a new one via call agent
- task-board-panel.tsx: Add session selector dropdown in both Create
  and Edit task modals that appears when an agent is selected and has
  active sessions
- store/index.ts: Add agent and channel fields to Session interface

Closes #395

* fix(gateway): ensure gateways table exists before health probe

The gateways table is created lazily by the gateways API (ensureTable).
The health route was querying it directly without CREATE IF NOT EXISTS,
causing SqliteError: no such table: gateways in fresh databases (E2E tests,
Docker first-boot).

Add ensureGatewaysTable() inline to mirror the pattern in route.ts.
2026-03-16 11:34:28 +07:00
nyk e7aa7e6a91
fix: reduce server memory footprint (#405)
* fix: reduce server memory footprint across session parsing, caching, and rate limiting

- Stream-parse Claude JSONL session files instead of loading entire files into memory
- Add 50MB file size cap to skip oversized session transcripts
- Add 30s TTL cache to getAllGatewaySessions() to avoid redundant disk reads per scheduler tick
- Cap rate limiter maps at 10,000 entries with oldest-first eviction
- Add request.signal abort listener to SSE route for defense-in-depth cleanup
- Add test for rate limiter maxEntries eviction behavior

* fix: address audit findings across all memory-fix files

claude-sessions.ts:
- Wrap readline loop in try/finally to ensure rl.close() on error paths
- Guard statSync in file loop to handle files deleted between readdir and stat
- Fix variable shadowing: rename inner `now` to `nowSec` to avoid confusion
- Update throttle timestamp on empty scan results (prevents repeated disk scans)
- Skip sidechain-only sessions (zero user+assistant messages)

sessions.ts:
- Decouple `active` flag from cache — compute at read time to prevent stale data
- Remove activeWithinMs from cache key to eliminate cache thrashing between
  callers using different windows (Infinity vs default)
- Add invalidateSessionCache() and call it after pruneGatewaySessionsOlderThan

events/route.ts:
- Null out cleanup after first call to prevent double-invoke
- Remove unnecessary `if (request.signal)` guard (always defined on NextRequest)

rate-limit.test.ts:
- Rewrite eviction test with maxRequests=1 to actually prove eviction occurred
- Add assertion that non-evicted entries remain tracked
2026-03-16 11:30:02 +07:00
HonzysClawdbot b6717b8bf8
fix: remove duplicate task title constraint, improve delete handling and scrolling (#386)
- Remove duplicate title check from POST /api/tasks (closes #368)\n- Scope recurring tasks duplicate check by project_id\n- Fix task deletion error handling — show errors to user (closes #369)\n- Enable vertical scrolling on Kanban board (closes #376)\n- Refactor nodes route to use RPC via callOpenClawGateway\n- Handle read-only filesystem in gateway config registration\n- Add screenshot-drift CI workflow and guide\n- Docker compose: add host-gateway for reaching host gateway
2026-03-15 18:31:15 +07:00
Héctor Arriola d980fc1a4e
fix: use gateway call agent for notification delivery (#381)
Switches notification delivery from sessions_send to gateway call agent command. No longer requires session_key — uses agent name (recipient) directly. Timeout increased 10s to 30s.
2026-03-15 18:31:05 +07:00
Brixyy 8d671cb782
fix: scope memory health diagnostics to allowed prefixes (#367)
When memoryAllowedPrefixes is configured, scan only those subdirectories instead of the entire MEMORY_PATH. Falls back to full scan if no prefixes are set.\n\nCloses #366
2026-03-15 18:30:46 +07:00
Héctor Arriola c537f31088
fix(i18n): add missing translations for agentHistory, documents, gatewayConfig (#378)
Adds translation keys to en.json and es.json for agentHistory, documents, and gatewayConfig namespaces.
2026-03-15 18:30:43 +07:00
Héctor Arriola d89183ee48
fix: fetch notifications immediately when recipient changes (#380)
Notifications were stale until the next poll after switching recipients. Now fetchNotifications() is called immediately on recipient change.
2026-03-15 18:29:21 +07:00
nyk 2449363868
fix: stop forcing dangerouslyDisableDeviceAuth + fix exec security value
- Remove unconditional `dangerouslyDisableDeviceAuth = true` from MC
  origin registration. MC should only add its origin to allowedOrigins,
  not silently downgrade the gateway's device auth security posture.

- Replace invalid `sandbox` value with `allowlist` in security scan
  and auto-fix for `tools.exec.security`. Current OpenClaw validates
  only: deny, allowlist, full. The old `sandbox` value was rejected.

Closes #357, closes #356
2026-03-14 21:44:11 +07:00
Brixyy 3525c4543f
fix(i18n): add missing agentSquadPhase3 translation namespace 2026-03-14 21:31:42 +07:00