loadout-ai 0.5.6 → 0.5.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 CHANGED
@@ -2,6 +2,29 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.5.8 - 2026-07-21
6
+
7
+ ### Fixed
8
+
9
+ - Make `install --mode custom` genuinely additive: it now keeps existing managed
10
+ skills active and does not replace the saved profile.
11
+
12
+ ## 0.5.7 - 2026-07-21
13
+
14
+ ### Changed
15
+
16
+ - Explain that `setup --mode custom` reconciles the complete selected profile, while
17
+ `install --mode custom --package <id>` adds a package without retiring the current
18
+ managed profile.
19
+ - Show package-by-package progress during complete uninstall and stop calling an
20
+ approved `uninstall --yes` operation a dry run.
21
+
22
+ ### Fixed
23
+
24
+ - Preserve pre-existing skill trees that users explicitly adopted into Loadout when
25
+ removing one package or completely uninstalling Loadout. Removal now forgets
26
+ ownership and leaves adopted bytes in place, including legacy `adopted-*` records.
27
+
5
28
  ## 0.5.6 - 2026-07-21
6
29
 
7
30
  ### Changed
package/MASTER_PLAN.md CHANGED
@@ -6,12 +6,78 @@ Category: Developer Tools
6
6
  Team size: 3
7
7
  Target submission: July 21, 2026 at 5:00 PM Pacific / July 22 at 4:00 AM Dubai
8
8
 
9
- ## Current status and remaining work (July 21, 2026)
10
-
11
- This is the authoritative active list. The long phase history below is retained as
12
- an archival engineering record, not a second active plan and not a command to build
13
- every speculative system before users can test Loadout. Completed implementation
14
- plans and contributor-specific plans have been consolidated here and removed.
9
+ ## Launch finish line (authoritative, July 21, 2026)
10
+
11
+ This is the only active checklist. Everything under **Archived implementation
12
+ history** is evidence of how the product was built, not unfinished launch scope.
13
+
14
+ ### Product complete
15
+
16
+ - [x] Publish the CLI as `loadout-ai@0.5.8`; keep the product usable without cloning
17
+ this repository or providing an OpenAI/Anthropic API key.
18
+ - [x] Ship Stable, Power, Maximum, and Custom profiles with preview-first apply,
19
+ snapshots, drift protection, explicit rollback, removal, and complete uninstall.
20
+ - [x] Detect and manage skills across supported agent adapters while preserving
21
+ unrelated and unmanaged files.
22
+ - [x] Ship a 53-source pinned catalog, daily read-only discovery/update checks,
23
+ existing-skill reconciliation, and project-aware recommendation/optimization.
24
+ - [x] Credit and support the MIT Humanizer and Obsidian Skills sources. Humanizer is
25
+ available through Custom mode; Obsidian is recommended for detected vaults.
26
+ - [x] Ship three explicit MCP recipes for Playwright, Chrome DevTools, and read-only
27
+ GitHub, plus the separately reviewed Graphify runtime-tool recipe.
28
+ - [x] Remove the conflicting dashboard and make the CLI the only product surface.
29
+ - [x] Publish clear npm setup, testing, upstream attribution, trust boundaries, and a
30
+ detailed account of how Codex and GPT-5.6 were used in the README.
31
+ - [x] Pass the complete local release gate and the latest hosted CI run on `main`.
32
+ - [x] Preserve pre-existing adopted skills during removal and complete uninstall;
33
+ distinguish additive Custom installation from whole-profile Custom setup, and
34
+ show truthful progress during large approved uninstalls.
35
+
36
+ ### Final founder acceptance
37
+
38
+ - [x] Install the exact public npm release, verify `loadout --version`, and scan the
39
+ founder's restored real profiles. Stable, Power, Maximum, project optimization,
40
+ Humanizer, Graphify, both-host Playwright MCP lifecycles, rollback, complete
41
+ uninstall, and clean reinstall were exercised during founder acceptance.
42
+ - [x] Keep the GitHub repository name `loadout`. The product remains **Loadout** and
43
+ the npm package/CLI identities remain `loadout-ai` / `loadout`.
44
+ - [x] Record explicit decisions for all six `NOASSERTION` sources in
45
+ `docs/UPSTREAM_LICENSE_DECISIONS.md` without inventing a license claim.
46
+
47
+ ### Submission work
48
+
49
+ - [ ] Record the real CLI demo using `docs/DEMO_SCRIPT.md`; keep it under three
50
+ minutes, include a voiceover, upload it publicly to YouTube, and verify the URL.
51
+ - [ ] Replace the README demo placeholder with the final YouTube link.
52
+ - [ ] In the voiceover, explain what Loadout does and how Codex and GPT-5.6 were used.
53
+ - [ ] Run `/feedback` in Codex, copy the resulting session ID, and enter it in Devpost.
54
+ - [x] Confirm the public repository URL is accessible to Devpost and OpenAI.
55
+ - [x] Confirm all team invitations are accepted. Both teammates are collaborators and
56
+ there are no pending repository invitations.
57
+ - [ ] Select **Developer Tools**, complete the edited Devpost description, and submit
58
+ rather than leaving a draft.
59
+
60
+ ### Deliberately not part of this submission
61
+
62
+ These are not launch blockers and should not be rebuilt before submission:
63
+
64
+ - A dashboard or second frontend surface.
65
+ - Hosted accounts, GitHub OAuth, cloud sync, analytics, or enterprise administration.
66
+ - Automatic installation of newly discovered projects or arbitrary third-party
67
+ installer execution.
68
+ - A universal quality score, fabricated benchmark results, or automatic claims that
69
+ stars prove safety or usefulness.
70
+ - A production-hosted signed intelligence service, a second executable runtime tool,
71
+ speculative adapter features without user demand, or ten external user studies.
72
+ - Restoring GitHub-hosted Actions capacity before submission; the full gate can run
73
+ locally, and the latest completed `main` CI is already passing.
74
+
75
+ ## Archived current-status diary (historical, not active scope)
76
+
77
+ This section preserves the chronological implementation and founder-testing record.
78
+ Its unchecked boxes may describe older release numbers, superseded acceptance paths,
79
+ external research, or intentionally deferred work. They are not active launch tasks;
80
+ use the launch finish line above.
15
81
 
16
82
  ### Implemented product work
17
83
 
@@ -2135,7 +2201,7 @@ small PRs, no long-lived branches.
2135
2201
 
2136
2202
  ## 25. Immediate next tasks
2137
2203
 
2138
- Use the `Current remaining work` section at the top of this document. The next action
2139
- is founder acceptance testing with `docs/USER_TEST_GUIDE.md`; do not add a new hosted
2140
- service, provider dependency, or frontend surface until an observed user-testing issue
2141
- justifies it.
2204
+ Use **Launch finish line** at the top of this document. The next actions are the short
2205
+ founder acceptance remainder, the recorded demo, `/feedback`, and Devpost submission.
2206
+ Do not add a hosted service, provider dependency, dashboard, or speculative feature
2207
+ before the deadline.
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="./docs/assets/loadout-workflow.png" alt="Loadout workflow: choose extensions, inspect sources, preview changes, apply through a managed snapshot, and undo safely across supported AI coding agents." width="960">
2
+ <img src="./docs/assets/loadout-workflow.png" alt="Loadout discovers skills, tools, and MCP servers, keeps them in a screened library, matches an active set to each project, and manages them across AI coding agents." width="960">
3
3
  </p>
4
4
 
5
5
  <h1 align="center">Loadout</h1>
@@ -7,36 +7,50 @@
7
7
  <p align="center"><strong>Agent extensions, under control.</strong></p>
8
8
 
9
9
  <p align="center">
10
- A local CLI for inspecting, previewing, installing, and undoing managed extensions for AI coding agents.
10
+ <strong>The package manager for your AI coding setup.</strong><br>
11
+ Discover broadly. Activate the right tools for each project. Stay current without starting over.
11
12
  </p>
12
13
 
13
14
  <p align="center">
14
15
  <a href="https://github.com/VirajMishra1/loadout/actions/workflows/ci.yml"><img src="https://github.com/VirajMishra1/loadout/actions/workflows/ci.yml/badge.svg" alt="CI status"></a>
16
+ <a href="https://www.npmjs.com/package/loadout-ai"><img src="https://img.shields.io/npm/v/loadout-ai?color=cb3837&amp;logo=npm" alt="npm version"></a>
17
+ <a href="https://www.npmjs.com/package/loadout-ai"><img src="https://img.shields.io/npm/dm/loadout-ai?color=cb3837&amp;label=downloads" alt="npm downloads"></a>
18
+ <a href="https://github.com/VirajMishra1/loadout"><img src="https://img.shields.io/github/stars/VirajMishra1/loadout?style=flat&amp;logo=github" alt="GitHub stars"></a>
15
19
  <a href="./package.json"><img src="https://img.shields.io/badge/Node.js-%3E%3D20-339933?logo=node.js&amp;logoColor=white" alt="Node.js 20 or newer"></a>
16
20
  <a href="./LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="MIT License"></a>
17
21
  </p>
18
22
 
19
23
  <p align="center">
20
- <a href="#how-it-works">How it works</a> ·
21
24
  <a href="#install">Install</a> ·
25
+ <a href="#why-loadout">Why Loadout</a> ·
22
26
  <a href="#profiles">Profiles</a> ·
27
+ <a href="#catalog-and-discovery">Discover</a> ·
23
28
  <a href="#trust-and-limits">Trust</a> ·
24
- <a href="#command-reference">Commands</a> ·
25
- <a href="#development">Development</a>
29
+ <a href="#command-reference">Commands</a>
26
30
  </p>
27
31
 
28
- > [!IMPORTANT]
29
- > Installation is version-pinned so the code you test matches these docs. The commands below target `loadout-ai@0.5.6`; review the preview before every apply.
32
+ ## Install
33
+
34
+ You need Node.js 20 or newer and Git.
35
+
36
+ ```bash
37
+ npm install --global loadout-ai@0.5.8
38
+ loadout setup --mode stable
39
+ ```
40
+
41
+ The second command detects your agents and previews the 30-skill Stable loadout.
42
+ Nothing changes until you approve it. If anything goes wrong, start with the
43
+ [user test guide](./docs/USER_TEST_GUIDE.md).
30
44
 
31
45
  ## How it works
32
46
 
33
47
  **Choose -> Inspect -> Preview -> Apply -> Undo**
34
48
 
35
- 1. **Choose** a bounded profile or explicit packages.
36
- 2. **Inspect** pinned source and catalog metadata separately before setup.
37
- 3. **Preview** detected agents, aggregate repository, directory, and collision counts, warnings, skipped entries, and package IDs needing approval without changing agent target files.
38
- 4. **Apply** by rerunning with `--yes`; Loadout recomputes from current state before using a snapshot-backed transaction.
39
- 5. **Undo** the latest supported mutation with drift checks that protect later edits.
49
+ 1. **Choose** Stable, Power, Maximum, or your own package list.
50
+ 2. **Inspect** where each extension comes from and what it can do.
51
+ 3. **Preview** every planned change without changing agent files.
52
+ 4. **Apply** with `--yes`; Loadout saves a rollback snapshot first.
53
+ 5. **Undo** with `loadout rollback` if you change your mind.
40
54
 
41
55
  ### Abridged terminal transcript
42
56
 
@@ -61,47 +75,70 @@ Restored snapshot <snapshot-id>
61
75
 
62
76
  The final preview sentence above is captured CLI wording. A later `--yes` invocation recomputes the plan from pinned sources and current agent and filesystem state; it does not persist or prove identity with the earlier preview.
63
77
 
64
- Preview may populate Loadout's own cache; it leaves agent target files unchanged. Review its aggregate counts, warnings, skipped entries, and package IDs needing approval before deciding whether to run a later apply command.
78
+ Preview may fill Loadout's private download cache, but it does not change your agent
79
+ files. Review the summary and warnings before approving an apply command.
65
80
 
66
81
  ## Why Loadout
67
82
 
68
- Skills, plugins, MCP servers, and agent settings tend to accumulate one experiment at a time. Eventually it becomes hard to remember what is installed, where it came from, or how to undo it. In a game, a loadout is the deliberate set of tools chosen before a mission. Loadout brings that same discipline to AI coding agents: inspect the available equipment, choose intentionally, apply it through managed changes, and remove or roll it back later.
83
+ Loadout started with a frustrating question: **why does improving an AI coding agent
84
+ still mean opening twenty GitHub tabs?**
69
85
 
70
- - **One managed inventory.** List installed packages, inspect drift, and track what Loadout owns across configured agent paths.
71
- - **Preview by default.** Setup, updates, removal, MCP recipes, and uninstall expose a plan before their supported writes.
72
- - **Recoverable changes.** Snapshots and managed-file hashes support rollback while refusing to overwrite later user edits.
86
+ Useful skills, plugins, MCP servers, and settings arrive one experiment at a time.
87
+ Soon it is hard to remember what is installed, where it came from, whether something
88
+ better launched yesterday, or how to undo a change. The name comes from games, where
89
+ your loadout is the set of tools you choose for the mission. This does the same for AI
90
+ coding agents without making you rebuild the setup for every agent and every project.
73
91
 
74
- ## Install
92
+ Most extension tools begin with a repo you already know. Loadout begins one step
93
+ earlier: **what is actually worth knowing?** It stays with you after installation.
75
94
 
76
- You need Node.js 20 or newer and Git.
95
+ Loadout watches a much wider catalog than it activates. You can keep thousands of
96
+ technically screened skill copies in the disabled Maximum library, discover new projects as
97
+ they appear, and let each codebase pull a focused active set instead of dumping
98
+ everything into every prompt.
77
99
 
78
- ```bash
79
- npm install --global loadout-ai@0.5.6
80
- loadout --version
81
- loadout guide
82
- ```
100
+ | The usual workflow | The Loadout workflow |
101
+ | -------------------------------------------------------------- | ---------------------------------------------------------------- |
102
+ | Find recommendations across feeds and bookmarks | Watch one growing discovery catalog |
103
+ | Open every repo and guess whether to trust it | Inspect pinned sources, licenses, components, and risk findings |
104
+ | Copy skills separately into Claude, Codex, Cursor, and friends | Apply one reviewed selection across detected agents |
105
+ | Let every skill compete for context forever | Keep a bounded daily set or activate skills for this project |
106
+ | Hope updates do not break anything | Preview updates and protect every managed change with a snapshot |
107
+ | Manually remember what was changed | Scan, reconcile, remove, roll back, or completely uninstall |
83
108
 
84
- For source development instead:
85
-
86
- ```bash
87
- git clone https://github.com/VirajMishra1/loadout.git
88
- cd loadout
89
- npm ci
90
- npm run build
91
- npm link
92
- loadout --version
93
- ```
109
+ Loadout is local, open source, and preview-first. It does not need an OpenAI or
110
+ Anthropic API key to manage skills. MCP servers and executable tools stay behind
111
+ their own explicit setup and permission steps.
94
112
 
95
- For a first read-only preview, run:
113
+ ### Demo
96
114
 
97
- ```bash
98
- loadout setup --mode stable
99
- ```
115
+ **Demo video coming here.** The release walkthrough will show the real path, not a
116
+ mock UI: Stable install, cross-agent inventory, project optimization, update and
117
+ discovery checks, MCP setup, Graphify, rollback, and complete uninstall. The exact
118
+ under-three-minute [recording and voiceover script](./docs/DEMO_SCRIPT.md) is public.
100
119
 
101
- Nothing is installed until you explicitly approve the preview. See the [user test guide](./docs/USER_TEST_GUIDE.md) if linking, `PATH`, networking, risk approval, or rollback needs attention.
120
+ For now, the [end-to-end acceptance guide](./docs/USER_TEST_GUIDE.md) contains the same
121
+ commands you can run yourself.
102
122
 
103
123
  ## Stable workflow
104
124
 
125
+ ### Stable Boost: install the essentials and start building
126
+
127
+ Stable is the recommended daily driver: **30 selected skill directories from four
128
+ pinned public sources**, installed into each agent you choose. It covers planning,
129
+ implementation, debugging, testing, documentation, code review, frontend work,
130
+ performance, Git, shipping, and more without turning every discovered skill on.
131
+
132
+ | Included source | What Stable takes from it | GitHub |
133
+ | ---------------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
134
+ | [Superpowers](https://github.com/obra/superpowers) | Planning, execution, testing, review, verification | [![GitHub stars](https://img.shields.io/github/stars/obra/superpowers?style=flat&label=stars)](https://github.com/obra/superpowers) |
135
+ | [Context7](https://github.com/upstash/context7) | Current documentation and MCP workflows | [![GitHub stars](https://img.shields.io/github/stars/upstash/context7?style=flat&label=stars)](https://github.com/upstash/context7) |
136
+ | [Addy Osmani Agent Skills](https://github.com/addyosmani/agent-skills) | Engineering, frontend, debugging, performance, docs, shipping | [![GitHub stars](https://img.shields.io/github/stars/addyosmani/agent-skills?style=flat&label=stars)](https://github.com/addyosmani/agent-skills) |
137
+ | [Agent Skills Marketplace](https://github.com/wshobson/agents) | Architecture, review, error handling, JavaScript, Python | [![GitHub stars](https://img.shields.io/github/stars/wshobson/agents?style=flat&label=stars)](https://github.com/wshobson/agents) |
138
+
139
+ Every row links directly to the upstream project. Loadout does not claim ownership
140
+ or endorsement; it pins, credits, screens, and selects from their public work.
141
+
105
142
  ```bash
106
143
  # Preview for detected agents
107
144
  loadout setup --mode stable
@@ -109,18 +146,20 @@ loadout setup --mode stable
109
146
  # Recompute from current state and apply after reviewing the preview
110
147
  loadout setup --mode stable --yes
111
148
 
112
- # Inspect managed state, then undo the latest supported mutation
113
- loadout list
114
- loadout health --explain
149
+ # Inspect managed state, then undo the install if needed
150
+ loadout status
151
+ loadout scan
115
152
  loadout rollback
116
153
  ```
117
154
 
118
- Stable currently selects 30 skill directories from four pinned, SPDX-identified, policy-selected public sources. Selection policy is evidence, not a claim that the sources are safe, trusted, human-reviewed, benchmarked, or the right choice for every user.
155
+ Stable is Loadout's strongest general starting point, not a claim that one setup is
156
+ best for every person or project. Run `loadout profiles stable --json` when you want
157
+ the machine-readable selection.
119
158
 
120
159
  ## Manage skills you already have
121
160
 
122
- Loadout can compare existing Claude, Codex, Cursor, and other detected-agent skills
123
- with complete skill trees from pinned catalog sources:
161
+ Already have skills? Loadout can compare them with exact catalog copies and manage
162
+ the ones it can identify confidently:
124
163
 
125
164
  ```bash
126
165
  # Read-only inventory and source/update comparison
@@ -134,26 +173,84 @@ loadout reconcile --yes
134
173
  loadout reconcile --replace-outdated
135
174
  ```
136
175
 
137
- Unknown or ambiguous copies remain untouched. Replacing an outdated tree is a
138
- separate `--replace-outdated --yes` transaction, may require `--approve-risk`, and
139
- creates one rollback snapshot. Once adopted or replaced, `loadout update` tracks the
140
- exact upstream repository and skill unit while preserving the agent path already in
141
- use.
176
+ Unknown or ambiguous copies stay untouched. Replacing an old copy is a separate,
177
+ previewed transaction with its own rollback snapshot. Managed copies can then be
178
+ checked by `loadout update` without moving them to a different agent path.
142
179
 
143
180
  ## Profiles
144
181
 
145
- | Profile | Scope |
146
- | ----------- | --------------------------------------------------------------------- |
147
- | **Stable** | 30 active everyday skills from four pinned sources |
148
- | **Power** | A deliberately larger active toolkit from eight pinned collections |
149
- | **Maximum** | Every screened skill in a disabled library; activate relevant subsets |
150
- | **Custom** | Only package IDs explicitly supplied by the user |
182
+ Loadout is opinionated when you want it to be and precise when you do not.
183
+
184
+ ### Power Boost: a larger cross-project toolkit
185
+
186
+ Power draws a skill-level allowlist from eight major collections. The prepared set
187
+ is deduplicated and invalid units are quarantined, so the final count can be lower
188
+ than the raw allowlist. In current acceptance testing it prepared about 50 active
189
+ skills per agent.
190
+
191
+ | Included source | Focus | GitHub |
192
+ | ------------------------------------------------------------------------ | --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
193
+ | [Anthropic Skills](https://github.com/anthropics/skills) | Documents, frontend, MCP building, web testing | [![GitHub stars](https://img.shields.io/github/stars/anthropics/skills?style=flat&label=stars)](https://github.com/anthropics/skills) |
194
+ | [OpenAI Skills](https://github.com/openai/skills) | CLI, docs, browser work, images, security | [![GitHub stars](https://img.shields.io/github/stars/openai/skills?style=flat&label=stars)](https://github.com/openai/skills) |
195
+ | [Vercel Agent Skills](https://github.com/vercel-labs/agent-skills) | React, web design, composition, deployment | [![GitHub stars](https://img.shields.io/github/stars/vercel-labs/agent-skills?style=flat&label=stars)](https://github.com/vercel-labs/agent-skills) |
196
+ | [Superpowers](https://github.com/obra/superpowers) | Planning, debugging, testing, collaboration | [![GitHub stars](https://img.shields.io/github/stars/obra/superpowers?style=flat&label=stars)](https://github.com/obra/superpowers) |
197
+ | [UI UX Pro Max](https://github.com/nextlevelbuilder/ui-ux-pro-max-skill) | UI systems, slides, styling, product design | [![GitHub stars](https://img.shields.io/github/stars/nextlevelbuilder/ui-ux-pro-max-skill?style=flat&label=stars)](https://github.com/nextlevelbuilder/ui-ux-pro-max-skill) |
198
+ | [Context7](https://github.com/upstash/context7) | Current documentation and MCP workflows | [![GitHub stars](https://img.shields.io/github/stars/upstash/context7?style=flat&label=stars)](https://github.com/upstash/context7) |
199
+ | [Agent Skills Marketplace](https://github.com/wshobson/agents) | Architecture, testing, APIs, TypeScript, Python | [![GitHub stars](https://img.shields.io/github/stars/wshobson/agents?style=flat&label=stars)](https://github.com/wshobson/agents) |
200
+ | [Awesome Copilot](https://github.com/github/awesome-copilot) | Codebase knowledge, plans, browser and security workflows | [![GitHub stars](https://img.shields.io/github/stars/github/awesome-copilot?style=flat&label=stars)](https://github.com/github/awesome-copilot) |
201
+
202
+ ```bash
203
+ loadout setup --mode power
204
+ ```
151
205
 
152
- Run `loadout profiles` to compare them and `loadout setup --mode <profile>` to preview one. Stable limits context. Power trades more context for broader always-available capability. Maximum gives you the largest library without injecting thousands of skills into every prompt; `loadout optimize --project .` chooses a relevant working set. MCP-only entries stay on a separate approval path.
206
+ ### Maximum Library: download broadly, activate intelligently
207
+
208
+ Maximum is for explorers. It downloads every non-archived, technically screened
209
+ skill component in the catalog into Loadout's **disabled local library**. Disabled
210
+ means cached and available, not injected into agent context. Then let the current
211
+ project choose a focused active set:
212
+
213
+ ```bash
214
+ loadout setup --mode maximum
215
+ loadout recommend --project . --agent codex
216
+ loadout optimize --project . --agents codex,claude-code --limit 30
217
+ loadout optimize --project . --agents codex,claude-code --limit 30 --yes
218
+ ```
219
+
220
+ This is the difference between “install everything” and “have everything ready.”
221
+ The first overloads agents; the second gives you a large library with a small,
222
+ relevant active loadout.
223
+
224
+ ### Custom: take exact control
225
+
226
+ Use `setup` when the listed packages should become the complete managed profile for
227
+ the selected agents. Packages from the previous managed profile that are not listed
228
+ will be retired, and the preview names every retirement:
229
+
230
+ ```bash
231
+ loadout setup --mode custom --package superpowers --package context7
232
+ ```
233
+
234
+ Use `install` when you only want to add a package without replacing the current
235
+ managed profile:
236
+
237
+ ```bash
238
+
239
+ # Install the reviewed Humanizer writing skill into Codex
240
+ loadout install --mode custom --package humanizer --agents codex
241
+
242
+ # Install the reviewed Obsidian skills explicitly
243
+ loadout install --mode custom --package obsidian-skills --agents codex,claude-code
244
+ ```
245
+
246
+ Run `loadout profiles` to compare every mode. MCP servers always use a separate
247
+ approval step. Obsidian skills are also proposed automatically when `recommend` or
248
+ `optimize` detects an Obsidian vault; they are not added to the universal Stable set.
153
249
 
154
250
  ## MCP integrations
155
251
 
156
- MCP servers are not silently started by Stable, Power, or Maximum. List the reviewed recipes and their credential requirements:
252
+ Profiles never start MCP servers silently. First list the available recipes and see
253
+ which ones need credentials:
157
254
 
158
255
  ```bash
159
256
  loadout mcp-recipe
@@ -171,14 +268,15 @@ loadout mcp-recipe playwright --agent claude-code
171
268
  loadout mcp-recipe playwright --agent claude-code --yes
172
269
  ```
173
270
 
174
- Configuration does not launch the server. A real bounded handshake requires the separate `--connect --approve-risk` action. Credentialed recipes accept environment or keychain references, never secret values in command output.
271
+ Configuration alone does not start the server. Test a real connection separately
272
+ with `--connect --approve-risk`. Loadout can reference credentials from environment
273
+ variables or the OS keychain without printing their values.
175
274
 
176
275
  ## Optional runtime tools
177
276
 
178
- [Graphify](https://github.com/Graphify-Labs/graphify) is available as a separate,
179
- reviewed local runtime recipe because it installs an executable as well as an agent
180
- skill. It does not need an OpenAI or Anthropic API key. Loadout previews the pinned
181
- artifact, permissions, targets, and rollback scope before doing anything:
277
+ [Graphify](https://github.com/Graphify-Labs/graphify) is an optional codebase graph
278
+ tool. It installs both a command and an agent skill, so Loadout keeps it separate from
279
+ the normal profiles. It does not require an OpenAI or Anthropic API key:
182
280
 
183
281
  ```bash
184
282
  loadout tool graphify --agents codex,claude-code
@@ -186,11 +284,38 @@ loadout tool graphify --agents codex,claude-code --yes --approve-risk
186
284
  loadout tool graphify --remove --agents codex,claude-code --yes --approve-risk
187
285
  ```
188
286
 
189
- Graphify is intentionally not hidden inside Stable, Power, or Maximum: executable
190
- tools always remain an explicit choice.
287
+ Executable tools remain an explicit choice instead of hiding inside a profile.
191
288
 
192
289
  ## Catalog and discovery
193
290
 
291
+ ### GitHub moves every day. Your loadout should not stand still.
292
+
293
+ The catalog is not a frozen “top 50” list. Loadout separates **discovery** from
294
+ **installation** so a viral repo can be noticed quickly without being trusted
295
+ blindly. Candidates enter a review queue; catalog entries are pinned and inspected;
296
+ only the bounded Stable policy gets the strongest automatic recommendation.
297
+
298
+ ```bash
299
+ # Find candidates across configured discovery sources
300
+ loadout discover --source all --queue
301
+
302
+ # Inspect the queue and one candidate before promotion
303
+ loadout review-queue
304
+ loadout candidate inspect owner/repository
305
+
306
+ # Check whether managed active or disabled-library sources changed
307
+ loadout update
308
+ loadout health --updates
309
+ ```
310
+
311
+ Daily checks are opt-in and read-only. They tell you what changed; they do not
312
+ silently rewrite your agents:
313
+
314
+ ```bash
315
+ loadout autopilot --yes
316
+ loadout autopilot --status
317
+ ```
318
+
194
319
  <!-- loadout:catalog-coverage:start -->
195
320
 
196
321
  The bundled catalog currently contains **53 credited public repositories** across **39 categories**: **34 have skill components** and **19 are MCP-only**. All 53 are technically screened and pinned; 4 sources are selected by the bounded Stable policy. See every linked source, license status, component type, and pinned commit in **[Catalog and upstream credits](./docs/CATALOG.md)**.
@@ -228,6 +353,10 @@ The checked-in discovery report proves only its dated snapshot, not the success
228
353
 
229
354
  <!-- loadout:current-limits:end -->
230
355
 
356
+ The six records have an explicit public-release decision rather than an assumed
357
+ license. Read [Upstream license decisions](./docs/UPSTREAM_LICENSE_DECISIONS.md) for
358
+ the source-by-source record and the boundary applied to Power, Maximum, and Custom.
359
+
231
360
  Read the [security policy](./SECURITY.md), [catalog policy](./docs/CATALOG_POLICY.md), and [credential and update policy](./docs/CREDENTIAL_AND_UPDATE_POLICY.md) before trusting third-party content.
232
361
 
233
362
  ## Agent support
@@ -250,20 +379,99 @@ Configured paths and disposable filesystem lifecycle tests do not prove that nat
250
379
 
251
380
  ## Command reference
252
381
 
253
- | Job | Command |
254
- | ---------------------------------- | ------------------------------------------- |
255
- | Guided read-only path | `loadout guide` |
256
- | Preview or apply a profile | `loadout setup --mode stable [--yes]` |
257
- | List and inspect managed state | `loadout list`; `loadout health --explain` |
258
- | Compare/manage existing skills | `loadout reconcile [--refresh]` |
259
- | Browse or search | `loadout catalog`; `loadout search <words>` |
260
- | Recommend for a project | `loadout recommend --project .` |
261
- | Preview or apply updates | `loadout update [--yes]` |
262
- | Undo the latest supported mutation | `loadout rollback` |
263
- | Remove one managed package | `loadout remove <package>` |
264
- | Preview complete removal | `loadout uninstall` |
265
- | List reviewed MCP integrations | `loadout mcp-recipe` |
266
- | Discover the full surface | `loadout --help`; `loadout advanced` |
382
+ Start at the top and stop whenever Loadout does everything you need.
383
+
384
+ | Priority | What it does | Command |
385
+ | -------: | --------------------------------------------------------------- | ------------------------------------------------------------------ |
386
+ | 1 | Opens the beginner-friendly guided path | `loadout guide` |
387
+ | 2 | Previews the recommended 30-skill daily setup | `loadout setup --mode stable` |
388
+ | 3 | Previews the broader Power setup | `loadout setup --mode power` |
389
+ | 4 | Downloads the broad screened library, disabled by default | `loadout setup --mode maximum` |
390
+ | 5 | Shows Loadout-managed packages and active skills | `loadout status`; `loadout library` |
391
+ | 6 | Inventories skills across detected agents without changing them | `loadout scan` |
392
+ | 7 | Explains what fits the current repository | `loadout recommend --project . --agent codex` |
393
+ | 8 | Previews a bounded project-specific active set | `loadout optimize --project . --limit 30` |
394
+ | 9 | Compares existing skills with reviewed catalog copies | `loadout reconcile --refresh` |
395
+ | 10 | Checks managed active and disabled-library sources for changes | `loadout update` |
396
+ | 11 | Finds newly launched or newly popular candidates | `loadout discover --source all --queue` |
397
+ | 12 | Shows candidates waiting for deeper review | `loadout review-queue` |
398
+ | 13 | Lists MCP recipes and credential needs | `loadout mcp-recipe`; `loadout mcp-recipe --credential-free` |
399
+ | 14 | Previews an MCP configuration | `loadout mcp-recipe playwright --agent codex` |
400
+ | 15 | Lists and installs isolated runtime tools such as Graphify | `loadout tool`; `loadout tool graphify --agents codex,claude-code` |
401
+ | 16 | Lists snapshots or restores the latest managed change | `loadout rollback --list`; `loadout rollback` |
402
+ | 17 | Previews removal of one managed package | `loadout remove <package-id>` |
403
+ | 18 | Previews complete removal of Loadout-managed state | `loadout uninstall` |
404
+ | 19 | Enables read-only daily discovery and update checks | `loadout autopilot --yes` |
405
+ | 20 | Shows the complete CLI | `loadout --help`; `loadout advanced` |
406
+
407
+ Most mutating commands are dry runs first. After reading the preview, add `--yes` to
408
+ apply. Commands with executable or connection risk require the additional approval
409
+ shown in their output.
410
+
411
+ ## Built with Codex and GPT-5.6
412
+
413
+ Loadout was built during OpenAI Build Week by a three-person team working with Codex
414
+ and GPT-5.6. Codex was not a chat box bolted onto the finished project. It was the
415
+ engineering environment we used to plan, build, test, and repeatedly challenge the
416
+ product while it was taking shape.
417
+
418
+ ### From a broad idea to a working product
419
+
420
+ The starting idea was simple: one install that gives every coding agent the best
421
+ extensions on GitHub. The difficult part was everything hidden inside that sentence.
422
+ What counts as “best”? How much should stay active? What happens to skills a user
423
+ already has? How do you update a repository without silently trusting new code? How
424
+ do you undo changes across several agents?
425
+
426
+ We used GPT-5.6 through Codex for the repo-wide reasoning behind those decisions.
427
+ Together, we turned the idea into three distinct modes: a bounded Stable daily
428
+ driver, a larger Power setup, and a Maximum library that keeps broad optionality
429
+ without loading thousands of skills into every prompt.
430
+
431
+ | Part of the build | How we used Codex and GPT-5.6 | What made it into Loadout |
432
+ | ------------------ | ---------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
433
+ | Product planning | Broke the original idea into testable user journeys and challenged unsafe assumptions | Stable, Power, Maximum, Custom, project optimization, discovery, updates, and complete uninstall |
434
+ | Architecture | Traced how catalogs, adapters, agent directories, manifests, and snapshots affect one another | A local TypeScript CLI with a shared catalog, 12 agent adapters, and snapshot-backed transactions |
435
+ | Ecosystem research | Compared repositories, checked source layouts and licenses, and separated popularity from evidence | 53 pinned catalog sources plus a discovery snapshot watching 240 repositories |
436
+ | Implementation | Wrote and refactored CLI commands, schemas, source fetchers, installers, active-set logic, and MCP configuration | The published `loadout-ai` package and the commands documented above |
437
+ | Safety work | Looked for scripts, hooks, binaries, credential references, target collisions, stale previews, and external edits | Preview-first changes, quarantined skill units, explicit risk approval, drift protection, and rollback |
438
+ | Testing | Generated adversarial cases, reproduced failures from real terminal sessions, and converted them into regression tests | 625 passing tests, CLI and README end-to-end flows, package smoke tests, and a 1,000-skill performance gate |
439
+ | Team integration | Audited teammate branches, compared them with `main`, prepared focused pull requests, and checked what was actually complete | One public history instead of three disconnected prototypes |
440
+ | Release work | Verified npm contents, version behavior, GitHub metadata, documentation claims, and public CI | A public npm package, credited upstream catalog, release evidence, and a reproducible verification command |
441
+
442
+ ### Real testing changed the code
443
+
444
+ Codex was most useful when the neat plan met a messy laptop. A few examples:
445
+
446
+ - A Graphify install appeared in Claude Code but vanished from Codex inventory
447
+ because the generated runtime skill and the normal skill scanner used different
448
+ Codex paths. The scan now recognizes managed runtime-tool skills explicitly.
449
+ - Update checks repeatedly timed out on large repositories. We measured the real
450
+ clone cost, changed the update path to check remote commit metadata first, and only
451
+ fetch a full snapshot when a pinned source actually changed.
452
+ - Existing unmanaged skills could occupy the same target as a Stable install.
453
+ Instead of overwriting them, Loadout now stops, scans, compares, and offers a
454
+ separate reconciliation path for exact or unambiguous matches.
455
+ - ChatGPT and Claude subscriptions were easy to confuse with separately billed API
456
+ access. Setup now asks about API access explicitly, while credentialed MCP servers
457
+ remain separate from automatic skill installation.
458
+
459
+ Those fixes came from a loop we repeated throughout the week: run the real command,
460
+ paste the exact output into Codex, trace the behavior through the codebase, write a
461
+ regression test, fix the smallest responsible layer, and run the full release gate.
462
+
463
+ ### What the team owned
464
+
465
+ The humans chose the product direction, selected the tradeoffs, reviewed upstream
466
+ projects, tested Loadout on real Codex and Claude Code profiles, approved risky
467
+ operations, and made every release decision. GPT-5.6 helped with high-context design,
468
+ debugging, and review; Codex handled the implementation loop and verification tools.
469
+ Neither replaced human judgment about what should be installed on someone else's
470
+ machine.
471
+
472
+ Loadout itself does **not** call GPT-5.6 and does not require an OpenAI API key to
473
+ manage skills. Codex and GPT-5.6 helped build the tool; they are not a hidden runtime
474
+ dependency.
267
475
 
268
476
  ## Development
269
477
 
@@ -291,8 +499,8 @@ The repository's mixed README product-flow test uses an isolated build, disposab
291
499
  - [Daily discovery snapshot](./docs/DISCOVERED.md)
292
500
  - [Candidate inspection and promotion](./docs/CANDIDATE_INTELLIGENCE.md)
293
501
  - [Credential and update policy](./docs/CREDENTIAL_AND_UPDATE_POLICY.md)
294
- - [Repository stabilization record](./docs/REPOSITORY_STABILIZATION.md)
295
- - [Engineering plan](./MASTER_PLAN.md) and [changelog](./CHANGELOG.md)
502
+ - [Upstream license decisions](./docs/UPSTREAM_LICENSE_DECISIONS.md)
503
+ - [Changelog](./CHANGELOG.md)
296
504
 
297
505
  ## Contributing, security, and attribution
298
506
 
package/dist/src/cli.js CHANGED
@@ -264,7 +264,7 @@ async function runSetup(options) {
264
264
  reader?.close();
265
265
  }
266
266
  }
267
- const LOADOUT_VERSION = "0.5.6";
267
+ const LOADOUT_VERSION = "0.5.8";
268
268
  function durableSchedulerLauncher() {
269
269
  return [
270
270
  join(dirname(process.execPath), process.platform === "win32" ? "npx.cmd" : "npx"),
@@ -1020,11 +1020,12 @@ program
1020
1020
  .option("--remove-cli", "also uninstall the global loadout-ai npm command")
1021
1021
  .action(async (options) => {
1022
1022
  const plan = await buildUninstallPlan();
1023
- console.log(formatUninstallPlan(plan));
1023
+ console.log(formatUninstallPlan(plan, { applying: Boolean(options.yes) }));
1024
1024
  if (!options.yes)
1025
1025
  return;
1026
1026
  const result = await applyUninstall(plan, undefined, {
1027
1027
  force: options.force,
1028
+ onProgress: (message) => console.log(`→ ${message}`),
1028
1029
  });
1029
1030
  console.log(`Removed ${result.removedPackages} managed package(s), ${result.removedRuntimeTools} runtime tool(s), daily jobs, cache, library, and Loadout state.`);
1030
1031
  if (options.removeCli) {
@@ -2710,6 +2711,7 @@ program
2710
2711
  const prepared = await prepareCatalogInstall(setupSelection(options.mode, packageIds), {
2711
2712
  requestedAgents: parseAgentSelection(options.agents),
2712
2713
  onProgress: printSetupProgress,
2714
+ additive: options.mode === "custom",
2713
2715
  });
2714
2716
  console.log(formatPreparedCatalogInstall(prepared, {
2715
2717
  details: options.details,
@@ -195,6 +195,7 @@ export async function applySkillAdoption(plan, options = {}) {
195
195
  }, async (freshPlan, snapshot) => {
196
196
  await options.beforeRecord?.();
197
197
  await recordInstall(freshPlan.installPlan, snapshot.id, {
198
+ ownershipOrigin: "adopted",
198
199
  ...(freshPlan.repository ? { repository: freshPlan.repository } : {}),
199
200
  ...(freshPlan.resolvedCommit
200
201
  ? { resolvedCommit: freshPlan.resolvedCommit }
@@ -179,7 +179,7 @@ export async function prepareCatalogInstall(selection, options = {}) {
179
179
  });
180
180
  return false;
181
181
  });
182
- const reconciliation = selection.mode === "maximum"
182
+ const reconciliation = selection.mode === "maximum" || options.additive
183
183
  ? {
184
184
  obsoleteActivationKeys: [],
185
185
  obsoletePackageIds: [],
@@ -189,6 +189,7 @@ export async function prepareCatalogInstall(selection, options = {}) {
189
189
  : await planManagedProfileReconciliation(usableEntries);
190
190
  return {
191
191
  selection,
192
+ additive: options.additive ?? false,
192
193
  resolution,
193
194
  agents,
194
195
  entries: usableEntries,
@@ -217,6 +218,8 @@ export function formatPreparedCatalogInstall(prepared, options = {}) {
217
218
  `Separately billed model API access: ${formatModelApiAccess(prepared.access)} (ChatGPT and Claude subscriptions do not count as API access)`,
218
219
  "Automatic skill setup does not require an OpenAI, Anthropic, or OpenRouter API key; credentialed MCP/runtime integrations remain explicit and deferred.",
219
220
  ];
221
+ if (prepared.additive)
222
+ lines.push("Additive install: existing managed skills will stay active.");
220
223
  if (directoriesPerAgent > RECOMMENDED_ACTIVE_SKILL_LIMIT)
221
224
  lines.push(`Capacity notice: about ${directoriesPerAgent} skill directories per agent exceeds Stable's ${RECOMMENDED_ACTIVE_SKILL_LIMIT}-skill bound.${prepared.selection.mode === "maximum" ? " Maximum stores them in the disabled library; optimize or activate a project-relevant working set." : prepared.selection.mode === "power" ? " Power is the explicit larger active mode; choose Stable or project optimization when lower context use matters." : " Use project-aware activation for a smaller working set."}`);
222
225
  if (failures.length)
@@ -263,11 +266,15 @@ export async function applyPreparedCatalogInstall(prepared, options = {}) {
263
266
  })
264
267
  : applySkillInstallBatch(prepared.entries, [], {
265
268
  replaceManagedTargets: true,
266
- reconcileManagedTargets: true,
269
+ reconcileManagedTargets: !prepared.additive,
267
270
  ...(prepared.reconciliation
268
271
  ? { expectedReconciliation: prepared.reconciliation }
269
272
  : {}),
270
- afterRecord: () => recordInstalledProfile(prepared).then(() => undefined),
273
+ ...(prepared.additive
274
+ ? {}
275
+ : {
276
+ afterRecord: () => recordInstalledProfile(prepared).then(() => undefined),
277
+ }),
271
278
  });
272
279
  }
273
280
  export function formatCatalogApplyGuidance(riskApprovalRequired) {
@@ -31,6 +31,10 @@ snapshot before changing managed files. Recover with: loadout rollback
31
31
  Reconcile is also read-only unless you add --yes. Exact matches can be managed
32
32
  without rewriting them; outdated replacements remain a separate explicit choice.
33
33
 
34
+ Setup reconciles the complete selected profile. To add one catalog package without
35
+ retiring the current managed profile, use:
36
+ loadout install --mode custom --package <id>
37
+
34
38
  Nothing above changes your agents. For the full maintainer/tooling surface, run:
35
39
  loadout advanced
36
40
  `.trim();
@@ -237,6 +237,7 @@ export async function applyReconcilePlan(plan, options = {}) {
237
237
  const entries = selected.map((item) => ({
238
238
  plan: installPlanFor(item, item.status === "outdated"),
239
239
  metadata: {
240
+ ownershipOrigin: "adopted",
240
241
  repository: item.candidate.repository,
241
242
  resolvedCommit: item.candidate.commit,
242
243
  reviewed: true,
@@ -11,6 +11,12 @@ export async function planRemove(packageId) {
11
11
  const trackedMcp = (state.mcpInstalls ?? []).filter((entry) => entry.packageId === packageId);
12
12
  if (!record && !trackedMcp.length)
13
13
  throw new Error(`Package is not managed by Loadout: ${packageId}`);
14
+ // Older releases encoded reconciled/adopted ownership in the generated id.
15
+ // Preserve that compatibility so upgrading Loadout protects already-adopted
16
+ // user content even before the new explicit state field has been written.
17
+ const preserveFiles = Boolean(record &&
18
+ (record.ownershipOrigin === "adopted" ||
19
+ record.packageId.startsWith("adopted-")));
14
20
  const files = await Promise.all((record?.files ?? []).map(async (file) => {
15
21
  const managedPath = managedFileReadPath(packageId, file.path, state.activations ?? []);
16
22
  try {
@@ -28,7 +34,9 @@ export async function planRemove(packageId) {
28
34
  return { path: managedPath, status: "missing" };
29
35
  }
30
36
  }));
31
- const modified = files.filter((file) => file.status === "modified");
37
+ const modified = preserveFiles
38
+ ? []
39
+ : files.filter((file) => file.status === "modified");
32
40
  const mcpServers = await Promise.all(trackedMcp.map(async (entry) => {
33
41
  try {
34
42
  if (entry.configFormat === "codex-toml") {
@@ -76,6 +84,11 @@ export async function planRemove(packageId) {
76
84
  }));
77
85
  const modifiedMcp = mcpServers.filter((entry) => entry.status === "modified");
78
86
  const warnings = [
87
+ ...(preserveFiles
88
+ ? [
89
+ "This package adopted pre-existing files; removal will forget Loadout ownership and preserve those files in place.",
90
+ ]
91
+ : []),
79
92
  ...(modified.length
80
93
  ? [`${modified.length} managed file(s) were modified outside Loadout.`]
81
94
  : []),
@@ -89,6 +102,7 @@ export async function planRemove(packageId) {
89
102
  warnings.push("Removal is blocked unless --force is used.");
90
103
  return {
91
104
  packageId,
105
+ preserveFiles,
92
106
  files,
93
107
  mcpServers,
94
108
  blocked: modified.length > 0 || modifiedMcp.length > 0,
@@ -103,17 +117,18 @@ export async function applyRemove(plan, options = {}) {
103
117
  const existing = fresh.files
104
118
  .filter((file) => file.status !== "missing")
105
119
  .map((file) => file.path);
120
+ const removableFiles = fresh.preserveFiles ? [] : existing;
106
121
  const configPaths = [
107
122
  ...new Set(fresh.mcpServers
108
123
  .filter((entry) => entry.status !== "missing")
109
124
  .map((entry) => entry.configPath)),
110
125
  ];
111
126
  return {
112
- targets: [...existing, ...configPaths, installStatePath()],
113
- value: { fresh, existing, configPaths },
127
+ targets: [...removableFiles, ...configPaths, installStatePath()],
128
+ value: { fresh, removableFiles, configPaths },
114
129
  };
115
- }, async ({ fresh, existing, configPaths }) => {
116
- for (const file of existing)
130
+ }, async ({ fresh, removableFiles, configPaths }) => {
131
+ for (const file of removableFiles)
117
132
  await rm(file, { force: true });
118
133
  for (const configPath of configPaths) {
119
134
  const relevant = fresh.mcpServers.filter((entry) => entry.configPath === configPath && entry.status !== "missing");
@@ -143,7 +158,9 @@ export async function applyRemove(plan, options = {}) {
143
158
  proposed: { ...current, mcpServers: servers },
144
159
  });
145
160
  }
146
- await forgetInstall(plan.packageId);
161
+ await forgetInstall(plan.packageId, {
162
+ dropActivations: fresh.preserveFiles,
163
+ });
147
164
  }, { label: `remove ${plan.packageId}` });
148
165
  return applied.snapshotId;
149
166
  }
@@ -145,6 +145,9 @@ async function createInstallRecord(plan, snapshotId, metadata = {}) {
145
145
  const files = (await Promise.all([...new Set(plan.files.map((file) => file.target))].map(hashDirectory))).flat();
146
146
  return {
147
147
  packageId: plan.packageId,
148
+ ...(metadata.ownershipOrigin
149
+ ? { ownershipOrigin: metadata.ownershipOrigin }
150
+ : {}),
148
151
  ...(metadata.repository ? { repository: metadata.repository } : {}),
149
152
  ...(metadata.resolvedCommit
150
153
  ? { resolvedCommit: metadata.resolvedCommit }
@@ -311,7 +314,7 @@ export async function recordMcpInstall(record) {
311
314
  ];
312
315
  await writeInstallState(state);
313
316
  }
314
- export async function forgetInstall(packageId) {
317
+ export async function forgetInstall(packageId, options = {}) {
315
318
  const state = await readInstallState();
316
319
  const installs = state.installs.filter((entry) => entry.packageId !== packageId);
317
320
  const mcpInstalls = (state.mcpInstalls ?? []).filter((entry) => entry.packageId !== packageId);
@@ -323,13 +326,15 @@ export async function forgetInstall(packageId) {
323
326
  installs,
324
327
  ...(state.profile ? { profile: state.profile } : {}),
325
328
  mcpInstalls,
326
- activations: (state.activations ?? []).map((entry) => entry.packageId === packageId
327
- ? {
328
- ...entry,
329
- installationState: "removed",
330
- activationState: "disabled",
331
- updatedAt: new Date().toISOString(),
332
- }
333
- : entry),
329
+ activations: options.dropActivations
330
+ ? (state.activations ?? []).filter((entry) => entry.packageId !== packageId)
331
+ : (state.activations ?? []).map((entry) => entry.packageId === packageId
332
+ ? {
333
+ ...entry,
334
+ installationState: "removed",
335
+ activationState: "disabled",
336
+ updatedAt: new Date().toISOString(),
337
+ }
338
+ : entry),
334
339
  });
335
340
  }
@@ -85,19 +85,25 @@ export async function applyUninstall(plan, dependencies = {}, options = {}) {
85
85
  if (fresh.blocked && !options.force)
86
86
  throw new Error(`Complete uninstall is blocked because managed files were modified. Review them, or re-run with --force. ${fresh.warnings.join(" ")}`);
87
87
  for (const id of fresh.runtimeTools) {
88
+ options.onProgress?.(`Removing runtime tool: ${id}`);
88
89
  const runtimePlan = await planRuntimeTool(id, {
89
90
  action: "remove",
90
91
  stateHome: fresh.stateHome,
91
92
  });
92
93
  await applyRuntimeToolPlan(runtimePlan, { approveRisk: true });
93
94
  }
94
- for (const packagePlan of fresh.packages)
95
+ for (const [index, packagePlan] of fresh.packages.entries()) {
96
+ options.onProgress?.(`${packagePlan.preserveFiles ? "Forgetting adopted ownership" : "Removing managed package"} [${index + 1}/${fresh.packages.length}]: ${packagePlan.packageId}`);
95
97
  await applyRemove(packagePlan, { force: options.force });
98
+ }
96
99
  await removeEmptyManagedDirectories(fresh.packages);
97
- if (fresh.schedulers.length)
100
+ if (fresh.schedulers.length) {
101
+ options.onProgress?.("Removing daily read-only schedules");
98
102
  await (dependencies.unschedule
99
103
  ? dependencies.unschedule(fresh.schedulers)
100
104
  : applyNativeSchedulerBundle(fresh.schedulers));
105
+ }
106
+ options.onProgress?.("Deleting Loadout cache, library, history, and state");
101
107
  await rm(fresh.stateHome, { recursive: true, force: true });
102
108
  return {
103
109
  removedPackages: fresh.packages.length,
@@ -112,7 +118,7 @@ export async function uninstallGlobalCli() {
112
118
  windowsHide: true,
113
119
  });
114
120
  }
115
- export function formatUninstallPlan(plan) {
121
+ export function formatUninstallPlan(plan, options = {}) {
116
122
  const modifiedPaths = plan.packages.flatMap((entry) => entry.files
117
123
  .filter((file) => file.status === "modified")
118
124
  .map((file) => file.path));
@@ -137,7 +143,13 @@ export function formatUninstallPlan(plan) {
137
143
  "",
138
144
  ...plan.warnings.map((warning) => `Warning: ${warning}`),
139
145
  "",
140
- "Dry run only. Re-run with `loadout uninstall --yes` to remove Loadout-managed data.",
141
- "Add `--remove-cli` to also uninstall the global npm command.",
146
+ ...(options.applying
147
+ ? [
148
+ "Approved removal is starting. Large libraries can take several minutes; progress will be shown below.",
149
+ ]
150
+ : [
151
+ "Dry run only. Re-run with `loadout uninstall --yes` to remove Loadout-managed data.",
152
+ "Add `--remove-cli` to also uninstall the global npm command.",
153
+ ]),
142
154
  ].join("\n");
143
155
  }
@@ -269,6 +269,7 @@ const fileHashSchema = z.object({ path: text, sha256 });
269
269
  export const installRecordSchema = z
270
270
  .object({
271
271
  packageId: text,
272
+ ownershipOrigin: z.enum(["installed", "adopted"]).optional(),
272
273
  repository: optionalText,
273
274
  resolvedCommit: optionalText,
274
275
  targetAgents: z.array(agentIdSchema),
@@ -0,0 +1,156 @@
1
+ # Loadout demo and voiceover
2
+
3
+ Target length: **2:35 to 2:50**. Record the real CLI, cut fetch waits and typing, and do
4
+ not show the retired dashboard. The final YouTube upload must be public.
5
+
6
+ ## Before recording
7
+
8
+ 1. Close terminals that show tokens, private paths you do not want public, or unrelated
9
+ work. Increase terminal font size and use a window about 120 columns wide.
10
+ 2. Confirm the release and product health:
11
+
12
+ ```bash
13
+ npm install --global loadout-ai@0.5.8
14
+ hash -r
15
+ loadout --version
16
+ loadout health
17
+ ```
18
+
19
+ 3. Finish the remaining founder acceptance path before recording. Keep the useful
20
+ successful output in terminal history, but start the recording from a clean prompt.
21
+ 4. Rehearse the voiceover once. Use macOS Screenshot (`Shift-Command-5`) with your
22
+ microphone, OBS, or another recorder. Record at normal speed; speed the final cut
23
+ to 1.1x only if necessary.
24
+
25
+ ## Shot list and exact narration
26
+
27
+ ### 0:00 to 0:15: the problem
28
+
29
+ **Screen:** README hero, then a terminal showing `loadout --version`.
30
+
31
+ **Say:**
32
+
33
+ > AI coding extensions are scattered across GitHub. You find a skill on X, an MCP
34
+ > server on Reddit, copy it into one agent, and later have no idea where it came from
35
+ > or how to undo it. I built Loadout: one local CLI to discover, inspect, install,
36
+ > update, and roll back agent extensions across Codex, Claude Code, and other agents.
37
+
38
+ ### 0:15 to 0:50: one safe install
39
+
40
+ **Screen:** Run the preview, then apply. Cut the fetch wait, not the result.
41
+
42
+ ```bash
43
+ loadout setup --mode stable --agents codex,claude-code --api-access none
44
+ loadout setup --mode stable --agents codex,claude-code --api-access none --yes
45
+ ```
46
+
47
+ **Say:**
48
+
49
+ > Stable selects thirty useful skill directories per agent from four pinned public
50
+ > sources. The first run is a preview: it shows the sources, targets, credentials, and
51
+ > safety findings without changing agent files. When I approve it, Loadout applies one
52
+ > transaction and gives me a rollback snapshot. My ChatGPT and Claude subscriptions
53
+ > are not treated as API keys, and normal skill setup does not need one.
54
+
55
+ ### 0:50 to 1:12: see what changed and undo it
56
+
57
+ **Screen:**
58
+
59
+ ```bash
60
+ loadout scan
61
+ loadout status
62
+ loadout rollback --list
63
+ loadout rollback --snapshot <stable-snapshot-id>
64
+ ```
65
+
66
+ **Say:**
67
+
68
+ > Scan separates Loadout-managed skills from files I already had. Status keeps source
69
+ > and version ownership, and rollback restores the exact pre-install snapshot while
70
+ > preserving unrelated skills. I use the exact snapshot ID shown by the install, so
71
+ > there is no ambiguity. Complete uninstall is available too.
72
+
73
+ ### 1:12 to 1:42: broad catalog, focused project
74
+
75
+ **Screen:** Show the profile choices, catalog coverage, and a real project
76
+ recommendation. These commands are read-only and do not require a prepared Maximum
77
+ library.
78
+
79
+ ```bash
80
+ loadout profiles
81
+ loadout catalog --coverage
82
+ loadout recommend --project . --agent codex
83
+ ```
84
+
85
+ **Say:**
86
+
87
+ > Loadout has three useful levels. Stable installs a bounded daily set. Power is
88
+ > broader. Maximum keeps a large screened library disabled instead of dumping every
89
+ > skill into every prompt. For this TypeScript CLI, the project recommender proposes
90
+ > tools for documentation, testing, security, and MCP work without changing anything.
91
+
92
+ ### 1:42 to 2:05: MCP, tools, and custom skills
93
+
94
+ **Screen:**
95
+
96
+ ```bash
97
+ loadout mcp-recipe --credential-free
98
+ loadout mcp-recipe playwright --agent codex
99
+ loadout tool graphify --agents codex,claude-code
100
+ loadout install --mode custom --package humanizer --agents codex
101
+ ```
102
+
103
+ **Say:**
104
+
105
+ > MCP servers and executable tools are never hidden inside a profile. Playwright is a
106
+ > separately previewed MCP recipe; Graphify is a pinned runtime tool; and a catalog
107
+ > skill such as Humanizer can be installed directly through Custom mode. Each path
108
+ > discloses permissions and credentials before approval.
109
+
110
+ ### 2:05 to 2:25: today and tomorrow
111
+
112
+ **Screen:**
113
+
114
+ ```bash
115
+ loadout update
116
+ loadout discover --limit 5
117
+ ```
118
+
119
+ **Say:**
120
+
121
+ > Update checks managed pinned sources without silently changing them. Discovery
122
+ > watches a wider ecosystem and queues new projects for review, so something going
123
+ > viral can be noticed quickly without being trusted blindly.
124
+
125
+ ### 2:25 to 2:48: Codex, GPT-5.6, and close
126
+
127
+ **Screen:** README section “Built with Codex and GPT-5.6”, then return to the hero.
128
+
129
+ **Say:**
130
+
131
+ > We used Codex and GPT-5.6 throughout the build: architecture, threat modelling,
132
+ > cross-platform implementation, repo-wide debugging, tests, and the real founder
133
+ > acceptance loop. Those tests caught rollback, project-scope, inventory, and update
134
+ > bugs on my actual Codex and Claude profiles. Loadout itself stays local and does not
135
+ > require an OpenAI API key. One command gives your AI agents a loadout you can
136
+ > understand, improve, and undo.
137
+
138
+ ## Final edit and upload
139
+
140
+ - Remove loading screens, typing pauses, repeated commands, notifications, and secrets.
141
+ - Keep terminal output readable at 1080p; do not use a synthetic dashboard or mock data.
142
+ - Add a small title card: **Loadout: Agent extensions, under control.**
143
+ - Export under three minutes and upload publicly to YouTube.
144
+ - Watch the uploaded video once, confirm audio and text are legible, then paste the
145
+ exact public URL into README and Devpost.
146
+
147
+ ## Submission checklist
148
+
149
+ - [ ] Public YouTube video is under three minutes and its URL opens signed out.
150
+ - [ ] Voiceover explains the product, Codex usage, and GPT-5.6 usage.
151
+ - [ ] `/feedback` was run in Codex and the session ID is in Devpost.
152
+ - [ ] Repository URL is accessible to Devpost and OpenAI.
153
+ - [ ] README has npm setup and the judge testing path.
154
+ - [ ] Every teammate has accepted the Devpost invitation.
155
+ - [ ] Category is **Developer Tools**.
156
+ - [ ] Submission is submitted, not left as a draft.
@@ -0,0 +1,90 @@
1
+ # Devpost submission copy
2
+
3
+ Edit this in your own voice before submitting. Replace the video placeholder and
4
+ check every link while signed out.
5
+
6
+ ## Project name
7
+
8
+ Loadout
9
+
10
+ ## Tagline
11
+
12
+ One CLI to discover, install, update, and undo the best extensions for your AI coding
13
+ agents.
14
+
15
+ ## Category
16
+
17
+ Developer Tools
18
+
19
+ ## Short category and project answer
20
+
21
+ We are building for the Developer Tools category. Loadout is a local CLI that finds,
22
+ screens, installs, updates, and rolls back skills, MCP servers, and runtime tools
23
+ across Codex, Claude Code, Cursor, and other coding agents, with project-aware
24
+ recommendations and a daily read-only discovery feed.
25
+
26
+ ## Project description
27
+
28
+ Improving an AI coding agent still means hunting through GitHub, Reddit, X, and
29
+ bookmarks, then copying files into several different agent directories. A week later,
30
+ you may not remember where a skill came from, whether a better option has appeared,
31
+ or how to remove it safely.
32
+
33
+ Loadout turns that mess into one local CLI. Stable installs a bounded 30-skill daily
34
+ setup from four pinned public sources. Power prepares a broader toolkit. Maximum
35
+ keeps thousands of screened skill copies in a disabled local library, then recommends
36
+ a focused active set for the current project. Custom mode installs one exact package
37
+ without replacing the rest of your setup.
38
+
39
+ Every change is previewed first. Loadout records source and version ownership, checks
40
+ for collisions and risky files, protects user edits, and creates a rollback snapshot
41
+ before it changes managed files. MCP servers and executable tools remain separate,
42
+ explicit choices. The normal skill workflow does not require an OpenAI or Anthropic
43
+ API key.
44
+
45
+ The bundled catalog credits 53 pinned public repositories. A generated discovery
46
+ snapshot currently watches 240 repositories, including 216 candidates that have not
47
+ been promoted into the catalog. Loadout treats popularity as a reason to inspect a
48
+ project, not proof that it is safe or useful.
49
+
50
+ We built Loadout with Codex and GPT-5.6 during OpenAI Build Week. We used Codex for
51
+ architecture, implementation, repository research, threat modelling, cross-platform
52
+ work, and the founder testing loop. Real tests on Codex and Claude Code exposed bugs
53
+ in rollback history, update performance, project activation, MCP configuration,
54
+ runtime-tool inventory, and adopted-skill removal. Each reproducible failure became a
55
+ regression test. The current release passes 625 tests, packaged CLI journeys, public
56
+ CI, and a 1,000-skill performance gate.
57
+
58
+ Loadout is published on npm and the code is public. The dashboard was deliberately
59
+ removed because it duplicated the CLI and made the product harder to understand. The
60
+ result is the product we wanted to use ourselves: one command-line control layer for
61
+ the extensions around every AI coding agent.
62
+
63
+ ## Links
64
+
65
+ - GitHub: https://github.com/VirajMishra1/loadout
66
+ - npm: https://www.npmjs.com/package/loadout-ai
67
+ - Release: https://github.com/VirajMishra1/loadout/releases/tag/v0.5.8
68
+ - Demo: PASTE_PUBLIC_YOUTUBE_URL_HERE
69
+
70
+ ## Judge testing path
71
+
72
+ ```bash
73
+ npm install --global loadout-ai@0.5.8
74
+ loadout --version
75
+ loadout guide
76
+ loadout setup --mode stable
77
+ ```
78
+
79
+ The Stable command previews first. It changes nothing until the reviewer approves
80
+ the plan. The README and user test guide cover rollback, Maximum, project
81
+ recommendations, MCP recipes, Graphify, discovery, and complete uninstall.
82
+
83
+ ## Final fields to verify
84
+
85
+ - Category is Developer Tools.
86
+ - All three teammates appear on the Devpost submission.
87
+ - The public YouTube URL works while signed out.
88
+ - The Codex `/feedback` session ID is present.
89
+ - The GitHub, npm, and video links are correct.
90
+ - The submission is submitted, not saved as a draft.
@@ -0,0 +1,32 @@
1
+ # Upstream license decisions
2
+
3
+ Reviewed on July 21, 2026 for the public `0.5.8` release.
4
+
5
+ Loadout records `NOASSERTION` when it cannot identify one repository-wide SPDX
6
+ license from the inspected source. Popularity, an official publisher, or a public
7
+ GitHub repository does not replace a license grant.
8
+
9
+ ## Release decision
10
+
11
+ The six records below remain in the credited catalog as source metadata. Loadout
12
+ does not copy their source into the npm package, claim ownership, or assign them a
13
+ license. A selected profile may fetch a pinned upstream snapshot only after showing
14
+ the user a preview. MCP configuration and executable tools remain separate explicit
15
+ actions.
16
+
17
+ None of these six records is part of Stable. Stable continues to use four sources
18
+ with identified SPDX licenses. People who select Power, Maximum, or a Custom package
19
+ must review the linked upstream terms before using content marked `NOASSERTION`.
20
+
21
+ | Catalog record | Upstream source | Recorded decision |
22
+ | ------------------------------ | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
23
+ | OpenAI Skills Catalog | [openai/skills](https://github.com/openai/skills) | Retain the pinned catalog pointer with `NOASSERTION`; no repository-wide root license was identified. |
24
+ | Anthropic Skills | [anthropics/skills](https://github.com/anthropics/skills) | Retain the pinned catalog pointer with `NOASSERTION`; no repository-wide root license was identified. |
25
+ | Vercel Agent Skills | [vercel-labs/agent-skills](https://github.com/vercel-labs/agent-skills) | Retain the pinned catalog pointer with `NOASSERTION`; no repository-wide root license was identified. |
26
+ | Vercel Skills | [vercel-labs/skills](https://github.com/vercel-labs/skills) | Retain the pinned catalog pointer with `NOASSERTION`; no repository-wide root license was identified. |
27
+ | Sentry MCP | [getsentry/sentry-mcp](https://github.com/getsentry/sentry-mcp) | Retain the pinned catalog pointer with `NOASSERTION`; the root license file is not identified as a standard SPDX license by GitHub. |
28
+ | Model Context Protocol Servers | [modelcontextprotocol/servers](https://github.com/modelcontextprotocol/servers) | Retain the pinned catalog pointer with `NOASSERTION`; the root license file is not identified as a standard SPDX license by GitHub. |
29
+
30
+ This is a transparent product policy decision, not legal advice or a claim that the
31
+ upstream material may be redistributed under Loadout's MIT license. Each upstream
32
+ project keeps its own copyright and terms.
@@ -211,7 +211,7 @@ cleanup deliberately deletes Loadout's snapshots, so it is the last lifecycle te
211
211
  ## Troubleshooting and recovery
212
212
 
213
213
  - **`loadout` is not found after installation:** confirm `npm install --global
214
- loadout-ai@0.5.6` completed, run `hash -r`, and confirm npm's global binary
214
+ loadout-ai@0.5.8` completed, run `hash -r`, and confirm npm's global binary
215
215
  directory is on `PATH`. For a source checkout, run `npm run build` and `npm link`.
216
216
  - **A preview asks for `--approve-risk`:** read the reported scripts, domains,
217
217
  credentials, binaries, or instruction findings. If you accept that specific plan,
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loadout-ai",
3
- "version": "0.5.6",
3
+ "version": "0.5.8",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "description": "Universal upgrade manager for AI coding agents",