@pilotspace/add 1.7.2 → 1.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/GETTING-STARTED.md +5 -2
- package/README.md +7 -0
- package/bin/cli.js +69 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,33 @@ All notable changes to the ADD method (`@pilotspace/add` on npm,
|
|
|
4
4
|
`pilotspace-add` on PyPI) are documented here. The format follows
|
|
5
5
|
[Keep a Changelog](https://keepachangelog.com/); versions follow semver.
|
|
6
6
|
|
|
7
|
+
## [1.7.3] — 2026-06-18
|
|
8
|
+
|
|
9
|
+
Multi-agent installer reach (`multi-agent-installer`). Additive; no breaking
|
|
10
|
+
changes — the non-interactive byte stream is unchanged for existing agents and
|
|
11
|
+
the engine (`add.py`) is byte-identical.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- **Seven new agent profiles in the installer** — `add init` now detects and
|
|
15
|
+
onboards **Cursor, Windsurf, Trae, GitHub Copilot, Cline, Aider, and Gemini
|
|
16
|
+
CLI** (best-effort env detection, overridable in the interactive picker), in
|
|
17
|
+
addition to Claude Code, Codex, and OpenCode. Each gets the context file it
|
|
18
|
+
actually auto-loads: `AGENTS.md` for most, `.clinerules` for Cline. Unknown
|
|
19
|
+
agents still degrade to the generic `AGENTS.md`. Mirrored byte-for-decision
|
|
20
|
+
across both installer twins (`bin/cli.js` + `src/add_method/_installer.py`).
|
|
21
|
+
- **Gemini CLI settings wiring (`.gemini/settings.json`)** — because Gemini CLI
|
|
22
|
+
auto-loads `GEMINI.md` (not `AGENTS.md`), the installer now performs a
|
|
23
|
+
fail-soft, idempotent, key-preserving merge of `.gemini/settings.json` so its
|
|
24
|
+
`context.fileName` includes `AGENTS.md` — the installer's first JSON-config
|
|
25
|
+
write. Re-running is a no-op; a malformed or unwritable settings file warns and
|
|
26
|
+
is skipped without aborting the install.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
- **Onboarding docs name the full agent set** — the README ("Works with your
|
|
30
|
+
agent") and `GETTING-STARTED.md` now list all ten supported agents and how
|
|
31
|
+
each loads ADD; only Claude Code runs the `/add` skill natively, every other
|
|
32
|
+
agent follows the same loop through the phase guides via the CLI.
|
|
33
|
+
|
|
7
34
|
## [1.7.2] — 2026-06-18
|
|
8
35
|
|
|
9
36
|
Test-coverage and project-hygiene patch. Additive; no breaking changes.
|
package/GETTING-STARTED.md
CHANGED
|
@@ -135,8 +135,11 @@ python3 .add/tooling/add.py status
|
|
|
135
135
|
`add.py status` is the resume point: project stage, active task, current phase.
|
|
136
136
|
And `add.py guide` tells you what the current phase needs — its `guide :` line
|
|
137
137
|
names the exact phase-guide file to read (`.claude/skills/add/phases/…` — plain
|
|
138
|
-
markdown), which is how **any
|
|
139
|
-
ADD through the
|
|
138
|
+
markdown), which is how **any agent** — Claude Code, Codex, OpenCode, Cursor,
|
|
139
|
+
Windsurf, Trae, Gemini CLI, GitHub Copilot, Cline, Aider — follows ADD through the
|
|
140
|
+
CLI alone. The installer detects which one you're in and drops the file it reads
|
|
141
|
+
(`CLAUDE.md`, `AGENTS.md`, or `.clinerules`; for Gemini CLI it also wires
|
|
142
|
+
`.gemini/settings.json`).
|
|
140
143
|
|
|
141
144
|
> Tip: shorten typing with an alias — `alias add="python3 .add/tooling/add.py"` —
|
|
142
145
|
> then you can run `add status`, `add guide`, etc. These are override and resume
|
package/README.md
CHANGED
|
@@ -117,6 +117,13 @@ ADD is AI-first: you talk to the agent; it drives the method. In Claude Code, ru
|
|
|
117
117
|
|
|
118
118
|
> `/add` — *"I want to let users transfer money between their own accounts."*
|
|
119
119
|
|
|
120
|
+
**Works with your agent.** The installer detects which coding agent you're in and
|
|
121
|
+
drops the context file it reads — so ADD drives through the CLI under **Claude Code,
|
|
122
|
+
Codex, OpenCode, Cursor, Windsurf, Trae, Gemini CLI, GitHub Copilot, Cline, and
|
|
123
|
+
Aider** (anything else falls back to a generic `AGENTS.md`). Only Claude Code runs
|
|
124
|
+
the `/add` skill natively; every other agent follows the same loop through the
|
|
125
|
+
phase guides via `add.py status` / `guide`.
|
|
126
|
+
|
|
120
127
|
The agent orients from `state.json`, **sizes your request into a milestone** (you
|
|
121
128
|
confirm the shape), then drafts each feature's **specification bundle** — Spec +
|
|
122
129
|
Scenarios + Contract + Tests as one bundle — and you give **one approval at the
|
package/bin/cli.js
CHANGED
|
@@ -91,6 +91,27 @@ const AGENT_PROFILES = [
|
|
|
91
91
|
{ id: "opencode", label: "OpenCode", integration_file: "AGENTS.md",
|
|
92
92
|
env: ["OPENCODE"], envPrefix: "OPENCODE",
|
|
93
93
|
next_step: "Open OpenCode — it reads AGENTS.md; say what you want to build." },
|
|
94
|
+
{ id: "cursor", label: "Cursor", integration_file: "AGENTS.md",
|
|
95
|
+
env: ["CURSOR_AGENT", "CURSOR_TRACE_ID"], envPrefix: "CURSOR_",
|
|
96
|
+
next_step: "Open Cursor — it reads AGENTS.md; say what you want to build." },
|
|
97
|
+
{ id: "windsurf", label: "Windsurf", integration_file: "AGENTS.md",
|
|
98
|
+
env: ["WINDSURF", "WINDSURF_ENV"], envPrefix: "WINDSURF_",
|
|
99
|
+
next_step: "Open Windsurf — Cascade reads AGENTS.md; say what you want to build." },
|
|
100
|
+
{ id: "trae", label: "Trae", integration_file: "AGENTS.md",
|
|
101
|
+
env: ["TRAE_AI_IDE"], envPrefix: "TRAE_",
|
|
102
|
+
next_step: "Open Trae — it reads AGENTS.md; say what you want to build." },
|
|
103
|
+
{ id: "copilot", label: "GitHub Copilot", integration_file: "AGENTS.md",
|
|
104
|
+
env: ["COPILOT_AGENT"], envPrefix: null, // NOT a GITHUB_ prefix — too broad (CI sets GITHUB_*)
|
|
105
|
+
next_step: "Open GitHub Copilot — it reads AGENTS.md; say what you want to build." },
|
|
106
|
+
{ id: "cline", label: "Cline", integration_file: ".clinerules",
|
|
107
|
+
env: ["CLINE_ACTIVE"], envPrefix: "CLINE_",
|
|
108
|
+
next_step: "Open Cline — it reads .clinerules; say what you want to build." },
|
|
109
|
+
{ id: "aider", label: "Aider", integration_file: "AGENTS.md",
|
|
110
|
+
env: [], envPrefix: "AIDER_",
|
|
111
|
+
next_step: "Open Aider — add AGENTS.md to its context (`.aider.conf.yml` `read:` or `--read AGENTS.md`), then say what you want to build." },
|
|
112
|
+
{ id: "gemini", label: "Gemini CLI", integration_file: "AGENTS.md",
|
|
113
|
+
env: ["GEMINI_CLI", "GEMINI_SANDBOX"], envPrefix: "GEMINI_",
|
|
114
|
+
next_step: "Open Gemini CLI — ADD wired .gemini/settings.json to load AGENTS.md; say what you want to build." },
|
|
94
115
|
{ id: "generic", label: "your AI agent", integration_file: "AGENTS.md",
|
|
95
116
|
env: [], envPrefix: null, next_step: GENERIC_NEXT },
|
|
96
117
|
];
|
|
@@ -151,7 +172,7 @@ function detectAgentEnriched(env, target, which) {
|
|
|
151
172
|
try {
|
|
152
173
|
if (target && fs.existsSync(path.join(target, "CLAUDE.md"))) return byId.claude; // repo signal
|
|
153
174
|
} catch (_e) { /* fall through */ }
|
|
154
|
-
for (const id of ["claude", "codex", "opencode"]) {
|
|
175
|
+
for (const id of ["claude", "codex", "opencode", "cursor", "windsurf", "trae", "copilot", "cline", "aider"]) {
|
|
155
176
|
try { if (which(id)) return byId[id]; } catch (_e) { /* probe absent */ } // machine signal
|
|
156
177
|
}
|
|
157
178
|
return base; // generic
|
|
@@ -376,6 +397,48 @@ function writeIntentNote(target, intent) {
|
|
|
376
397
|
} catch (_e) { return false; }
|
|
377
398
|
}
|
|
378
399
|
|
|
400
|
+
// Merge <target>/.gemini/settings.json so context.fileName includes "AGENTS.md" — the pointer
|
|
401
|
+
// ADD writes for the gemini profile. Gemini CLI defaults to GEMINI.md and lets it win when both
|
|
402
|
+
// exist, so AGENTS.md must be named in the config to load. Read-merge-write: preserves every other
|
|
403
|
+
// key; idempotent; fail-soft (an unparsable/unwritable file warns + skips, never aborts the drop).
|
|
404
|
+
// Returns created|updated|unchanged|skipped. Twin of _installer.py:_write_gemini_settings.
|
|
405
|
+
function writeGeminiSettings(target) {
|
|
406
|
+
const geminiDir = path.join(target, ".gemini");
|
|
407
|
+
const settings = path.join(geminiDir, "settings.json");
|
|
408
|
+
try {
|
|
409
|
+
let data = {};
|
|
410
|
+
let created = true;
|
|
411
|
+
if (fs.existsSync(settings)) {
|
|
412
|
+
created = false;
|
|
413
|
+
let raw;
|
|
414
|
+
try { raw = fs.readFileSync(settings, "utf8"); data = JSON.parse(raw); }
|
|
415
|
+
catch (_e) {
|
|
416
|
+
warn("could not parse " + settings + " — leaving it untouched; skipped");
|
|
417
|
+
return "skipped";
|
|
418
|
+
}
|
|
419
|
+
if (data === null || typeof data !== "object" || Array.isArray(data)) {
|
|
420
|
+
warn(settings + " is not a JSON object — leaving it untouched; skipped");
|
|
421
|
+
return "skipped";
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
let context = data.context;
|
|
425
|
+
if (context === null || typeof context !== "object" || Array.isArray(context)) context = {};
|
|
426
|
+
let names = context.fileName;
|
|
427
|
+
if (typeof names === "string") names = [names];
|
|
428
|
+
else if (!Array.isArray(names)) names = [];
|
|
429
|
+
if (names.includes("AGENTS.md")) return "unchanged"; // idempotent
|
|
430
|
+
names = names.concat(["AGENTS.md"]);
|
|
431
|
+
context.fileName = names;
|
|
432
|
+
data.context = context;
|
|
433
|
+
fs.mkdirSync(geminiDir, { recursive: true });
|
|
434
|
+
fs.writeFileSync(settings, JSON.stringify(data, null, 2) + "\n");
|
|
435
|
+
return created ? "created" : "updated";
|
|
436
|
+
} catch (e) {
|
|
437
|
+
warn("could not write " + settings + " — " + (e && e.message ? e.message : e) + "; skipped");
|
|
438
|
+
return "skipped"; // design-for-failure: never abort the install
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
379
442
|
// The drop — now a RECONCILE: restore missing managed trees + refresh present ones
|
|
380
443
|
// (sweep orphans) + report per-tree status. Byte-compatible handoff with the prior
|
|
381
444
|
// installer. The interactive path resolves a target then calls straight into this.
|
|
@@ -389,6 +452,10 @@ function dropFiles(args, target, profile, intent) {
|
|
|
389
452
|
// Best-effort + fail-soft — never aborts the successful drop above.
|
|
390
453
|
writeAgentPointer(target, profile);
|
|
391
454
|
|
|
455
|
+
// Gemini CLI auto-loads GEMINI.md, not AGENTS.md — so for the gemini profile we ALSO merge
|
|
456
|
+
// .gemini/settings.json (context.fileName) to load the AGENTS.md pointer. Fail-soft + idempotent.
|
|
457
|
+
if (profile.id === "gemini") writeGeminiSettings(target);
|
|
458
|
+
|
|
392
459
|
// Optional build-intent NOTE for `/add` to read — "" (skip / non-interactive) -> no-op.
|
|
393
460
|
writeIntentNote(target, intent);
|
|
394
461
|
|
|
@@ -779,4 +846,5 @@ module.exports = {
|
|
|
779
846
|
whichSync: whichSync,
|
|
780
847
|
scopeOptions: scopeOptions,
|
|
781
848
|
writeIntentNote: writeIntentNote,
|
|
849
|
+
writeGeminiSettings: writeGeminiSettings,
|
|
782
850
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pilotspace/add",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.3",
|
|
4
4
|
"description": "ADD (AI-Driven Development). One skill. Eight steps. Five disciplines. Every feature ships through the loop — a minimal, state-tracked Claude Code skill that ships the AIDD book as its trust layer.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"add": "bin/cli.js"
|