Skip to content

HarperFast/Developer-Relations-Agents

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

93 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mission Control

The single pane of glass over Harper's DevRel content factory — a control room that shows, in real time, what the agent crew (Kakashi, Jiraiya, Sasuke, Naruto, Shikamaru) is doing, what's queued, what shipped, what it scheduled, and whether any of those claims are actually true.

Mission Control renders only what is actually in the database — there is no mock data anywhere. Empty panels tell you what's missing and which endpoint fills them. The agents run on Claude, do real work (draft content, build reference repos, research the market, reply to community issues), and write everything back through the same REST APIs the UI reads.


Table of contents


Getting it up and running

Prerequisites

  • Node 24.13.1 (see .nvmrcnvm use picks it up).
  • Harper is installed as a dev dependency (harper ^5.1.9), so no global install is needed.
  • An Anthropic API key to actually run the agents (optional for just browsing the UI). Provide it via the ANTHROPIC_API_KEY env var or connect it in Settings at runtime.

Install and run

npm install
npm run dev             # harper dev . — app on http://localhost:9926

Open http://localhost:9926. On first boot the app seeds the crew roster and mission statement (configuration, not activity), so agents start away with empty panels until they do work.

The dev script clears dist/ first. See the ordering note in config.yaml: the static component must be listed before @harperfast/vite, and in dev dist/ must not exist — otherwise REST requests get swallowed instead of falling through to your resources.

Other scripts

npm test                 # unit tests (src/**, resources/** *.test.ts)
npm run test:integration # integration tests via @harperfast/integration-testing
npm run lint             # eslint
npm run build            # vite production build → dist/
npm run start            # harper run . (production: serves the built dist/)
npm run export:projects  # mirror each Project in the DB to projects/<slug>/project.yaml
npm run research         # run a one-off research pass (scripts/run-research.mjs)
npm run deploy           # deploy to Harper Fabric (CLI_TARGET in .env)

Environment

Copy .env.example to .env. The loadEnv directive in config.yaml reads it at boot, so ANTHROPIC_API_KEY / GITHUB_TOKEN resolve from memory with no DB read (avoiding a cold-start race). Recognized vars:

Var Purpose
ANTHROPIC_API_KEY Runs the agents. Falls back to the stored AppSetting if unset.
GITHUB_TOKEN GitHub sync + community sweep + issue push.
CLI_TARGET Harper Fabric cluster URL for npm run deploy.

Project manifests (projects/) — the DB is the source of truth; npm run export:projects mirrors each Project (name, repo, agent map, and issues with their assigned agent) to a git-tracked projects/<slug>/project.yaml at the repo root. A pre-commit hook keeps these current — enable it once per clone:

git config core.hooksPath .githooks   # run from the repo root

The hook re-exports and stages projects/ before each commit; if Harper isn't running it skips silently, so it never blocks a commit. Override the target with HARPER_URL=….


Architecture

Mission Control is a single Harper application that is both the backend and the host for the frontend — one process, one database, no separate API server.

┌──────────────────────────── Harper instance (:9926) ─────────────────────────────┐
│                                                                                   │
│  schemas/*.graphql ──► mission_control database (9 tables, HNSW vector index)     │
│                                                                                   │
│  resources/*.ts  ──►  auto REST + WebSocket endpoints                             │
│     ├─ tables.ts          table extensions (server-side write logic)              │
│     ├─ crew/*             the agent runtime — Claude calls, task loop, triage     │
│     ├─ scheduler.ts       in-process cron chains (declared vs. observed jobs)     │
│     ├─ integrations/*     GitHub, Slack, Google Calendar/Drive                    │
│     ├─ memory/*           vector embeddings for semantic memory search            │
│     ├─ community/*        community-issue sweep                                   │
│     └─ seed.ts            idempotent roster + mission bootstrap                    │
│                                                                                   │
│  static (dist/**)  ──►  serves the built React app                                │
│  @harperfast/vite  ──►  dev server + HMR in `harper dev`, build in `harper run`   │
│                                                                                   │
└───────────────────────────────────────────────────────────────────────────────────┘
        ▲  REST reads / writes + WebSocket live subscriptions
        │
┌───────┴──────────── React 19 SPA (src/) ─────────────┐
│  TanStack Router (hash history) + TanStack Query      │
│  Tailwind v4 + Radix + Harper design tokens           │
│  feature-sliced: features/<name>/ + integrations/api/ │
└───────────────────────────────────────────────────────┘

Key architectural facts:

  • No build step for the backend. Resources are TypeScript loaded directly by Harper's jsResource loader (type-stripping). config.yaml wires the built-in components: rest, graphqlSchema, jsResource, @harperfast/schema-codegen, static, and @harperfast/vite.
  • Schema-first. One GraphQL file defines the tables; the codegen component emits types (schemas/types.ts, schemas/globalTypes.d.ts) so resource code is schema-aware.
  • Endpoints are derived from class names. A Resource subclass named CrewRun registers at /CrewRun. Feature folders re-export their classes through a barrel at the top of resources/ (crew.ts, integrations.ts) so the loader derives the URL from the barrel's directory (root), not the subfolder.
  • Everything is live. Every table has a WebSocket endpoint at its path; the frontend's useLiveTable hook subscribes and re-renders on change.
  • The scheduler runs in-process. resources/scheduler.ts arms setTimeout chains aligned to cron slots, elected onto a single worker thread. It models declared vs. observed work: a ScheduledJob is a claim, a JobRun is the evidence, and the Calendar screen reconciles the two and flags stalled jobs.

Backend module map (resources/)

Path Responsibility
seed.ts Seeds the crew roster + mission + default settings on boot (idempotent).
tables.ts Table extensions — server-side write logic (e.g. WorkItem.post composes titles and pushes GitHub issues).
crew.ts Barrel re-exporting the crew runtime. Implementation in crew/*.
crew/agent.ts runCrewAgent — load persona + model, mark working, call Claude, settle to idle, emit heartbeats. Hosts CrewRun.
crew/tick.ts crewTick — one whole-crew heartbeat. Hosts CrewTick.
crew/orchestration.ts Task-aware runner, autonomous research, and report → task triage (mutually recursive, kept in one module).
crew/triage.ts Kakashi's routing of unrouted board items.
crew/builder.ts / coding-agent.ts The full coding agent (shell + files) for reference-repo builds.
crew/claude.ts The Claude API/SDK call wrapper.
crew/deliverables.ts Persists reviewable outputs (Docs / research reports).
crew/rollup.ts Kakashi's weekly status rollup.
scheduler.ts All recurring jobs (see Scheduled jobs).
integrations/* GitHub sync, Slack digest/context, Google Calendar/Drive OAuth + sync.
memory/* MemoryEntry embeddings (Voyage) and vector search.
community/* Community-issue sweep + reply-task queueing.
settings.ts Secret + preference endpoints (AnthropicKey, GithubToken, VoyageKey, …).

The agent crew

The crew is a fixed roster of five specialists seeded from resources/seed.ts. Each is a CrewAgent record carrying a role, a hand-written system prompt (persona), an autonomy tier, and a Claude model. They all answer from the same shared mission: create content and build runnable reference projects that showcase Harper to its ICP.

Agent Role Model Autonomy What it does
Kakashi 🥷 Chief of Staff / DevRel Lead (orchestrator) claude-sonnet-5 Fully autonomous, internal Holds strategy; maintains one prioritized, deduped work queue; routes incoming signals to the right specialist; triages research reports into assigned tasks; files a weekly status rollup. Directs, never publishes and never works tasks as a specialist.
Jiraiya ✍️ Content claude-opus-4-8 Draft-and-queue Writes long-form, publish-ready articles (~1,200–2,000 words) grounded in Shikamaru's research. Lands drafts in the Content queue for human review — never auto-publishes. Opus for depth.
Sasuke 🛠️ Engineering & DX claude-opus-4-8 Propose-only Builds real, runnable reference repos on Harper and keeps docs/quickstarts correct against the live API. Scaffolds and opens work for human merge; the most compute- and review-heavy agent.
Naruto 💬 Community & Social claude-haiku-4-5 Draft-and-queue The front line with developers. Monitors GitHub/Slack/forums (via the community sweep), drafts genuinely helpful replies to real issues, and distributes shipped output. Every reply is a draft for human review. Haiku for volume/speed.
Shikamaru 📊 Research & Intelligence claude-sonnet-5 Fully autonomous, internal Tracks the competitive/edge/DBaaS landscape and synthesizes crew signals into ranked, cited intelligence reports. Runs weekly with web search; its reports auto-triage into board tasks. Internal only.

How an agent runs (crew/agent.tsrunCrewAgent): load the roster record → build the system prompt (verbatim custom persona + shared mission) → flip the agent to working and heartbeat before the model call (so the UI shows work in flight) → call Claude → settle back to idle and heartbeat completion (with token count + duration). Failures settle the agent and log an error heartbeat.

Autonomy tiers are honest labels for how far the crew is trusted:

  • propose-only — scaffolds/opens PRs; a human merges (Sasuke).
  • draft-and-queue — produces a draft that lands in a review queue; a human ships it (Jiraiya, Naruto).
  • fully-autonomous-internal — acts without human gating, but only produces internal artifacts, never anything externally published (Kakashi, Shikamaru).

Nothing the crew produces ever moves straight to done. Everything lands in review for a human.


Running the crew

The agents run on Claude (resources/crew/); the key comes from ANTHROPIC_API_KEY (env) or the stored setting.

Trigger What it does
POST /CrewRun/ { agentId, prompt } Ad-hoc: invoke one agent with a free-text prompt; returns the model's text.
POST /CrewTick/ { agentId } Task-aware, single agent: the agent claims its top-priority backlog WorkItem (backlog → doing, parents skipped), produces the deliverable, writes a MemoryEntry (and a Doc for content/docs tasks), and moves the item to review. Explicit trigger, so the coding-agent path and (for Shikamaru) an autonomous web-research pass are allowed.
POST /CrewTick/ (no body) Whole-crew tick — Kakashi triages first, then every specialist works its next task.
Autorun (crewAutorun setting) The scheduler runs a whole-crew tick every minute. Off by default; toggle in Settings → Workspace (or use per-agent "Run now" on Team / "Run crew now" on Overview). Bounded to one task per agent per tick to cap spend.

Each tick records a crew-tick JobRun so the Calendar reconciles it. Assigning a task (a board create, or a research-spawned task) also kicks the owning agent to start immediately rather than waiting for the next autorun tick.


How data gets in (the agent contract)

The crew (or any script) writes through the same REST APIs the UI reads:

Claim Endpoint Behavior
"I'm alive / doing X" POST /Heartbeat/ { agentId, message, level, activity?, agentStatus? } Logs the line and updates the agent's live status/activity/lastHeartbeat on the roster.
"This work exists" POST /WorkItem/ { title, ownerId, status, projectId, priority } Lands on the Tasks board; timestamps stamped server-side. If the project is tied to a GitHub repo, also opens a real Issue.
"I scheduled a job" POST /ScheduledJob/ { id, name, cronExpr, ownerId, enabled, declaredAt } A declaration — a claim, not evidence.
"The job actually ran" POST /JobRun/ { jobId, ok, note } The evidence; updates the job's lastRunAt. The Calendar reconciles declarations vs. runs and flags stalled jobs loudly.
"I remembered something" POST /MemoryEntry/ { type: daily|longterm, agentId, content, projectId? } Persisted in Harper (not flat files), embedded for vector search when an embeddings key is configured.
"I wrote something" POST /Doc/ { title, type, status, projectId, authorAgentId, words, path } Indexed on the Docs screen with provenance.

Every table also has a WebSocket endpoint (same path); the UI subscribes and updates live.


Scheduled jobs

resources/scheduler.ts arms these in-process cron chains on one elected worker. Each declares a ScheduledJob and writes a JobRun per fire, so the Calendar reconciles it. "Gated" jobs mirror enabled to whether the relevant integration/setting is on, so a disconnected integration reads as disabled, not stalled.

Job Cadence Owner Gated by
GitHub sync every 15 min always on
Crew tick (autorun) every minute Kakashi crewAutorun setting (default off)
Weekly research Mon 07:00 ET Shikamaru standing schedule (Shikamaru's only auto cadence)
Weekly rollup Fri 16:00 ET Kakashi standing schedule
Community sweep every 30 min Naruto GitHub token present
Slack digest top of each hour Kakashi Slack connected
Google Calendar sync every 15 min Kakashi Google connected
Google Drive sync every 30 min Jiraiya Google connected

Screens

  • Overview — mission, crew health stats, who's working right now, live heartbeat stream, what moves each project forward today.
  • Tasks — the shared work log as a Board (drag cards between columns) or Swimlanes (agent × status). The crew picks up assigned work each tick.
  • Calendar — every declared cron job reconciled against actual runs; "declared but not running" is flagged in red at the top.
  • Projects — initiatives with progress, synced from GitHub Projects (POST /GithubSync/ pulls issue/PR counts and Project-V2 item status into WorkItems).
  • Memory — daily journal + long-term memory from the vector-indexed MemoryEntry table; semantic search via /MemorySearch/ when a Voyage key is configured, keyword otherwise.
  • Docs — everything the crew has written, filterable, with type/status/provenance.
  • Community — community issues surfaced by the sweep and the crew's draft replies awaiting approval.
  • Team — mission statement, org structure, autonomy tiers, per-agent Claude model pickers, and editable system prompts, persisted to Harper.
  • Research — Shikamaru's filed intelligence reports.
  • Settings — Anthropic key connect/validate/remove, GitHub + embeddings keys, Slack/Google integrations, heartbeat interval, notification prefs, autorun toggle.

⌘K searches tasks, docs, and memory from anywhere.


Data model

One schema file, schemas/mission-control.graphql, defines nine tables in the mission_control database:

CrewAgent, Project, WorkItem, Heartbeat, ScheduledJob, JobRun, MemoryEntry (HNSW vector index on embedding), Doc, and AppSetting (not exported — holds secrets).

Tables that need server-side write logic are extended in resources/ (e.g. WorkItem, Heartbeat) rather than @export-ed directly. resources/seed.ts seeds the crew roster and mission on first boot — that's configuration, not activity. Agents start away with no activity because none has been reported.


Frontend structure

The src/ tree follows the feature-sliced layout used in HarperFast/studio:

src/
  main.tsx              # mounts <App/>
  App.tsx               # QueryClient + Router providers
  index.css             # Tailwind entry (imports assets/harper-tokens.css)
  assets/               # design tokens, fonts
  components/           # cross-feature components (Shell, CommandK)
    ui/                 # design-system primitives, one per file (+ barrel index.ts)
  config/               # apiClient (fetch wrapper), constants
  hooks/                # shared hooks (useLiveTable)
  integrations/api/     # data layer — TanStack Query hooks, one file per entity
  lib/                  # pure utilities (cn, timeAgo, cron, types) + co-located tests
  react-query/          # QueryClient instance
  router/               # rootRoute, routeTree, router
  features/<name>/      # one folder per screen: <Name>Screen.tsx + routes.ts

Each feature owns its screen and its routes.ts (a createRoute bound to the shared rootRoute); router/routeTree.ts assembles them. Query/mutation hooks live in integrations/api/<entity>.ts because entities are shared across features. Routing uses hash history, so every page loads from / and deep links work against the single cacheable index.html.


Integrations & secrets

Secrets — the Anthropic API key, GitHub token, and Voyage embeddings key — are managed through /AnthropicKey/, /GithubToken/, /VoyageKey/ and stored in the non-exported AppSetting table. They never leave the server; the endpoints return presence/masked state only. Env vars (ANTHROPIC_API_KEY, GITHUB_TOKEN) take precedence and resolve from memory to avoid a cold-start race.

External integrations wired in resources/integrations/:

  • GitHub — repo sync into the Tasks board, Project-V2 status, community-issue sweep, and outbound Issue creation from board tasks.
  • Slack (bot token) — hourly crew-status digest + recent-channel context fed to Naruto/Shikamaru.
  • Google Calendar/Drive (OAuth refresh token) — mirror scheduled jobs to Calendar and shipped content to a Drive folder, pulling both back.

Reference-project conventions (for Sasuke)

Every reference/example project the crew scaffolds follows these rules:

  • Scaffold with npm create harper@latest — never hand-rolled.
  • React or Vue, always TypeScript; styling is Tailwind CSS + shadcn/ui.
  • Integration tests with @harperfast/integration-testing — a project isn't done or mergeable without them.
  • One project per folder under a top-level projects/ directory (e.g. projects/realtime-leaderboard/).
  • Database naming convention: each project gets its own Harper database named as the project folder slug with hyphens replaced by underscores — projects/realtime-leaderboard/database: "realtime_leaderboard" in its schema. No two projects share a database; Mission Control's own data stays in mission_control.

About

Agents to streamline Harper's developer relations workflows

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages