loadout-ai 0.6.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 (133) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/README.md +129 -26
  3. package/catalog/discovered.json +28469 -24524
  4. package/dist/src/cli.js +7 -2
  5. package/dist/src/commands/agents.js +6 -23
  6. package/dist/src/commands/catalog.js +186 -102
  7. package/dist/src/commands/health.js +6 -6
  8. package/dist/src/commands/inventory.js +19 -120
  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 +20 -9
  14. package/dist/src/core/{adapters.js → agents/adapters.js} +2 -2
  15. package/dist/src/core/{agent-inspection.js → agents/agent-inspection.js} +48 -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} +5 -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} +59 -11
  26. package/dist/src/core/{safety.js → catalog/safety.js} +36 -7
  27. package/dist/src/core/{skill-compare.js → catalog/skill-compare.js} +1 -1
  28. package/dist/src/core/{skill-inventory.js → catalog/skill-inventory.js} +3 -3
  29. package/dist/src/core/{skills.js → catalog/skills.js} +1 -1
  30. package/dist/src/core/{candidate-intelligence.js → discovery/candidate-intelligence.js} +6 -6
  31. package/dist/src/core/{discovery-connector.js → discovery/discovery-connector.js} +2 -2
  32. package/dist/src/core/{evaluate.js → discovery/evaluate.js} +2 -2
  33. package/dist/src/core/{mcp-registry-discovery.js → discovery/mcp-registry-discovery.js} +1 -1
  34. package/dist/src/core/{observations.js → discovery/observations.js} +3 -3
  35. package/dist/src/core/{review-queue.js → discovery/review-queue.js} +2 -2
  36. package/dist/src/core/{skills-sh-discovery.js → discovery/skills-sh-discovery.js} +1 -1
  37. package/dist/src/core/{adopt.js → install/adopt.js} +3 -3
  38. package/dist/src/core/{catalog-install.js → install/catalog-install.js} +11 -11
  39. package/dist/src/core/{file-lock.js → install/file-lock.js} +1 -1
  40. package/dist/src/core/{install.js → install/install.js} +5 -5
  41. package/dist/src/core/{package.js → install/package.js} +3 -3
  42. package/dist/src/core/{reconcile.js → install/reconcile.js} +5 -5
  43. package/dist/src/core/{remove.js → install/remove.js} +4 -4
  44. package/dist/src/core/{snapshot.js → install/snapshot.js} +1 -1
  45. package/dist/src/core/{source.js → install/source.js} +22 -8
  46. package/dist/src/core/{sync.js → install/sync.js} +9 -9
  47. package/dist/src/core/{transaction.js → install/transaction.js} +1 -1
  48. package/dist/src/core/{uninstall.js → install/uninstall.js} +4 -4
  49. package/dist/src/core/{update.js → install/update.js} +4 -4
  50. package/dist/src/core/{cli-guide.js → reporting/cli-guide.js} +29 -45
  51. package/dist/src/core/reporting/completion.js +90 -0
  52. package/dist/src/core/{doctor.js → reporting/doctor.js} +5 -10
  53. package/dist/src/core/{freshness-alerts.js → reporting/freshness-alerts.js} +5 -5
  54. package/dist/src/core/{health.js → reporting/health.js} +6 -6
  55. package/dist/src/core/{loadout-card.js → reporting/loadout-card.js} +1 -1
  56. package/dist/src/core/{readme-claims.js → reporting/readme-claims.js} +1 -1
  57. package/dist/src/core/{readme-facts.js → reporting/readme-facts.js} +2 -2
  58. package/dist/src/core/{share-report.js → reporting/share-report.js} +3 -3
  59. package/dist/src/core/{upgrade.js → reporting/upgrade.js} +7 -7
  60. package/dist/src/core/routing/first-party-skills.js +118 -0
  61. package/dist/src/core/routing/handoff.js +314 -0
  62. package/dist/src/core/{model-config.js → routing/model-config.js} +4 -4
  63. package/dist/src/core/routing/policy.js +147 -0
  64. package/dist/src/core/{route.js → routing/route.js} +202 -39
  65. package/dist/src/core/{api.js → runtime/api.js} +4 -4
  66. package/dist/src/core/{canary.js → runtime/canary.js} +1 -1
  67. package/dist/src/core/{github.js → runtime/github.js} +1 -1
  68. package/dist/src/core/{mcp-recipes.js → runtime/mcp-recipes.js} +1 -1
  69. package/dist/src/core/{mcp.js → runtime/mcp.js} +2 -2
  70. package/dist/src/core/{scheduler.js → runtime/scheduler.js} +4 -4
  71. package/dist/src/core/{active-policy.js → workspace/active-policy.js} +2 -2
  72. package/dist/src/core/{active-set.js → workspace/active-set.js} +2 -2
  73. package/dist/src/core/{improve.js → workspace/improve.js} +3 -3
  74. package/dist/src/core/{manifest.js → workspace/manifest.js} +2 -2
  75. package/dist/src/core/{outcomes.js → workspace/outcomes.js} +3 -3
  76. package/dist/src/core/{portable.js → workspace/portable.js} +3 -3
  77. package/dist/src/core/{profile-state.js → workspace/profile-state.js} +1 -1
  78. package/dist/src/core/{recommend.js → workspace/recommend.js} +1 -1
  79. package/dist/src/core/{state.js → workspace/state.js} +3 -3
  80. package/docs/CANDIDATE_INTELLIGENCE.md +9 -2
  81. package/docs/CATALOG.md +1 -1
  82. package/docs/CREDENTIAL_AND_UPDATE_POLICY.md +1 -1
  83. package/docs/DISCOVERED.md +250 -248
  84. package/docs/FEATURE_TEST_MATRIX.md +7 -260
  85. package/docs/GITHUB_AUTHORIZATION.md +5 -0
  86. package/docs/PROVENANCE_AND_COMPARISON.md +1 -1
  87. package/docs/RELEASE_REVIEW.md +0 -1
  88. package/docs/evidence/readme-claims.json +22 -19
  89. package/package.json +7 -4
  90. package/skills/loadout-curator/SKILL.md +105 -0
  91. package/skills/loadout-router/SKILL.md +85 -0
  92. package/MASTER_PLAN.md +0 -2207
  93. package/dist/src/core/completion.js +0 -143
  94. package/dist/src/core/handoff.js +0 -161
  95. package/docs/ACTIVE_SET.md +0 -53
  96. package/docs/COMPATIBILITY_POLICY.md +0 -22
  97. package/docs/CONVERSION_AND_SANDBOX.md +0 -27
  98. package/docs/EVALUATION_PROTOCOL_V1.md +0 -300
  99. package/docs/HEAD_TO_HEAD_EVALUATION.md +0 -79
  100. package/docs/PROVIDER_CONFIGURATION.md +0 -45
  101. package/docs/README_RESEARCH.md +0 -36
  102. package/docs/REPOSITORY_STABILIZATION.md +0 -190
  103. package/docs/SAFE_UPDATE_DEMO.md +0 -25
  104. package/docs/SCHEMA_DECISIONS.md +0 -25
  105. package/docs/SUBMISSION_COPY.md +0 -90
  106. package/docs/TEAM_POLICY.md +0 -18
  107. package/docs/superpowers/plans/2026-07-19-relatable-readme-hero.md +0 -283
  108. package/docs/superpowers/plans/2026-07-20-loadout-readme-explainer.md +0 -116
  109. package/docs/superpowers/plans/2026-07-20-project-activation-safety.md +0 -469
  110. package/docs/superpowers/specs/2026-07-19-relatable-readme-hero-design.md +0 -80
  111. package/docs/superpowers/specs/2026-07-20-loadout-readme-explainer-design.md +0 -55
  112. package/docs/superpowers/specs/2026-07-20-project-activation-safety-design.md +0 -228
  113. /package/dist/src/core/{agent-health-score.js → agents/agent-health-score.js} +0 -0
  114. /package/dist/src/core/{agent-versions.js → agents/agent-versions.js} +0 -0
  115. /package/dist/src/core/{conversion.js → agents/conversion.js} +0 -0
  116. /package/dist/src/core/{paths.js → agents/paths.js} +0 -0
  117. /package/dist/src/core/{runtime-tool-recipe.js → agents/runtime-tool-recipe.js} +0 -0
  118. /package/dist/src/core/{catalog-coverage.js → catalog/catalog-coverage.js} +0 -0
  119. /package/dist/src/core/{skill-security.js → catalog/skill-security.js} +0 -0
  120. /package/dist/src/core/{community.js → discovery/community.js} +0 -0
  121. /package/dist/src/core/{github-discovery.js → discovery/github-discovery.js} +0 -0
  122. /package/dist/src/core/{private-discovery.js → discovery/private-discovery.js} +0 -0
  123. /package/dist/src/core/{ranking.js → discovery/ranking.js} +0 -0
  124. /package/dist/src/core/{atomic-file.js → install/atomic-file.js} +0 -0
  125. /package/dist/src/core/{diff.js → install/diff.js} +0 -0
  126. /package/dist/src/core/{update-watch.js → install/update-watch.js} +0 -0
  127. /package/dist/src/core/{loadout-badge.js → reporting/loadout-badge.js} +0 -0
  128. /package/dist/src/core/{terminal.js → reporting/terminal.js} +0 -0
  129. /package/dist/src/core/{access.js → routing/access.js} +0 -0
  130. /package/dist/src/core/{credentials.js → routing/credentials.js} +0 -0
  131. /package/dist/src/core/{sandbox.js → runtime/sandbox.js} +0 -0
  132. /package/dist/src/core/{active-limit.js → workspace/active-limit.js} +0 -0
  133. /package/dist/src/core/{target-occupancy.js → workspace/target-occupancy.js} +0 -0
@@ -1,143 +0,0 @@
1
- const commands = [
2
- "guide",
3
- "advanced",
4
- "setup",
5
- "upgrade",
6
- "init",
7
- "lock",
8
- "export",
9
- "import",
10
- "audit",
11
- "create",
12
- "pack",
13
- "publish",
14
- "search",
15
- "add",
16
- "unadd",
17
- "list",
18
- "scan",
19
- "reconcile",
20
- "status",
21
- "versions",
22
- "skill-audit",
23
- "doctor",
24
- "health",
25
- "compare",
26
- "optimize",
27
- "activate",
28
- "enable",
29
- "disable",
30
- "adopt",
31
- "library",
32
- "update",
33
- "rollback",
34
- "discover",
35
- "candidate",
36
- "review-queue",
37
- "review",
38
- "alerts",
39
- "alert-ignore",
40
- "alert-pin",
41
- "alert-unpin",
42
- "alert-pins",
43
- "mcp",
44
- "mcp-recipe",
45
- "mcp-config",
46
- "models",
47
- "credentials",
48
- "schedule",
49
- "unschedule",
50
- "autopilot",
51
- "tool",
52
- "report",
53
- "share",
54
- "card",
55
- "compare-loadouts",
56
- "badge",
57
- "inspect",
58
- "evaluate",
59
- "watch",
60
- "sandbox-run",
61
- "codex-mcp-config",
62
- "plan",
63
- "install",
64
- "convert",
65
- "canary",
66
- "capabilities",
67
- "catalog",
68
- "profiles",
69
- "recommend",
70
- "improve",
71
- "improve-feedback",
72
- "sync",
73
- "outcome",
74
- "outcomes",
75
- "remove",
76
- "uninstall",
77
- "serve",
78
- "completion",
79
- ];
80
- const modelCommands = ["status", "set", "verify"];
81
- const credentialCommands = ["status", "set", "check", "delete"];
82
- const candidateCommands = ["list", "inspect", "propose"];
83
- export function renderShellCompletion(shell) {
84
- const words = commands.join(" ");
85
- switch (shell) {
86
- case "bash":
87
- return `# Loadout command completion
88
- _loadout() {
89
- local current="\${COMP_WORDS[COMP_CWORD]}"
90
- local commands="${words}"
91
- if [[ COMP_CWORD -eq 1 ]]; then
92
- COMPREPLY=( $(compgen -W "$commands" -- "$current") )
93
- elif [[ COMP_CWORD -eq 2 && "\${COMP_WORDS[1]}" == "models" ]]; then
94
- COMPREPLY=( $(compgen -W "${modelCommands.join(" ")}" -- "$current") )
95
- elif [[ COMP_CWORD -eq 2 && "\${COMP_WORDS[1]}" == "credentials" ]]; then
96
- COMPREPLY=( $(compgen -W "${credentialCommands.join(" ")}" -- "$current") )
97
- elif [[ COMP_CWORD -eq 2 && "\${COMP_WORDS[1]}" == "candidate" ]]; then
98
- COMPREPLY=( $(compgen -W "${candidateCommands.join(" ")}" -- "$current") )
99
- fi
100
- }
101
- complete -F _loadout loadout
102
- `;
103
- case "zsh":
104
- return `#compdef loadout
105
- typeset -a commands model_commands credential_commands candidate_commands
106
- commands=(${commands.map((command) => `'${command}'`).join(" ")})
107
- model_commands=(${modelCommands.map((command) => `'${command}'`).join(" ")})
108
- credential_commands=(${credentialCommands.map((command) => `'${command}'`).join(" ")})
109
- candidate_commands=(${candidateCommands.map((command) => `'${command}'`).join(" ")})
110
- if (( CURRENT == 2 )); then
111
- _describe 'command' commands
112
- elif (( CURRENT == 3 )) && [[ $words[2] == models ]]; then
113
- _describe 'models command' model_commands
114
- elif (( CURRENT == 3 )) && [[ $words[2] == credentials ]]; then
115
- _describe 'credentials command' credential_commands
116
- elif (( CURRENT == 3 )) && [[ $words[2] == candidate ]]; then
117
- _describe 'candidate command' candidate_commands
118
- fi
119
- `;
120
- case "fish":
121
- return [
122
- ...commands.map((command) => `complete -c loadout -f -n '__fish_use_subcommand' -a ${command}`),
123
- ...modelCommands.map((command) => `complete -c loadout -f -n '__fish_seen_subcommand_from models' -a ${command}`),
124
- ...credentialCommands.map((command) => `complete -c loadout -f -n '__fish_seen_subcommand_from credentials' -a ${command}`),
125
- ...candidateCommands.map((command) => `complete -c loadout -f -n '__fish_seen_subcommand_from candidate' -a ${command}`),
126
- ]
127
- .join("\n")
128
- .concat("\n");
129
- case "powershell":
130
- return `Register-ArgumentCompleter -Native -CommandName loadout -ScriptBlock {
131
- param($wordToComplete, $commandAst, $cursorPosition)
132
- $elements = @($commandAst.CommandElements | ForEach-Object { $_.Extent.Text })
133
- $candidates = if ($elements.Count -ge 2 -and $elements[1] -eq 'models') { @(${modelCommands.map((command) => `'${command}'`).join(", ")}) } elseif ($elements.Count -ge 2 -and $elements[1] -eq 'credentials') { @(${credentialCommands.map((command) => `'${command}'`).join(", ")}) } elseif ($elements.Count -ge 2 -and $elements[1] -eq 'candidate') { @(${candidateCommands.map((command) => `'${command}'`).join(", ")}) } else { @(${commands.map((command) => `'${command}'`).join(", ")}) }
134
- $candidates | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) }
135
- }
136
- `;
137
- }
138
- }
139
- export function parseCompletionShell(value) {
140
- if (["bash", "zsh", "fish", "powershell"].includes(value))
141
- return value;
142
- throw new Error("Supported shells: bash, zsh, fish, powershell");
143
- }
@@ -1,161 +0,0 @@
1
- import { readFile, writeFile, mkdir } from "node:fs/promises";
2
- import { join } from "node:path";
3
- import { randomUUID } from "node:crypto";
4
- import { writeFileAtomically } from "./atomic-file.js";
5
- const HANDOFF_DIR = ".handoff";
6
- const MESSAGES_FILE = "messages.jsonl";
7
- const PROTOCOL_FILE = "PROTOCOL.md";
8
- function handoffDir(projectRoot) {
9
- return join(projectRoot, HANDOFF_DIR);
10
- }
11
- function messagesPath(projectRoot) {
12
- return join(handoffDir(projectRoot), MESSAGES_FILE);
13
- }
14
- export async function isHandoffInitialized(projectRoot) {
15
- try {
16
- await readFile(join(handoffDir(projectRoot), PROTOCOL_FILE), "utf8");
17
- return true;
18
- }
19
- catch {
20
- return false;
21
- }
22
- }
23
- export async function initHandoff(projectRoot) {
24
- const dir = handoffDir(projectRoot);
25
- await mkdir(dir, { recursive: true });
26
- const protocol = [
27
- "# Handoff Protocol",
28
- "",
29
- "This directory enables asynchronous task handoff between AI coding agents.",
30
- "Generated by `loadout handoff init`. Compatible with the JSONL handoff convention.",
31
- "",
32
- "## Message types",
33
- "",
34
- "- **task**: assign work to another agent",
35
- "- **handoff**: transfer in-progress work with context",
36
- "- **question**: ask another agent for input",
37
- "- **done**: signal completion",
38
- "- **status**: progress update",
39
- "- **error**: report a failure",
40
- "- **cancel**: withdraw a task",
41
- "",
42
- "## Files",
43
- "",
44
- "- `messages.jsonl` — append-only message log (one JSON object per line)",
45
- "- `PROTOCOL.md` — this file",
46
- "",
47
- "## Usage",
48
- "",
49
- "```",
50
- "loadout handoff send codex 'write unit tests for auth module'",
51
- "loadout handoff send claude-code 'review the API changes' --context 'see PR #42'",
52
- "loadout handoff status",
53
- "loadout handoff done <message-id>",
54
- "```",
55
- "",
56
- "Agents read this directory on wake. Loadout manages the message log;",
57
- "each agent's own CLAUDE.md / AGENTS.md can reference .handoff/ for pickup.",
58
- "",
59
- ].join("\n");
60
- await writeFileAtomically(join(dir, PROTOCOL_FILE), protocol);
61
- // Create empty messages file if it doesn't exist
62
- try {
63
- await readFile(messagesPath(projectRoot));
64
- }
65
- catch {
66
- await writeFile(messagesPath(projectRoot), "", "utf8");
67
- }
68
- return dir;
69
- }
70
- export async function sendHandoff(projectRoot, to, description, options = {}) {
71
- if (!(await isHandoffInitialized(projectRoot))) {
72
- throw new Error("Handoff not initialized. Run `loadout handoff init` first.");
73
- }
74
- const message = {
75
- id: randomUUID().slice(0, 8),
76
- type: options.type ?? "task",
77
- from: options.from ?? "user",
78
- to,
79
- description,
80
- ...(options.context ? { context: options.context } : {}),
81
- timestamp: new Date().toISOString(),
82
- };
83
- const path = messagesPath(projectRoot);
84
- const line = JSON.stringify(message) + "\n";
85
- await writeFile(path, line, { flag: "a" });
86
- return message;
87
- }
88
- export async function markDone(projectRoot, messageId) {
89
- const messages = await readMessages(projectRoot);
90
- const original = messages.find((m) => m.id === messageId);
91
- if (!original)
92
- throw new Error(`Message '${messageId}' not found`);
93
- if (original.type === "done")
94
- throw new Error(`Message '${messageId}' is already done`);
95
- return sendHandoff(projectRoot, original.from, `Completed: ${original.description}`, {
96
- from: original.to,
97
- type: "done",
98
- context: `Resolves ${messageId}`,
99
- });
100
- }
101
- export async function readMessages(projectRoot) {
102
- if (!(await isHandoffInitialized(projectRoot)))
103
- return [];
104
- try {
105
- const content = await readFile(messagesPath(projectRoot), "utf8");
106
- return content
107
- .split("\n")
108
- .filter(Boolean)
109
- .map((line) => JSON.parse(line));
110
- }
111
- catch {
112
- return [];
113
- }
114
- }
115
- export async function getHandoffState(projectRoot) {
116
- const initialized = await isHandoffInitialized(projectRoot);
117
- const messages = initialized ? await readMessages(projectRoot) : [];
118
- const doneIds = new Set(messages
119
- .filter((m) => m.type === "done")
120
- .flatMap((m) => {
121
- const match = m.context?.match(/Resolves (\w+)/);
122
- return match ? [match[1]] : [];
123
- }));
124
- const pending = messages.filter((m) => m.type === "task" && !doneIds.has(m.id));
125
- const done = messages.filter((m) => m.type === "task" && doneIds.has(m.id));
126
- return {
127
- initialized,
128
- directory: handoffDir(projectRoot),
129
- messages,
130
- pending,
131
- done,
132
- };
133
- }
134
- export function formatHandoffStatus(state) {
135
- if (!state.initialized)
136
- return "Handoff not initialized. Run `loadout handoff init`.";
137
- if (state.messages.length === 0)
138
- return "No handoff messages yet. Send one with `loadout handoff send <agent> <task>`.";
139
- const lines = [];
140
- if (state.pending.length) {
141
- lines.push(`Pending (${state.pending.length}):`);
142
- for (const m of state.pending) {
143
- lines.push(` ${m.id} ${m.from} → ${m.to} ${m.description}`);
144
- }
145
- }
146
- if (state.done.length) {
147
- if (lines.length)
148
- lines.push("");
149
- lines.push(`Done (${state.done.length}):`);
150
- for (const m of state.done) {
151
- lines.push(` ${m.id} ${m.from} → ${m.to} ${m.description}`);
152
- }
153
- }
154
- const other = state.messages.filter((m) => m.type !== "task" && m.type !== "done");
155
- if (other.length) {
156
- if (lines.length)
157
- lines.push("");
158
- lines.push(`Other messages: ${other.length}`);
159
- }
160
- return lines.join("\n");
161
- }
@@ -1,53 +0,0 @@
1
- # Reviewed library and active-set contract
2
-
3
- Loadout separates four facts that package managers often collapse into one word:
4
-
5
- - **cache**: `missing` or `downloaded` says whether Loadout has a private byte-for-byte
6
- library copy;
7
- - **review**: `unreviewed`, `reviewed`, or `quarantined` records evidence policy and
8
- never follows popularity alone;
9
- - **installation**: `installed` or `removed` records whether Loadout still manages the
10
- package; and
11
- - **activation**: `active` or `disabled` is per skill unit and per agent, because one
12
- skill from a collection can be visible to Claude Code while another stays disabled
13
- for Codex.
14
-
15
- Maximum Library starts reviewed skill units as `downloaded + reviewed + installed +
16
- disabled`. It can therefore hold hundreds of candidates without exposing hundreds of
17
- instructions to an agent. Power is an intentionally broader active profile; Stable is
18
- the smallest active foundation.
19
-
20
- An initial install is active and may have `cache:missing`. On the first disable,
21
- Loadout verifies that every managed file is unchanged and that no untracked file would
22
- be removed, copies the complete skill directories into its private library, verifies
23
- their hashes, and only then removes the agent-visible copies. This is the explicit
24
- migration boundary for older installations.
25
-
26
- `enable` verifies the private library hashes and refuses to overwrite any occupied
27
- agent target. It restores the exact cached bytes but keeps the library copy. Both
28
- commands are dry-run by default, can change several packages and agents under one
29
- snapshot, write a durable transaction journal before mutation, and can be reversed by
30
- `loadout rollback --snapshot <id>`.
31
-
32
- Only Loadout-managed skill directories participate. Existing unmanaged content is
33
- never silently adopted, moved, or deleted. MCP entries and other executable/configured
34
- components are deliberately outside active-set toggling; they retain their existing
35
- explicit configuration and removal workflows.
36
-
37
- A disabled package must be enabled before its tracked source can be updated. This
38
- prevents the update workflow from silently recreating agent-visible files and makes the
39
- activation transition explicit.
40
-
41
- ## Commands
42
-
43
- ```bash
44
- loadout library
45
- loadout disable <package-or-package/skill> [more-selectors] [--agents codex,claude-code]
46
- loadout disable <package-or-package/skill> --yes
47
- loadout enable <package-or-package/skill> --yes
48
- loadout activate --project . --limit 30
49
- loadout optimize --project .
50
- loadout rollback --snapshot <id>
51
- ```
52
-
53
- Machine-readable planning and results are available with `--json`.
@@ -1,22 +0,0 @@
1
- # Compatibility policy
2
-
3
- Loadout uses the same adapter matrix in inspection and installation. Each
4
- agent/component cell is one of:
5
-
6
- - **native** — Loadout writes the documented component format to the
7
- agent-owned location.
8
- - **adapted** — Loadout has a reviewed, tested mapping to an agent-specific
9
- layout or explicit config writer. The plan warns about the adaptation.
10
- - **unsupported** — Loadout does not infer a location, convert the component,
11
- or write anything.
12
-
13
- All supported platforms (Windows, macOS, and Linux) use this policy. WSL is
14
- Linux-side only: Loadout manages the POSIX home directory and never silently
15
- rewrites a Windows profile. Agent adapters are deliberately conservative:
16
- skills are native wherever a documented skill directory exists; commands,
17
- rules, and agents are native only where the adapter supplies a concrete
18
- directory; MCP is config-scoped and adapted only through its explicit JSON or
19
- Codex TOML planner; and plugin manifests are inspected/normalized but their
20
- runtime hooks are never converted or executed.
21
-
22
- Use `loadout capabilities --inspect` to view the matrix and local inventory.
@@ -1,27 +0,0 @@
1
- # Conversion loss reports and installer sandbox boundary
2
-
3
- ## Cross-agent conversion
4
-
5
- The only safe initial conversion target is a static instruction file. A source skill
6
- can be copied to an agent's documented native skill directory when that adapter marks
7
- skills `native`. For a target that supports only commands, Loadout may create one
8
- explicit command wrapper pointing at the same static instructions.
9
-
10
- Every conversion emits a loss report containing source component, target component,
11
- preserved fields, dropped fields, and the reason. Hooks, subagents, lifecycle scripts,
12
- dynamic variables, permissions, and MCP servers are never silently converted. A loss
13
- report with dropped executable behavior requires user approval and defaults to no
14
- write.
15
-
16
- ## Third-party installer threat model
17
-
18
- An installer can read secrets, write outside its target, alter shell startup files,
19
- open network connections, launch processes, or exploit the host. Therefore source
20
- repository scripts are never run on the host. Static package parsing is the normal
21
- path.
22
-
23
- If a future disposable sandbox runner is enabled, it must use a fresh filesystem,
24
- read-only source mount, no host home mount, no inherited environment variables, no
25
- Docker socket, restricted network disabled by default, bounded CPU/memory/time, and
26
- an exported file manifest. Its output is an untrusted proposal that still goes through
27
- the normal plan/safety/approval path. Failure or timeout discards the sandbox.