This page describes how the KubeStellar Console project is developed, tested, and maintained. It covers the hybrid human + AI-agentic model, issue lifecycle, PR requirements, and how to contribute.
KubeStellar Console uses a hybrid human + AI-agentic development model. Human contributors handle design decisions, architecture changes, and complex features, while an automated agentic pipeline handles routine bug fixes, documentation updates, and well-scoped improvements.
This approach enables:
For the concrete quality-control system that catches AI mistakes, prevents repeat mistakes, and handles failed or rejected PRs, see Agentic Quality Controls.
cmd/console/ Server entry point
cmd/kc-agent/ Local agent (bridges browser to kubeconfig + MCP)
pkg/agent/ AI providers (Claude, OpenAI, Gemini)
pkg/api/ HTTP/WS server + handlers
pkg/mcp/ MCP bridge to Kubernetes
pkg/store/ SQLite database layer
web/src/ React + TypeScript frontend
components/cards/ Dashboard card components
hooks/ Data fetching hooks (useCached*)
lib/ Utilities, card registry, demo data
deploy/helm/ Helm chart
Frontend:
Backend:
log/slog (structured logging)Deployment:
The console has two backend implementations:
Both implement the same API contract. When adding Go API handlers, check if a corresponding Netlify Function needs updating in web/netlify/functions/*.mts.
Routes WITH Netlify parity (public/stateless data):
/api/youtube/* — YouTube content feed/api/medium/* — Blog feed/api/rewards/* — GitHub contributor rewards/api/missions/* — Mission catalog/api/github-pipelines — CI/CD status/api/analytics-* — Analytics endpointsRoutes WITHOUT Netlify parity (backend-only, require K8s/DB/agent):
/api/settings, /api/persistence/* — SQLite database/api/dashboards/*, /api/cards/* — Dashboard CRUD/api/namespaces, /api/rbac/* — Live cluster access/api/agent/*, /api/kagent/* — Local agent bridgeIssues reach the project through two paths:
kubestellar/consoleIssues are classified by complexity:
| Label | Complexity | Typical Scope | Handler |
|---|---|---|---|
S | Simple | Typo, label fix, config tweak | Agentic pipeline |
M | Medium | Bug fix, new card, hook change | Agentic pipeline or human |
C | Complex | Architecture change, new feature | Human contributor |
Classification is performed automatically based on issue content, labels, and historical patterns. Maintainers can override classification at any time.
good first issue are reserved for human contributorsagentic are eligible for automated processingThe console project employs an automated agentic pipeline that processes eligible issues end-to-end.
┌──────────────┐ ┌─────────────┐ ┌──────────┐
Issue Filed │────▶│ Scanner Agent │────▶│ Fix Agent │────▶│ PR Open │
└──────────────┘ └─────────────┘ └──────────┘
│ │
Reads filtered Creates worktree
issue list Makes fix, commits
(S/M classified) Pushes branch
S or M complexityfix/<issue-number>)Fixes #NNNauthored-by: bot for visibilityEvery PR gets automatically labeled with a tier/* label based on which files it touches. This determines review scrutiny.
| Tier | Label | What it covers | Review Level |
|---|---|---|---|
| 0 | tier/0-automatic | Lockfiles, go.sum, docs (*.md), i18n files, snapshots, generated artifacts | Fast-track eligible |
| 1 | tier/1-lightweight | Test-only changes, editor config (.prettierrc, .editorconfig) | Lightweight review |
| 2 | tier/2-standard | Everything not in other tiers | Standard review |
| 3 | tier/3-restricted | CODEOWNERS, workflows, auth code, security docs, Helm RBAC | Enhanced scrutiny |
Classification rules:
This system enables fast iteration on safe changes while ensuring security-sensitive changes get appropriate review.
Manual coding PRs are discouraged because:
isDemoData wiring, useCardLoadingState, locale strings)All PRs — human or AI — must pass the same 9 CI gates before merge. There is no separate path for AI-generated code.
The most valuable contributions are tests:
Tests define expected behavior — agents then implement the code to make tests pass. A failing test PR is more useful than a code PR.
If you want to contribute code, use of the supported agents:
| Agent | Model | Status | Notes |
|---|---|---|---|
| Claude Code | Claude Opus 4.5/4.6 | Strongly recommended | Knows full codebase, all patterns, card rules |
| GitHub Copilot | Multiple | Supported | Used for automated PR fixes |
| Google Gemini | Gemini models | Supported | Code generation |
| OpenAI Codex | GPT models | Supported | Code generation |
Install Claude Code:
npm install -g @anthropic-ai/claude-code
New monitoring cards for CNCF projects (Karmada, Falco, KEDA, etc.) belong in kubestellar/console-marketplace, not in the main console repo. The marketplace loads cards on-demand to avoid bundle bloat.
PRs adding card components to web/src/components/cards/ will be redirected to console-marketplace.
Every pull request — whether from a human or an agent — must meet these requirements:
All commits must include a Signed-off-by trailer for Developer Certificate of Origin compliance:
git commit -s -m "✨ Add cluster health polling"
<emoji> <Short description in imperative mood (under 72 chars)>
<Optional longer description>
Signed-off-by: Name <email>
| Emoji | Type | When to Use |
|---|---|---|
| ✨ | Feature | New functionality |
| 🐛 | Bug fix | Fixing broken behavior |
| 📖 | Docs | Documentation changes |
| 📝 | Proposal | Design proposals |
| ⚠️ | Breaking change | API or behavior changes |
| 🌱 | Other | Tests, CI, refactoring, tooling |
The first line of the PR body must be Fixes #NNN where NNN is the issue number. This ensures GitHub automatically closes the issue when the PR is merged.
All of the following checks must pass:
PRs must be rebased on main before merge (no merge commits):
git fetch origin main
git rebase origin/main
End-to-end tests in web/e2e/ verify full user flows:
web/e2e/visual/) — screenshot comparisons catch unintended layout changesBest practices:
expect(locator).toBeVisible() over waitForTimeout()test('card shows cached data on warm return', ...)Go tests in pkg/ and cmd/ cover:
Best practices:
require for fatal assertions, assert for non-fatalAny PR modifying UI must:
web/e2e/visual/Mission KB YAML files are validated against a JSON schema on every PR to prevent malformed mission definitions from reaching production.
any, no implicit any(data || []) before .map(), .filter(), .join()t() from react-i18next, never raw stringscn() utility for merging classNamestext-foreground, bg-card, etc., not hardcoded colorslog/slogmake([]T, 0) not var x []T (nil slices serialize as null)docs/security/SECURITY-AI.md# Clone the repository
git clone https://github.com/kubestellar/console.git
cd console
# Start in mock mode (no OAuth required)
./start-dev.sh
# Or with GitHub OAuth (requires .env with GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET)
./startup-oauth.sh
| Service | Port |
|---|---|
| Frontend (Vite) | 5174 |
| Backend (Go/Fiber) | 8080 |
| KC Agent WebSocket | 8585 |
Before opening a PR, ensure build and lint pass:
cd web
npm run build
npm run lint
These patterns are mandatory for all code contributions. Violations will cause CI failures or runtime bugs.
Every dashboard card component must follow these rules:
Wire isDemoData and isRefreshing — destructure from the cached hook and pass to useCardLoadingState():
const { data, isLoading, isRefreshing, isDemoData, isFailed } = useCachedPods()
useCardLoadingState({
isLoading,
isRefreshing, // Required for refresh icon animation
isDemoData, // Required for Demo badge + yellow outline
hasAnyData: data.length > 0,
isFailed,
})
Never show demo data during loading — hook’s isDemoFallback must be false while isLoading is true
Always use useCache / useCached* hooks for data fetching — never raw fetch() in card components
Array safety — guard all array operations with (data || []) before .map(), .filter(), .join(), etc.
Always use DeduplicatedClusters() when iterating clusters. Multiple kubeconfig contexts can point to the same physical cluster — without dedup, resources get listed/counted twice.
clusters := DeduplicatedClusters(contexts)
for _, cluster := range clusters {
// safe to iterate
}
Every numeric literal must be a named constant:
// WRONG
setTimeout(fn, 5000)
// CORRECT
const WS_RECONNECT_MS = 5000
setTimeout(fn, WS_RECONNECT_MS)
This applies to timeouts, intervals, percentages, retries, pixel values — everything.
Never hardcode API keys, tokens, or credentials. Use environment variables:
os.Getenv()import.meta.env.VITE_*.env (gitignored) or runtime env varsBefore adding any workflow that calls an LLM, read the AI Security Guide covering:
Fork the kubestellar/console repository
Clone your fork and create a branch from main:
git checkout -b fix/your-issue-number
Make changes following the code standards above
Validate locally:
cd web && npm run build && npm run lint
Commit with DCO sign-off and emoji prefix:
git commit -s -m "🐛 Fix cluster count in sidebar"
Push and open a PR:
Fixes #NNNAddress review feedback if any, then rebase if needed
question labelThe development methodology itself is a living document and continuously evolving.
If you encounter issues with the development process, methodology, or tooling:
kubestellar/console repository with label process or meta/feedback to report workflow frictionkubestellar/docs with label kind/documentationExamples of process issues:
This page lives in the kubestellar/docs repository at docs/content/console/development.md. To suggest changes:
git clone https://github.com/kubestellar/docs.git
cd docs
git checkout -b update-console-dev-docs
# Edit docs/content/console/development.md
git commit -s -m "📖 Update console development methodology"
git push origin update-console-dev-docs
# Open PR against kubestellar/docs
PRs to improve this documentation are always welcome and do not require prior discussion.
The console follows continuous deployment — changes merged to main are deployed to the hosted instance at console.kubestellar.io via Netlify.