From fb49c1b2dd6093cf9bb14e044eba6cb1552b9c8f Mon Sep 17 00:00:00 2001 From: Kaja Date: Tue, 16 Jun 2026 15:27:53 +0200 Subject: [PATCH 1/3] Add welcome-to-plain front-door skill MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Orientation + routing skill for cold users: explains what *codeplain and ***plain are and how the spec → render → code+tests loop works, then routes to forge-plain, init-plain-project, or add-feature. Does not teach syntax. Ships automatically via the existing recursive copy in bin/cli.mjs — no installer, manifest, or legacy-detection changes needed. Co-Authored-By: Claude Opus 4.8 (1M context) --- forge/skills/welcome-to-plain/SKILL.md | 95 ++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 forge/skills/welcome-to-plain/SKILL.md diff --git a/forge/skills/welcome-to-plain/SKILL.md b/forge/skills/welcome-to-plain/SKILL.md new file mode 100644 index 0000000..c91bffb --- /dev/null +++ b/forge/skills/welcome-to-plain/SKILL.md @@ -0,0 +1,95 @@ +--- +name: welcome-to-plain +description: >- + Friendly front door to *codeplain and the ***plain spec language. Explains + what ***plain is, why spec-driven development matters, and how the + spec → render → code+tests loop works — adapting to how much the user already + knows — then routes them to the right next step. Use when the user is new to + codeplain / ***plain, asks "what is codeplain", "how does this work", + "getting started", "intro to plain", or has just installed plain-forge and + doesn't know where to begin. Hands off to forge-plain, init-plain-project, or + add-feature. Does NOT teach syntax — forge-plain does that by writing specs. +--- + +# Welcome to *codeplain + +## Your Role + +You are the **front door** for someone new to `*codeplain` and the `***plain` spec language. Your only two jobs are: + +1. **Orient** — explain *what* `***plain` is, *why* spec-driven development is worth caring about, and *how* the spec → render → code loop works, at whatever depth the user needs. +2. **Route** — hand them off to the skill that starts the real work. + +You do **not** teach `***plain` syntax here, and you do **not** author any specs. That is `forge-plain`'s job — the user learns the syntax by watching `forge-plain` write the spec *with* them. Do **not** invoke `load-plain-reference`: this skill is orientation, not authoring, and pulling the full language reference into context here is wasted effort. + +Keep the whole interaction **short and conversational**. This is a warm welcome and a signpost, not a lecture. Never block the user — if they want to start building immediately, let them skip straight to the routing step. + +## Step 1 — Calibrate + +Before explaining anything, gauge how much the user already knows so the explanation lands at the right depth. Ask **one** `AskUserQuestion`: + +> "Have you worked with spec-driven or code-generation tools before?" + +Offer these options (plus the automatic free-form catch-all): + +- **New to this** — never used spec-driven development or codegen tools. +- **I've used codegen before** — familiar with the idea; wants the differentiator, not the basics. +- **Just get me building** — skip the explainer entirely. + +If the user picks **"Just get me building,"** skip Step 2 and go straight to Step 3. + +## Step 2 — Explain (depth set by Step 1) + +Cover the four points below, tightly. For a **new** user, walk all four. For an **experienced** user, lead with the differentiator and skip the basics. + +- **What it is.** `***plain` is a markdown-like language for describing software *intent* in natural language. `*codeplain` is the renderer that turns a `.plain` spec into production-ready, tested code. + +- **Why it matters.** You maintain the **spec**, not the code. The generated code is a regeneratable artifact — it lands in `plain_modules/` and is read-only. When something needs to change, you change the spec and re-render; you never hand-edit the output. Conformance tests are part of the contract that gates correctness. + +- **How it works.** Write a `.plain` spec → run `codeplain` → code (and tests) land under `plain_modules/` → you iterate on the *spec*, never the generated code. A `.plain` file has four sections — name them at a glance, but do **not** drill into syntax: + - `***definitions***` — the concepts in your system. + - `***functional specs***` — what the software should do. + - `***implementation reqs***` — how it should be built (language, frameworks, conventions, unit tests). + - `***test reqs***` — how conformance tests are run. + +- **A concrete moment.** Show a tiny side-by-side so it clicks — the spec a person writes vs. what `codeplain` produces from it. Keep it illustrative, not a lesson: + + ```plain + ***functional specs*** + + - Display "hello, world" + + ***acceptance tests*** + - :App: should exit with status code 0. + + ***implementation reqs*** + + - :Implementation: should be in Python. + - :MainExecutableFile: of :App: should be called "hello_world.py". + ``` + + From that, `codeplain` renders a working `hello_world.py` under `plain_modules/` **plus** the tests that prove it satisfies the spec. Offer to draw the **spec → render → code + tests** flow as a quick diagram if the user is a visual thinker. + +- **For experienced users, lead with the differentiator:** unlike one-shot code generators, the spec is the **durable source of truth** and is *re-rendered* — not generated once and then edited by hand. Conformance tests are part of that contract, not an afterthought. That's the whole point: you evolve the spec, the code follows. + +Then move straight to routing. + +## Step 3 — Route + +Ask **one** `AskUserQuestion` — "What would you like to do next?" — and hand off by invoking the matching skill by name (the same way `forge-plain` invokes its sub-skills). Offer: + +| Choice | Hand off to | When | +|--------|-------------|------| +| **Build something new, guided** | `forge-plain` | New project from scratch — full one-question-at-a-time interview ending in a real render. | +| **Quick scaffold, I'll write specs** | `init-plain-project` | Wants a project skeleton fast, then writes functional specs against it. | +| **Add to an existing `***plain` project** | `add-feature` | The `.plain` project already exists and they want to extend it. | +| **Just learning / not yet** | *(none)* | Point them at the docs (`https://plainlang.org/`), the example projects, and the community on Discord (`https://discord.gg/cgbynb9hFq`), then stop. | + +Once the user chooses, invoke the corresponding skill immediately. Do not re-explain — the next skill takes it from here. + +## Guardrails + +- **Never block the user.** They can jump to building at any point; "Just get me building" must always short-circuit to Step 3. +- **Never author specs in this skill** and **never teach `***plain` syntax** — that belongs to `forge-plain` and `load-plain-reference`. +- **Keep it brief.** Orientation and a signpost, nothing more. +- **Question style:** keep questions short and plain-worded — one idea per sentence, concrete options plus a free-form catch-all. From d3b719a249d25ecd0962ad99dce87688141fa2a4 Mon Sep 17 00:00:00 2001 From: Kaja Date: Tue, 16 Jun 2026 15:27:53 +0200 Subject: [PATCH 2/3] Add CLAUDE.md guidance for the repo Co-Authored-By: Claude Opus 4.8 (1M context) --- CLAUDE.md | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..446c0d5 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,50 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## What this repo is + +`plain-forge` is an **npm-distributed installer CLI**. Its job is to copy a tree of authoring content (skills, rules, docs) into an AI coding agent's directory (`.claude/`, `.codex/`, `.forgecode/`, or `.agents/`) so that agent can help users write `***plain` specs for the [codeplain](https://codeplain.ai) renderer. + +There are two distinct kinds of content here, and they almost never change together: + +- **The CLI** (`bin/cli.mjs`) — the install/update/uninstall machinery. This is the only executable code in the repo. +- **The payload** (`forge/skills/`, `forge/rules/`) — Markdown skills and rules that get copied verbatim onto disk. Editing a skill is editing documentation/prompts, not program logic. + +## Commands + +```bash +npm test # run the full test suite (node --test over test/**/*.test.mjs) +node --test test/cli.test.mjs # run one test file +node --test --test-name-pattern "compareVersions" test/cli.test.mjs # run tests matching a name + +node bin/cli.mjs install --agent claude --scope project # exercise the CLI locally +node bin/cli.mjs update +node bin/cli.mjs uninstall --agent claude --scope project +``` + +There is **no build step.** Install copies `forge/` straight to disk. The `build`/`clean` scripts in `package.json` (and the `runtimes/**` glob in `tsconfig.json`) reference `bin/forge-build.ts` and a `runtimes/` directory that do not exist — they are stale; ignore them. `tsx`/`typescript` are devDependencies but unused; there are no runtime dependencies. + +## Architecture of the CLI (`bin/cli.mjs`) + +A single ~700-line ESM file, pure Node stdlib, no deps. It exports its internals at the bottom so `test/cli.test.mjs` can unit-test them directly (alongside spawning the CLI as a subprocess for end-to-end checks). Keep that export list in sync when adding testable helpers. + +The whole design centers on the **install manifest** at `/.plain-forge/manifest.json`, which records exactly which files plain-forge wrote. This is what lets `update` and `uninstall` touch only plain-forge's own files and never the user's or third-party skills sharing the same directory. + +- `AGENTS` maps an agent name → its directory (`.claude`, etc.); `SCOPES` is `project` (cwd) vs `global` ($HOME). `CONTENT_DIRS` = `skills`, `rules`, `docs` — note `forge/docs/` may not exist; `copyTreeTracked` silently skips a missing source dir, so `docs` is effectively optional. +- **install** (`cmdInstall`): refuses if a manifest OR a signature install already exists; otherwise `writeContent` copies the tree and `writeManifest` records it. +- **update** (`cmdUpdate`): `detectInstalls` scans both scopes × all agents; `isUpToDate`/`compareVersions` skip installs whose manifest version ≥ package version; re-copies, then **prunes** files in the old manifest but not the new copy (`collectPruneCandidates`), confirming each deletion unless `--yes`. +- **uninstall** (`cmdUninstall`): deletes exactly the manifest's files, then the manifest, then empties upward. **Refuses** if there's no manifest (can't tell which files are ours). +- **Legacy detection**: installs predating manifests are recognized by `hasForgeSignature` — all of `FORGE_SIGNATURE_SKILLS` present. Legacy installs are refreshed without pruning and gain a manifest going forward. + +Two non-obvious invariants the code documents in comments and tests enforce: +- Non-TTY runs never delete anything without `--yes` (`promptConfirm` returns false when stdin isn't a TTY). +- `isInvokedDirectly` realpath-resolves both `argv[1]` and `import.meta.url` so the CLI still runs when invoked through a symlinked bin (npx / global install) but stays dormant on `import` from tests. + +When changing prune/uninstall/detection logic, update the manifest format and the legacy-signature list together — a mismatch silently strips or orphans users' installs. + +## The `forge/` payload + +`forge/skills/` holds ~29 skills (each a directory with `SKILL.md` and frontmatter `name`/`description`); `forge/rules/` holds the `***plain` spec-writing rules installed as workspace instructions. This content is the product — the README documents what each skill does. When editing skills, you are writing the prompts/instructions the downstream agent follows; match the existing one-question-at-a-time, write-immediately authoring style described in the skills themselves. The skills operate on `.plain` spec files and treat generated code under `plain_modules/` as a read-only artifact — never a place to edit. + +`package.json` ships only `bin/cli.mjs` and `forge/` to npm (see `files`), so anything outside those (README, tests, assets) is dev-only and not delivered to users. From 08ecd8b66f82f645d65e31e0c4f4d0176076bc25 Mon Sep 17 00:00:00 2001 From: Kaja Date: Tue, 23 Jun 2026 17:02:36 +0200 Subject: [PATCH 3/3] Added 'load-plain-reference" --- forge/skills/welcome-to-plain/SKILL.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/forge/skills/welcome-to-plain/SKILL.md b/forge/skills/welcome-to-plain/SKILL.md index c91bffb..639ab90 100644 --- a/forge/skills/welcome-to-plain/SKILL.md +++ b/forge/skills/welcome-to-plain/SKILL.md @@ -13,6 +13,8 @@ description: >- # Welcome to *codeplain +Always use the skill `load-plain-reference` to retrieve the ***plain syntax rules — but only if you haven't done so yet. + ## Your Role You are the **front door** for someone new to `*codeplain` and the `***plain` spec language. Your only two jobs are: @@ -28,15 +30,15 @@ Keep the whole interaction **short and conversational**. This is a warm welcome Before explaining anything, gauge how much the user already knows so the explanation lands at the right depth. Ask **one** `AskUserQuestion`: -> "Have you worked with spec-driven or code-generation tools before?" +> "Have you written `***plain` specs before?" Offer these options (plus the automatic free-form catch-all): -- **New to this** — never used spec-driven development or codegen tools. -- **I've used codegen before** — familiar with the idea; wants the differentiator, not the basics. -- **Just get me building** — skip the explainer entirely. +- **Yes, I know `***plain`** — ready to start building; skip the tour entirely. +- **No, but I know spec-driven dev** — familiar with keeping specs as the source of truth (OpenAPI, Protobuf, interface definitions, etc.); wants the differentiator, not the basics. Note: using AI coding assistants like Cursor or Copilot is *not* spec-driven dev — if that's their background, this is the wrong option. +- **No, I'm new to spec-driven dev** — may use agentic coding tools (Claude Code, Copilot, Cursor), but has not worked with a spec-as-source-of-truth workflow before. -If the user picks **"Just get me building,"** skip Step 2 and go straight to Step 3. +If the user picks **"Yes, I know `***plain`,"** skip Step 2 and go straight to Step 3. ## Step 2 — Explain (depth set by Step 1) @@ -81,7 +83,6 @@ Ask **one** `AskUserQuestion` — "What would you like to do next?" — and hand | Choice | Hand off to | When | |--------|-------------|------| | **Build something new, guided** | `forge-plain` | New project from scratch — full one-question-at-a-time interview ending in a real render. | -| **Quick scaffold, I'll write specs** | `init-plain-project` | Wants a project skeleton fast, then writes functional specs against it. | | **Add to an existing `***plain` project** | `add-feature` | The `.plain` project already exists and they want to extend it. | | **Just learning / not yet** | *(none)* | Point them at the docs (`https://plainlang.org/`), the example projects, and the community on Discord (`https://discord.gg/cgbynb9hFq`), then stop. |