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
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ jobs:
working-directory: apps/server
run: npm test

- name: Template quality gate
working-directory: apps/server
run: npm run test:templates

- name: Build
working-directory: apps/server
run: npm run build
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,15 @@ and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.ht
- Autopilot plan diagnostics: overall confidence score, node-level insights, and fallback template options.
- Contributor onboarding package: 10-minute tutorial, starter workflow file, and reusable docs templates.
- Real-world starter template pack (invoice approval, web scrape sync, CSV cleanup, email triage, health check alert).
- Template setup metadata and `GET /api/templates/:templateId` endpoint for wizard-driven setup.
- Template setup wizard in UI with required fields, connection checks, sample-input copy, and preflight-based readiness.
- Starter walkthrough panel in UI for first workflow onboarding.
- Activity pack roadmap model (`pack`, `phase`) with phase-focus summary in `/api/activities`.
- Activity roadmap doc: `docs/ACTIVITY_PACK_ROADMAP.md`.

### Changed
- CI now includes browser smoke validation (`Web E2E Smoke`).
- CI server job now runs an explicit template quality gate (`npm run test:templates`).
- Web editor keyboard shortcuts now include undo/redo and selection-aware delete behavior.
- Web recorder now follows capture -> review -> insert flow instead of immediate node injection.
- Autopilot now requires explicit confirm-before-create flow and uses richer starter templates for vague prompts.
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ It combines a drag-and-drop workflow studio, resilient execution, AI-assisted au
- Web automation (Playwright) and desktop automation (agent service)
- Recorder flows for web and desktop action capture with review-before-insert draft editing
- Autopilot workflow generation from natural-language prompts with confidence scoring and confirm-before-create review
- Template setup wizard with required fields, preflight checks, sample input copy, and run-readiness status
- In-app starter walkthrough for first workflow creation and publish path
- AI nodes: `transform_llm`, `document_understanding`, `clipboard_ai_transfer`
- Integrations (`http_api`, `postgresql`, `mysql`, `mongodb`, `google_sheets`, `airtable`, `s3`)
- Orchestrator queue with attended/unattended robots and dispatch lifecycle
Expand Down Expand Up @@ -68,7 +70,8 @@ Use built-in templates as a fast path from idea to first successful run:
Create from UI:
1. Open `Templates` in the left sidebar.
2. Select a starter template.
3. Click `Create Workflow`.
3. Complete `Template Setup Wizard` fields and click `Validate Setup`.
4. Click `Create Workflow`.

## Contributor Onboarding
New contributors should start here:
Expand Down Expand Up @@ -145,6 +148,7 @@ Tag pushes (`v*.*.*`) trigger `.github/workflows/release.yml`, which reruns vali
- `docs/ONBOARDING.md`
- `docs/tutorials/FIRST_AUTOMATION_10_MIN.md`
- `docs/examples/workflows/first-automation.workflow.json`
- `docs/ACTIVITY_PACK_ROADMAP.md`
- `docs/ARCHITECTURE.md`
- `docs/API_REFERENCE.md`
- `docs/DEPLOYMENT.md`
Expand Down
1 change: 1 addition & 0 deletions apps/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"start": "node dist/index.js",
"build": "tsc -p tsconfig.json",
"test": "node --import tsx --test src/**/*.test.ts",
"test:templates": "node --import tsx --test src/lib/templates.test.ts src/lib/templateQuality.test.ts",
"test:critical": "node --import tsx --test src/lib/execution-flows.test.ts src/lib/runDiff.test.ts src/lib/recorder.test.ts src/lib/agent.test.ts",
"prisma:generate": "prisma generate",
"prisma:migrate": "prisma migrate dev"
Expand Down
14 changes: 14 additions & 0 deletions apps/server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,20 @@ app.get("/api/templates", canReadTemplates, async (_req, res) => {
res.json(templates);
});

app.get("/api/templates/:templateId", canReadTemplates, async (req, res) => {
const templateId = String(req.params.templateId || "").trim();
if (!templateId) {
res.status(400).json({ error: "Template id is required" });
return;
}
const template = getWorkflowTemplate(templateId);
if (!template) {
res.status(404).json({ error: "Template not found" });
return;
}
res.json(template);
});

app.get("/api/activities", canReadActivities, async (_req, res) => {
const catalog = await cache.getOrSet("activities:catalog", CACHE_TTL.templatesMs, async () => listActivities());
res.json(catalog);
Expand Down
9 changes: 8 additions & 1 deletion apps/server/src/lib/activities.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,15 @@ import { listActivities } from "./activities.js";
test("listActivities exposes summary counts and target size", () => {
const catalog = listActivities();
assert.equal(catalog.targetLibrarySize, 300);
assert.ok(catalog.currentTotal >= 30);
assert.ok(catalog.currentTotal >= 90);
assert.ok(catalog.availableCount > 0);
assert.ok(catalog.plannedCount > 0);
assert.ok(catalog.byCategory.Core >= 1);
assert.ok(catalog.byPhase["phase-1"] > 0);
assert.ok(catalog.byPhase["phase-2"] > 0);
assert.ok(catalog.byPack["system-core"] > 0);
assert.ok(Array.isArray(catalog.roadmap));
assert.ok(catalog.roadmap.some((pack) => pack.id === "system-core"));
assert.ok(catalog.roadmap.some((pack) => pack.id === "integration-service"));
assert.ok(catalog.roadmap.some((pack) => pack.id === "ai-center"));
});
Loading
Loading