loadout-ai 0.5.9 → 0.7.0

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.
Files changed (108) hide show
  1. package/README.md +181 -121
  2. package/catalog/discovered.json +28066 -23196
  3. package/catalog/packages.json +2 -2
  4. package/dist/src/cli.js +2 -2
  5. package/dist/src/commands/agents.js +6 -23
  6. package/dist/src/commands/catalog.js +254 -27
  7. package/dist/src/commands/health.js +6 -6
  8. package/dist/src/commands/inventory.js +21 -121
  9. package/dist/src/commands/lifecycle.js +13 -51
  10. package/dist/src/commands/mcp.js +10 -73
  11. package/dist/src/commands/setup.js +5 -5
  12. package/dist/src/commands/sharing.js +11 -108
  13. package/dist/src/commands/support.js +42 -11
  14. package/dist/src/core/{adapters.js → agents/adapters.js} +2 -2
  15. package/dist/src/core/{agent-inspection.js → agents/agent-inspection.js} +26 -6
  16. package/dist/src/core/{codex-mcp.js → agents/codex-mcp.js} +1 -1
  17. package/dist/src/core/{health-score-evidence.js → agents/health-score-evidence.js} +8 -8
  18. package/dist/src/core/{runtime-tools.js → agents/runtime-tools.js} +2 -2
  19. package/dist/src/core/{audit.js → catalog/audit.js} +4 -4
  20. package/dist/src/core/{catalog.js → catalog/catalog.js} +18 -5
  21. package/dist/src/core/{components.js → catalog/components.js} +2 -2
  22. package/dist/src/core/{conformance.js → catalog/conformance.js} +2 -2
  23. package/dist/src/core/{profiles.js → catalog/profiles.js} +2 -2
  24. package/dist/src/core/{provenance.js → catalog/provenance.js} +3 -3
  25. package/dist/src/core/{registry.js → catalog/registry.js} +1 -1
  26. package/dist/src/core/{skill-compare.js → catalog/skill-compare.js} +1 -1
  27. package/dist/src/core/{skill-inventory.js → catalog/skill-inventory.js} +3 -3
  28. package/dist/src/core/{skills.js → catalog/skills.js} +1 -1
  29. package/dist/src/core/{candidate-intelligence.js → discovery/candidate-intelligence.js} +6 -6
  30. package/dist/src/core/{discovery-connector.js → discovery/discovery-connector.js} +2 -2
  31. package/dist/src/core/{evaluate.js → discovery/evaluate.js} +2 -2
  32. package/dist/src/core/{mcp-registry-discovery.js → discovery/mcp-registry-discovery.js} +1 -1
  33. package/dist/src/core/{observations.js → discovery/observations.js} +3 -3
  34. package/dist/src/core/{review-queue.js → discovery/review-queue.js} +9 -4
  35. package/dist/src/core/{skills-sh-discovery.js → discovery/skills-sh-discovery.js} +1 -1
  36. package/dist/src/core/{adopt.js → install/adopt.js} +3 -3
  37. package/dist/src/core/{catalog-install.js → install/catalog-install.js} +11 -11
  38. package/dist/src/core/{file-lock.js → install/file-lock.js} +1 -1
  39. package/dist/src/core/{install.js → install/install.js} +5 -5
  40. package/dist/src/core/{package.js → install/package.js} +3 -3
  41. package/dist/src/core/{reconcile.js → install/reconcile.js} +5 -5
  42. package/dist/src/core/{remove.js → install/remove.js} +4 -4
  43. package/dist/src/core/{snapshot.js → install/snapshot.js} +1 -1
  44. package/dist/src/core/{source.js → install/source.js} +1 -1
  45. package/dist/src/core/{sync.js → install/sync.js} +9 -9
  46. package/dist/src/core/{transaction.js → install/transaction.js} +1 -1
  47. package/dist/src/core/{uninstall.js → install/uninstall.js} +4 -4
  48. package/dist/src/core/{update.js → install/update.js} +4 -4
  49. package/dist/src/core/reporting/cli-guide.js +103 -0
  50. package/dist/src/core/reporting/doctor.js +141 -0
  51. package/dist/src/core/{freshness-alerts.js → reporting/freshness-alerts.js} +5 -5
  52. package/dist/src/core/{health.js → reporting/health.js} +6 -6
  53. package/dist/src/core/{loadout-card.js → reporting/loadout-card.js} +1 -1
  54. package/dist/src/core/{readme-claims.js → reporting/readme-claims.js} +1 -1
  55. package/dist/src/core/{readme-facts.js → reporting/readme-facts.js} +2 -2
  56. package/dist/src/core/{share-report.js → reporting/share-report.js} +3 -3
  57. package/dist/src/core/{upgrade.js → reporting/upgrade.js} +7 -7
  58. package/dist/src/core/routing/first-party-skills.js +118 -0
  59. package/dist/src/core/routing/handoff.js +278 -0
  60. package/dist/src/core/{model-config.js → routing/model-config.js} +4 -4
  61. package/dist/src/core/routing/route.js +539 -0
  62. package/dist/src/core/{api.js → runtime/api.js} +4 -4
  63. package/dist/src/core/{canary.js → runtime/canary.js} +1 -1
  64. package/dist/src/core/{github.js → runtime/github.js} +1 -1
  65. package/dist/src/core/{mcp-recipes.js → runtime/mcp-recipes.js} +1 -1
  66. package/dist/src/core/{mcp.js → runtime/mcp.js} +2 -2
  67. package/dist/src/core/{scheduler.js → runtime/scheduler.js} +4 -4
  68. package/dist/src/core/{active-policy.js → workspace/active-policy.js} +2 -2
  69. package/dist/src/core/{active-set.js → workspace/active-set.js} +2 -2
  70. package/dist/src/core/{improve.js → workspace/improve.js} +3 -3
  71. package/dist/src/core/{manifest.js → workspace/manifest.js} +2 -2
  72. package/dist/src/core/{outcomes.js → workspace/outcomes.js} +3 -3
  73. package/dist/src/core/{portable.js → workspace/portable.js} +3 -3
  74. package/dist/src/core/{profile-state.js → workspace/profile-state.js} +1 -1
  75. package/dist/src/core/{recommend.js → workspace/recommend.js} +1 -1
  76. package/dist/src/core/{state.js → workspace/state.js} +3 -3
  77. package/docs/CATALOG.md +2 -2
  78. package/docs/DISCOVERED.md +249 -247
  79. package/docs/UPSTREAM_LICENSE_DECISIONS.md +19 -12
  80. package/docs/evidence/readme-claims.json +22 -19
  81. package/package.json +2 -1
  82. package/skills/loadout-curator/SKILL.md +105 -0
  83. package/skills/loadout-router/SKILL.md +120 -0
  84. package/dist/src/core/cli-guide.js +0 -118
  85. package/dist/src/core/doctor.js +0 -95
  86. /package/dist/src/core/{agent-health-score.js → agents/agent-health-score.js} +0 -0
  87. /package/dist/src/core/{agent-versions.js → agents/agent-versions.js} +0 -0
  88. /package/dist/src/core/{conversion.js → agents/conversion.js} +0 -0
  89. /package/dist/src/core/{paths.js → agents/paths.js} +0 -0
  90. /package/dist/src/core/{runtime-tool-recipe.js → agents/runtime-tool-recipe.js} +0 -0
  91. /package/dist/src/core/{catalog-coverage.js → catalog/catalog-coverage.js} +0 -0
  92. /package/dist/src/core/{safety.js → catalog/safety.js} +0 -0
  93. /package/dist/src/core/{skill-security.js → catalog/skill-security.js} +0 -0
  94. /package/dist/src/core/{community.js → discovery/community.js} +0 -0
  95. /package/dist/src/core/{github-discovery.js → discovery/github-discovery.js} +0 -0
  96. /package/dist/src/core/{private-discovery.js → discovery/private-discovery.js} +0 -0
  97. /package/dist/src/core/{ranking.js → discovery/ranking.js} +0 -0
  98. /package/dist/src/core/{atomic-file.js → install/atomic-file.js} +0 -0
  99. /package/dist/src/core/{diff.js → install/diff.js} +0 -0
  100. /package/dist/src/core/{update-watch.js → install/update-watch.js} +0 -0
  101. /package/dist/src/core/{completion.js → reporting/completion.js} +0 -0
  102. /package/dist/src/core/{loadout-badge.js → reporting/loadout-badge.js} +0 -0
  103. /package/dist/src/core/{terminal.js → reporting/terminal.js} +0 -0
  104. /package/dist/src/core/{access.js → routing/access.js} +0 -0
  105. /package/dist/src/core/{credentials.js → routing/credentials.js} +0 -0
  106. /package/dist/src/core/{sandbox.js → runtime/sandbox.js} +0 -0
  107. /package/dist/src/core/{active-limit.js → workspace/active-limit.js} +0 -0
  108. /package/dist/src/core/{target-occupancy.js → workspace/target-occupancy.js} +0 -0
@@ -1,31 +1,38 @@
1
1
  # Upstream license decisions
2
2
 
3
- Reviewed on July 21, 2026 for the public release catalog.
3
+ Reviewed on July 21, 2026 for the public release catalog. Re-reviewed on August 30,
4
+ 2026: two of the original six records had identifiable repository-wide licenses and
5
+ were updated in `catalog/packages.json`; four remain `NOASSERTION`.
4
6
 
5
7
  Loadout records `NOASSERTION` when it cannot identify one repository-wide SPDX
6
8
  license from the inspected source. Popularity, an official publisher, or a public
7
9
  GitHub repository does not replace a license grant.
8
10
 
9
- ## Release decision
11
+ ## Resolved out of NOASSERTION (August 30, 2026)
10
12
 
11
- The six records below remain in the credited catalog as source metadata. Loadout
13
+ | Catalog record | Upstream source | Recorded decision |
14
+ | -------------- | --------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
15
+ | Vercel Skills | [vercel-labs/skills](https://github.com/vercel-labs/skills) | Updated `license` to `MIT`. The repository now carries a root `LICENSE` file (MIT, Vercel, Inc., 2026) and GitHub's license API confirms `mit`. No longer `NOASSERTION`. |
16
+ | Sentry MCP | [getsentry/sentry-mcp](https://github.com/getsentry/sentry-mcp) | Updated `license` to `FSL-1.1-ALv2`. The root `LICENSE.md` is the Functional Source License 1.1, Apache-2.0 Future License — a single, identifiable repository-wide license, just not one GitHub's detector classifies as a standard OSS license. **This is not a permissive OSI license**: it forbids "Competing Use" (offering the software, or a substitute for it, as a competing commercial product or service) until it converts to Apache-2.0 two years after each release. Sentry MCP is not part of Stable and should stay out of any default/non-custom mode; Power, Maximum, or Custom selections must show this restriction before fetch, not just a generic "review upstream terms" notice. |
17
+
18
+ ## Remaining NOASSERTION (four records)
19
+
20
+ The four records below remain in the credited catalog as source metadata. Loadout
12
21
  does not copy their source into the npm package, claim ownership, or assign them a
13
22
  license. A selected profile may fetch a pinned upstream snapshot only after showing
14
23
  the user a preview. MCP configuration and executable tools remain separate explicit
15
24
  actions.
16
25
 
17
- None of these six records is part of Stable. Stable continues to use four sources
26
+ None of these four records is part of Stable. Stable continues to use four sources
18
27
  with identified SPDX licenses. People who select Power, Maximum, or a Custom package
19
28
  must review the linked upstream terms before using content marked `NOASSERTION`.
20
29
 
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. |
30
+ | Catalog record | Upstream source | Recorded decision |
31
+ | ------------------------------ | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
32
+ | OpenAI Skills Catalog | [openai/skills](https://github.com/openai/skills) | Retain `NOASSERTION`; the repository has no root `LICENSE` file of any kind. |
33
+ | Anthropic Skills | [anthropics/skills](https://github.com/anthropics/skills) | Retain `NOASSERTION`; the repository has no root `LICENSE` file of any kind. |
34
+ | Vercel Agent Skills | [vercel-labs/agent-skills](https://github.com/vercel-labs/agent-skills) | Retain `NOASSERTION`; the repository has no root `LICENSE` file of any kind. |
35
+ | Model Context Protocol Servers | [modelcontextprotocol/servers](https://github.com/modelcontextprotocol/servers) | Retain `NOASSERTION`; the root `LICENSE` file itself states the project is mid-transition from MIT to Apache-2.0 — new/relicensed contributions are Apache-2.0, contributions whose authors have not consented to relicensing remain MIT. No single SPDX identifier covers the whole repository, so this is a genuine mixed-license case, not a missing-file case. |
29
36
 
30
37
  This is a transparent product policy decision, not legal advice or a claim that the
31
38
  upstream material may be redistributed under Loadout's MIT license. Each upstream
@@ -21,7 +21,7 @@
21
21
  "status": "proven",
22
22
  "evidence": [
23
23
  "catalog/packages.json",
24
- "src/core/catalog-coverage.ts",
24
+ "src/core/catalog/catalog-coverage.ts",
25
25
  "tests/catalog-coverage.test.ts"
26
26
  ]
27
27
  },
@@ -31,7 +31,7 @@
31
31
  "summary": "Stable selection is defined by the checked-in policy and allowlist.",
32
32
  "evidenceClass": "policy-selected",
33
33
  "status": "proven",
34
- "evidence": ["src/core/profiles.ts", "tests/profiles.test.ts"]
34
+ "evidence": ["src/core/catalog/profiles.ts", "tests/profiles.test.ts"]
35
35
  },
36
36
  {
37
37
  "id": "selection.power",
@@ -39,7 +39,7 @@
39
39
  "summary": "Power selection is defined by the checked-in policy and allowlist.",
40
40
  "evidenceClass": "policy-selected",
41
41
  "status": "proven",
42
- "evidence": ["src/core/profiles.ts", "tests/profiles.test.ts"]
42
+ "evidence": ["src/core/catalog/profiles.ts", "tests/profiles.test.ts"]
43
43
  },
44
44
  {
45
45
  "id": "selection.maximum",
@@ -47,7 +47,10 @@
47
47
  "summary": "Maximum selection keeps optional components in Loadout's managed library rather than activating every component.",
48
48
  "evidenceClass": "integration-verified",
49
49
  "status": "bounded",
50
- "evidence": ["src/core/active-set.ts", "tests/active-set.test.ts"]
50
+ "evidence": [
51
+ "src/core/workspace/active-set.ts",
52
+ "tests/active-set.test.ts"
53
+ ]
51
54
  },
52
55
  {
53
56
  "id": "agents.support",
@@ -56,7 +59,7 @@
56
59
  "evidenceClass": "integration-verified",
57
60
  "status": "bounded",
58
61
  "evidence": [
59
- "src/core/adapters.ts",
62
+ "src/core/agents/adapters.ts",
60
63
  "tests/adapters.test.ts",
61
64
  "tests/adapter-conformance.test.ts"
62
65
  ]
@@ -79,7 +82,7 @@
79
82
  "evidenceClass": "integration-verified",
80
83
  "status": "proven",
81
84
  "evidence": [
82
- "src/core/install.ts",
85
+ "src/core/install/install.ts",
83
86
  "tests/transaction.test.ts",
84
87
  "tests/install.test.ts"
85
88
  ]
@@ -90,7 +93,7 @@
90
93
  "summary": "Update workflows present a bounded local plan before an explicit apply step.",
91
94
  "evidenceClass": "integration-verified",
92
95
  "status": "proven",
93
- "evidence": ["src/core/update.ts", "tests/update.test.ts"]
96
+ "evidence": ["src/core/install/update.ts", "tests/update.test.ts"]
94
97
  },
95
98
  {
96
99
  "id": "updates.saved-profile",
@@ -99,8 +102,8 @@
99
102
  "evidenceClass": "integration-verified",
100
103
  "status": "proven",
101
104
  "evidence": [
102
- "src/core/profile-state.ts",
103
- "src/core/update.ts",
105
+ "src/core/workspace/profile-state.ts",
106
+ "src/core/install/update.ts",
104
107
  "tests/profile-state.test.ts",
105
108
  "tests/update.test.ts"
106
109
  ]
@@ -111,7 +114,7 @@
111
114
  "summary": "Managed installation treats recursively empty leftover skill directories as unoccupied while retaining collision protection for files and symlinks.",
112
115
  "evidenceClass": "integration-verified",
113
116
  "status": "proven",
114
- "evidence": ["src/core/install.ts", "tests/install.test.ts"]
117
+ "evidence": ["src/core/install/install.ts", "tests/install.test.ts"]
115
118
  },
116
119
  {
117
120
  "id": "rollback.snapshot",
@@ -120,7 +123,7 @@
120
123
  "evidenceClass": "integration-verified",
121
124
  "status": "proven",
122
125
  "evidence": [
123
- "src/core/snapshot.ts",
126
+ "src/core/install/snapshot.ts",
124
127
  "tests/snapshot.test.ts",
125
128
  "tests/transaction.test.ts"
126
129
  ]
@@ -131,7 +134,7 @@
131
134
  "summary": "Recommendations expose bounded repository and local evidence rather than universal quality claims.",
132
135
  "evidenceClass": "unit-verified",
133
136
  "status": "bounded",
134
- "evidence": ["src/core/recommend.ts", "tests/recommend.test.ts"]
137
+ "evidence": ["src/core/workspace/recommend.ts", "tests/recommend.test.ts"]
135
138
  },
136
139
  {
137
140
  "id": "trust.stages",
@@ -140,7 +143,7 @@
140
143
  "evidenceClass": "structural",
141
144
  "status": "proven",
142
145
  "evidence": [
143
- "src/core/profiles.ts",
146
+ "src/core/catalog/profiles.ts",
144
147
  "tests/profiles.test.ts",
145
148
  "docs/CATALOG_POLICY.md"
146
149
  ]
@@ -152,7 +155,7 @@
152
155
  "evidenceClass": "integration-verified",
153
156
  "status": "proven",
154
157
  "evidence": [
155
- "src/core/github-discovery.ts",
158
+ "src/core/discovery/github-discovery.ts",
156
159
  "tests/daily-discovery.test.ts",
157
160
  "tests/review-queue.test.ts"
158
161
  ]
@@ -177,7 +180,7 @@
177
180
  "status": "proven",
178
181
  "evidence": [
179
182
  "src/cli.ts",
180
- "src/core/mcp-recipes.ts",
183
+ "src/core/runtime/mcp-recipes.ts",
181
184
  "tests/cli-help.test.ts",
182
185
  "tests/mcp-recipes.test.ts"
183
186
  ]
@@ -188,7 +191,7 @@
188
191
  "summary": "MCP configuration uses explicit plans and keeps credentials outside persisted shared manifests.",
189
192
  "evidenceClass": "integration-verified",
190
193
  "status": "proven",
191
- "evidence": ["src/core/mcp.ts", "tests/mcp-config.test.ts"]
194
+ "evidence": ["src/core/runtime/mcp.ts", "tests/mcp-config.test.ts"]
192
195
  },
193
196
  {
194
197
  "id": "manifests.portability",
@@ -197,7 +200,7 @@
197
200
  "evidenceClass": "structural",
198
201
  "status": "proven",
199
202
  "evidence": [
200
- "src/core/manifest.ts",
203
+ "src/core/workspace/manifest.ts",
201
204
  "src/shared/schemas.ts",
202
205
  "tests/manifest.test.ts"
203
206
  ]
@@ -209,8 +212,8 @@
209
212
  "evidenceClass": "integration-verified",
210
213
  "status": "bounded",
211
214
  "evidence": [
212
- "src/core/uninstall.ts",
213
- "src/core/remove.ts",
215
+ "src/core/install/uninstall.ts",
216
+ "src/core/install/remove.ts",
214
217
  "tests/uninstall.test.ts"
215
218
  ]
216
219
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loadout-ai",
3
- "version": "0.5.9",
3
+ "version": "0.7.0",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "description": "Universal upgrade manager for AI coding agents",
@@ -11,6 +11,7 @@
11
11
  "files": [
12
12
  "dist/src",
13
13
  "catalog",
14
+ "skills",
14
15
  "docs",
15
16
  "README.md",
16
17
  "CHANGELOG.md",
@@ -0,0 +1,105 @@
1
+ ---
2
+ name: loadout-curator
3
+ description: Decide which agent skills, MCP servers, and tools should be active for the current repository, and keep that set current. Use when the user asks what skills they should install, why an agent is missing context about their stack, whether their setup is up to date, or when starting work in an unfamiliar codebase.
4
+ ---
5
+
6
+ # Loadout Curator
7
+
8
+ Match the active skill set to the repository in front of you. Too few skills and
9
+ the agent lacks context; too many and every prompt carries weight it does not
10
+ need.
11
+
12
+ This skill wraps the `loadout` CLI so the catalog, provenance, and safety
13
+ findings stay current rather than being copied into this file.
14
+
15
+ ## Prerequisite
16
+
17
+ ```bash
18
+ loadout --version
19
+ ```
20
+
21
+ If that fails, tell the user to install it (`npm install --global loadout-ai`)
22
+ and stop; do not guess at catalog contents.
23
+
24
+ ## Starting work in a repository
25
+
26
+ Read what the codebase actually is before suggesting anything:
27
+
28
+ ```bash
29
+ loadout recommend --project .
30
+ ```
31
+
32
+ This prints detected signals (languages, frameworks, test runners) and
33
+ rule-based suggestions with a confidence label. The signals are the useful part
34
+ — they tell you what the repository is without you reading every file.
35
+
36
+ Report the detected stack first, then the suggestions worth acting on. Skip
37
+ low-confidence suggestions unless the user asks for the full list.
38
+
39
+ `recommend` reads the project and the catalog. It does not prove quality, and it
40
+ says so; repeat that framing rather than presenting suggestions as verified.
41
+
42
+ ## Proposing an active set
43
+
44
+ ```bash
45
+ loadout optimize --project .
46
+ ```
47
+
48
+ This proposes which already-downloaded library skills should be active here.
49
+ Use it when the user has a Maximum-mode library, or after `recommend` shows the
50
+ project needs something different from what is on.
51
+
52
+ Present the proposal as a diff in plain words — what turns on, what turns off,
53
+ and why — before the user approves. Both commands are read-only until `--yes`.
54
+
55
+ ## Installing something new
56
+
57
+ ```bash
58
+ loadout setup --mode custom --package <id> # preview
59
+ loadout setup --mode custom --package <id> --yes # apply
60
+ ```
61
+
62
+ Never run the `--yes` form on your own initiative. Show the preview, summarize
63
+ what it adds and to which agents, and let the user approve. Loadout snapshots
64
+ before writing, and `loadout rollback` undoes the last apply — say so, because
65
+ it lowers the cost of trying something.
66
+
67
+ If the preview reports safety findings (scripts, network domains, instruction
68
+ overrides), read them out specifically. Do not summarize a finding as "minor."
69
+
70
+ ## Checking whether the setup is current
71
+
72
+ ```bash
73
+ loadout status # health grade and what is managed
74
+ loadout health # safer updates and local drift
75
+ loadout alerts # archived, stale, or changed upstream sources
76
+ ```
77
+
78
+ Run these when the user asks whether their setup is up to date, or when an agent
79
+ behaves oddly and stale or drifted skills could explain it.
80
+
81
+ `alerts` reporting an archived upstream is worth raising unprompted — an
82
+ archived source will not receive fixes.
83
+
84
+ ## Inspecting before trusting
85
+
86
+ For a source not yet in the catalog:
87
+
88
+ ```bash
89
+ loadout inspect --repository <owner/name>
90
+ ```
91
+
92
+ This clones at an immutable commit and classifies what it finds. Use it when the
93
+ user asks about a repository you cannot otherwise vouch for. Report what it
94
+ actually contains rather than what its README claims.
95
+
96
+ ## Judgment this skill does not replace
97
+
98
+ - A large active set is not automatically wrong; a monorepo touching several
99
+ stacks legitimately needs more than a single-purpose service.
100
+ - Detected signals describe dependencies, not intent. A repository with a test
101
+ runner installed but no tests still needs testing skills.
102
+ - The catalog is a review queue with provenance, not a quality ranking. High
103
+ star counts are evidence of popularity only.
104
+ - Never enable an MCP server that needs credentials without walking the user
105
+ through what it will access first.
@@ -0,0 +1,120 @@
1
+ ---
2
+ name: loadout-router
3
+ description: Choose the right model tier and agent for a coding task, and hand work off between Claude Code and Codex. Use when the user asks which model to use, mentions running low on usage or quota, wants to save tokens or cost, asks whether to switch to Opus/Sonnet/Haiku or a GPT tier, or wants to delegate a task to another agent.
4
+ ---
5
+
6
+ # Loadout Router
7
+
8
+ Route each coding task to the cheapest model that still does it well, and hand
9
+ work between agents when a different one is better suited.
10
+
11
+ This skill wraps the `loadout` CLI, so the model catalog and pricing stay
12
+ current with the installed version rather than going stale in this file.
13
+
14
+ ## Prerequisite
15
+
16
+ Check once per session:
17
+
18
+ ```bash
19
+ loadout --version
20
+ ```
21
+
22
+ If that fails, tell the user to install it (`npm install --global loadout-ai`)
23
+ and answer from general knowledge instead of guessing at specifics.
24
+
25
+ ## Choosing a model
26
+
27
+ Run the router with the task described in plain words:
28
+
29
+ ```bash
30
+ loadout route <task description>
31
+ ```
32
+
33
+ It classifies the task into one of six phases — plan, implement, review, test,
34
+ debug, document — and prints the recommended tier, the models in that tier with
35
+ current prices, which of the user's installed agents can run them, and a cheaper
36
+ fallback with its tradeoff.
37
+
38
+ Report the recommendation and the reason. Name the actual model, not just the
39
+ tier. If the output lists a `Conserve:` alternative, mention it only when the
40
+ user cares about cost or quota, otherwise it is noise.
41
+
42
+ When the user is explicit about the phase, skip classification:
43
+
44
+ ```bash
45
+ loadout route --phase review
46
+ ```
47
+
48
+ ## When the user is low on usage
49
+
50
+ If the user mentions running out, being rate limited, conserving quota, or
51
+ stretching a plan, add `--conserve`:
52
+
53
+ ```bash
54
+ loadout route --conserve <task description>
55
+ ```
56
+
57
+ This drops each phase one tier and prints the tradeoff you are accepting. Say
58
+ what is being given up — "shallower architectural reasoning, so review the plan
59
+ more carefully" — rather than presenting it as a free win.
60
+
61
+ Neither Claude Code nor Codex exposes remaining quota programmatically, so never
62
+ claim to know how much the user has left. `--conserve` is a user-driven choice,
63
+ not a measurement.
64
+
65
+ ## Comparing models and cost
66
+
67
+ ```bash
68
+ loadout route --models
69
+ loadout route --models --provider anthropic
70
+ loadout route --models --tier fast
71
+ loadout route --cost
72
+ ```
73
+
74
+ Use these when the user asks what is available or what something costs. Prices
75
+ are per-million-token list rates; actual spend depends on prompt size, so give
76
+ ratios ("roughly 4x cheaper") rather than predicting a dollar total.
77
+
78
+ ## Handing work to another agent
79
+
80
+ When a different agent suits the task better — or the user asks to delegate —
81
+ use the handoff log. Check it is set up:
82
+
83
+ ```bash
84
+ loadout handoff status
85
+ ```
86
+
87
+ If uninitialized, run `loadout handoff init` first. Then send the task:
88
+
89
+ ```bash
90
+ loadout handoff send codex "write unit tests for the auth module" --context "see src/auth.ts"
91
+ ```
92
+
93
+ Put anything the receiving agent needs into `--context`: file paths, the
94
+ decision you already made, what you deliberately left out. The other agent has
95
+ none of this conversation.
96
+
97
+ Sending a task is a real side effect on a shared file. Confirm with the user
98
+ before sending unless they asked for the handoff themselves.
99
+
100
+ ## Reading your own inbox
101
+
102
+ At the start of a session, and after finishing a task, check whether another
103
+ agent left you work:
104
+
105
+ ```bash
106
+ loadout handoff inbox claude-code
107
+ ```
108
+
109
+ If it lists tasks, work them in order and run the `loadout handoff done <id>`
110
+ command it prints for each one. If it reports none, continue as normal and do
111
+ not mention it.
112
+
113
+ ## Judgment this skill does not replace
114
+
115
+ - A "simple" task in an unfamiliar or high-risk area still deserves a stronger
116
+ model. The classifier reads keywords, not stakes.
117
+ - Security-sensitive, migration, and data-loss paths are worth frontier tier
118
+ regardless of what phase they classify as.
119
+ - If the user has already chosen a model, do not argue unless the choice is
120
+ clearly wrong for the work.
@@ -1,118 +0,0 @@
1
- /** Plain-language entry points for people using the CLI, not maintaining it. */
2
- export const BEGINNER_GUIDE = `
3
- START HERE
4
-
5
- 1. See what Loadout currently manages
6
- loadout library
7
- loadout scan
8
- loadout reconcile
9
-
10
- 2. Preview the recommended everyday setup
11
- loadout setup --mode stable
12
- loadout profiles
13
-
14
- 3. Find additions that fit the project in this folder
15
- loadout recommend --project .
16
- loadout optimize --project .
17
-
18
- 4. Check for safer updates and new discoveries
19
- loadout health
20
- loadout alerts
21
- loadout candidate list --limit 10
22
-
23
- 5. See reviewed MCP integrations and their credential needs
24
- loadout mcp-recipe
25
- loadout mcp-recipe --credential-free
26
- loadout mcp-recipe playwright --agent codex
27
-
28
- If you decide to install something, Loadout shows a preview first and creates a
29
- snapshot before changing managed files. Recover with: loadout rollback
30
-
31
- Reconcile is also read-only unless you add --yes. Exact matches can be managed
32
- without rewriting them; outdated replacements remain a separate explicit choice.
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
-
38
- Nothing above changes your agents. For the full maintainer/tooling surface, run:
39
- loadout advanced
40
- `.trim();
41
- export const ADVANCED_GUIDE = [
42
- "ADVANCED COMMANDS",
43
- "",
44
- "These remain available, but are hidden from the first screen so daily use stays simple.",
45
- "",
46
- "Discovery and evidence: candidate, discover, review-queue, compare, evaluate, capabilities, skill-audit.",
47
- "Manifests and sharing: init, add, unadd, lock, export, import, audit, create, pack, publish, share, card, badge.",
48
- "Integrations and safety: mcp-recipe, mcp-config, codex-mcp-config, credentials, models, sandbox-run, canary, convert.",
49
- "Lifecycle extras: plan, adopt, uninstall, profiles, versions, outcomes, improve, autopilot, tool, watch, schedule, unschedule, serve.",
50
- "",
51
- "Use `loadout <command> --help` for exact options. Every mutation-capable command previews first or requires --yes.",
52
- ].join("\n");
53
- /**
54
- * The first-screen help shows only the everyday core (~24 commands). Everything
55
- * else stays fully available and runnable, just omitted from the default help so
56
- * the surface reads as a focused product rather than a tool dump. `loadout
57
- * advanced` lists the hidden surface; `loadout <command> --help` documents each.
58
- */
59
- export const HIDDEN_FROM_FIRST_SCREEN = new Set([
60
- // manifests, authoring, sharing
61
- "init",
62
- "lock",
63
- "export",
64
- "import",
65
- "audit",
66
- "create",
67
- "pack",
68
- "publish",
69
- "add",
70
- "unadd",
71
- "share",
72
- "card",
73
- "badge",
74
- "compare-loadouts",
75
- "search",
76
- // analytics / evidence / discovery
77
- "report",
78
- "outcomes",
79
- "outcome",
80
- "improve",
81
- "improve-feedback",
82
- "compare",
83
- "versions",
84
- "skill-audit",
85
- "capabilities",
86
- "candidate",
87
- "discover",
88
- "review-queue",
89
- "review",
90
- "inspect",
91
- "propose",
92
- "evaluate",
93
- // integrations / credentials / runtime
94
- "credentials",
95
- "models",
96
- "completion",
97
- "mcp-recipe",
98
- "mcp-config",
99
- "codex-mcp-config",
100
- "sandbox-run",
101
- "convert",
102
- "canary",
103
- "serve",
104
- // lifecycle extras
105
- "plan",
106
- "adopt",
107
- "uninstall",
108
- "profiles",
109
- "autopilot",
110
- "tool",
111
- "watch",
112
- "schedule",
113
- "unschedule",
114
- "alert-ignore",
115
- "alert-pin",
116
- "alert-unpin",
117
- "alert-pins",
118
- ]);
@@ -1,95 +0,0 @@
1
- import { access, constants } from "node:fs/promises";
2
- import { dirname } from "node:path";
3
- import { detectAgents, directoryExists, loadoutHome, userHome, } from "./paths.js";
4
- import { inspectAgents } from "./agent-inspection.js";
5
- async function writable(path) {
6
- // A not-yet-created directory is healthy when any existing ancestor is
7
- // writable; this handles first-run paths such as ~/.agents/skills.
8
- let candidate = path;
9
- while (true) {
10
- try {
11
- await access(candidate, constants.W_OK);
12
- return true;
13
- }
14
- catch {
15
- const parent = dirname(candidate);
16
- if (parent === candidate)
17
- return false;
18
- candidate = parent;
19
- }
20
- }
21
- }
22
- export async function runDoctor() {
23
- const home = userHome();
24
- const stateHome = loadoutHome();
25
- const loadoutHomeExists = await directoryExists(stateHome);
26
- const loadoutHomeWritable = await writable(stateHome);
27
- const agents = await detectAgents();
28
- const inventories = await inspectAgents(agents);
29
- const diagnosedAgents = await Promise.all(agents.map(async (agent, index) => {
30
- const exists = await directoryExists(agent.skillsDirectory);
31
- const canWrite = await writable(agent.skillsDirectory);
32
- const issues = [];
33
- if (!agent.installed)
34
- issues.push(`Install or configure ${agent.displayName} to enable it.`);
35
- if (!exists)
36
- issues.push("Skills directory does not exist yet; Loadout will create it during install.");
37
- if (!canWrite)
38
- issues.push("Skills directory is not writable; check permissions or choose another home.");
39
- return {
40
- agent,
41
- inventory: inventories[index],
42
- skillsRootExists: exists,
43
- writable: canWrite,
44
- issues,
45
- };
46
- }));
47
- const issues = [];
48
- if (!loadoutHomeExists)
49
- issues.push("Loadout state directory does not exist yet; it will be created on first install.");
50
- if (!loadoutHomeWritable)
51
- issues.push("Loadout state directory is not writable; check LOADOUT_HOME permissions.");
52
- if (!diagnosedAgents.some(({ agent }) => agent.installed)) {
53
- issues.push("No supported agent executable was detected on PATH.");
54
- }
55
- return {
56
- platform: process.platform,
57
- userHome: home,
58
- loadoutHome: stateHome,
59
- loadoutHomeExists,
60
- loadoutHomeWritable,
61
- agents: diagnosedAgents,
62
- issues,
63
- };
64
- }
65
- export function formatDoctorReport(report) {
66
- const lines = [
67
- "Loadout doctor",
68
- `Platform: ${report.platform}`,
69
- `User home: ${report.userHome}`,
70
- `State home: ${report.loadoutHome}`,
71
- ];
72
- lines.push(`State status: ${report.loadoutHomeExists ? "present" : "not created"} (${report.loadoutHomeWritable ? "writable" : "not writable"})`, "", "Agents:");
73
- for (const entry of report.agents) {
74
- const status = entry.agent.installed ? "detected" : "not found";
75
- lines.push(` ${entry.agent.installed ? "✓" : "○"} ${entry.agent.displayName}: ${status}`, ` skills: ${entry.agent.skillsDirectory} (${entry.skillsRootExists ? "present" : "will be created"}, ${entry.writable ? "writable" : "not writable"})`);
76
- for (const component of entry.inventory.components) {
77
- const detail = component.scanned
78
- ? `${component.directoryExists ? `${component.entries.length} filesystem item(s)` : "not created"}${component.directory ? ` at ${component.directory}` : ""}`
79
- : (component.note ?? "not inspected");
80
- lines.push(` ${component.type}: ${component.compatibility}; ${detail}`);
81
- }
82
- for (const warning of entry.inventory.warnings)
83
- lines.push(` ! ${warning}`);
84
- for (const issue of entry.issues)
85
- lines.push(` ! ${issue}`);
86
- }
87
- if (report.issues.length) {
88
- lines.push("", "Recommendations:");
89
- for (const issue of report.issues)
90
- lines.push(` ! ${issue}`);
91
- }
92
- else
93
- lines.push("", "No global blocking issues found.");
94
- return lines.join("\n");
95
- }