Skip to content

Commit 9352df7

Browse files
Make AGENTS.md the single instruction file; add Gemini pointer, drop Cursor/Windsurf duplication (closes #145) (#149)
AGENTS.md is Launchpad's one agent-instruction contract. Projections must never duplicate it - they only add what a tool needs to read it. - Gemini CLI: new opt-in `gemini` projection writes a minimal .gemini/settings.json that sets context.fileName to AGENTS.md, so Gemini reads the canonical file instead of a separate GEMINI.md. Adds a CONFIG file kind for vendor config that points at canonical output. - Cursor and Windsurf: removed their rule-file projections. Both read a root AGENTS.md natively (Cursor as always-on rules; Windsurf/Cascade via the same rules engine as .windsurf/rules), so the generated .cursor/rules and .windsurf/rules files only duplicated the contract and could drift. Nothing is emitted for them now. The Cursor MCP-client integration is untouched. No engine change; projections remain auto-discovered AgentProjection beans. Updates docs and changelog.
1 parent fc2226c commit 9352df7

17 files changed

Lines changed: 211 additions & 585 deletions

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99
### Added
10+
- **Gemini CLI compatibility projection**: An opt-in `gemini` `AgentProjection` points Gemini CLI at the canonical `AGENTS.md` instead of emitting a redundant context file. It writes a minimal `.gemini/settings.json` setting `context.fileName` to `AGENTS.md`, so Gemini reads the single source-of-truth contract with no duplicated content to drift out of sync. An existing hand-authored `.gemini/settings.json` is never clobbered. Adds a `CONFIG` file kind for vendor files that point at canonical output. Enable it via `projections: ["claude", "gemini"]` in the standards manifest or by ticking Gemini CLI in the TUI projection picker; no engine change was required (closes #145).
1011
- **Anthropic (Claude) cloud preparation provider**: An opt-in, paid synthesis backend on the `PreparationProvider` SPI (`provider=anthropic`), shipped via the Spring AI Anthropic starter. It is explicit-selection only - `autoDetectable()` is `false`, so auto-detection never routes preparation to a paid API even when a key is present; local AI stays the default. Authentication is vendor-specific (`launchpad.ai.anthropic.api-key`, bound from `LAUNCHPAD_ANTHROPIC_API_KEY`, falling back to the shared key), with its own cloud base URL and `anthropic-version`. A missing key or an unreachable endpoint degrades cleanly to deterministic-only output instead of crashing. Adding it was a single new bean plus its config - no router or health-checker changes (toward #144).
1112
- **Project readiness evaluator**: `ReadinessEvaluator.evaluate(Path)` returns a read-only `ReadinessResult` (status, structured reason lines, recommended action, last-prepared timestamp) derived from a project's prepared artifacts (`AGENTS.md` and the `.launchpad/*.json` sidecars) and its provenance stamp - the deterministic verdict the readiness dashboard renders. `ProvenanceHeader` gains a `parse(...)` inverse of `render()` (closes #122).
1213
- **Output contract docs**: `docs/output-contract.adoc` documents every file a scan writes - layout, section structure, provenance stamp, write/merge actions, stable-vs-experimental tiers, and versioning - so downstream tools integrate against a contract instead of snapshot-testing prose. Adds a `docs/index.adoc` landing page (closes #91).
@@ -42,6 +43,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4243
- **Manifest now required for a pack**: A standards source resolves only with a `standards-pack.yml` declaring a supported `schemaVersion` (closes #84).
4344

4445
### Removed
46+
- **Cursor and Windsurf rule-file projections**: Dropped the `cursor` (`.cursor/rules/*.mdc`) and `windsurf` (`.windsurf/rules/*.md`) projections. Both tools read a root `AGENTS.md` natively (Cursor applies it as always-on rules; Windsurf/Cascade discovers it through the same rules engine as `.windsurf/rules`), so those generated files only duplicated the canonical contract and could drift out of sync. `AGENTS.md` is the single agent-instruction file; nothing is emitted for Cursor or Windsurf. The Cursor MCP-client integration is unaffected.
4547
- **Redundant Renderers**: Removed `BuildProfilesRenderer` and duplicate synthesis paths.
4648
- **Legacy Artifacts**: Removed obsolete planning markers and redundant tests.
4749
- **Legacy flat-file standards mode**: Dropped the manifest-less fallback that read bare `rules.yml` / `skills.yml` from the root of a standards source. Every pack is now a versioned manifest, so there is no second, unversioned load path (closes #84).

docs/architecture.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ This ordering is deliberate. Deterministic analysis is fast, repeatable, and doe
2222

2323
=== Vendor-neutral output
2424

25-
Generated context files use a standard shape (`AGENTS.md` + `.ai/`) that any AI assistant can read. Agent-specific formats (Claude Code skills, Cursor rules, Windsurf rules) are produced as optional projections on top of the canonical output, not as replacements for it.
25+
Generated context files use a standard shape (`AGENTS.md` + `.ai/`) that any AI assistant can read. `AGENTS.md` is the single agent-instruction contract; projections never duplicate it. Tools that read `AGENTS.md` natively (Cursor, Windsurf) get no generated file at all. Optional projections add only what a tool needs on top of the canonical output -- Claude Code slash-command skills, or a `.gemini/settings.json` that points Gemini CLI at `AGENTS.md` -- never a replacement for it.
2626

2727
The standards companions (`.ai/engineering-rules.md`, `.ai/skills.md`, `.ai/checklists.md`) emit one stable-slug heading per rule, skill, and checklist -- each anchor derived from the record's stable id, not its title -- so downstream sandbox indexers chunk the corpus one item at a time. `AGENTS.md` itself stays standards-free.
2828

docs/getting-started.adoc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ Press `s` to apply all plans. Launchpad backs up any file it changes to `.launch
9898
│ ├── checklists.md # checklists from your standards pack
9999
│ └── index.md # index of all .ai/ files
100100
├── .claude/skills/<id>/SKILL.md # Claude Code slash-command stubs (one per skill)
101-
├── .cursor/rules/<id>.mdc # Cursor rules (if Cursor projection is enabled)
102101
└── .launchpad/
103102
├── scan.json # structured scan cache (read by MCP server and audit)
104103
├── audit.md # audit findings (if standards pack has check: rules)

docs/output-contract.adoc

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,16 @@ tier (see <<Stability tiers>>).
2828
----
2929
<project-root>/
3030
├── AGENTS.md # primary agent-instructions file [stable layout / experimental prose]
31+
├── .gemini/
32+
│ └── settings.json # points Gemini CLI at AGENTS.md (opt-in) [stable]
3133
├── .ai/
3234
│ ├── index.md # navigation index + skills list [stable]
3335
│ ├── stack.md # detected stack and dependencies [stable]
3436
│ ├── engineering-rules.md # rules (only if rules exist) [stable]
3537
│ ├── skills.md # skills (only if skills exist) [stable]
3638
│ └── checklists.md # checklists (only if checklists exist) [stable]
3739
├── .claude/
38-
│ └── skills/<skill-id>/SKILL.md # Claude Code projection (default-on) [stable]
39-
├── .cursor/
40-
│ └── rules/*.mdc # Cursor projection (opt-in) [stable]
41-
├── .windsurf/
42-
│ └── rules/*.md # Windsurf projection (opt-in) [stable]
40+
│ └── skills/<skill-id>/SKILL.md # Claude Code slash commands (default-on) [stable]
4341
└── .launchpad/
4442
├── project.model.json # deterministic structure graph [stable, versioned]
4543
├── standards.index.json # deterministic standards records [stable, versioned]
@@ -50,9 +48,17 @@ tier (see <<Stability tiers>>).
5048

5149
Conditional companions (`engineering-rules.md`, `skills.md`, `checklists.md`)
5250
are written only when the resolved standards pack contributes that record type.
53-
The projection directories appear only for enabled projections - `claude` is
54-
on by default; `cursor` and `windsurf` are opt-in via the standards manifest's
55-
`projections` list.
51+
The projection outputs appear only for enabled projections - `claude` is on by
52+
default and `gemini` is opt-in, via the standards manifest's `projections` list
53+
or the TUI projection picker.
54+
55+
`AGENTS.md` is the single agent-instruction contract; projections never
56+
duplicate it. Cursor and Windsurf read `AGENTS.md` natively (root = always-on
57+
rules), so Launchpad generates no vendor instruction files for them. Gemini CLI
58+
defaults to a different file name but is configurable, so the `gemini` projection
59+
emits only a `.gemini/settings.json` that points `context.fileName` at
60+
`AGENTS.md`. The `claude` projection emits Claude Code slash commands, which are
61+
invokable workflows rather than an instruction file.
5662

5763
== Generated files
5864

@@ -67,12 +73,43 @@ on by default; `cursor` and `windsurf` are opt-in via the standards manifest's
6773
| `.ai/skills.md` | `SKILLS` | deterministic (from pack) | only if skills exist
6874
| `.ai/checklists.md` | `CONTEXT` | deterministic (from pack) | only if checklists exist
6975
| `.claude/skills/<id>/SKILL.md` | `SKILL` | deterministic projection | per skill (default-on)
70-
| `.cursor/rules/*.mdc` | `RULES` / `SKILL` | deterministic projection | opt-in
71-
| `.windsurf/rules/*.md` | `RULES` / `SKILL` | deterministic projection | opt-in
76+
| `.gemini/settings.json` | `CONFIG` | deterministic projection | opt-in
7277
|===
7378

79+
=== Cursor and Windsurf
80+
81+
Neither tool gets a generated file. Cursor reads a root `AGENTS.md` natively
82+
(applied as always-on rules, alongside any `.cursor/rules`), and Windsurf/Cascade
83+
discovers a root `AGENTS.md` through the same rules engine that powers
84+
`.windsurf/rules`. Because both already consume the canonical contract, Launchpad
85+
emits nothing for them - `AGENTS.md` is the single source of truth.
86+
87+
=== Gemini CLI projection
88+
89+
The `gemini` projection does *not* emit a separate context file. Gemini CLI
90+
loads its project context from a configurable file name (default `GEMINI.md`),
91+
so rather than duplicate `AGENTS.md` into a `GEMINI.md` that would clutter the
92+
repo and drift out of sync, the projection writes a minimal
93+
`.gemini/settings.json` that sets `context.fileName` to `AGENTS.md`:
94+
95+
[source,json]
96+
----
97+
{
98+
"context": {
99+
"fileName": "AGENTS.md"
100+
}
101+
}
102+
----
103+
104+
Gemini CLI then reads the single source-of-truth contract directly. The settings
105+
file carries no JSON comment markers, so an existing hand-authored
106+
`.gemini/settings.json` is classified `SKIP` and never clobbered - developers who
107+
already maintain that file add `context.fileName: "AGENTS.md"` themselves. Enable
108+
the projection with `projections: ["claude", "gemini"]` in the standards manifest
109+
or by ticking Gemini CLI in the TUI projection picker.
110+
74111
`Kind` is the stable `FileKind` discriminator carried on every generated file
75-
(`CONTEXT`, `RULES`, `SKILL`, `SKILLS`, `INDEX`). "Deterministic" means the
112+
(`CONTEXT`, `RULES`, `SKILL`, `SKILLS`, `INDEX`, `CONFIG`). "Deterministic" means the
76113
content is assembled from the scan and standards pack with no model call;
77114
"AI-synthesized" means a local model authored the prose (with a deterministic
78115
fallback when synthesis is disabled).
@@ -158,8 +195,8 @@ rely on this decision table:
158195
*Stable* - safe to integrate against; changes here follow the versioning policy
159196
below:
160197

161-
* File paths and directory layout (`AGENTS.md`, `.ai/*`, `.claude/`, `.cursor/`,
162-
`.windsurf/`, `.launchpad/*`).
198+
* File paths and directory layout (`AGENTS.md`, `.ai/*`, `.claude/`,
199+
`.gemini/settings.json`, `.launchpad/*`).
163200
* The `launchpad:provenance` and `launchpad:managed:start/end` marker tokens.
164201
* The `FileKind` discriminator and the write-action decision table.
165202
* `.ai/*` heading anchors (explicit `{#slug}` anchors derived from each record's

docs/standards-packs.adoc

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,15 @@ includes:
7171
7272
projections:
7373
- claude
74-
- cursor
74+
- gemini
7575
----
7676

77-
The `projections` field controls which agent-native formats are emitted alongside `AGENTS.md`:
77+
The `projections` field controls which agent-native outputs are emitted alongside `AGENTS.md`. Projections never duplicate `AGENTS.md`; they only add what a tool needs to consume it:
7878

7979
* `claude` -- `.claude/skills/<id>/SKILL.md` for Claude Code slash-command discovery
80-
* `cursor` -- `.cursor/rules/<id>.mdc`
81-
* `windsurf` -- `.windsurfrules`
80+
* `gemini` -- `.gemini/settings.json` that points Gemini CLI's `context.fileName` at `AGENTS.md`
81+
82+
Cursor and Windsurf are not listed: both read a root `AGENTS.md` natively, so no projection is needed for them.
8283

8384
Omit `projections` to use the default (`claude` only). Set it to `[]` to disable all projections.
8485

@@ -305,7 +306,7 @@ When adding a new HTTP route or extending the API surface.
305306

306307
Anchor slugs must be unique: two ids that collapse to the same slug (e.g. `foo.bar` and `foo-bar`) are an authoring conflict and fail the scan, rather than being silently de-duplicated in the output.
307308

308-
Agent projections (`.claude/skills/`, `.cursor/rules/`, `.windsurf/`) are generated from the same source -- editing the YAML updates all outputs on the next scan.
309+
Agent projections (`.claude/skills/`, `.gemini/settings.json`) are generated from the same source -- editing the YAML updates all outputs on the next scan.
309310

310311
== Machine-readable sidecar
311312

src/main/java/com/acltabontabon/launchpad/template/GeneratedFile.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ public enum FileKind {
1111
RULES, // engineering rules files
1212
SKILL, // one skill, vendor-native projection file (e.g. .claude/skills/<id>/SKILL.md)
1313
SKILLS, // canonical aggregated skills companion (.ai/skills.md)
14-
INDEX // .ai/index.md, directory indexes
14+
INDEX, // .ai/index.md, directory indexes
15+
CONFIG // vendor tool config that points the tool at canonical output (e.g. .gemini/settings.json)
1516
}
1617

1718
public String filename() {

src/main/java/com/acltabontabon/launchpad/template/projection/cursor/CursorMdcRenderer.java

Lines changed: 0 additions & 105 deletions
This file was deleted.

src/main/java/com/acltabontabon/launchpad/template/projection/cursor/CursorRulesProjection.java

Lines changed: 0 additions & 75 deletions
This file was deleted.

0 commit comments

Comments
 (0)