@execuro-sw-ecosystem/sw-ecosystem-agentic-harness 0.1.6 → 0.1.8
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 +87 -0
- package/CONTRIBUTING.md +13 -4
- package/README.md +67 -36
- package/SECURITY.md +1 -1
- package/bin/cli.mjs +21 -15
- package/lib/actions.mjs +1 -45
- package/lib/commands.mjs +111 -109
- package/lib/content.mjs +31 -1
- package/lib/guide.mjs +39 -38
- package/lib/hosts.mjs +44 -42
- package/lib/lock.mjs +51 -14
- package/lib/out.mjs +27 -6
- package/lib/prompt.mjs +18 -23
- package/lib/render.mjs +365 -0
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/skills/sw-design-requirements/SKILL.md +1 -1
- package/skills/sw-design-requirements/reference/editor-gate.md +1 -1
- package/skills/sw-design-requirements/reference/editor-mode.md +2 -2
- package/skills/sw-design-solution/SKILL.md +1 -1
- package/skills/sw-design-solution/reference/editor-mode.md +2 -2
- package/skills/sw-discover-tender/SKILL.md +2 -2
- package/skills/sw-discover-tender/reference/editor-session.md +3 -3
- package/skills/sw-discover-tender/reference/procedure.md +2 -2
- package/skills/sw-setup/SKILL.md +19 -17
- package/skills/sw-setup/reference/rows.md +120 -77
- package/lib/extra-components.mjs +0 -117
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,93 @@ release.
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.1.8] - 2026-09-19
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **The lock file moved to `var/sw-ai-sdk/harness.lock.json`, and the
|
|
15
|
+
`.gitignore` line is gone with it.** A Shopware project ignores the whole of
|
|
16
|
+
`var/` through the `shopware/core` Flex recipe (`/var/*`, with a single
|
|
17
|
+
`!/var/.htaccess` negation) and already keeps its machine-local state there
|
|
18
|
+
— `var/cache`, `var/log` — so the installer no longer creates a directory in
|
|
19
|
+
the repository root and no longer writes to `.gitignore` at all. A root with
|
|
20
|
+
no `var/` (`--scope user` under $HOME, or a checkout that is not a Shopware
|
|
21
|
+
project) keeps `.sw-ai-sdk/` and its managed line, unchanged. Nothing here
|
|
22
|
+
reads a path outside the install root, on any platform.
|
|
23
|
+
**Migration is automatic and lossless:** a lock still at the old path is
|
|
24
|
+
read, rewritten to the new one, and the old file, its directory and the
|
|
25
|
+
managed `.gitignore` block are removed. Declined rules, recorded agents and
|
|
26
|
+
file hashes all survive, so the first run after upgrading reinstalls nothing
|
|
27
|
+
— it reports `migrated[]` in `--json` and one line in the human summary.
|
|
28
|
+
`lock_file` in every result body now carries the resolved path; anything
|
|
29
|
+
that hard-coded `.sw-ai-sdk/` should read that key instead.
|
|
30
|
+
|
|
31
|
+
### Removed
|
|
32
|
+
|
|
33
|
+
- **BREAKING: the "extra component" mechanism is gone.** The CLI no longer
|
|
34
|
+
detects, installs, updates or removes the two optional visual editors
|
|
35
|
+
(Specs Editor, Tender Discovery Tool); each package installs its own skill,
|
|
36
|
+
orchestrated by the `sw-setup` skill. Removed with it: the
|
|
37
|
+
`extra_components[]` key from `status --json`, the `--no-extra-components`
|
|
38
|
+
flag on `install`/`plan`/`apply`, the `skipped` field from `plan`'s and
|
|
39
|
+
`apply`'s `summary` (nothing else could produce that state), the
|
|
40
|
+
`skill-copy` action kind, and the "Optional extra components" section of
|
|
41
|
+
`guide`. Anything reading `extra_components[]` or counting `summary.skipped`
|
|
42
|
+
must stop.
|
|
43
|
+
**Why:** the mechanism had never once worked. It spawned `npx --no-install
|
|
44
|
+
<pkg>@<pin> install-skill --print` and required stdout to begin with `---`,
|
|
45
|
+
but both editors document a `source:`/`next_step:` preamble before the skill
|
|
46
|
+
document, so the check could never pass and neither skill was ever installed.
|
|
47
|
+
`--no-install` also suppresses installing but not resolving, so every
|
|
48
|
+
`status`, `plan` and `apply` issued a real request to the npm registry —
|
|
49
|
+
`status` was never offline-safe, contrary to what the module claimed.
|
|
50
|
+
- The two editors are now invoked as `@latest` everywhere, including in the
|
|
51
|
+
`allowed-tools` permission grants of `sw-design-requirements`,
|
|
52
|
+
`sw-design-solution` and `sw-discover-tender`, which still named an exact
|
|
53
|
+
version and would therefore have denied the calls. The `@latest` check now
|
|
54
|
+
guards `allowed-tools` lines as well as prose.
|
|
55
|
+
|
|
56
|
+
### Added
|
|
57
|
+
|
|
58
|
+
- `status --json` reports `skills_dir` per agent — the directory that agent
|
|
59
|
+
actually reads skills from, and the `--target` `sw-setup` hands to an
|
|
60
|
+
editor package's own `install-skill`/`uninstall-skill`.
|
|
61
|
+
|
|
62
|
+
## [0.1.7] - 2026-09-19
|
|
63
|
+
|
|
64
|
+
### Changed
|
|
65
|
+
|
|
66
|
+
- **BREAKING: `install`, `status`, `plan` and `uninstall` print a human
|
|
67
|
+
summary, not JSON.** Typing `install` and getting several hundred lines of
|
|
68
|
+
JSON made success unreadable; the result object is now rendered for a
|
|
69
|
+
person on stdout — what changed, grouped by coding agent, and the restart
|
|
70
|
+
each one needs. A run with nothing to do is one line. Conflicts, drift and
|
|
71
|
+
manual steps are never collapsed: each names its file and its remedy, and
|
|
72
|
+
an agent this project has not installed is never named at all. Pass
|
|
73
|
+
`--json` for the previous object, unchanged apart from the key rename
|
|
74
|
+
below, and `--verbose` for the per-file detail alongside the summary.
|
|
75
|
+
**Every skill, script or agent parsing this output must add `--json`.**
|
|
76
|
+
- **BREAKING: `--host` is now `--agent`, with no alias.** `--host` is
|
|
77
|
+
rejected as an unknown option (exit 2, with runnable `--agent` help), the
|
|
78
|
+
`hosts` key in every result body is now `agents`, and the lock file records
|
|
79
|
+
`agents`. A lock written by an earlier version under `hosts` is still read
|
|
80
|
+
and is rewritten as `agents` on the next run, so an existing install keeps
|
|
81
|
+
its recorded selection. Consistent with the earlier
|
|
82
|
+
`--no-companions` -> `--no-extra-components` break.
|
|
83
|
+
**WARNING — the lock migration is one-way:** writing `agents` drops the
|
|
84
|
+
legacy `hosts` key, so after any run of this version an older pinned CLI
|
|
85
|
+
(`npx …@0.1.6`) exits 2 in that repository with "no --host given, this
|
|
86
|
+
repository has no recorded install". Verified against the published 0.1.6
|
|
87
|
+
tarball.
|
|
88
|
+
- `install` invoked with a bad flag now reports `install`, not `apply`, in
|
|
89
|
+
its usage help.
|
|
90
|
+
|
|
91
|
+
### Fixed
|
|
92
|
+
|
|
93
|
+
- `status` no longer labels a conflict as "edited since install". Its
|
|
94
|
+
`drift[]` entries now carry the action's `state`, and the human renderer
|
|
95
|
+
titles conflicts as conflicts.
|
|
96
|
+
|
|
10
97
|
## [0.1.6] - 2026-09-18
|
|
11
98
|
|
|
12
99
|
### Changed
|
package/CONTRIBUTING.md
CHANGED
|
@@ -15,7 +15,7 @@ npm run gen:check # generated adapters match their sources
|
|
|
15
15
|
node scripts/check-pack.mjs # the tarball matches the files allow-list
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
If you edited an agent or a skill, regenerate the
|
|
18
|
+
If you edited an agent or a skill, regenerate the per-agent adapters first and
|
|
19
19
|
commit the result:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
@@ -29,14 +29,23 @@ npm run gen
|
|
|
29
29
|
`scripts/gen-copilot-agents.mjs`. Never hand-edit them — run `npm run gen`
|
|
30
30
|
and commit the output. `npm run gen:check` fails the build on drift.
|
|
31
31
|
- **Every `SKILL.md` stays under 8192 bytes**, Codex's effective cap and the
|
|
32
|
-
smallest of the four
|
|
33
|
-
cap, move material into `reference/*.md` beside it — that is
|
|
32
|
+
smallest of the four coding agents'. A test enforces it. When a skill grows
|
|
33
|
+
past the cap, move material into `reference/*.md` beside it — that is
|
|
34
34
|
**reorganisation, never compression**. Audit the split against the
|
|
35
35
|
pre-split file line by line; do not drop meaning to make the number work.
|
|
36
|
-
- **Skills stay
|
|
36
|
+
- **Skills stay agent-neutral.** No `${CLAUDE_SKILL_DIR}`, no `$ARGUMENTS`, no
|
|
37
37
|
`SendMessage` or `subagent_type`, no literal `.claude/…` path. Any prose that
|
|
38
38
|
asks the user a question names both Claude Code's and Codex's question
|
|
39
39
|
tools, not just one.
|
|
40
|
+
- **The result object is the model; `lib/render.mjs` is only a view.** Every
|
|
41
|
+
command builds one body, `--json` prints it verbatim and the human summary
|
|
42
|
+
is rendered from that same body — never assembled beside it. The renderer is
|
|
43
|
+
pure `body -> string` with no I/O, so it is unit-tested in
|
|
44
|
+
`test/render.test.mjs` without a terminal. Human text goes to stdout (it is
|
|
45
|
+
the result); only the interactive picker and warnings go to stderr.
|
|
46
|
+
- **Test suites pass `--json`.** `test/helpers.mjs`'s `run()` appends it for
|
|
47
|
+
every call; only a suite that is about the human output opts out with
|
|
48
|
+
`{ json: false }`.
|
|
40
49
|
- **The installer never prompts, never fetches, and writes atomically.**
|
|
41
50
|
Every file is written to a temporary path and renamed. A change that breaks
|
|
42
51
|
any of those three properties is a change to the contract this package
|
package/README.md
CHANGED
|
@@ -43,34 +43,50 @@ identity, not an npm package name — and can be run standalone in any stdio MCP
|
|
|
43
43
|
client without this harness.
|
|
44
44
|
|
|
45
45
|
The two editors are **optional add-ons**, and each ships its own skill inside
|
|
46
|
-
its package rather than here.
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
its package rather than here. They are not this CLI's business at all: it
|
|
47
|
+
neither detects nor installs them. `sw-setup` owns their whole lifecycle —
|
|
48
|
+
it offers them, and installs, updates and removes each one with that
|
|
49
|
+
package's own `install-skill`/`uninstall-skill --target <skills dir>`. A
|
|
50
|
+
project that declines is fully set up without them, and `--editor` on
|
|
51
|
+
`sw-design-requirements`, `sw-design-solution` or `sw-discover-tender` then
|
|
52
|
+
stops with one line saying so.
|
|
49
53
|
|
|
50
54
|
## Commands
|
|
51
55
|
|
|
52
56
|
| Command | What it does |
|
|
53
57
|
| --- | --- |
|
|
54
|
-
| `install` | installs into the resolved
|
|
55
|
-
| `status` | read-only; what is installed, what drifted,
|
|
58
|
+
| `install` | installs into the resolved coding agent(s) (see Flags below); the same as `apply --yes` |
|
|
59
|
+
| `status` | read-only; what is installed, what drifted, and each agent's `skills_dir` |
|
|
56
60
|
| `plan` | the exact changes, written as a diff; writes nothing |
|
|
57
61
|
| `apply --yes` | performs them |
|
|
58
62
|
| `uninstall --yes` | removes what the lock file records |
|
|
59
63
|
| `guide` | the install protocol, the single source of truth |
|
|
60
64
|
|
|
61
|
-
Flags: `--
|
|
65
|
+
Flags: `--agent claude-code|codex|copilot|cursor` (repeatable), `--scope
|
|
62
66
|
project|user` (default `project`), `--root <path>` (default the current
|
|
63
67
|
directory), `--yes` (required by `apply` and `uninstall` — `install` implies
|
|
64
|
-
it), and `--
|
|
65
|
-
packages).
|
|
68
|
+
it), `--json` and `--verbose` (see Output below).
|
|
66
69
|
|
|
67
|
-
`install`/`apply` resolve which
|
|
68
|
-
given; else the
|
|
69
|
-
question); else, with a terminal attached, an interactive picker;
|
|
70
|
-
with the four `install --
|
|
71
|
-
never hangs. `status` and `uninstall` are unaffected by this and
|
|
72
|
-
covering every
|
|
73
|
-
no lock it previews all four and says so.
|
|
70
|
+
`install`/`apply` resolve which coding agent(s) to write into, in order:
|
|
71
|
+
`--agent` if given; else the agents a lock file already records (a re-run
|
|
72
|
+
needs no question); else, with a terminal attached, an interactive picker;
|
|
73
|
+
else exit 2 with the four `install --agent <a>` commands as `help` — it never
|
|
74
|
+
guesses and never hangs. `status` and `uninstall` are unaffected by this and
|
|
75
|
+
keep covering every agent by default; `plan` writes nothing, so with no
|
|
76
|
+
`--agent` and no lock it previews all four and says so.
|
|
77
|
+
|
|
78
|
+
### Output
|
|
79
|
+
|
|
80
|
+
`install`, `status`, `plan` and `uninstall` print a short human summary on
|
|
81
|
+
stdout — what changed, grouped by coding agent, and the restart each one
|
|
82
|
+
needs. When nothing changed, that is a single line. Conflicts, drift and
|
|
83
|
+
manual steps are always shown in full, with the file and the remedy, because
|
|
84
|
+
those are the only things you have to act on.
|
|
85
|
+
|
|
86
|
+
`--json` prints the result object instead: the same body, with the per-file
|
|
87
|
+
detail, a `next_step` on every success and a `help` array of runnable commands
|
|
88
|
+
on every error. **Anything parsing this output must pass `--json`.**
|
|
89
|
+
`--verbose` keeps the human summary but adds the per-file detail.
|
|
74
90
|
|
|
75
91
|
## Install
|
|
76
92
|
|
|
@@ -86,9 +102,9 @@ The command's output tells you which ones and how.
|
|
|
86
102
|
|
|
87
103
|
`apply` refuses without `--yes`. Neither `apply` nor `install` prompts for
|
|
88
104
|
consent — typing the verb, or passing `--yes`, is the consent — but with no
|
|
89
|
-
`--
|
|
105
|
+
`--agent`, no existing lock and no terminal (Codex's question tool does not
|
|
90
106
|
block outside Plan mode, and CI has no terminal either), it exits 2 rather
|
|
91
|
-
than guess. Add `--
|
|
107
|
+
than guess. Add `--agent claude-code` (repeatable) to install into one agent,
|
|
92
108
|
and `--scope user` to install into your home directory instead of this
|
|
93
109
|
repository. The default scope is the project — nothing is written under `~`
|
|
94
110
|
unless you ask.
|
|
@@ -105,6 +121,17 @@ unless you ask.
|
|
|
105
121
|
`AGENTS.md` gets a managed block too — Codex, Copilot and Cursor read it, and
|
|
106
122
|
Codex never reads `CLAUDE.md`.
|
|
107
123
|
|
|
124
|
+
The installer's own state — the lock file recording what it wrote — goes to
|
|
125
|
+
`var/sw-ai-sdk/harness.lock.json`. A Shopware project already ignores the whole
|
|
126
|
+
of `var/` through the `shopware/core` Flex recipe (`/var/*`) and already keeps
|
|
127
|
+
its machine-local state there, so the repository root stays clean and **no
|
|
128
|
+
`.gitignore` line is written at all**. A root with no `var/` — `--scope user`
|
|
129
|
+
under your home directory, or a checkout that is not a Shopware project —
|
|
130
|
+
falls back to `.sw-ai-sdk/` and gets the managed `.gitignore` line as before.
|
|
131
|
+
An install recorded at the old path is moved on the next `install`, which also
|
|
132
|
+
takes back the `.gitignore` line it no longer needs; nothing is reinstalled and
|
|
133
|
+
no declined rule is forgotten.
|
|
134
|
+
|
|
108
135
|
### What it will not do
|
|
109
136
|
|
|
110
137
|
- **It never overwrites a file it did not install.** A file already at one of
|
|
@@ -124,15 +151,16 @@ Undo everything with:
|
|
|
124
151
|
npx -y @execuro-sw-ecosystem/sw-ecosystem-agentic-harness@latest uninstall --yes
|
|
125
152
|
```
|
|
126
153
|
|
|
127
|
-
It removes exactly what the lock file at
|
|
154
|
+
It removes exactly what the lock file at `var/sw-ai-sdk/harness.lock.json` records,
|
|
128
155
|
keeps anything you hand-edited, and tells you what it kept.
|
|
129
156
|
|
|
130
157
|
### From a skill
|
|
131
158
|
|
|
132
|
-
`sw-setup` is a stub: it runs `status`, renders the table, asks once,
|
|
133
|
-
`apply --yes`.
|
|
134
|
-
|
|
135
|
-
protocol
|
|
159
|
+
`sw-setup` is a stub: it runs `status --json`, renders the table, asks once,
|
|
160
|
+
and runs `apply --yes --json`. A skill always passes `--json`; the bare
|
|
161
|
+
commands print the human summary. It deliberately restates none of the
|
|
162
|
+
protocol, because an installed skill file goes stale and the CLI does not.
|
|
163
|
+
Anything that needs the protocol runs:
|
|
136
164
|
|
|
137
165
|
```bash
|
|
138
166
|
npx -y @execuro-sw-ecosystem/sw-ecosystem-agentic-harness@latest guide
|
|
@@ -146,16 +174,16 @@ Three things update on different schedules.
|
|
|
146
174
|
| --- | --- |
|
|
147
175
|
| This package — skills, sub-agents, permission rules, MCP registrations | `npx -y @execuro-sw-ecosystem/sw-ecosystem-agentic-harness@latest install` |
|
|
148
176
|
| The MCP servers (`ShopwareDevKnowledgeBase`, `playwright`) | By themselves. They are registered as `@latest`, so your agent fetches the newest build the next time it starts one. Nothing to run. |
|
|
149
|
-
| Specs Editor, Tender Discovery Tool |
|
|
177
|
+
| Specs Editor, Tender Discovery Tool | `sw-setup` does, by re-running each package's own `install-skill` at `@latest` — see below. |
|
|
150
178
|
|
|
151
179
|
### The optional editors
|
|
152
180
|
|
|
153
|
-
|
|
154
|
-
|
|
181
|
+
They are installed, updated and removed by the `sw-setup` skill, not by this
|
|
182
|
+
CLI, and there is no version to match against this package:
|
|
155
183
|
|
|
156
184
|
```bash
|
|
157
|
-
|
|
158
|
-
|
|
185
|
+
npx -y @execuro-sw-ecosystem/sw-specs-editor@latest install-skill --target <skills dir>
|
|
186
|
+
npx -y @execuro-sw-ecosystem/sw-tender-discovery-tool@latest install-skill --target <skills dir>
|
|
159
187
|
```
|
|
160
188
|
|
|
161
189
|
- `sw-specs-editor` backs the `--editor` flag on `sw-design-requirements` and
|
|
@@ -163,22 +191,25 @@ npm i -D @execuro-sw-ecosystem/sw-tender-discovery-tool@0.1.0
|
|
|
163
191
|
- `sw-tender-discovery-tool` backs the `--editor` flag and the `.xlsx` import
|
|
164
192
|
on `sw-discover-tender`.
|
|
165
193
|
|
|
166
|
-
|
|
167
|
-
`
|
|
168
|
-
|
|
194
|
+
`<skills dir>` is the `skills_dir` this CLI reports for that agent in
|
|
195
|
+
`status --json`. Re-running the same line is the update — `@latest` plus the
|
|
196
|
+
editor's own "already current" path makes it idempotent — and
|
|
197
|
+
`uninstall-skill` with the same `--target` removes it. Nothing needs to be
|
|
198
|
+
re-run here afterwards.
|
|
169
199
|
|
|
170
200
|
Re-running `install` is safe at any time: it rewrites only what it owns,
|
|
171
201
|
leaves anything you hand-edited alone (reported as drift), and records the new
|
|
172
|
-
version in the lock file.
|
|
173
|
-
reads its configuration at
|
|
202
|
+
version in the lock file. It prints one line when there was nothing to change.
|
|
203
|
+
Restart your coding agent afterwards — every host reads its configuration at
|
|
204
|
+
startup.
|
|
174
205
|
|
|
175
206
|
`@latest` matters. Without it, `npx` can reuse a copy already in its cache or
|
|
176
207
|
in this project's `node_modules`, so you would silently keep running the
|
|
177
208
|
version you first installed.
|
|
178
209
|
|
|
179
210
|
To look before you change anything: `... @latest status` reports
|
|
180
|
-
`installed_version`, any drift, and
|
|
181
|
-
|
|
211
|
+
`installed_version`, any drift, and each agent's `skills_dir`. It writes
|
|
212
|
+
nothing.
|
|
182
213
|
|
|
183
214
|
## Prerequisites
|
|
184
215
|
|
|
@@ -334,7 +365,7 @@ repository is development-only.**
|
|
|
334
365
|
|
|
335
366
|
### Every `SKILL.md` is capped at 8 KB
|
|
336
367
|
|
|
337
|
-
Codex's effective skill-body limit is the smallest of the four
|
|
368
|
+
Codex's effective skill-body limit is the smallest of the four coding agents', so it is
|
|
338
369
|
the budget every skill is written to. Overflow lives in `reference/*.md` beside
|
|
339
370
|
each `SKILL.md`, loaded on demand. A test enforces the cap, so the gate is
|
|
340
371
|
mechanical rather than a review habit.
|
|
@@ -343,7 +374,7 @@ mechanical rather than a review habit.
|
|
|
343
374
|
|
|
344
375
|
| Symptom | What it means | What to do |
|
|
345
376
|
| --- | --- | --- |
|
|
346
|
-
| `state: "conflict"` | A file we did not install already sits at that path. It is never overwritten. | Move or delete the existing file, or `--
|
|
377
|
+
| `state: "conflict"` | A file we did not install already sits at that path. It is never overwritten. | Move or delete the existing file, or `--agent`-scope the run away from it, then re-run `apply`. |
|
|
347
378
|
| `state: "drift"` | You (or something else) edited a file this installer wrote. It is left alone on every later run. | Nothing to fix — this is by design. Re-run `status` to confirm it is the only thing reported. |
|
|
348
379
|
| A manual step for `.vscode/mcp.json` | That file is JSONC (comments or trailing commas). Rewriting it would destroy your notes, so it is never touched automatically. | Add the printed snippet to `.vscode/mcp.json` yourself, under the `servers` key. |
|
|
349
380
|
| `.codex/` reported read-only | Codex's default workspace-write sandbox makes `.codex/` and `.agents/` read-only from inside a Codex session. | Run the installer from a plain shell, not from inside Codex. |
|
package/SECURITY.md
CHANGED
|
@@ -41,7 +41,7 @@ scripts** on install, which removes a large part of the usual npm attack
|
|
|
41
41
|
surface.
|
|
42
42
|
|
|
43
43
|
Out of scope: vulnerabilities in the coding agents themselves, in the
|
|
44
|
-
separately published
|
|
44
|
+
separately published visual editors (they have their own repositories
|
|
45
45
|
and their own reporting), or in a third-party MCP server this package merely
|
|
46
46
|
registers, such as Playwright's (report those upstream).
|
|
47
47
|
|
package/bin/cli.mjs
CHANGED
|
@@ -28,32 +28,38 @@ const COMMANDS = {
|
|
|
28
28
|
|
|
29
29
|
const USAGE = `usage: sw-ecosystem-agentic-harness <command> [options]
|
|
30
30
|
|
|
31
|
-
install [--
|
|
32
|
-
status [--
|
|
33
|
-
plan [--
|
|
34
|
-
apply --yes [--
|
|
35
|
-
uninstall --yes [--
|
|
31
|
+
install [--agent <a>] [--scope project|user] [--root <path>]
|
|
32
|
+
status [--agent <a>] [--scope project|user] [--root <path>]
|
|
33
|
+
plan [--agent <a>] [--scope project|user] [--root <path>]
|
|
34
|
+
apply --yes [--agent <a>] [--scope project|user] [--root <path>]
|
|
35
|
+
uninstall --yes [--agent <a>] [--scope project|user] [--root <path>]
|
|
36
36
|
guide print the install protocol
|
|
37
37
|
|
|
38
38
|
install is apply --yes under a friendlier name: the whole install in one
|
|
39
39
|
command, no --yes needed — typing the verb is the consent for that write;
|
|
40
|
-
it can still ask which
|
|
40
|
+
it can still ask which coding agent(s), see below.
|
|
41
41
|
|
|
42
|
-
<
|
|
43
|
-
several. install/apply resolve which
|
|
44
|
-
given; else the
|
|
42
|
+
<a> is one of: claude-code, codex, copilot, cursor. Repeat --agent to select
|
|
43
|
+
several. install/apply resolve which agent(s) to use, in order: --agent if
|
|
44
|
+
given; else the agents already recorded in the lock file, if one exists;
|
|
45
45
|
else, with a terminal attached, an interactive picker; else exit 2 with
|
|
46
|
-
the four "... install --
|
|
47
|
-
keep covering every
|
|
46
|
+
the four "... install --agent <a>" commands as help. status and uninstall
|
|
47
|
+
keep covering every agent by default.
|
|
48
48
|
|
|
49
49
|
--scope defaults to project: nothing is written under your home directory
|
|
50
50
|
unless you ask for it. --root defaults to the current directory.
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
The two optional visual editors (Specs Editor, Tender Discovery Tool) are
|
|
53
|
+
not this CLI's business: each ships its own skill inside its own npm
|
|
54
|
+
package, and the sw-setup skill offers, installs, updates and removes
|
|
55
|
+
them.
|
|
54
56
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
--json print the result object instead of the human summary
|
|
58
|
+
--verbose include the per-file detail --json carries
|
|
59
|
+
|
|
60
|
+
install, status, plan and uninstall print a short human summary on stdout.
|
|
61
|
+
Add --json for the machine-readable object, which always carries a next_step.
|
|
62
|
+
Run \`sw-ecosystem-agentic-harness guide\` first — it is the install protocol.`;
|
|
57
63
|
|
|
58
64
|
const argv = process.argv.slice(2);
|
|
59
65
|
const cmd = argv[0];
|
package/lib/actions.mjs
CHANGED
|
@@ -20,13 +20,11 @@ import {
|
|
|
20
20
|
import { PKG_ROOT } from './content.mjs';
|
|
21
21
|
import { isDeclined } from './lock.mjs';
|
|
22
22
|
import { readFileSync } from 'node:fs';
|
|
23
|
-
import { EXTRA_COMPONENTS, probe } from './extra-components.mjs';
|
|
24
23
|
|
|
25
24
|
/** Preview one action against the filesystem. Reads only. */
|
|
26
25
|
export function preview(action, ctx) {
|
|
27
26
|
switch (action.kind) {
|
|
28
27
|
case 'file-copy': return previewFile(action, ctx);
|
|
29
|
-
case 'skill-copy': return previewSkill(action, ctx);
|
|
30
28
|
case 'json-merge': return previewJson(action, ctx);
|
|
31
29
|
case 'toml-fence':
|
|
32
30
|
case 'text-fence': return previewFence(action, ctx);
|
|
@@ -42,8 +40,7 @@ function previewFile(action, ctx) {
|
|
|
42
40
|
return previewBytes(action, ctx, shipped);
|
|
43
41
|
}
|
|
44
42
|
|
|
45
|
-
/** The adopt/conflict/drift/update ladder
|
|
46
|
-
* probed body instead of a shipped one, `skill-copy`. */
|
|
43
|
+
/** The adopt/conflict/drift/update ladder every byte-for-byte target walks. */
|
|
47
44
|
function previewBytes(action, ctx, bytes) {
|
|
48
45
|
const hash = sha256(bytes);
|
|
49
46
|
const target = abs(ctx.root, action.target);
|
|
@@ -74,35 +71,6 @@ function previewBytes(action, ctx, bytes) {
|
|
|
74
71
|
detail: 'shipped content changed' };
|
|
75
72
|
}
|
|
76
73
|
|
|
77
|
-
// ------------------------------------------------------------ skill-copy
|
|
78
|
-
|
|
79
|
-
/** Strip the probed body (a Buffer) before it lands anywhere near the
|
|
80
|
-
* action, which `commands.mjs` serialises straight to stdout. */
|
|
81
|
-
function stripProbeBody({ body, ...rest }) {
|
|
82
|
-
return rest;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function previewSkill(action, ctx) {
|
|
86
|
-
const component = EXTRA_COMPONENTS.find((c) => c.id === action.component);
|
|
87
|
-
const probed = probe(component, { platform: ctx.platform });
|
|
88
|
-
const probeSummary = stripProbeBody(probed);
|
|
89
|
-
|
|
90
|
-
if (!probed.available) {
|
|
91
|
-
const remedy = probed.state === 'absent'
|
|
92
|
-
? `npm i -D ${probed.spec}`
|
|
93
|
-
: 'check that npx works — probing needs network-free npx --no-install';
|
|
94
|
-
return {
|
|
95
|
-
...action, state: 'skipped', available: false,
|
|
96
|
-
probe: probeSummary, reason: probed.reason, remedy,
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return {
|
|
101
|
-
...previewBytes(action, ctx, probed.body),
|
|
102
|
-
available: true, probe: probeSummary, body: probed.body,
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
74
|
// ------------------------------------------------------------- json-merge
|
|
107
75
|
|
|
108
76
|
function previewJson(action, ctx) {
|
|
@@ -275,18 +243,6 @@ export function execute(action, ctx) {
|
|
|
275
243
|
return { kind: 'file-copy', host: action.host, target: action.target, source: action.source,
|
|
276
244
|
hash: action.hash, bytes: action.bytes, created_file: action.created_file !== false, dirs };
|
|
277
245
|
}
|
|
278
|
-
case 'skill-copy': {
|
|
279
|
-
// Collapses to a `file-copy` lock entry on purpose: `lock.record`,
|
|
280
|
-
// `lock.entries`, `revert` and `rebuild` need no extra-component-specific
|
|
281
|
-
// case, and `uninstall` needs no probe. `source` is provenance only —
|
|
282
|
-
// `revert` never reads it.
|
|
283
|
-
ensureDir(dirname(target));
|
|
284
|
-
writeAtomic(target, action.body);
|
|
285
|
-
const dirs = ancestorDirs(ctx.root, action.target);
|
|
286
|
-
return { kind: 'file-copy', host: action.host, target: action.target,
|
|
287
|
-
source: `npm:${action.package}#install-skill --print`,
|
|
288
|
-
hash: action.hash, bytes: action.bytes, created_file: action.created_file !== false, dirs };
|
|
289
|
-
}
|
|
290
246
|
case 'json-merge': {
|
|
291
247
|
// Recompute from what is on disk right now rather than writing the
|
|
292
248
|
// snapshot `preview` took. Several actions can target one file — the two
|