# Project export: Loadout

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: OpenAI Build Week
- Tagline: One install. Every AI coding agent, supercharged. Loadout finds, installs, updates, and safely rolls back the best skills, MCP servers, and tools from across GitHub.
- Devpost: https://devpost.com/software/skill-router
- GitHub: https://github.com/VirajMishra1/loadout
- Demo: https://www.npmjs.com/package/loadout-ai
- Video: https://www.youtube.com/embed/opNqJKX7xMw?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 4 GitHub contributor(s) — VirajMishra1 (141 commits), Nitish Reddy M (12 commits), Amartya Sai Andra (6 commits), github-actions[bot] (1 commits)

## Devpost submission (written by the team)

### Inspiration

Loadout started with a problem I kept running into myself: improving an AI coding agent still means hunting through GitHub, Reddit, X, and old bookmarks. A useful skill appears in one repository, an MCP server lives somewhere else, and a better tool launches the following week. New users do not know what is worth installing, while experienced users eventually lose track of where everything came from. Our first instinct was simple: find every popular repository and install all of it. We quickly learned why that would not work. GitHub stars are a useful discovery signal, but they do not prove that something is safe, maintained, compatible, or useful for the project in front of you. Loading thousands of skills also makes an agent harder to use, not better. That changed the idea. Instead of building a giant download script, we built a package manager for the extensions around AI coding agents.

### What it does

Loadout is a local, open-source CLI that discovers, installs, updates, recommends, and safely removes skills, MCP servers, and runtime tools across Codex, Claude Code, Cursor, and other coding agents. It offers four ways to build your setup: Stable installs a focused 30-skill daily setup from four pinned public sources. Power prepares a broader cross-project toolkit. Maximum downloads thousands of screened skill copies into a disabled local library, then activates a smaller set that matches the current project. Custom lets users install one exact package without replacing everything else. Loadout can scan skills that are already installed, detect collisions, recommend tools based on a repository, check managed sources for updates, and watch newly popular GitHub projects through a discovery queue. Every change is previewed before it is applied. Loadout protects existing files, records what it manages, and creates a rollback snapshot before changing an agent's setup. MCP servers and executable tools remain separate, explicit choices because they can require credentials or start external processes. The normal skill workflow does not require an OpenAI or Anthropic API key.

### How we built it

Loadout is a TypeScript and Node.js CLI built with Commander, Zod, and Vitest. Its catalog currently credits 53 pinned public repositories across 39 categories. A separate discovery snapshot observes 240 repositories, including 216 candidates that have not been promoted into the catalog. Discovery and installation are deliberately separate: a repository becoming popular is a reason to inspect it, not permission to install it automatically. The installation engine uses agent adapters, managed manifests, filesystem checks, and snapshot-backed transactions. Its adapter matrix covers 12 coding agents, while Stable, Power, Maximum, and project optimization all use the same underlying safety and rollback pipeline. We built Loadout during OpenAI Build Week as a three-person team working closely with Codex and GPT-5.6. We used Codex for product planning, repository research, architecture, implementation, debugging, code review, testing, and release preparation. GPT-5.6 was especially valuable when a change affected several connected systems, such as catalogs, agent directories, update behavior, and rollback history. The humans still made the product decisions, reviewed risky operations, tested releases on real machines, and decided what Loadout should trust. Challenges we faced The hardest part was not downloading files. It was making those downloads understandable and reversible. Different agents store skills and MCP configuration in different places. Users may already have files occupying those locations. Some repositories contain hundreds of valid components alongside a few suspicious or malformed ones. Updates can change code that was previously inspected, and large repositories can make a straightforward update check painfully slow. Real terminal testing exposed problems our initial plans missed: Graphify appeared inside Claude Code but was missing from Codex inventory because the installer and scanner recognized different Codex paths. Large update checks timed out because they fetched entire repositories even when nothing had changed. Existing unmanaged skills could collide with Stable installations. Removing adopted or externally modified files required stronger ownership and drift checks. ChatGPT and Claude subscriptions were easy to confuse with separately billed API access. Thousands of Maximum-library skills had to remain available without flooding every agent's active context. We fixed these problems by repeatedly running the real commands on Codex and Claude Code profiles, pasting the exact output into Codex, tracing the responsible code, and turning every reproducible failure into a regression test.

### What we learned

The biggest lesson was that more extensions do not automatically create a better agent. The useful product is a broad library paired with a small, relevant active set. We also learned that discovery, trust, and installation are three different decisions. Stars can help find a project. Static inspection can identify risks. Neither one proves that a tool is universally useful. Finally, safety is not just a security feature. Previewing changes, explaining credentials, protecting user edits, and making rollback obvious are all part of making a developer tool pleasant to use. What we are proud of Loadout is now published on npm as a real CLI rather than a hackathon-only interface. The current release includes: 53 credited and technically inspected catalog repositories A discovery snapshot observing 240 repositories Stable, Power, Maximum, and Custom workflows Project-aware recommendations and activation Skill reconciliation and update checks Explicit MCP and Graphify installation paths Support infrastructure for 12 coding agents Snapshot-backed rollback and complete uninstall 625 automated tests, packaged CLI journeys, and a 1,000-skill performance gate Most importantly, we used Loadout on our own Codex and Claude Code profiles and safely rolled the changes back.

### What's next

Next, we want to add repeatable package benchmarks, signed catalog releases, community loadouts, more credential-aware MCP recipes, and stronger ranking based on real user outcomes. The long-term goal is simple: when a better AI coding extension appears tomorrow, developers should not have to discover it by accident or rebuild their setup by hand.

## README (from the GitHub repository)

<h1 align="center">Loadout</h1>

<p align="center"><strong>Manage skills for 12 coding agents. Hand off and coordinate work between Claude Code and Codex.</strong></p>

<p align="center">
  <img src="./docs/assets/loadout-unified-workflow-v2.webp" alt="Loadout discovers, curates, and activates skills, tools, and MCP servers for coding agents, then helps Claude Code and Codex handoff and coordinate work through durable tasks, bundled context, ownership, contracts, and decisions." width="960">
</p>

<p align="center">
  <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>
  <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>
  <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>
  <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>
  <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>
  <a href="./LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="MIT License"></a>
</p>

<p align="center">
  <a href="#try-it-in-30-seconds">Quick start</a> ·
  <a href="#use-claude-code-and-codex-together">Two agents</a> ·
  <a href="#try-these-prompts">Agent skills</a> ·
  <a href="#safety-and-trust">Safety</a> ·
  <a href="#command-reference">Commands</a>
</p>

## Try it in 30 seconds

You need Node.js 20 or newer and Git.

```bash
npm install --global loadout-ai
loadout setup --mode stable --details
```

The second command detects your coding agents and previews the 30-skill Stable
loadout. It does not change agent files. Review the plan, then apply it:

```bash
loadout setup --mode stable --yes --approve-risk
loadout status
```

Loadout saves a rollback snapshot before applying changes. Run
`loadout rollback` to restore the previous managed state.

`--approve-risk` acknowledges the instruction-like files reported by the current
Stable preview. Use it only after reading those findings; it does not replace the
preview or the pinned-source checks.

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.

## What Loadout does

| Capability     | What you get                                                          |
| -------------- | --------------------------------------------------------------------- |
| **Discover**   | Find skills, tools, and MCP servers worth reviewing                   |
| **Curate**     | Inspect, screen, and pin sources before trusting them                 |
| **Activate**   | Install a focused set for this repository across your agents          |
| **Handoff**    | Pass durable tasks with bundled context between Claude Code and Codex |
| **Coordinate** | Share file ownership, contracts, decisions, and acknowledgements      |

The package manager works across supported agents. Handoff and coordination are
currently designed for Claude Code and Codex working in the same repository.

## Use Claude Code and Codex together

### Handoff: pass a task that survives sessions

```bash
loadout handoff codex "write unit tests for auth" --bundle src/auth.ts src/types.ts --verify "tests pass" --verify-command npm --verify-args '["test"]'
```

Codex sees the task when it checks its inbox, works from the attached bounded
context, and marks it done. Claude Code can then read the result. Handoffs live
in an append-only project log, so restarting either agent does not erase them.
Bundles contain secret-redacted text and are capped at 50 KiB total; still
review them before committing and never attach credential files.

### Coordinate: work at the same time without stepping on files

```bash
loadout coord start --agents claude-code,codex       # preview ownership
loadout coord start --agents claude-code,codex --yes # apply ownership
loadout coord snapshot codex                         # inspect shared state
loadout coord discuss start "REST or GraphQL?" --agents claude-code,codex --rounds 2 --max-turns 5
```

Coordination is structured shared project state, not shared memory or a merged
context window. Events reach an agent at safe turn boundaries or when it checks
its snapshot; Loadout does not interrupt a turn in progress.

### Let Claude and Codex debate one decision

You prompt once and Loadout calls both providers in bounded turns—propose,
critique, synthesize—then records the decision. Neither agent can inject into
the other's in-progress turn; events arrive at safe turn boundaries. Each
round consumes paid provider turns from your configured Claude and Codex quota.
The bounded design discussion reports its turn budget before it starts.

See the [live coordination guide](./docs/LIVE_COLLABORATION.md) for ownership,
contracts, acknowledgements, discussions, the local dashboard, and limitations.

## Try these prompts

Install Loadout's two first-party skills once so your agent knows the workflow:

```bash
loadout skills install loadout-handoff --yes
loadout skills install loadout-curator --yes
```

Then ask naturally:

> _"Hand the test writing to Codex."_
>
> _"What did Codex leave for me?"_
>
> _"Which skills should be active for this repo?"_

The curator helps choose a focused active set; the handoff skill manages inboxes
and coordination without making you relay every command.

## Install and choose your agent

For a reproducible install, pin the current release:

```bash
npm install --global loadout-ai@0.9.4
loadout setup --mode stable --details
loadout setup --mode stable --yes --approve-risk
loadout status
```

Stable is the recommended starting point: 30 selected skill directories from
four pinned public sources. Loadout auto-detects supported agents; use
`--agents` when you want to narrow the destination.

If anything fails, follow the [user test guide](./docs/USER_TEST_GUIDE.md).
For profiles, per-agent paths, MCP configuration, and advanced commands, use the
[full reference](./docs/REFERENCE.md).

## Safety and trust

**Choose -> Inspect -> Preview -> Apply -> Undo**

- Preview is the default for setup, updates, and removal.
- Every managed apply creates a rollback snapshot first.
- Catalog sources are pinned and technically inspected, not declared safe or useful by fiat.
- Static inspection reports scripts, hooks, binaries, domains, credential references, and unsupported components; it is not a security audit.
- Project recommendations read bounded local metadata. The documented local flow does not upload project source.
- MCP servers and executable tools stay behind separate preview, permission, and setup steps.
- Shared manifests store environment-variable or OS-keychain references, not secret values.

<!-- loadout:current-limits:start -->

- All catalog records have identified SPDX licenses. See the [recorded license decisions](./docs/UPSTREAM_LICENSE_DECISIONS.md) for the source-by-source record.

<!-- loadout:current-limits:end -->

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.

## Demo

<p align="center">
  <a href="https://www.youtube.com/watch?v=5NS5jcSlxm8">
    <img src="https://img.youtube.com/vi/5NS5jcSlxm8/maxresdefault.jpg" alt="Watch the 72-second Loadout demo" width="880">
  </a>
</p>

**[Watch the 72-second Loadout demo on YouTube](https://www.youtube.com/watch?v=5NS5jcSlxm8).**

## Why Loadout

Loadout started with a frustrating question: **why does improving an AI coding agent
still mean opening twe

[README truncated for size]

## Detected evidence (automated analysis)

Indexed codebase: 270 recognized source files, 2427 KB.
- JavaScript (language) — detected in the code
- TypeScript (language) — detected in the code
- Node.js (technology) — claimed on Devpost, not found in the code
- OpenAI (technology) — claimed on Devpost, not found in the code
- AI coding agent: Claude Code — evidence: config files committed to the repository

## Codebase structure (from repository index)

### Files (120 of 300)

```
.editorconfig
.gitattributes
.github/workflows/ci.yml
.github/workflows/daily-discovery.yml
.github/workflows/release.yml
.gitignore
.prettierignore
catalog/discovered.json
catalog/packages.json
CHANGELOG.md
docs/ACTIVE_SET_POLICY.md
docs/ACTIVE_SET.md
docs/CANDIDATE_INTELLIGENCE.md
docs/CATALOG_POLICY.md
docs/CATALOG.md
docs/COMMUNITY_DISCOVERY.md
docs/COMPATIBILITY_POLICY.md
docs/CONVERSION_AND_SANDBOX.md
docs/CREDENTIAL_AND_UPDATE_POLICY.md
docs/DEMO_SCRIPT.md
docs/DISCOVERED.md
docs/EVALUATION_PROTOCOL_V1.md
docs/EVALUATION_PROTOCOL.md
docs/evidence/live-checks-2026-07-19.json
docs/evidence/live-checks.schema.json
docs/evidence/readme-claims.json
docs/FEATURE_TEST_MATRIX.md
docs/GITHUB_AUTHORIZATION.md
docs/HEAD_TO_HEAD_EVALUATION.md
docs/PROVENANCE_AND_COMPARISON.md
docs/PROVIDER_CONFIGURATION.md
docs/README_RESEARCH.md
docs/RELEASE_REVIEW.md
docs/REPOSITORY_STABILIZATION.md
docs/SAFE_UPDATE_DEMO.md
docs/SCHEMA_DECISIONS.md
docs/SUBMISSION_COPY.md
docs/superpowers/plans/2026-07-19-relatable-readme-hero.md
docs/superpowers/plans/2026-07-20-loadout-readme-explainer.md
docs/superpowers/plans/2026-07-20-project-activation-safety.md
docs/superpowers/specs/2026-07-19-relatable-readme-hero-design.md
docs/superpowers/specs/2026-07-20-loadout-readme-explainer-design.md
docs/superpowers/specs/2026-07-20-project-activation-safety-design.md
docs/TEAM_POLICY.md
docs/TESTING.md
docs/UPSTREAM_LICENSE_DECISIONS.md
docs/USER_TEST_GUIDE.md
eslint.config.js
LICENSE
MASTER_PLAN.md
package.json
README.md
scripts/build-intelligence-feed.ts
scripts/check-catalog-attribution.mjs
scripts/check-discovery-artifacts.mjs
scripts/check-live-evidence.d.mts
scripts/check-live-evidence.mjs
scripts/check-readme-claims.d.mts
scripts/check-readme-claims.mjs
scripts/check-release-claims.ts
scripts/clean-dist.mjs
scripts/cli-product-flow.mjs
scripts/daily-discovery.d.mts
scripts/daily-discovery.mjs
scripts/package-smoke.mjs
scripts/readme-product-flow.mjs
scripts/scan-benchmark.mjs
scripts/update-readme-facts.d.mts
scripts/update-readme-facts.mjs
SECURITY.md
src/cli.ts
src/core/access.ts
src/core/active-limit.ts
src/core/active-policy.ts
src/core/active-set.ts
src/core/adapters.ts
src/core/adopt.ts
src/core/agent-health-score.ts
src/core/agent-inspection.ts
src/core/agent-versions.ts
src/core/api.ts
src/core/atomic-file.ts
src/core/audit.ts
src/core/benchmark-campaign.ts
src/core/benchmark-evidence.ts
src/core/benchmark-fixtures.ts
src/core/benchmark-runner.ts
src/core/benchmark-trust.ts
src/core/canary.ts
src/core/candidate-intelligence.ts
src/core/catalog-coverage.ts
src/core/catalog-install.ts
src/core/catalog-release.ts
src/core/catalog.ts
src/core/cli-guide.ts
src/core/codex-mcp.ts
src/core/community.ts
src/core/compatibility-intelligence.ts
src/core/completion.ts
src/core/components.ts
src/core/conformance.ts
src/core/conversion.ts
src/core/credentials.ts
src/core/diff.ts
src/core/discovery-connector.ts
src/core/doctor.ts
src/core/ecosystem-import.ts
src/core/evaluate.ts
src/core/file-lock.ts
src/core/freshness-alerts.ts
src/core/github-discovery.ts
src/core/github.ts
src/core/head-to-head.ts
src/core/health-score-evidence.ts
src/core/health.ts
src/core/improve.ts
src/core/install.ts
src/core/intelligence-feed-build.ts
src/core/intelligence-feed.ts
src/core/loadout-badge.ts
[180 more files omitted for size]
```

### Dependencies

- package.json: @eslint/js@^9.39.5, @types/node@^22.10.0, commander@^12.1.0, eslint@^9.39.5, eslint-config-prettier@^10.1.8, prettier@^3.9.5, tsx@^4.19.2, typescript@^5.7.2, typescript-eslint@^8.64.0, vitest@^4.1.10, zod@^4.4.3

### Recent commits (newest first)

- chore(discovery): refresh daily repository evidence
- chore(discovery): refresh daily repository evidence
- chore(discovery): refresh daily repository evidence
- chore(discovery): refresh daily repository evidence
- chore(discovery): refresh daily repository evidence
- chore(discovery): refresh daily repository evidence
- chore(discovery): refresh daily repository evidence
- chore(discovery): refresh daily repository evidence
- chore(discovery): refresh daily repository evidence
- chore(discovery): refresh daily repository evidence
- chore(discovery): refresh daily repository evidence
- chore(discovery): refresh daily repository evidence
- chore(discovery): refresh daily repository evidence
- chore(discovery): refresh daily repository evidence
- chore(discovery): refresh daily repository evidence
- chore(discovery): refresh daily repository evidence
- chore(discovery): refresh daily repository evidence
- chore(discovery): refresh daily repository evidence
- chore(discovery): refresh daily repository evidence
- chore(discovery): refresh daily repository evidence

## Key source files (fetched from GitHub, selected and truncated for size)

### SECURITY.md

```markdown
# Loadout threat model

Loadout handles third-party repositories and agent configuration, so its safety boundary is deliberately conservative.

## Protected actions

- Repository discovery uses a shallow Git fetch and reads files; it does not run package managers, lifecycle hooks, binaries, or scripts.
- Updates are compared by commit and file hash before mutation.
- New or changed scripts, hooks, binaries, embedded secret-like material, and suspicious instruction patterns are blocking findings.
- Network domains and environment-variable names are reported without exposing values. They require review when a policy or caller treats them as sensitive.
- Blocked updates can be quarantined as metadata under `$LOADOUT_HOME/quarantine`. Quarantine never installs or executes the fetched repository.
- Approved changes still run through a transactional snapshot and rollback path; approval is a human acknowledgement, not a claim that the package is safe.

## Explicit non-guarantees

Static inspection cannot prove that a package is benign. It may miss obfuscated behavior, interpreter-specific behavior, malicious content hidden in generated files, or risks introduced by an agent consuming a text instruction. Stars, repository age, and “official” labels are discovery signals, not security proofs.

Loadout does not currently sandbox arbitrary executables or automatically execute third-party installers. Users should review diffs, licenses, requested permissions, and provenance before approving a change.

```

### CHANGELOG.md

```markdown
# Changelog

## Unreleased

## 0.5.9 - 2026-07-21

### Fixed

- Preserve active Stable skills when preparing Maximum Library by reserving their
  managed targets before ordinary overlap deferral, while retaining fail-closed
  commit, quarantine, and missing-source validation.
- Run the canonical `npm run verify` release gate on ordinary pushes and pull
  requests so CI cannot silently omit evidence, README-flow, or package checks.

### Changed

- Use one shared 30-skill recommended active-set limit in planning, inventory,
  upgrade guidance, CLI defaults, and public workflow documentation.
- Clearly archive superseded dashboard-era release notes and keep the public launch
  checklist aligned with completed demo work and the current CLI-only product.

## 0.5.8 - 2026-07-21

### Fixed

- Make `install --mode custom` genuinely additive: it now keeps existing managed
  skills active and does not replace the saved profile.

## 0.5.7 - 2026-07-21

### Changed

- Explain that `setup --mode custom` reconciles the complete selected profile, while
  `install --mode custom --package <id>` adds a package without retiring the current
  managed profile.
- Show package-by-package progress during complete uninstall and stop calling an
  approved `uninstall --yes` operation a dry run.

### Fixed

- Preserve pre-existing skill trees that users explicitly adopted into Loadout when
  removing one package or completely uninstalling Loadout. Removal now forgets
  ownership and leaves adopted bytes in place, including legacy `adopted-*` records.

## 0.5.6 - 2026-07-21

### Changed

- Resolve each repository's default-branch commit with a lightweight Git metadata
  request before downloading files, deduplicate shared sources, and reuse exact
  cached changed revisions for safety review.
- Give changed repositories a bounded 120-second review window while keeping remote
  commit checks at 30 seconds, so large reviewed sources do not produce permanent
  false connectivity warnings under four-way concurrency.

### Fixed

- Complete update checks for large sources such as Scientific Agent Skills and
  Awesome Copilot without weakening static diff analysis, activating disabled skills,
  or treating a timed-out clone as a GitHub outage.

## 0.5.5 - 2026-07-21

### Changed

- Summarize update checks as active, disabled-library, current, and unavailable
  records; hide repetitive current-package lines by default while retaining complete
  JSON output and focused per-package review.
- Keep disabled Maximum-library copies pinned and explicitly state that newer
  upstream commits neither change nor reactivate agent-visible skills.
- Treat catalog sources represented by adopted units as present in saved-profile
  evaluation, and describe fully quarantined or unavailable profile sources without
  calling them missing upgrades.

### Fixed

- Deduplicate per-agent disabled update state and fetch a shared repository only once
  when several adopted skill units track the same upstream s
[truncated — 11396 more characters]
```

### package.json

```
{
  "name": "loadout-ai",
  "version": "0.5.9",
  "private": false,
  "license": "MIT",
  "description": "Universal upgrade manager for AI coding agents",
  "type": "module",
  "bin": {
    "loadout": "dist/src/cli.js"
  },
  "files": [
    "dist/src",
    "catalog",
    "docs",
    "README.md",
    "CHANGELOG.md",
    "MASTER_PLAN.md",
    "SECURITY.md",
    "LICENSE"
  ],
  "repository": {
    "type": "git",
    "url": "git+https://github.com/VirajMishra1/loadout.git"
  },
  "homepage": "https://github.com/VirajMishra1/loadout#readme",
  "bugs": {
    "url": "https://github.com/VirajMishra1/loadout/issues"
  },
  "publishConfig": {
    "access": "public"
  },
  "keywords": [
    "ai-agents",
    "codex",
    "claude-code",
    "mcp",
    "skills"
  ],
  "engines": {
    "node": ">=20"
  },
  "scripts": {
    "clean": "node scripts/clean-dist.mjs",
    "prebuild": "npm run clean",
    "build": "tsc -p tsconfig.json",
    "prepack": "npm run build",
    "dev": "tsx src/cli.ts",
    "format": "prettier --write .",
    "format:check": "prettier --check .",
    "lint": "eslint src tests vitest.config.ts",
    "test": "vitest run",
    "test:watch": "vitest",
    "test:e2e": "npm run test:e2e:cli",
    "pretest:e2e:cli": "npm run build",
    "test:e2e:cli": "node scripts/cli-product-flow.mjs",
    "test:e2e:readme": "node scripts/readme-product-flow.mjs",
    "test:package": "node scripts/package-smoke.mjs",
    "pretest:performance": "npm run build",
    "test:performance": "node scripts/scan-benchmark.mjs",
    "typecheck": "tsc -p tsconfig.json --noEmit",
    "readme:update": "node scripts/update-readme-facts.mjs",
    "readme:check": "node scripts/update-readme-facts.mjs --check",
    "check:readme-claims": "npm run build && node scripts/check-readme-claims.mjs",
    "check:live": "node scripts/check-live-evidence.mjs",
    "check:evidence": "node scripts/check-catalog-attribution.mjs && node scripts/check-discovery-artifacts.mjs && npm run check:readme-claims && node --import tsx scripts/check-release-claims.ts",
    "feed:build": "node --import tsx scripts/build-intelligence-feed.ts",
    "verify": "npm run format:check && npm run lint && npm run typecheck && npm run check:evidence && npm test -- --run && npm run test:e2e:cli && npm run test:e2e:readme && npm run test:package && npm run test:performance",
    "verify:full": "npm run verify"
  },
  "dependencies": {
    "commander": "^12.1.0",
    "zod": "^4.4.3"
  },
  "devDependencies": {
    "@eslint/js": "^9.39.5",
    "@types/node": "^22.10.0",
    "eslint": "^9.39.5",
    "eslint-config-prettier": "^10.1.8",
    "prettier": "^3.9.5",
    "tsx": "^4.19.2",
    "typescript": "^5.7.2",
    "typescript-eslint": "^8.64.0",
    "vitest": "^4.1.10"
  }
}

```

### vitest.config.ts

```typescript
import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    include: ["tests/**/*.test.ts"],
    exclude: ["dist/**", "node_modules/**"],
    setupFiles: ["tests/setup.ts"],
    // Atomic filesystem tests are reliable but can exceed Vitest's five-second
    // default on Windows Defender/NTFS. This is not an application SLA.
    testTimeout: 20_000,
    hookTimeout: 20_000,
  },
});

```

### eslint.config.js

```javascript
import js from "@eslint/js";
import prettierConfig from "eslint-config-prettier";
import tseslint from "typescript-eslint";

export default tseslint.config(
  {
    ignores: ["coverage/**", "dist/**", "node_modules/**"],
  },
  js.configs.recommended,
  ...tseslint.configs.recommended,
  prettierConfig,
  {
    files: ["src/**/*.ts", "tests/**/*.ts", "vitest.config.ts"],
    rules: {
      "@typescript-eslint/no-explicit-any": "off",
    },
  },
);

```

### tests/readme-claims.test.ts

```typescript
import { describe, expect, it } from "vitest";
import { parseReadmeClaimManifest } from "../src/core/readme-claims.js";

describe("README claim manifest", () => {
  it("rejects proven claims without authoritative evidence", () => {
    expect(() =>
      parseReadmeClaimManifest({
        schemaVersion: 1,
        claims: [
          {
            id: "catalog.coverage",
            section: "What Loadout manages",
            summary: "The catalog has generated coverage facts.",
            evidenceClass: "structural",
            status: "proven",
            evidence: [],
          },
        ],
      }),
    ).toThrow(/authoritative evidence/i);
  });
});

```

### tests/setup.ts

```typescript
import { mkdirSync, mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { afterAll } from "vitest";

// Every Vitest file starts inside a disposable profile. Individual tests may
// replace these paths, but their "original" value is always this sandbox—not a
// developer's real ~/.loadout or agent configuration.
const sandbox = mkdtempSync(join(tmpdir(), "loadout-vitest-"));
process.env.LOADOUT_HOME = join(sandbox, ".loadout");
process.env.LOADOUT_USER_HOME = join(sandbox, "user-home");
mkdirSync(process.env.LOADOUT_HOME, { recursive: true });
mkdirSync(process.env.LOADOUT_USER_HOME, { recursive: true });

afterAll(() => rmSync(sandbox, { recursive: true, force: true }));

```

### tests/conversion.test.ts

```typescript
import { describe, expect, it } from "vitest";
import { compileConversion } from "../src/core/conversion.js";

describe("loss-reported static conversion", () => {
  it("converts a subagent prompt into a reviewable Codex skill", () => {
    const result = compileConversion(
      {
        kind: "subagent",
        name: "Review Agent",
        body: "Inspect the diff and list regressions.",
        metadata: { model: "premium", tools: "shell" },
      },
      "codex-skill",
    );
    expect(result.relativePath).toBe("skills/review-agent/SKILL.md");
    expect(result.content).toContain("Inspect the diff");
    expect(result.dropped.length).toBeGreaterThan(1);
    expect(result.requiresApproval).toBe(true);
  });

  it("turns a hook into a non-executable review artifact", () => {
    const result = compileConversion(
      { kind: "hook", name: "pre-commit", body: "run the checks" },
      "static-review",
    );
    expect(result.relativePath).toContain("conversion-reports");
    expect(result.content).not.toContain("#!/bin/");
    expect(result.dropped[0]?.field).toContain("execution");
  });
});

```

### tests/release-workflow.test.ts

```typescript
import { readFile } from "node:fs/promises";
import { describe, expect, it } from "vitest";

describe("npm release workflow", () => {
  it("keeps the verified provenance publishing contract", async () => {
    const workflow = await readFile(".github/workflows/release.yml", "utf8");

    expect(workflow).toContain("id-token: write");
    expect(workflow).toContain("node-version: 24");
    expect(workflow).toContain("package-manager-cache: false");
    expect(workflow).toContain("npm@11.5.1");
    expect(workflow).toContain("npm run verify");
    expect(workflow).toContain(
      `test "\${GITHUB_REF_NAME}" = "v$(node -p "require('./package.json').version")"`,
    );
    expect(workflow).toContain("npm publish --access public --provenance");
  });

  it("pins third-party actions to immutable commits with version comments", async () => {
    const workflow = await readFile(".github/workflows/release.yml", "utf8");

    expect(workflow).toMatch(/actions\/checkout@[0-9a-f]{40}\s+# v5/);
    expect(workflow).toMatch(/actions\/setup-node@[0-9a-f]{40}\s+# v6/);
    expect(workflow).not.toMatch(/uses:\s+[^\s@]+@v\d+(?:\s|$)/m);
  });
});

```

### tests/update-watch.test.ts

```typescript
import { describe, expect, it, vi } from "vitest";
import {
  checkForUpdates,
  startUpdateWatcher,
} from "../src/core/update-watch.js";

describe("read-only update watcher", () => {
  it("summarizes pending updates without applying them", async () => {
    const notification = await checkForUpdates(async () => [
      {
        packageId: "demo",
        status: "update-available",
        action: "Review first",
        targetAgents: ["codex"],
      },
    ]);
    expect(notification.message).toContain("1 update");
    expect(notification.updates[0]?.packageId).toBe("demo");
  });

  it("notifies immediately and can be stopped", async () => {
    vi.useFakeTimers();
    try {
      const notifications: string[] = [];
      const stop = startUpdateWatcher({
        intervalMs: 1_000,
        check: async () => [],
        notify: (notification) => notifications.push(notification.message),
      });
      await Promise.resolve();
      await Promise.resolve();
      expect(notifications).toHaveLength(1);
      stop();
      await vi.advanceTimersByTimeAsync(2_000);
      expect(notifications).toHaveLength(1);
    } finally {
      vi.useRealTimers();
    }
  });
});

```

[256 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]