loadout-ai 0.5.7 → 0.5.9
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 +24 -0
- package/MASTER_PLAN.md +22 -22
- package/README.md +29 -18
- package/catalog/discovered.json +56105 -9991
- package/catalog/packages.json +2 -1
- package/dist/src/cli.js +26 -2978
- package/dist/src/commands/agents.js +168 -0
- package/dist/src/commands/catalog.js +578 -0
- package/dist/src/commands/health.js +98 -0
- package/dist/src/commands/inventory.js +416 -0
- package/dist/src/commands/lifecycle.js +411 -0
- package/dist/src/commands/mcp.js +424 -0
- package/dist/src/commands/setup.js +67 -0
- package/dist/src/commands/sharing.js +358 -0
- package/dist/src/commands/support.js +226 -0
- package/dist/src/core/active-limit.js +2 -0
- package/dist/src/core/active-policy.js +2 -1
- package/dist/src/core/catalog-install.js +57 -13
- package/dist/src/core/catalog.js +2 -96
- package/dist/src/core/cli-guide.js +39 -34
- package/dist/src/core/completion.js +2 -20
- package/dist/src/core/github.js +3 -2
- package/dist/src/core/health-score-evidence.js +2 -2
- package/dist/src/core/health.js +83 -0
- package/dist/src/core/install.js +8 -3
- package/dist/src/core/loadout-card.js +14 -2
- package/dist/src/core/skill-inventory.js +3 -3
- package/dist/src/core/skills.js +6 -7
- package/dist/src/core/source.js +10 -3
- package/dist/src/core/upgrade.js +10 -9
- package/docs/ACTIVE_SET.md +1 -1
- package/docs/ACTIVE_SET_POLICY.md +1 -1
- package/docs/DEMO_SCRIPT.md +23 -22
- package/docs/DISCOVERED.md +249 -253
- package/docs/RELEASE_REVIEW.md +28 -143
- package/docs/SUBMISSION_COPY.md +90 -0
- package/docs/UPSTREAM_LICENSE_DECISIONS.md +32 -0
- package/docs/USER_TEST_GUIDE.md +1 -1
- package/docs/evidence/readme-claims.json +2 -14
- package/package.json +4 -3
- package/dist/src/core/benchmark-campaign.js +0 -496
- package/dist/src/core/benchmark-evidence.js +0 -458
- package/dist/src/core/benchmark-fixtures.js +0 -1157
- package/dist/src/core/benchmark-runner.js +0 -301
- package/dist/src/core/benchmark-trust.js +0 -795
- package/dist/src/core/catalog-release.js +0 -287
- package/dist/src/core/compatibility-intelligence.js +0 -465
- package/dist/src/core/ecosystem-import.js +0 -1072
- package/dist/src/core/head-to-head.js +0 -437
- package/dist/src/core/intelligence-feed-build.js +0 -59
- package/dist/src/core/intelligence-feed.js +0 -353
- package/dist/src/core/registry-api.js +0 -97
- package/dist/src/core/release-claims.js +0 -175
- package/dist/src/core/signing.js +0 -115
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { detectAgents, parseAgentSelection } from "../core/paths.js";
|
|
2
|
+
import { DEFAULT_ACTIVE_SKILL_LIMIT } from "../core/active-limit.js";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { writeFileAtomically } from "../core/atomic-file.js";
|
|
5
|
+
import { applyActivationChange, formatActivationPlan, planActivationChange, } from "../core/active-set.js";
|
|
6
|
+
import { applyProjectActivation, formatProjectActivation, planProjectActivation, } from "../core/active-policy.js";
|
|
7
|
+
import { applyNativeSchedulerBundle, formatNativeScheduler, planNativeScheduler, } from "../core/scheduler.js";
|
|
8
|
+
import { REVIEWED_RUNTIME_TOOLS, applyRuntimeToolPlan, formatRuntimeToolPlan, planRuntimeTool, } from "../core/runtime-tools.js";
|
|
9
|
+
import { buildLoadoutCard } from "../core/loadout-card.js";
|
|
10
|
+
import { buildLoadoutBadge, formatLoadoutBadgeUsage, parseLoadoutBadgeMetric, } from "../core/loadout-badge.js";
|
|
11
|
+
import { collectOption, durableSchedulerLauncher } from "./support.js";
|
|
12
|
+
export function registerAgents(program) {
|
|
13
|
+
for (const workflow of ["activate", "optimize"]) {
|
|
14
|
+
program
|
|
15
|
+
.command(workflow)
|
|
16
|
+
.description(workflow === "activate"
|
|
17
|
+
? "Select and activate inspected library skills for a project"
|
|
18
|
+
: "Scan a project and propose rule-selected inspected active-set additions")
|
|
19
|
+
.option("--project <path>", "project directory to scan", ".")
|
|
20
|
+
.option("--agents <ids>", "comma-separated agent ids")
|
|
21
|
+
.option("--limit <count>", `maximum active skills per agent (recommended default: ${DEFAULT_ACTIVE_SKILL_LIMIT})`, String(DEFAULT_ACTIVE_SKILL_LIMIT))
|
|
22
|
+
.option("--pin <selector>", "always prioritize package/skill or skill", collectOption, [])
|
|
23
|
+
.option("--yes", "apply the proposed activation transaction")
|
|
24
|
+
.option("--json", "emit machine-readable JSON")
|
|
25
|
+
.action(async (options) => {
|
|
26
|
+
const agents = options.agents
|
|
27
|
+
?.split(",")
|
|
28
|
+
.map((value) => value.trim())
|
|
29
|
+
.filter(Boolean);
|
|
30
|
+
const plan = await planProjectActivation(options.project, {
|
|
31
|
+
...(agents?.length ? { agents } : {}),
|
|
32
|
+
limit: Number(options.limit),
|
|
33
|
+
pins: options.pin,
|
|
34
|
+
});
|
|
35
|
+
if (!options.yes) {
|
|
36
|
+
console.log(options.json
|
|
37
|
+
? JSON.stringify(plan, null, 2)
|
|
38
|
+
: `${formatProjectActivation(plan)}\nDry run only. Re-run with --yes to activate this reviewed set.`);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const snapshotId = await applyProjectActivation(plan);
|
|
42
|
+
console.log(options.json
|
|
43
|
+
? JSON.stringify({ plan, snapshotId }, null, 2)
|
|
44
|
+
: `${formatProjectActivation(plan)}\nApplied and verified. Snapshot: ${snapshotId}\nRollback: loadout rollback --snapshot ${snapshotId}`);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
for (const action of [
|
|
48
|
+
"enable",
|
|
49
|
+
"disable",
|
|
50
|
+
]) {
|
|
51
|
+
program
|
|
52
|
+
.command(action)
|
|
53
|
+
.description(`${action === "enable" ? "Activate" : "Deactivate"} Loadout-managed skills without deleting the reviewed-library copy`)
|
|
54
|
+
.argument("<packages...>", "one or more managed package ids")
|
|
55
|
+
.option("--agents <ids>", "comma-separated agent ids")
|
|
56
|
+
.option("--yes", "apply the transaction; otherwise show a plan")
|
|
57
|
+
.option("--json", "emit machine-readable JSON")
|
|
58
|
+
.action(async (packageIds, options) => {
|
|
59
|
+
const agents = options.agents
|
|
60
|
+
?.split(",")
|
|
61
|
+
.map((value) => value.trim())
|
|
62
|
+
.filter(Boolean);
|
|
63
|
+
if (agents?.length) {
|
|
64
|
+
const known = new Set((await detectAgents()).map((agent) => agent.id));
|
|
65
|
+
const unknown = agents.filter((agent) => !known.has(agent));
|
|
66
|
+
if (unknown.length)
|
|
67
|
+
throw new Error(`Unknown agent id(s): ${unknown.join(", ")}`);
|
|
68
|
+
}
|
|
69
|
+
const plan = await planActivationChange(action, packageIds, {
|
|
70
|
+
...(agents?.length ? { agents } : {}),
|
|
71
|
+
});
|
|
72
|
+
if (!options.yes) {
|
|
73
|
+
console.log(options.json
|
|
74
|
+
? JSON.stringify(plan, null, 2)
|
|
75
|
+
: `${formatActivationPlan(plan)}\nDry run only. Re-run with --yes to apply this exact transaction.`);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const snapshotId = await applyActivationChange(plan);
|
|
79
|
+
console.log(options.json
|
|
80
|
+
? JSON.stringify({ plan, snapshotId }, null, 2)
|
|
81
|
+
: `${formatActivationPlan(plan)}\nApplied. Snapshot: ${snapshotId}`);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
program
|
|
85
|
+
.command("autopilot")
|
|
86
|
+
.description("Preview or enable both daily read-only discovery and update radar jobs")
|
|
87
|
+
.option("--time <HH:MM>", "local daily check time", "09:00")
|
|
88
|
+
.option("--remove", "remove both daily radar jobs")
|
|
89
|
+
.option("--yes", "apply both native scheduler changes atomically")
|
|
90
|
+
.option("--json", "emit machine-readable JSON")
|
|
91
|
+
.action(async (options) => {
|
|
92
|
+
const action = options.remove
|
|
93
|
+
? "unschedule"
|
|
94
|
+
: "schedule";
|
|
95
|
+
const plans = ["updates", "discovery"].map((job) => planNativeScheduler(action, {
|
|
96
|
+
time: options.time,
|
|
97
|
+
launcher: durableSchedulerLauncher(),
|
|
98
|
+
job,
|
|
99
|
+
}));
|
|
100
|
+
if (!options.yes) {
|
|
101
|
+
console.log(options.json
|
|
102
|
+
? JSON.stringify({ action, plans }, null, 2)
|
|
103
|
+
: `${plans.map(formatNativeScheduler).join("\n\n")}\n\nDry run only. Re-run with --yes to ${options.remove ? "remove" : "enable"} both read-only jobs.`);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const snapshotId = await applyNativeSchedulerBundle(plans);
|
|
107
|
+
console.log(options.json
|
|
108
|
+
? JSON.stringify({ action, plans, snapshotId }, null, 2)
|
|
109
|
+
: `Loadout Autopilot ${options.remove ? "removed" : "enabled"}: daily update radar + multi-source candidate discovery.\nNo scheduled command can install, promote, or execute a candidate. Snapshot: ${snapshotId}`);
|
|
110
|
+
});
|
|
111
|
+
program
|
|
112
|
+
.command("badge")
|
|
113
|
+
.description("Generate telemetry-free Shields endpoint JSON from the local privacy-safe card")
|
|
114
|
+
.option("--metric <metric>", "evidence, active-skills, managed-packages, or mcp", "evidence")
|
|
115
|
+
.option("--output <path>", "write endpoint JSON to this path")
|
|
116
|
+
.action(async (options) => {
|
|
117
|
+
const badge = buildLoadoutBadge(await buildLoadoutCard(), parseLoadoutBadgeMetric(options.metric));
|
|
118
|
+
if (!options.output)
|
|
119
|
+
return console.log(JSON.stringify(badge, null, 2));
|
|
120
|
+
const output = resolve(options.output);
|
|
121
|
+
await writeFileAtomically(output, `${JSON.stringify(badge, null, 2)}\n`);
|
|
122
|
+
console.log(formatLoadoutBadgeUsage(output));
|
|
123
|
+
});
|
|
124
|
+
program
|
|
125
|
+
.command("tool")
|
|
126
|
+
.description("Preview, install, or remove an explicitly reviewed runtime-tool recipe")
|
|
127
|
+
.argument("[id]", "runtime tool id; omit to list reviewed recipes")
|
|
128
|
+
.option("--agents <ids>", "comma-separated target agent ids")
|
|
129
|
+
.option("--remove", "restore pre-install agent state and remove the runtime")
|
|
130
|
+
.option("--yes", "apply the exact displayed plan")
|
|
131
|
+
.option("--approve-risk", "approve installing and running the exact reviewed external artifact")
|
|
132
|
+
.option("--json", "emit machine-readable JSON")
|
|
133
|
+
.action(async (id, options) => {
|
|
134
|
+
if (!id) {
|
|
135
|
+
if (options.remove || options.yes || options.approveRisk)
|
|
136
|
+
throw new Error("Select a runtime tool id for this operation");
|
|
137
|
+
const listed = REVIEWED_RUNTIME_TOOLS.map((recipe) => ({
|
|
138
|
+
id: recipe.id,
|
|
139
|
+
displayName: recipe.displayName,
|
|
140
|
+
version: recipe.version,
|
|
141
|
+
source: recipe.source,
|
|
142
|
+
artifactSha256: recipe.artifactSha256,
|
|
143
|
+
}));
|
|
144
|
+
console.log(options.json
|
|
145
|
+
? JSON.stringify(listed, null, 2)
|
|
146
|
+
: listed
|
|
147
|
+
.map((recipe) => `${recipe.id} — ${recipe.displayName} ${recipe.version} — ${recipe.source}`)
|
|
148
|
+
.join("\n"));
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const plan = await planRuntimeTool(id, {
|
|
152
|
+
action: options.remove ? "remove" : "install",
|
|
153
|
+
requestedAgents: parseAgentSelection(options.agents),
|
|
154
|
+
});
|
|
155
|
+
if (!options.yes) {
|
|
156
|
+
console.log(options.json
|
|
157
|
+
? JSON.stringify(plan, null, 2)
|
|
158
|
+
: `${formatRuntimeToolPlan(plan)}\n\nDry run only. Re-run with --yes --approve-risk to apply this exact runtime recipe.`);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
if (!options.approveRisk)
|
|
162
|
+
throw new Error("Runtime tool changes require --approve-risk after reviewing the preview");
|
|
163
|
+
const result = await applyRuntimeToolPlan(plan, { approveRisk: true });
|
|
164
|
+
console.log(options.json
|
|
165
|
+
? JSON.stringify({ plan, result }, null, 2)
|
|
166
|
+
: `${plan.recipe.displayName} ${result.action === "install" ? "installed and registered" : "removed and prior agent state restored"}. Snapshot: ${result.snapshotId}`);
|
|
167
|
+
});
|
|
168
|
+
}
|