loadout-ai 0.7.0 → 0.8.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 (44) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/README.md +33 -33
  3. package/catalog/discovered.json +26880 -24184
  4. package/dist/src/cli.js +5 -0
  5. package/dist/src/commands/catalog.js +103 -116
  6. package/dist/src/core/agents/agent-inspection.js +26 -4
  7. package/dist/src/core/catalog/registry.js +58 -10
  8. package/dist/src/core/catalog/safety.js +36 -7
  9. package/dist/src/core/install/source.js +21 -7
  10. package/dist/src/core/reporting/cli-guide.js +3 -3
  11. package/dist/src/core/reporting/completion.js +42 -95
  12. package/dist/src/core/reporting/doctor.js +3 -5
  13. package/dist/src/core/routing/handoff.js +94 -58
  14. package/dist/src/core/routing/policy.js +147 -0
  15. package/dist/src/core/routing/route.js +25 -153
  16. package/docs/CANDIDATE_INTELLIGENCE.md +9 -2
  17. package/docs/CATALOG.md +1 -1
  18. package/docs/CREDENTIAL_AND_UPDATE_POLICY.md +1 -1
  19. package/docs/DISCOVERED.md +252 -251
  20. package/docs/FEATURE_TEST_MATRIX.md +7 -260
  21. package/docs/GITHUB_AUTHORIZATION.md +5 -0
  22. package/docs/PROVENANCE_AND_COMPARISON.md +1 -1
  23. package/docs/RELEASE_REVIEW.md +0 -1
  24. package/package.json +6 -4
  25. package/skills/loadout-router/SKILL.md +43 -78
  26. package/MASTER_PLAN.md +0 -2207
  27. package/docs/ACTIVE_SET.md +0 -53
  28. package/docs/COMPATIBILITY_POLICY.md +0 -22
  29. package/docs/CONVERSION_AND_SANDBOX.md +0 -27
  30. package/docs/EVALUATION_PROTOCOL_V1.md +0 -300
  31. package/docs/HEAD_TO_HEAD_EVALUATION.md +0 -79
  32. package/docs/PROVIDER_CONFIGURATION.md +0 -45
  33. package/docs/README_RESEARCH.md +0 -36
  34. package/docs/REPOSITORY_STABILIZATION.md +0 -190
  35. package/docs/SAFE_UPDATE_DEMO.md +0 -25
  36. package/docs/SCHEMA_DECISIONS.md +0 -25
  37. package/docs/SUBMISSION_COPY.md +0 -90
  38. package/docs/TEAM_POLICY.md +0 -18
  39. package/docs/superpowers/plans/2026-07-19-relatable-readme-hero.md +0 -283
  40. package/docs/superpowers/plans/2026-07-20-loadout-readme-explainer.md +0 -116
  41. package/docs/superpowers/plans/2026-07-20-project-activation-safety.md +0 -469
  42. package/docs/superpowers/specs/2026-07-19-relatable-readme-hero-design.md +0 -80
  43. package/docs/superpowers/specs/2026-07-20-loadout-readme-explainer-design.md +0 -55
  44. package/docs/superpowers/specs/2026-07-20-project-activation-safety-design.md +0 -228
@@ -4,17 +4,8 @@
4
4
  // Prices as of August 2026.
5
5
  export const MODEL_CATALOG = [
6
6
  // --- Anthropic (Claude Code) ---
7
- {
8
- id: "claude-fable-5",
9
- provider: "anthropic",
10
- name: "Claude Fable 5",
11
- tier: "frontier",
12
- inputCostPer1M: 10,
13
- outputCostPer1M: 50,
14
- nativeAgents: ["claude-code"],
15
- current: true,
16
- generation: "5",
17
- },
7
+ // Haiku and the 4.x line are deliberately absent: for real coding work the
8
+ // choice is Opus or Sonnet, and offering a weaker tier invites picking it.
18
9
  {
19
10
  id: "claude-opus-5",
20
11
  provider: "anthropic",
@@ -37,51 +28,7 @@ export const MODEL_CATALOG = [
37
28
  current: true,
38
29
  generation: "5",
39
30
  },
40
- {
41
- id: "claude-opus-4-8",
42
- provider: "anthropic",
43
- name: "Claude Opus 4.8",
44
- tier: "frontier",
45
- inputCostPer1M: 5,
46
- outputCostPer1M: 25,
47
- nativeAgents: ["claude-code"],
48
- current: false,
49
- generation: "4",
50
- },
51
- {
52
- id: "claude-opus-4-6",
53
- provider: "anthropic",
54
- name: "Claude Opus 4.6",
55
- tier: "frontier",
56
- inputCostPer1M: 5,
57
- outputCostPer1M: 25,
58
- nativeAgents: ["claude-code"],
59
- current: false,
60
- generation: "4",
61
- },
62
- {
63
- id: "claude-sonnet-4-6",
64
- provider: "anthropic",
65
- name: "Claude Sonnet 4.6",
66
- tier: "standard",
67
- inputCostPer1M: 3,
68
- outputCostPer1M: 15,
69
- nativeAgents: ["claude-code"],
70
- current: false,
71
- generation: "4",
72
- },
73
- {
74
- id: "claude-haiku-4-5",
75
- provider: "anthropic",
76
- name: "Claude Haiku 4.5",
77
- tier: "fast",
78
- inputCostPer1M: 1,
79
- outputCostPer1M: 5,
80
- nativeAgents: ["claude-code"],
81
- current: true,
82
- generation: "4",
83
- },
84
- // --- OpenAI (Codex) — GPT-5.6 family ---
31
+ // --- OpenAI (Codex) — the current GPT-5.6 tiers only ---
85
32
  {
86
33
  id: "gpt-5.6-sol",
87
34
  provider: "openai",
@@ -115,98 +62,6 @@ export const MODEL_CATALOG = [
115
62
  current: true,
116
63
  generation: "5.6",
117
64
  },
118
- // --- OpenAI — GPT-5.5 ---
119
- {
120
- id: "gpt-5.5",
121
- provider: "openai",
122
- name: "GPT-5.5",
123
- tier: "frontier",
124
- inputCostPer1M: 5,
125
- outputCostPer1M: 30,
126
- nativeAgents: ["codex"],
127
- current: true,
128
- generation: "5.5",
129
- },
130
- // --- OpenAI — GPT-5.4 family ---
131
- {
132
- id: "gpt-5.4",
133
- provider: "openai",
134
- name: "GPT-5.4",
135
- tier: "standard",
136
- inputCostPer1M: 2.5,
137
- outputCostPer1M: 15,
138
- nativeAgents: ["codex"],
139
- current: true,
140
- generation: "5.4",
141
- },
142
- {
143
- id: "gpt-5.4-mini",
144
- provider: "openai",
145
- name: "GPT-5.4 Mini",
146
- tier: "fast",
147
- inputCostPer1M: 0.75,
148
- outputCostPer1M: 4.5,
149
- nativeAgents: ["codex"],
150
- current: true,
151
- generation: "5.4",
152
- },
153
- // --- OpenAI — Codex-specific ---
154
- {
155
- id: "gpt-5.1-codex",
156
- provider: "openai",
157
- name: "GPT-5.1 Codex",
158
- tier: "standard",
159
- inputCostPer1M: 1.25,
160
- outputCostPer1M: 10,
161
- nativeAgents: ["codex"],
162
- current: true,
163
- generation: "5.1",
164
- },
165
- // --- OpenAI — o-series reasoning ---
166
- {
167
- id: "o3-pro",
168
- provider: "openai",
169
- name: "o3-pro",
170
- tier: "frontier",
171
- inputCostPer1M: 20,
172
- outputCostPer1M: 80,
173
- nativeAgents: ["codex"],
174
- current: true,
175
- generation: "o3",
176
- },
177
- {
178
- id: "o3",
179
- provider: "openai",
180
- name: "o3",
181
- tier: "frontier",
182
- inputCostPer1M: 2,
183
- outputCostPer1M: 8,
184
- nativeAgents: ["codex"],
185
- current: true,
186
- generation: "o3",
187
- },
188
- {
189
- id: "o4-mini",
190
- provider: "openai",
191
- name: "o4-mini",
192
- tier: "standard",
193
- inputCostPer1M: 1.1,
194
- outputCostPer1M: 4.4,
195
- nativeAgents: ["codex"],
196
- current: true,
197
- generation: "o4",
198
- },
199
- {
200
- id: "o3-mini",
201
- provider: "openai",
202
- name: "o3-mini",
203
- tier: "standard",
204
- inputCostPer1M: 1.1,
205
- outputCostPer1M: 4.4,
206
- nativeAgents: ["codex"],
207
- current: true,
208
- generation: "o3",
209
- },
210
65
  ];
211
66
  const TIER_LABELS = {
212
67
  frontier: "Frontier (deep reasoning)",
@@ -435,11 +290,28 @@ export function formatRouteRecommendation(rec, context = {}) {
435
290
  const { available, missing } = checked
436
291
  ? resolveAvailableAgents(rec.suggestedAgents, context.installedAgents)
437
292
  : { available: rec.suggestedAgents, missing: [] };
438
- // Only recommend models an available agent can actually run.
293
+ // Only recommend models an available agent can actually run. Not every
294
+ // provider offers every tier — Claude Code has no fast tier — so when the
295
+ // recommended tier holds nothing the user can reach, step up to the nearest
296
+ // tier that does rather than naming a model they cannot run.
439
297
  const runnable = checked
440
298
  ? modelsRunnableBy(rec.models, available)
441
299
  : rec.models;
442
- const shown = (runnable.length ? runnable : rec.models).slice(0, 4);
300
+ const stepUp = {
301
+ fast: "standard",
302
+ standard: "frontier",
303
+ };
304
+ let effective = runnable;
305
+ let tier = rec.tier;
306
+ let substituted;
307
+ while (checked && available.length && !effective.length && stepUp[tier]) {
308
+ const next = stepUp[tier];
309
+ effective = modelsRunnableBy(modelsForTier(next), available);
310
+ if (effective.length)
311
+ substituted = { from: rec.tier, to: next };
312
+ tier = next;
313
+ }
314
+ const shown = (effective.length ? effective : rec.models).slice(0, 4);
443
315
  const modelNames = shown.map((m) => `${m.name} ($${m.inputCostPer1M}/$${m.outputCostPer1M})`);
444
316
  const lines = [
445
317
  `Phase: ${rec.phase}`,
@@ -448,6 +320,8 @@ export function formatRouteRecommendation(rec, context = {}) {
448
320
  `Agents: ${available.length ? available.join(", ") : "none detected"}${missing.length ? ` (not installed: ${missing.join(", ")})` : ""}`,
449
321
  `Why: ${rec.reason}`,
450
322
  ];
323
+ if (substituted)
324
+ lines.push(`Note: your agents have no ${substituted.from}-tier model, so this shows`, ` the ${substituted.to} tier instead.`);
451
325
  if (rec.conserveAlternative) {
452
326
  const alt = rec.conserveAlternative;
453
327
  const altCheapest = cheapestInTier(alt.tier);
@@ -456,9 +330,7 @@ export function formatRouteRecommendation(rec, context = {}) {
456
330
  // Actionable next step: hand this task to a detected agent.
457
331
  if (context.description && available.length) {
458
332
  const target = available[0];
459
- lines.push(``, `Hand off:`, ` loadout handoff send ${target} ${shellQuote(context.description)}`);
460
- if (context.handoffReady === false)
461
- lines.push(` (run \`loadout handoff init\` once to enable)`);
333
+ lines.push(``, `Hand off:`, ` loadout handoff ${target} ${shellQuote(context.description)}`);
462
334
  }
463
335
  return lines.join("\n");
464
336
  }
@@ -93,10 +93,16 @@ powers, platform behavior, category, and catalog policy.
93
93
 
94
94
  ## Distribute a trusted catalog release
95
95
 
96
- Maintainers sign a technically screened full catalog array with an Ed25519 key kept outside the
96
+ > **Not implemented.** The signing flow below is a design sketch. `loadout keygen`,
97
+ > `loadout catalog-sign`, and `loadout catalog-update` do not exist in the CLI
98
+ > today; the catalog ships in the package and is verified by the evidence gate
99
+ > instead. Kept here as the intended shape, not as instructions.
100
+
101
+ Maintainers would sign a technically screened full catalog array with an Ed25519 key kept outside the
97
102
  repository:
98
103
 
99
104
  ```bash
105
+ # Design sketch — these commands do not exist yet.
100
106
  loadout keygen --private-key /secure/catalog-private.pem \
101
107
  --public-key ./catalog-public.pem
102
108
  loadout catalog-sign --catalog ./catalog/packages.json \
@@ -104,9 +110,10 @@ loadout catalog-sign --catalog ./catalog/packages.json \
104
110
  --output ./catalog.signed.json
105
111
  ```
106
112
 
107
- Users preview the verified release before trusting it:
113
+ Users would preview the verified release before trusting it:
108
114
 
109
115
  ```bash
116
+ # Design sketch — these commands do not exist yet.
110
117
  loadout catalog-update --source ./catalog.signed.json \
111
118
  --public-key ./catalog-public.pem
112
119
  loadout catalog-update --source ./catalog.signed.json \
package/docs/CATALOG.md CHANGED
@@ -12,7 +12,7 @@ Thank you to every maintainer and contributor whose work appears here. Loadout d
12
12
  - **License** is the SPDX identifier recorded in `catalog/packages.json` from GitHub metadata. **Review required** corresponds to `NOASSERTION`: no SPDX identifier was reported, so users must inspect the upstream terms instead of assuming permission.
13
13
  - **Reviewed revision** links to the immutable commit inspected for catalog admission. It is not necessarily the newest upstream commit.
14
14
 
15
- The machine-readable catalog remains the source of truth. Run `loadout catalog --coverage --json` to inspect coverage and `loadout capabilities` to inspect what each local agent adapter can actually manage.
15
+ The machine-readable catalog remains the source of truth. Run `loadout catalog --coverage --json` to inspect coverage and `loadout doctor --verbose` to inspect what each local agent adapter can actually manage.
16
16
 
17
17
  ## All 53 credited repositories
18
18
 
@@ -26,6 +26,6 @@ verification restores the snapshot and quarantines the candidate commit. A user
26
26
  revoke a policy at any time; revocation prevents future mutations but never deletes
27
27
  existing snapshots.
28
28
 
29
- The local `loadout canary` command implements the non-mutating static gate. A
29
+ Update safety runs as a non-mutating static gate during `loadout upgrade` previews. A
30
30
  transaction layer must provide verification and promotion callbacks before a
31
31
  candidate can be promoted; the command itself never installs a candidate.