diff --git a/.changeset/adopt-cloud-work.md b/.changeset/adopt-cloud-work.md deleted file mode 100644 index 18e935f7c..000000000 --- a/.changeset/adopt-cloud-work.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/the-framework': minor ---- - -A cloud run's record now follows the branch its session actually worked on (#1601). A web run hands the task to claude.ai and ends; the session does the work on a `claude/*` branch of the cloud's own naming, never the designated run branch — so every surface keyed to the recorded branch (the session row, PR resolution, CI watch, merge) said "nothing committed" while the work sat on origin, and the armed draft PR never opened. The hand-off now pushes an anchor — an empty commit unique to the run, minted without moving any branch — as the ref the session clones at, so the session's branch is recognizable later by plain ancestry. A daemon pass matches each settled web run to the one `claude/*` head descending from its anchor and patches the run's archive with the branch and its PR, opening the armed draft PR itself when the session never did. Web-run teardown stops pushing the empty `tf-agent-*` branch to origin (the scratch-ref sweep clears the ones already there, and learns that an anchor tip — an empty commit on a landed parent — holds no work). diff --git a/.changeset/auto-onboard-installs.md b/.changeset/auto-onboard-installs.md deleted file mode 100644 index e2975946e..000000000 --- a/.changeset/auto-onboard-installs.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/the-framework': patch ---- - -The repos-directory auto-scan is removed (#1600): the daemon no longer installs and registers every repo under a configured directory at boot (the `reposDirectory`/`reposDirectoryAutoGrant` preferences are gone with it) — the dashboard's "Add project" is the one onboarding path, so a repo is always installed before any agent touches it. Two fixes ride along: activation now means the install-written `.the-framework/.gitignore` exists (not merely the `.the-framework/` directory), and the repo-root `branches` shortcut is hidden through the repo-level git exclude the moment it is created. diff --git a/.changeset/data-branch.md b/.changeset/data-branch.md deleted file mode 100644 index 6e8ba3ea7..000000000 --- a/.changeset/data-branch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/the-framework': minor ---- - -Everything The Framework writes now lives on one dedicated branch, `tf-data` (#1582): the tickets (plans and locks included), the `TODO_AGENTS.md` task queue, and the per-user session archives. Main is 100% code, 0% framework data. The branch is checked out at `.the-framework/branches/tf-data` with a root `tickets` symlink into it, and the daemon is its one local writer: every write is a serialized sync → apply → commit → push cycle, pulled eagerly on the daemon's clock, so every machine and cloud session converges on the same data and a lost race re-applies the intent instead of clobbering anyone's work — which retires the promote-the-queue-off-a-branch machinery (`queue-promote.ts`), the archive committer (`agent-commit.ts`), and ticket-locks' own commit/push dance. Agents read the data via `git show` and write it by committing to the branch directly per the new "The data branch" prompt protocol; a pinned drain's queue entry is checked off by the daemon once the run's ending reports the work published. Hard switch, no migration code: move `tickets/`, `TODO_AGENTS.md`, and `.the-framework/*/agents/**` off main onto the branch by hand. diff --git a/.changeset/decoy-question-filtered.md b/.changeset/decoy-question-filtered.md deleted file mode 100644 index 79da1968b..000000000 --- a/.changeset/decoy-question-filtered.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/the-framework': patch ---- - -The bridge no longer reports the protocol's own rendered examples as a question the session asked. Every Claude web session page opens with the run's prompt, which quotes the whole protocol — and two of its examples slipped the old decoy filter: the browser-handoff one (placeholders joined by punctuation in the title, literal labels) and the approval one (literal end to end). On a live page the dashboard rendered an answerable question card for a session that had asked nothing, one click away from typing into its real composer. The content script now discards everything rendered inside the transcript's opening message, catches placeholder-plus-punctuation titles, and matches the two literal examples verbatim; the extension and the daemon's expected version move to 0.8.1 together, so a not-yet-reloaded extension is refused loudly instead of continuing to report decoys. diff --git a/.changeset/drain-claims-ticket-locks.md b/.changeset/drain-claims-ticket-locks.md deleted file mode 100644 index 6a793a298..000000000 --- a/.changeset/drain-claims-ticket-locks.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/the-framework': minor ---- - -A drain now claims its entry's ticket with a committed, pushed `.lock.md` before its agent starts, closing the last gap #1420 named: planning already made this cross-machine claim, but implementation runs were booked only in the daemon's memory, so two daemons on different machines could implement the same ticket. Only entries that link back to a ticket are claimed — a self-contained TODO has nothing on disk to lock and keeps the queue document as its coordination point — and an entry whose ticket was claimed elsewhere is dropped from the batch for a later tick to reconsider, never re-implemented. The drain's prompt carries the same claim contract the pinned plan prompt does: the agent removes the ticket, its plan, and its lock in the PR that closes it, and stops if the lock names someone else. A drain-mode claim skips only on an existing lock, since the plan it also finds is the drain's input rather than a rival's work. diff --git a/.changeset/extension-version-gate.md b/.changeset/extension-version-gate.md deleted file mode 100644 index ff6fc6b73..000000000 --- a/.changeset/extension-version-gate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/the-framework': minor ---- - -A browser extension whose version does not match the daemon's is now blocked outright instead of half-working. A stale extension never failed loudly — it missed messages and silently ignored fields the newer protocol added, which read as dashboard bugs and burned debugging sessions on a problem whose only fix is reloading the extension. Every bridge call now states the extension's version, and a daemon expecting another refuses every route with an error naming both versions and the update path; the options page's connection test shows that answer verbatim, and the dashboard's bridge settings say the extension is blocked — with both versions — instead of the bridge merely looking disconnected. A test keeps the daemon's expected version and the extension's manifest in lockstep, so one cannot be bumped without the other. diff --git a/.changeset/flat-branches-view.md b/.changeset/flat-branches-view.md deleted file mode 100644 index 5ef0cc4d3..000000000 --- a/.changeset/flat-branches-view.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/the-framework': minor ---- - -Agent checkouts now live at `.the-framework/branches/`, each in a directory named as its branch (`tf-agent-`, enabled by #1581's slash-free names), with a relative `branches` shortcut at the repo root — so `cd branches/` reaches any session's checkout by the name the dashboard shows (#1580). When a session renames its branch, a background pass adds a sibling symlink under the new name, so a rename costs a link instead of moving a checkout under a live agent. The old `.the-framework/worktrees/` location is gone — pre-release, zero users, no compatibility kept. Only the framework's own links are ever created or removed — a user's file, directory, or symlink at any of these paths is left alone. diff --git a/.changeset/layout-gate.md b/.changeset/layout-gate.md deleted file mode 100644 index 30cabbafd..000000000 --- a/.changeset/layout-gate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/the-framework': minor ---- - -The layout gate (#1575): a build refuses to run in a repo whose committed layout marker records a different bookkeeping layout, instead of committing files under names the repo no longer uses. Install records the marker; the repo's own is pinned to the build by a test, so a layout rename cannot land without regenerating it. diff --git a/.changeset/one-github-sync-preset.md b/.changeset/one-github-sync-preset.md deleted file mode 100644 index fa70bc93c..000000000 --- a/.changeset/one-github-sync-preset.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/the-framework': minor ---- - -The separate "Import tickets from GitHub" preset is gone; "Update from GitHub" is the one GitHub sync. The update prompt already treats an empty `tickets/` as its first import — every open issue comes across — so the import preset was a second button for the same work, and two entry points meant two prompts to keep honest. Every surface that offered the import (the empty backlog panel, the onboarding checklist) now offers the update under its own label, sending the same preset text verbatim wherever it is pressed. diff --git a/.changeset/project-errors.md b/.changeset/project-errors.md deleted file mode 100644 index b440d8ba8..000000000 --- a/.changeset/project-errors.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/the-framework': patch ---- - -The dashboard shows what the daemon finds wrong with a project (#1500): a per-project error state the daemon's background jobs set and clear, carried on the project list and rendered as a red dot in the sidebar and a banner on the project's page. The first emitter is the data-branch sync (#1599): a push origin rejects, or a repository with no remote at all, is an error the user sees now rather than a line on the daemon's stdout — cleared by the first sync that converges. diff --git a/.changeset/release-abandoned-drain-locks.md b/.changeset/release-abandoned-drain-locks.md deleted file mode 100644 index 9e7e05f65..000000000 --- a/.changeset/release-abandoned-drain-locks.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/the-framework': patch ---- - -A ticket claim whose agent settled with nothing to hand off is now released by the daemon. The lock's normal release is the agent's own PR deleting it, but a drain that finishes without a single commit — say it closed the issue through `gh` instead of code — never opens that PR, so the ticket, plan, lock, and queue entry all survived a cleanly-finished agent and every later sweep dropped the entry as "already claimed": the queue livelocked on a dead claim until a human clicked Release (#1583). The release keys off the run's own recorded ending, never a timer (#1420's no-staleness rule stands), and frees only a lock still naming the exact agent the sweep minted it for — a lock naming anyone else is someone's live claim and is left alone. diff --git a/MEMORY.md b/MEMORY.md index 74b965473..841327e49 100644 --- a/MEMORY.md +++ b/MEMORY.md @@ -7,6 +7,7 @@ - **The unit of work is an *agent*** — not a run or a session. The CLI that drives it (`claude`, `codex`) is the *driver*. - **Zero migration code.** Manual migration is good; code that migrates is not. A renamed or deleted thing leaves nothing behind — no fallback to the old name, no key alias, no old-format branch, no upgrade step. Nor a notice about what was dropped: a warning about data nobody has is still code nobody needs. - **Haiku is out of scope.** It skips the session-finish protocol, so unattended work started on it always ends as an unmerged draft PR that a human has to finish. We deliberately don't work around this: no model floor that overrides the model a user picked, and no refusal to arm the hand-off. The dashboard's warning is the whole treatment — it teaches and never blocks. +- **The version line stays in `0.x`.** The releases are experimental, and while the major is `0` a minor bump is allowed to break — so no experiment ever costs a major. ## Before modifying this file diff --git a/README.md b/README.md index 02f971617..c38a4ce50 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ **Autonomous AI programming.** Stop babysitting your coding agents. Make the important decisions, let AI do the rest. -[![npm](https://img.shields.io/npm/v/@gemstack/the-framework)](https://www.npmjs.com/package/@gemstack/the-framework) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE) [![Discord](https://img.shields.io/badge/Discord-join-5865F2?logo=discord&logoColor=white)](https://discord.gg/qc8zvdzWNR) +[![npm](https://img.shields.io/npm/v/framework)](https://www.npmjs.com/package/framework) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE) [![Discord](https://img.shields.io/badge/Discord-join-5865F2?logo=discord&logoColor=white)](https://discord.gg/qc8zvdzWNR)
@@ -17,9 +17,9 @@ Stop babysitting your coding agents. Make the important decisions, let AI do the ```bash # Install -npm i -g @gemstack/the-framework +npm i -g framework the-framework # Spins up the dashboard # Or one-shot (no install): -npx @gemstack/the-framework # Spins up the dashboard +npx framework # Spins up the dashboard ``` diff --git a/packages/the-framework.ai/pages/index/Hero.tsx b/packages/the-framework.ai/pages/index/Hero.tsx index 25442a82d..e3741aa21 100644 --- a/packages/the-framework.ai/pages/index/Hero.tsx +++ b/packages/the-framework.ai/pages/index/Hero.tsx @@ -3,13 +3,13 @@ import { useCopy } from './copy' import { kickerStyle, mono } from './ui' export const PMS = { - npm: { try: 'npx @gemstack/the-framework', install: 'npm i -g @gemstack/the-framework' }, - pnpm: { try: 'pnpm dlx @gemstack/the-framework', install: 'pnpm add -g @gemstack/the-framework' }, - bun: { try: 'bunx @gemstack/the-framework', install: 'bun add -g @gemstack/the-framework' }, + npm: { try: 'npx framework', install: 'npm i -g framework' }, + pnpm: { try: 'pnpm dlx framework', install: 'pnpm add -g framework' }, + bun: { try: 'bunx framework', install: 'bun add -g framework' }, // `yarn dlx` is Yarn 2+ (Berry), which removed `yarn global add` — so the install line // falls back to npm, which every yarn user has, rather than pairing two commands no // single yarn generation can both run. - yarn: { try: 'yarn dlx @gemstack/the-framework', install: 'npm i -g @gemstack/the-framework' }, + yarn: { try: 'yarn dlx framework', install: 'npm i -g framework' }, } as const export type Pm = keyof typeof PMS diff --git a/packages/the-framework.ai/pages/index/ui.tsx b/packages/the-framework.ai/pages/index/ui.tsx index d64055197..fd4cc3ccc 100644 --- a/packages/the-framework.ai/pages/index/ui.tsx +++ b/packages/the-framework.ai/pages/index/ui.tsx @@ -1,8 +1,8 @@ import type { CSSProperties, ReactNode } from 'react' export const DISCORD_URL = 'https://discord.gg/qc8zvdzWNR' -export const GITHUB_URL = 'https://github.com/gemstack-land/the-framework' -export const NPM_URL = 'https://www.npmjs.com/package/@gemstack/the-framework' +export const GITHUB_URL = 'https://github.com/framework/the-framework' +export const NPM_URL = 'https://www.npmjs.com/package/framework' export const mono = "'IBM Plex Mono', monospace" as const diff --git a/packages/the-framework.ai/pages/press/+Page.tsx b/packages/the-framework.ai/pages/press/+Page.tsx index 6eb39b0b4..022efa5b1 100644 --- a/packages/the-framework.ai/pages/press/+Page.tsx +++ b/packages/the-framework.ai/pages/press/+Page.tsx @@ -73,7 +73,7 @@ export default function Page() {

The name is written The Framework (capital T, capital - F), and the package is @gemstack/the-framework. + F), and the package is framework.

diff --git a/packages/the-framework/README.md b/packages/the-framework/README.md index 83f63e168..28dc87297 100644 --- a/packages/the-framework/README.md +++ b/packages/the-framework/README.md @@ -1,4 +1,4 @@ -# @gemstack/the-framework +# framework **The Framework** — autonomous AI programming: humans make the important decisions while coding agents run unattended. @@ -8,16 +8,16 @@ gets a throwaway copy of the repo, does its work, and hands the result off as a request. Your own checkout is never touched. ```bash -npm i -g @gemstack/the-framework +npm i -g framework cd ~/code/my-repo -framework # serves the dashboard at http://127.0.0.1:4200 +the-framework # serves the dashboard at http://127.0.0.1:4200 ``` ## The CLI is four options and no verbs ``` -framework Serve the dashboard in the foreground. Ctrl+C closes it and +the-framework Serve the dashboard in the foreground. Ctrl+C closes it and every session it is running. --port Dashboard port (default: 4200). @@ -74,5 +74,5 @@ in prose. [`SPEC.md`](./SPEC.md) at the package root is the place to start. ## Status -Pre-release and unversioned. There are no users to keep compatible, so the code -prefers being clean over being backward-compatible. +Pre-release, published from the `0.x` line. There are no users to keep compatible, +so the code prefers being clean over being backward-compatible. diff --git a/packages/the-framework/dashboard/README.md b/packages/the-framework/dashboard/README.md index f9465b9e5..65bdefc51 100644 --- a/packages/the-framework/dashboard/README.md +++ b/packages/the-framework/dashboard/README.md @@ -38,7 +38,7 @@ merging the package removed. ## Run it ```bash -pnpm --filter @gemstack/the-framework dev:dashboard +pnpm --filter framework dev:dashboard # open http://localhost:4300 ``` @@ -50,5 +50,5 @@ configuration travels to it as a JSON spec (`--agent `), never as flags. ## Tests `vitest` with a jsdom environment, which is why the package runs two test runners: `node --test` -over the compiled `src/`, then `vitest` over this directory. `pnpm --filter @gemstack/the-framework test` +over the compiled `src/`, then `vitest` over this directory. `pnpm --filter framework test` runs both. diff --git a/packages/the-framework/dashboard/components/AgentOverview.tsx b/packages/the-framework/dashboard/components/AgentOverview.tsx index 0d94a0928..f3ce2d56f 100644 --- a/packages/the-framework/dashboard/components/AgentOverview.tsx +++ b/packages/the-framework/dashboard/components/AgentOverview.tsx @@ -7,7 +7,7 @@ import { cn } from '../lib/utils.js' // The agent overview (#431): the "moat" the wrapped agent's own chat cannot show, rebuilt // on the new dashboard. Each card is a pure projection of the event stream (run-view.ts -// in @gemstack/the-framework) — the agent's status and a link +// in `framework`) — the agent's status and a link // to the live session. Cards render only when their data has arrived, so an early agent // shows nothing extra. export function AgentOverview({ events }: { events: FrameworkEvent[] }) { diff --git a/packages/the-framework/dashboard/lib/preferences.ts b/packages/the-framework/dashboard/lib/preferences.ts index 76b1624ee..829db6461 100644 --- a/packages/the-framework/dashboard/lib/preferences.ts +++ b/packages/the-framework/dashboard/lib/preferences.ts @@ -303,7 +303,7 @@ export function usePreferenceSources(): PreferenceSources { const EMPTY_SOURCES: PreferenceSources = {} -// Autopilot's default-on moved into @gemstack/the-framework with the rest of the preferences -> +// Autopilot's default-on moved into `framework` with the rest of the preferences -> // run options mapping (#858), so the daemon resolves it the same way. Re-exported here because // every component reaches for it through this module. diff --git a/packages/the-framework/dashboard/vite.config.ts b/packages/the-framework/dashboard/vite.config.ts index 43a52b56f..3688f1b19 100644 --- a/packages/the-framework/dashboard/vite.config.ts +++ b/packages/the-framework/dashboard/vite.config.ts @@ -88,7 +88,7 @@ function frameworkDevDaemon(): Plugin { // plain HTTP (`POST /_rpc/`, plus an SSE stream for the live feed). `index.html` beside this // file is the whole entry; the daemon serves the built output as static files with an SPA fallback. export default defineConfig({ - // The dashboard is a directory inside @gemstack/the-framework rather than a package of its own + // The dashboard is a directory inside `framework` rather than a package of its own // (A7), so `root` is pinned to this file's directory instead of inherited from the cwd — the // scripts that run it live one level up. root: fileURLToPath(new URL('.', import.meta.url)), diff --git a/packages/the-framework/package.json b/packages/the-framework/package.json index e4fa60189..8bc9476bd 100644 --- a/packages/the-framework/package.json +++ b/packages/the-framework/package.json @@ -1,6 +1,6 @@ { - "name": "@gemstack/the-framework", - "version": "0.0.0", + "name": "framework", + "version": "0.7.0", "description": "The (AI) Framework: turnkey, zero-config AI orchestration that wraps a coding-agent CLI (Claude Code) as a black box and takes you from an idea to a running app. Vite for AI.", "keywords": [ "ai", @@ -10,17 +10,16 @@ "framework", "codegen", "cli", - "turnkey", - "gemstack" + "turnkey" ], "license": "MIT", - "homepage": "https://github.com/gemstack-land/the-framework/tree/main/packages/the-framework#readme", + "homepage": "https://github.com/framework/the-framework/tree/main/packages/the-framework#readme", "bugs": { - "url": "https://github.com/gemstack-land/the-framework/issues" + "url": "https://github.com/framework/the-framework/issues" }, "repository": { "type": "git", - "url": "https://github.com/gemstack-land/the-framework", + "url": "https://github.com/framework/the-framework", "directory": "packages/the-framework" }, "type": "module", diff --git a/packages/the-framework/src/layout.ts b/packages/the-framework/src/layout.ts index 9755d2f83..75796c4cb 100644 --- a/packages/the-framework/src/layout.ts +++ b/packages/the-framework/src/layout.ts @@ -68,7 +68,7 @@ export async function checkLayout(cwd: string, fs: StoreFs = nodeStoreFs()): Pro `${THE_FRAMEWORK_DIR}/${LAYOUT_FILE}, so running it here would commit files under names ` + `the repo does not use (#1575).\n\nthis build writes:\n${layoutMarker()}\nthe repo records:\n${recorded}\n` + `A published build that predates a repo-side rename does this: update ` + - `@gemstack/the-framework to a build matching the repo, or — if this build is the newer ` + + `framework to a build matching the repo, or — if this build is the newer ` + `side — rewrite the marker with its layout and land that as the rename's own commit.`, } } diff --git a/packages/the-framework/src/update-check.ts b/packages/the-framework/src/update-check.ts index 52347a398..e22da1332 100644 --- a/packages/the-framework/src/update-check.ts +++ b/packages/the-framework/src/update-check.ts @@ -6,7 +6,7 @@ */ /** The npm package this CLI ships as; the registry key for the version check. */ -export const PACKAGE_NAME = '@gemstack/the-framework' +export const PACKAGE_NAME = 'framework' /** Fetches the latest published version of `pkg`, or undefined on any failure. Injectable for tests. */ export type VersionFetcher = (pkg: string) => Promise