@pilotspace/add 1.7.1 → 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 +46 -0
- package/GETTING-STARTED.md +5 -2
- package/README.md +16 -0
- package/SECURITY.md +48 -0
- package/bin/cli.js +69 -1
- package/package.json +4 -3
- package/skill/add/SKILL.md +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,52 @@ 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
|
+
|
|
34
|
+
## [1.7.2] — 2026-06-18
|
|
35
|
+
|
|
36
|
+
Test-coverage and project-hygiene patch. Additive; no breaking changes.
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
- **PTY harness for clack interactive coverage (`installer-smarts-polish`)** — a
|
|
40
|
+
reusable PTY test helper (`tooling/pty_clack.py`) drives the clack
|
|
41
|
+
select/confirm prompts, so the agent-select step and the interactive
|
|
42
|
+
happy-path are exercised under a real pseudo-terminal in CI (previously
|
|
43
|
+
node-syntax-checked and logic-unit-tested only).
|
|
44
|
+
- **`SECURITY.md` security policy** — supported-version table, private
|
|
45
|
+
vulnerability reporting via GitHub Security Advisories, and response SLAs;
|
|
46
|
+
shipped in both the npm tarball and the PyPI sdist/wheel.
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
- **Brand tagline** — refreshed to *"One skill. Eight steps. Five disciplines.
|
|
50
|
+
Every feature ships through the loop."* across the README, the npm/PyPI
|
|
51
|
+
package descriptions, and the Claude Code plugin manifest.
|
|
52
|
+
|
|
7
53
|
## [1.7.1] — 2026-06-18
|
|
8
54
|
|
|
9
55
|
Installer depth and method quality release: the onboarding installer gains
|
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
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# ADD — AI-Driven Development
|
|
2
2
|
|
|
3
|
+
**One skill. Eight steps. Five disciplines. Every feature ships through the loop.**
|
|
4
|
+
|
|
3
5
|
> A minimal, state-tracked Claude Code skill for building software when the AI
|
|
4
6
|
> writes the code and **you** own the two things it cannot do alone: decide *what*
|
|
5
7
|
> to build, and *verify* it is correct.
|
|
@@ -115,6 +117,13 @@ ADD is AI-first: you talk to the agent; it drives the method. In Claude Code, ru
|
|
|
115
117
|
|
|
116
118
|
> `/add` — *"I want to let users transfer money between their own accounts."*
|
|
117
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
|
+
|
|
118
127
|
The agent orients from `state.json`, **sizes your request into a milestone** (you
|
|
119
128
|
confirm the shape), then drafts each feature's **specification bundle** — Spec +
|
|
120
129
|
Scenarios + Contract + Tests as one bundle — and you give **one approval at the
|
|
@@ -149,6 +158,13 @@ be upset to lose is "the code," you're still working the old way.
|
|
|
149
158
|
Start at [`docs/README.md`](./docs/README.md) — Foundations → the six steps →
|
|
150
159
|
operating it across a team → templates, prompts, and a full worked example.
|
|
151
160
|
|
|
161
|
+
## What's next
|
|
162
|
+
|
|
163
|
+
**Dynamic Agent Skills** — the next scope: skills that adapt at runtime to the
|
|
164
|
+
project's current state, stage, and active phase rather than loading a static
|
|
165
|
+
guide. The agent picks the right depth and tooling automatically as the project
|
|
166
|
+
evolves.
|
|
167
|
+
|
|
152
168
|
## Develop
|
|
153
169
|
|
|
154
170
|
```bash
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
ADD (AI-Driven Development) ships as [`@pilotspace/add`](https://www.npmjs.com/package/@pilotspace/add)
|
|
4
|
+
on npm and [`pilotspace-add`](https://pypi.org/project/pilotspace-add/) on PyPI. This policy
|
|
5
|
+
covers both distributions and the engine/tooling in this repository.
|
|
6
|
+
|
|
7
|
+
## Supported Versions
|
|
8
|
+
|
|
9
|
+
Security fixes land on the latest minor release line. Older lines are not
|
|
10
|
+
back-patched — upgrade to the latest `1.7.x` to receive fixes.
|
|
11
|
+
|
|
12
|
+
| Version | Supported |
|
|
13
|
+
| ------- | ------------------ |
|
|
14
|
+
| 1.7.x | :white_check_mark: |
|
|
15
|
+
| < 1.7 | :x: |
|
|
16
|
+
|
|
17
|
+
To check your installed version: `python3 .add/tooling/add.py status` (project),
|
|
18
|
+
`pip show pilotspace-add`, or `npm ls @pilotspace/add`.
|
|
19
|
+
|
|
20
|
+
## Reporting a Vulnerability
|
|
21
|
+
|
|
22
|
+
**Please do not open a public GitHub issue for security reports.**
|
|
23
|
+
|
|
24
|
+
Report privately through one of:
|
|
25
|
+
|
|
26
|
+
- **GitHub Security Advisories** (preferred) — open a private report via the
|
|
27
|
+
repository's **Security → Report a vulnerability** tab. This keeps the details
|
|
28
|
+
confidential until a fix ships.
|
|
29
|
+
- **Email** — `tindang.ht97@gmail.com` with subject `SECURITY: <short summary>`.
|
|
30
|
+
|
|
31
|
+
Please include:
|
|
32
|
+
|
|
33
|
+
- the affected version, platform, and install channel (npm / PyPI / source);
|
|
34
|
+
- a description of the issue and its impact;
|
|
35
|
+
- reproduction steps or a proof of concept, if available.
|
|
36
|
+
|
|
37
|
+
### What to expect
|
|
38
|
+
|
|
39
|
+
- **Acknowledgement** within **3 business days** of your report.
|
|
40
|
+
- **Triage assessment** (accepted / needs-info / declined, with rationale)
|
|
41
|
+
within **10 business days**.
|
|
42
|
+
- For **accepted** reports: a coordinated fix and release, with credit to you in
|
|
43
|
+
the release notes unless you prefer to remain anonymous. We will keep you
|
|
44
|
+
updated on remediation progress.
|
|
45
|
+
- For **declined** reports: an explanation of why the issue falls outside the
|
|
46
|
+
project's threat model.
|
|
47
|
+
|
|
48
|
+
Please give us a reasonable window to release a fix before any public disclosure.
|
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,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pilotspace/add",
|
|
3
|
-
"version": "1.7.
|
|
4
|
-
"description": "ADD (AI-Driven Development)
|
|
3
|
+
"version": "1.7.3",
|
|
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"
|
|
7
7
|
},
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
"docs/",
|
|
24
24
|
"README.md",
|
|
25
25
|
"GETTING-STARTED.md",
|
|
26
|
-
"CHANGELOG.md"
|
|
26
|
+
"CHANGELOG.md",
|
|
27
|
+
"SECURITY.md"
|
|
27
28
|
],
|
|
28
29
|
"keywords": [
|
|
29
30
|
"ai-driven-development",
|
package/skill/add/SKILL.md
CHANGED
|
@@ -85,7 +85,9 @@ unsharp intent? **Interview before you size** — explore and suggest first (`in
|
|
|
85
85
|
Once a request is classified `new-major`/`sub-milestone`, drafting the actual
|
|
86
86
|
`MILESTONE.md` (goal · scope · exit criteria · breadth-first tasks) is the second
|
|
87
87
|
half of intake: read `scope.md` for how to fill it well, the per-outcome behavior,
|
|
88
|
-
and the confirm-before-create rule.
|
|
88
|
+
and the confirm-before-create rule. Or if it's classified `task`/`change-request`,
|
|
89
|
+
create the task with `add.py new-task` and then read the phase guide for the first phase (probably `0-setup.md`).
|
|
90
|
+
You propose the draft; the human confirms.
|
|
89
91
|
|
|
90
92
|
## The flow and which file to load
|
|
91
93
|
|