Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
HR_API_KEY=
HR_CURSOR_AGENT_ID=
PORT=3000
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ node_modules/
.next/
dist/
coverage/
data/*.json
**/data/*.json
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Contributing

Thanks for helping improve Axiom.
Thanks for helping improve the HarnessRouter demo from the Harvard workshop.

1. Fork the repository and create a focused branch.
2. Keep HarnessRouter credentials in your local `.env` file only.
3. Run `npm test` and `npm run build` before opening a pull request.
4. Explain the user-facing behavior and security impact of your change.

Please keep pull requests small and avoid committing generated runtime data from `data/`.
Please keep pull requests small and avoid committing generated runtime data from `demos/*/data/`.
72 changes: 55 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,70 @@
# LumaCare
# HarnessRouter Demo at Harvard

A compassionate family care companion for parents and caregivers of children receiving cancer care, powered by a purpose-configured HarnessRouter agent.
Open-source demo repository for the HarnessRouter workshop at Harvard.

## Run locally
This repository contains two separate applications. The **Cursor-style coding app is the primary workshop demo**; **LumaCare is a second reference demo** showing how the same HarnessRouter patterns transfer to a different domain.

## Demos

### 1. Cursor-style coding app — primary demo

**Workshop:** Build a Cursor in 3 Steps

A coding-agent interface that demonstrates project-aware tasks, streamed output, persistent sessions, follow-up work, cancellation, and generated-file downloads.

[Open the Cursor-style demo guide](./demos/01-cursor-coding-app/README.md)

```bash
npm install
npm run dev
cp .env.example .env
# Add HR_API_KEY and HR_CURSOR_AGENT_ID to .env
npm run dev:cursor
```

Then open [http://localhost:3000](http://localhost:3000).

### 2. LumaCare — secondary reference demo

A family-care companion that uses the same secure streaming and session architecture in a healthcare-support experience.

[Open the LumaCare demo guide](./demos/02-lumacare/README.md)

```bash
# Add HR_API_KEY to .env; LumaCare's agent mapping is checked in
npm run dev:lumacare
```

Then open [http://localhost:3000](http://localhost:3000).

Run one demo at a time because both use port `3000` by default.

## Repository structure

```text
.
├── demos/
│ ├── 01-cursor-coding-app/ # Primary Harvard workshop demo
│ └── 02-lumacare/ # Secondary reference demo
├── .env.example # Shared local configuration template
├── package.json # npm workspace commands
└── README.md # Repository and demo index
```

Open `http://localhost:3000`. The server reads `HR_API_KEY` from the ignored `.env` file.
Each demo owns its frontend, server, tests, agent mapping, and documentation. This keeps the two products independent while making their shared HarnessRouter architecture easy to compare.

## What is included
## Prerequisites

- Calm, responsive family-facing care guidance experience
- Structured plain-language guides with urgent red flags, care-team questions, and practical support
- Data-only SSE parsing with immediate recovery-ID persistence
- Persistent Session Recall and Continue/Revise flows
- Product-level ownership checks for detail, continue, cancel, preview, and downloads
- Sandboxed HTML previews and authenticated artifact/archive proxying
- Demo identity switcher for exercising cross-user isolation
- Node.js 22 or newer
- A HarnessRouter API key
- A HarnessRouter coding-agent ID for the primary demo

## Commands

```bash
npm test # stream parser and ownership tests
npm run build # production frontend and server typecheck
npm run preview # serve the production build on port 3000
npm run dev:cursor # Run the primary coding demo
npm run dev:lumacare # Run the secondary LumaCare demo
npm test # Test both workspaces
npm run build # Build and type-check both workspaces
```

The committed feature mapping lives in `config/agents.json`. The HarnessRouter API key never reaches the browser. LumaCare provides supportive guidance only and never replaces the child's oncology team.
Credentials belong in an ignored `.env` file and never in source control. See each demo's README for its configuration and architecture.
3 changes: 3 additions & 0 deletions demos/01-cursor-coding-app/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
HR_API_KEY=
HR_CURSOR_AGENT_ID=
PORT=3000
51 changes: 51 additions & 0 deletions demos/01-cursor-coding-app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Cursor-style Coding App

The primary application for the **Build a Cursor in 3 Steps** HarnessRouter workshop at Harvard.

This demo shows how to turn a purpose-configured HarnessRouter coding agent into a product experience with streamed output, recoverable sessions, follow-up tasks, cancellation, and artifact downloads.

## Run it

From the repository root:

1. Install dependencies.

```bash
npm install
```

2. Copy `.env.example` to the repository root as `.env`, then set both values.

```dotenv
HR_API_KEY=your_key_here
HR_CURSOR_AGENT_ID=your_coding_agent_id
PORT=3000
```

3. Start the primary demo.

```bash
npm run dev:cursor
```

Open [http://localhost:3000](http://localhost:3000).

## Architecture

| Layer | Responsibility |
| --- | --- |
| `config/agents.json` | Declares the `coding_assistant` feature; `HR_CURSOR_AGENT_ID` supplies its HarnessRouter agent ID |
| `server/index.ts` | Keeps credentials server-side and proxies runs, sessions, cancellation, previews, and downloads |
| `src/api.ts` | Parses data-only server-sent events |
| `src/App.tsx` | Provides the Cursor-style coding-agent interface and session history |
| `tests/` | Covers stream parsing and cross-user session ownership |

The demo intentionally does not include a production repository sandbox. Configure the HarnessRouter coding agent with the tools and repository access appropriate to your workshop environment.

## Direct workspace commands

```bash
npm run test --workspace=@harnessrouter/cursor-coding-app
npm run build --workspace=@harnessrouter/cursor-coding-app
npm run preview:cursor
```
3 changes: 3 additions & 0 deletions demos/01-cursor-coding-app/config/agents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"coding_assistant": ""
}
14 changes: 14 additions & 0 deletions demos/01-cursor-coding-app/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#183b40" />
<meta name="description" content="A Cursor-style coding agent demo powered by HarnessRouter." />
<title>HarnessRouter Code — Cursor-style agent demo</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
29 changes: 29 additions & 0 deletions demos/01-cursor-coding-app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "@harnessrouter/cursor-coding-app",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "tsx server/index.ts",
"build": "vite build && tsc -p tsconfig.server.json --noEmit",
"preview": "NODE_ENV=production tsx server/index.ts",
"test": "node --import tsx --test tests/**/*.test.ts"
},
"dependencies": {
"dotenv": "^16.4.7",
"express": "^5.1.0",
"lucide-react": "^0.468.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@types/express": "^5.0.0",
"@types/node": "^22.10.5",
"@types/react": "^19.0.3",
"@types/react-dom": "^19.0.2",
"@vitejs/plugin-react": "^4.3.4",
"tsx": "^4.19.2",
"typescript": "^5.7.2",
"vite": "^6.0.7"
}
}
File renamed without changes.
Loading
Loading