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
21 changes: 21 additions & 0 deletions .changeset/remove-persona-skill-memory-547.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
'@gemstack/framework': minor
'@gemstack/ai-autopilot': minor
---

Remove the persona, skill, and project-memory framing. A run's system prompt is now the built-in #326 prompt plus your own `SYSTEM.md`, and nothing else. Nothing is read off disk and appended when the run starts.

A build used to append the personas and skills for its detected stack plus the full contents of the repo's memory files. On one measured 8,852-character build prompt that framing was about 5,000 characters, more than the designed prompt it was wrapping. None of that text was designed; it accumulated. Prompt text nobody reviewed is a defect, not a feature (#547).

Two things fall out of this:

- **The prompt preview is now exact.** The dashboard's "See actual prompt sent" (#520) had to carry a caveat that a build run appends more at run time. It no longer does, so the caveat is gone and what you read before the run is what the agent gets, for every run kind.
- **A build stops being opinionated about the stack.** #545 removed the architect turn, but the personas still hard-instructed a stack ("Default to Prisma"). With both gone, nothing tells the agent what to build on.

Skills and project memory are worth having as designed features later. They are not worth keeping in this shape.

Removed from `@gemstack/framework`: the `memory` / `extensions` / `composeExtensions` options on `runFramework`, the `framing` option on `composeRunSystem` (`RunSystemOptions` is now `SystemPromptOptions`), `loadRepoMemory` / `memoryFraming` / `MEMORY_FILES`, `discoverExtensions`, and the `--compose-extensions` flag. `readProjectSignals` moved to `project.js` and is still exported from the root; preset detection still runs and still narrates `Detected <framework>`.

Removed from `@gemstack/ai-autopilot`: the `personas/` and `extensions/` modules (`definePersona`, `composePersonas`, `personaInstructions`, `personaTools`, `personaAgent`, `personaWorkers`, `personaRoster`, `stackPersonas`, `neutralPersonas`, `presetPersonas`, `defineSkill`, `SkillRegistry`, `composeSkills`, `skillInstructions`, `FrameworkExtension` and its registry). `Preset` is now `{name, framework, signals}`, a pure detector; `DomainPreset` loses `skills` and keeps its loops, prompts, and modes.

`@gemstack/ai-skills` is untouched. It is a different thing (an on-disk `SKILL.md` loader for ai-sdk agents) and is unaffected by any of this.
2 changes: 1 addition & 1 deletion .changeset/see-system-prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

Let the user see the system prompt. Under the prompt editor, a `▶ See actual prompt sent` toggle shows the built-in prompt in full, with the `Vanilla` checkbox renamed to `Disable system prompt` (nobody knows what "Vanilla" means; the persisted `vanilla` key is unchanged). The preview renders through `composeRunSystem`, the same function a run composes with, so the toggles are shown doing what they really do.

The event log now renders the run's `system-prompt` event in full too. That event has always carried the exact text handed to the agent, and the dashboard was reducing it to a char count and dropping the rest, so the true prompt was already reaching the browser and being thrown away. That is the one that is byte-exact for a build run, where the repo's memory files, personas and skills are read off disk at run time.
The event log now renders the run's `system-prompt` event in full too. That event has always carried the exact text handed to the agent, and the dashboard was reducing it to a char count and dropping the rest, so the true prompt was already reaching the browser and being thrown away.

Reading the user's `SYSTEM.md` moves to `system-prompt-file.ts`, leaving `system-prompt.ts` free of Node imports so the composition can be imported in a browser. A test walks the compiled client barrel's import graph and fails if anything reachable from it imports `node:*`.
2 changes: 1 addition & 1 deletion .changeset/show-real-prompts-343.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
'@gemstack/framework': minor
---

Show the real prompts on the dashboard (#343). The framework now emits the exact system prompt it runs the agent under, the #326 block plus any persona / skill / memory framing, as a `system-prompt` event at session start (both the direct-prompt path and the full build path). A new "Prompts sent to Claude Code" panel renders it alongside each turn's user prompt (harvested from the `driver` `start` events already in the stream), so the normally-hidden prompt is fully visible for transparency. Prompt text renders as inert text, never markup. Read-only; nothing is gated on it.
Show the real prompts on the dashboard (#343). The framework now emits the exact system prompt it runs the agent under as a `system-prompt` event at session start (both the direct-prompt path and the full build path). A new "Prompts sent to Claude Code" panel renders it alongside each turn's user prompt (harvested from the `driver` `start` events already in the stream), so the normally-hidden prompt is fully visible for transparency. Prompt text renders as inert text, never markup. Read-only; nothing is gated on it.
2 changes: 1 addition & 1 deletion .changeset/single-system-assembly-501.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
"@gemstack/framework": minor
---

Assemble a run's system prompt in one place. The build path (`runFramework`) and the direct-prompt path (`runPrompt`) each inlined the same composition (the #326 prompt block, the always-on emit protocols, then the run's persona/skill/memory framing), and the two drifted apart, which is what dropped the #326 action layer from `--vanilla` builds (#500). Both now go through a single exported `composeRunSystem()` in `system-prompt.ts`, with unit tests pinning the order and the unconditional emit protocols so the two paths can never diverge again.
Assemble a run's system prompt in one place. The build path (`runFramework`) and the direct-prompt path (`runPrompt`) each inlined the same composition (the #326 prompt block, then the always-on emit protocols), and the two drifted apart, which is what dropped the #326 action layer from `--vanilla` builds (#500). Both now go through a single exported `composeRunSystem()` in `system-prompt.ts`, with unit tests pinning the order and the unconditional emit protocols so the two paths can never diverge again.
2 changes: 1 addition & 1 deletion Architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ The enduring design rule:
What shipped, built up from that seed (the state layer + the loop are the moat, not the prompts):

- **Supervisor** — the seed topology: plan -> dispatch subagents (bounded concurrency + token budget + per-subtask isolation) -> synthesize.
- **Personas** — reusable, stack-aware roles materialized into worker agents; **presets** (Vike flagship, Next.js) select the framework-specific ones by detecting the project's framework, on top of a framework-neutral core.
- **Presets** — framework detection (Vike flagship, Next.js) from a project's dependencies, so a run can narrate what it is working in.
- **Runner** — a pluggable sandbox seam (`FakeRunner` + a real `LocalRunner`; Docker/WebContainer/Flue are infra-gated adapters) where agents build and run an app.
- **Surfaces** — the same run in a terminal, an in-page UI, or a detached background handle, over one replayable event stream.
- **The loop** — an event-to-prompt-chain policy (a major change fires review + code-quality + security; a new UI flow fires QA + UX), gating on a `{ blockers }` verdict, with a data-driven **prompt library**.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Full documentation lives in [`docs/`](./docs/guide/index.md) (a hosted site is o
|---|---|---|---|
| [`ai‑sdk`](./packages/ai-sdk) | The agent runtime: providers, the agent loop, tools, streaming, middleware, structured output, memory, and evals. The engine the rest of the AI family builds on. | [Guide](./docs/packages/ai-sdk/index.md) | [![npm](https://img.shields.io/npm/v/@gemstack/ai-sdk)](https://www.npmjs.com/package/@gemstack/ai-sdk) |
| [`ai‑skills`](./packages/ai-skills) | Portable capability bundles: load `SKILL.md` skills (instructions + tools + resources) and compose them onto an agent on demand. | [Guide](./docs/packages/ai-skills.md) | [![npm](https://img.shields.io/npm/v/@gemstack/ai-skills)](https://www.npmjs.com/package/@gemstack/ai-skills) |
| [`ai‑autopilot`](./packages/ai-autopilot) | The AI‑building framework: a Supervisor (plan → dispatch → synthesize) plus stack‑aware personas, a runner sandbox, surfaces, a decisions ledger, an event‑triggered review/QA loop with a built‑in prompt library, framework presets (Vike/Next), and a bootstrap flow that takes an app from nothing to production‑grade. | [Guide](./docs/packages/ai-autopilot.md) | [![npm](https://img.shields.io/npm/v/@gemstack/ai-autopilot)](https://www.npmjs.com/package/@gemstack/ai-autopilot) |
| [`ai‑autopilot`](./packages/ai-autopilot) | The AI‑building framework: a Supervisor (plan → dispatch → synthesize) plus a runner sandbox, surfaces, an event‑triggered review/QA loop with a built‑in prompt library, framework presets (Vike/Next), and a bootstrap flow that takes an app from nothing to production‑grade. | [Guide](./docs/packages/ai-autopilot.md) | [![npm](https://img.shields.io/npm/v/@gemstack/ai-autopilot)](https://www.npmjs.com/package/@gemstack/ai-autopilot) |
| [`framework`](./packages/framework) | **The (AI) Framework**: turnkey, zero‑config orchestration built on `ai-autopilot`. Wraps a coding‑agent CLI (Claude Code) as a black box and takes an idea to a running app, with a live dashboard, Open Loop domain presets, an optional Docker sandbox, and a run relay for shared sessions. | [README](./packages/framework/README.md) | [![npm](https://img.shields.io/npm/v/@gemstack/framework)](https://www.npmjs.com/package/@gemstack/framework) |
| [`ai‑mcp`](./packages/ai-mcp) | The agent/MCP bridge: consume a remote MCP server's tools as agent tools, and expose an agent as an MCP server. | [Guide](./docs/packages/ai-mcp.md) | [![npm](https://img.shields.io/npm/v/@gemstack/ai-mcp)](https://www.npmjs.com/package/@gemstack/ai-mcp) |
| [`mcp`](./packages/mcp) | A standalone framework for *authoring* MCP servers: tools, resources, prompts, decorators, OAuth 2.1, a framework-neutral HTTP handler, and a test client. Agent-agnostic. | [Guide](./docs/packages/mcp.md) | [![npm](https://img.shields.io/npm/v/@gemstack/mcp)](https://www.npmjs.com/package/@gemstack/mcp) |
Expand Down Expand Up @@ -67,7 +67,7 @@ pnpm typecheck
pnpm test
```

This is a pnpm + Turborepo + Changesets monorepo. Runnable examples live under [`examples/`](./examples) — e.g. [`mcp-quickstart`](./examples/mcp-quickstart), [`autopilot-quickstart`](./examples/autopilot-quickstart) (personas + Supervisor + runner + surfaces), and [`bootstrap-quickstart`](./examples/bootstrap-quickstart) (the whole bootstrap flow, offline). See [`.changeset/README.md`](./.changeset/README.md) for the release flow.
This is a pnpm + Turborepo + Changesets monorepo. Runnable examples live under [`examples/`](./examples) — e.g. [`mcp-quickstart`](./examples/mcp-quickstart), [`autopilot-quickstart`](./examples/autopilot-quickstart) (Supervisor + runner + surfaces), and [`bootstrap-quickstart`](./examples/bootstrap-quickstart) (the whole bootstrap flow, offline). See [`.changeset/README.md`](./.changeset/README.md) for the release flow.

## Origin

Expand Down
2 changes: 1 addition & 1 deletion docs/packages/ai-autopilot.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pnpm add @gemstack/ai-autopilot @gemstack/ai-sdk

The Supervisor (below) is the seed topology. Built up from it, the package is a full framework for building software with agents — the state layer and the loop are the moat, not the prompts:

- **Personas + presets** — reusable, stack-aware roles materialized into worker agents; `presetPersonas` selects the framework-specific ones (Vike flagship, Next.js) by detecting the project's framework, on top of a framework-neutral core.
- **Presets** — framework detection (Vike flagship, Next.js) from a project's dependencies.
- **Runner** — a pluggable sandbox seam (`FakeRunner` + a real `LocalRunner`) where agents build and run an app; expose it to an agent with `runnerTools`.
- **Surfaces** — the same run in a terminal, an in-page UI, or a detached background handle, over one replayable event stream (`launchAutopilot`).
- **Decisions ledger** — durable memory of rejected ideas + settled choices (round-trips `DECISIONS.md`) so a run stops re-pitching what was turned down.
Expand Down
12 changes: 7 additions & 5 deletions examples/autopilot-quickstart/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
A runnable, end-to-end quickstart for [`@gemstack/ai-autopilot`](../../packages/ai-autopilot) — the four layers of the epic composed into one "build a feature" flow:

```
personas → Supervisor → runner (sandbox) → surfaces
workers → Supervisor → runner (sandbox) → surfaces
```

A lead planner decomposes the task **"Add a paginated Orders page backed by an orders table"** and routes each subtask to a stack-aware **persona** (`universal-orm-modeler`, `vike-page-builder`, `ui-intent-designer`). The **Supervisor** dispatches them; each persona worker acts inside a **runner** sandbox — writing Vike/ORM files through `runnerTools` — and progress is rendered through the **surfaces** (a terminal sink for live output, plus a background handle exposing events + result).
A lead planner decomposes the task **"Add a paginated Orders page backed by an orders table"** and routes each subtask to one of the example's own **worker** agents (`data-modeler`, `page-builder`, `ui-designer`). The **Supervisor** dispatches them; each worker acts inside a **runner** sandbox — writing files through `runnerTools` — and progress is rendered through the **surfaces** (a terminal sink for live output, plus a background handle exposing events + result).

The roster is the app's own: autopilot orchestrates the agents you hand it and adds nothing to their instructions.

It runs **offline**: `AiFake` scripts the model, so there's no API key and the output is deterministic.

Expand All @@ -27,10 +29,10 @@ pnpm --filter @gemstack/example-autopilot-quickstart test

## Going real

The only fakes here are `AiFake` (the model) and `FakeRunner` (the sandbox). To run it for real, drop `AiFake` and give the personas real model strings, and swap `FakeRunner` for a real runner adapter (a `FlueRunner`, WebContainer, or Docker sandbox) — the `Runner` interface is the same, so nothing else in the flow changes.
The only fakes here are `AiFake` (the model) and `FakeRunner` (the sandbox). To run it for real, drop `AiFake` and give the workers real model strings, and swap `FakeRunner` for a real runner adapter (a `FlueRunner`, WebContainer, or Docker sandbox) — the `Runner` interface is the same, so nothing else in the flow changes.

## What each file shows

- **`src/autopilot.ts`** — the composition: `personaWorkers` + `runnerTools`, `agentPlanner` fed the `personaRoster`, a `Supervisor`, and `launchAutopilot` + `terminalSink` for the surfaces.
- **`src/autopilot.ts`** — the composition: the worker roster + `runnerTools`, `agentPlanner` fed that roster, a `Supervisor`, and `launchAutopilot` + `terminalSink` for the surfaces.
- **`src/main.ts`** — the runnable demo.
- **`src/autopilot.test.ts`** — asserts the four layers actually compose (plan routes by persona, files land in the sandbox, surfaces capture events).
- **`src/autopilot.test.ts`** — asserts the four layers actually compose (plan routes by role, files land in the sandbox, surfaces capture events).
2 changes: 1 addition & 1 deletion examples/autopilot-quickstart/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@gemstack/example-autopilot-quickstart",
"version": "0.0.8",
"private": true,
"description": "Runnable end-to-end quickstart for @gemstack/ai-autopilot: personas + Supervisor + runner + surfaces composed into one build-a-feature flow, offline via AiFake.",
"description": "Runnable end-to-end quickstart for @gemstack/ai-autopilot: workers + Supervisor + runner + surfaces composed into one build-a-feature flow, offline via AiFake.",
"type": "module",
"scripts": {
"typecheck": "tsc --noEmit",
Expand Down
11 changes: 4 additions & 7 deletions examples/autopilot-quickstart/src/autopilot.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,16 @@ import assert from 'node:assert/strict'
import { runQuickstart, TASK } from './autopilot.js'

describe('autopilot quickstart: the four layers compose end-to-end', () => {
it('plans by persona, dispatches, acts in the sandbox, and surfaces progress', async () => {
it('plans by role, dispatches, acts in the sandbox, and surfaces progress', async () => {
const lines: string[] = []
const result = await runQuickstart(line => lines.push(line))

// Supervisor: three subtasks, each routed to a stack persona, all succeeded.
// Supervisor: three subtasks, each routed to a worker, all succeeded.
assert.equal(result.run.plan.length, 3)
assert.deepEqual(
result.run.plan.map(s => s.worker).sort(),
['data-modeler', 'ui-intent-designer', 'vike-page-builder'],
)
assert.deepEqual(result.run.plan.map(s => s.worker).sort(), ['data-modeler', 'page-builder', 'ui-designer'])
assert.ok(result.run.results.every(r => r.ok), 'every subtask succeeded')

// Runner: each persona worker wrote its file into the sandbox via runnerTools.
// Runner: each worker wrote its file into the sandbox via runnerTools.
assert.ok('database/schema.ts' in result.files)
assert.ok('pages/orders/+Page.jsx' in result.files)
assert.match(result.files['database/schema.ts']!, /orders/)
Expand Down
Loading
Loading