GET /api/tickets/export — portable JSON dump of all environments,
tickets, and attachments (version 1 format with _id/_parent_id for
relationship reconstruction).
POST /api/tickets/import — additive import; upserts environments by
prefix, creates tickets preserving parent-child structure, creates
attachments. Compatible with the matching Domus implementation so
tickets can be transferred between the two systems.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- mcp_server.py: use shlex.quote() on all shell-interpolated values to
prevent command injection via ticket title/description/human_id
- corvid/router.py: add alphanumeric-only regex validation for environment
prefix; add full ancestor cycle detection before setting parent_id;
import re
- Add SECURITY_REVIEW.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Allows agents to set an explicit startup script without triggering a
title/description/type change. Auto-generation still fires when those
fields change and startup_script is not provided.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Toggle now shows whenever a ticket has children (not gated on local filter visibility)
- showDetail() is async and fetches from API when ticket isn't in the local array,
caching results in extraTickets so subsequent navigation and row rendering work
- Sidepane async child fetch stores results in extraTickets for the same reason
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
scalar_one_or_none() raises MultipleResultsFound when more than one environment
exists. Use scalars().first() to pick the lowest-ID environment as the default.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Children outside the active status filter weren't in the local tickets array, causing
the row-level child count/toggle to be hidden and the sidepane to fall back to "#ID"
labels. Count badge now uses t.child_ids.length directly; sidepane fetches any missing
children via /api/tickets/{id} asynchronously.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Allows reassigning tickets between environments (e.g. HOME → GAME).
create_ticket and list_tickets already supported environment_id.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Setuptools was omitting non-Python files; add package-data glob so
templates and static assets are present after pip install.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
tickets_base.html is the canonical implementation; tickets.html just
extends it with no overrides, used by the standalone app.
The dashboard can now extend tickets_base.html directly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add corvid.svg — stylised blue crow on dark background
- Mount /static via StaticFiles in main.py
- Wire favicon in base.html
- Add aiofiles dep (required by StaticFiles)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Use hmac.compare_digest for constant-time key check (router.py)
- Move POSTGRES_PASSWORD out of docker-compose.yml into .env (was a
public default "corvid" now that the repo is public)
- Add .env.example with placeholder values
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- corvid/templates/base.html: simplified nav (Corvid logo, Tickets link only),
no user footer, no SSO — identical dark theme and component styles
- corvid/templates/tickets.html: copied verbatim from homelab-dashboard
(all API paths are relative, no user-specific references)
- corvid/main.py: /tickets HTML route + / redirect; templates loaded from
package dir so they work whether installed or run from source
- corvid/router.py: allow open access when TICKETS_API_KEY is not set
(local/dev mode) — set the key to require auth for external access
- pyproject.toml: add jinja2>=3.1 dependency
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extracts the ticket/attachment system into a reusable pip-installable package.
Centralises homelab MCP server (tickets, attachments, system logs) here.
- corvid package: models, router (make_router factory), config, standalone main
- Alembic migration chain for fresh standalone deployments
- Docker Compose for standalone deployment (port 8090)
- mcp_server.py: moved from homelab-dashboard, CORVID_REPO_PATH configurable
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>