Best for
- Use when seeding a configuration for a project that has none.
agents-inc/skills/src/skills/meta-config-stack-detect/SKILL.md
Inspect a codebase, a stack the user describes, or a description of what they want to build; map what is there to agents-inc catalog skills — or intent to candidate built-in stacks the user picks from — and emit a SeedPayload plus a human-readable proposal report. Use when seeding a configuration for a project that has none.
Decision brief
Quick Guide: Traverse what is in front of you — manifests, lockfiles, framework configs, one pass per workspace — or, where the user names nothing but the thing they want to build, offer candidate built-in stacks and wait for them to pick. Acquire the catalog and the stacks at r…
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/agents-inc/skills --skill "src/skills/meta-config-stack-detect"Inspect the Agent Skill "meta-config-stack-detect" from https://github.com/agents-inc/skills/blob/81d43a51211aca12c85dcc16085fa99014ec548e/src/skills/meta-config-stack-detect/SKILL.md at commit 81d43a51211aca12c85dcc16085fa99014ec548e. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
All output must follow project conventions in CLAUDE.md
The skill proposes; the existing machinery validates. Detection is deliberately judgment-shaped. A deterministic detector accumulates an unbounded edge-case matrix — every monorepo flavor, every module-federation layout, every exotic directory convention — and each new architect…
Traverse for evidence, not for coverage. Read the few files that settle questions and stop.
Traverse for evidence, not for coverage. Read the few files that settle questions and stop.
Review the “Signals that settle a question” section in the pinned source before continuing.
Permission review
The documentation asks the agent to run terminal commands or scripts.
| 2 | Machine-readable CLI output | The installed CLI may expose a JSON catalog flag (`search --json`, or a dedicated `catalog --json`) | Run the CLI's `--help` and read the flag list. Use the flag only if `--help` lists it. |The documentation asks the agent to read local files, directories, or repositories.
| 3 | Per-skill `metadata.yaml` | Read `metadata.yaml` from each skill directory in the fetched source cache or a marketplace checkout | Glob for `metadata.yaml` under the cache root or the checkout's skills directory. |Evidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 94/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 23 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Quick Guide: Traverse what is in front of you — manifests, lockfiles, framework configs, one pass per workspace — or, where the user names nothing but the thing they want to build, offer candidate built-in stacks and wait for them to pick. Acquire the catalog and the stacks at run time, map signals to catalog skill ids, mark how each assignment loads per the product's preload mapping, surface exclusive-category conflicts instead of resolving them, and emit a
SeedPayloadplus a proposal report. The skill proposes. The machinery downstream validates. Nothing is written unattended.
Detailed Resources:
SeedPayload, and the proposal report — then the same output reached the other way, from intent alone: candidates, the user's pick, and the gap the pick leaves<critical_requirements>
All output must follow project conventions in CLAUDE.md
(You MUST acquire the catalog at run time and map only to ids it contains — never propose a skill id from memory, and never inline a copy of the catalog into your reasoning as if it were current)
(You MUST acquire the built-in stacks the same way when intent is all the user has given you, offer candidates with the reason each is one, and wait for the USER to pick before any mapping runs — recommending is still proposing, never deciding)
(You MUST emit the proposal as a SeedPayload for a surface the user confirms — never write config files, never run install commands, never report a configuration as applied)
(You MUST mark each assignment's load state as the product's preload mapping has it, and lazy where you cannot read the mapping — never allocate slots, count preloads, or hold a budget of your own)
(You MUST surface exclusive-category disagreement as an unresolved conflict naming both candidates and their evidence — never resolve one silently)
(You MUST report every detected library that has no catalog skill, every part of the intent no candidate stack covers, and every major-version mismatch, in the human-readable report — the SeedPayload stays schema-pure and carries none of them)
</critical_requirements>
Auto-detection: stack detection, propose a config, seed a configuration, what skills does this project need, detect my stack, onboard this repo, what stack should I use, recommend a stack for what I am building, SeedPayload proposal
When to use:
Key patterns covered:
SeedPayload plus proposal reportWhen NOT to use:
The skill proposes; the existing machinery validates. Detection is deliberately judgment-shaped. A deterministic detector accumulates an unbounded edge-case matrix — every monorepo flavor, every module-federation layout, every exotic directory convention — and each new architecture becomes something to test. Judgment absorbs that long tail instead. Determinism is recovered at the boundary rather than in the detector: a proposal is only accepted if it survives the validation that already exists downstream — schema decoding, skill-existence checks, requires relations, conflict relations, and one-selection-per-exclusive-category. Nothing anywhere tests "does detection handle this build system"; the only guarantee that has to hold is that an invalid configuration cannot get through, and that guarantee is already built and already tested.
This is why there is no deterministic detector to imitate, and why the output shape matters more than the traversal. Get the payload right and a wrong guess is a checkbox the user unticks. Get the payload wrong and a right guess is unusable.
Three ways in, one concern. Files on disk, a stack the user names, and a description of what they want to build are three qualities of evidence for the same question — which skills should this configuration carry. The third is the weakest by a wide margin: intent names no library, so answering it means choosing among the stacks the product already ships, and choosing is the user's to do. Offer the candidates, say in one line why each is one, and wait. A recommendation the user never asked for and cannot see is a decision wearing a proposal's clothes.
Run-to-run variance is acceptable. Two runs over the same repository may propose slightly different sets. That is fine, and it is not a defect to engineer away. The output seeds a session the user confirms; it never writes configuration unattended. Variance that would be alarming in a build step is merely a different opening offer here.
Two artifacts, always. The machine-readable payload cannot hold everything worth saying — a library with no catalog skill, a version mismatch, an unresolved conflict, an assumption you defaulted. Those go in the human-readable report. Emitting one without the other loses either the automation or the honesty.
Naming third-party libraries is this skill's domain. Detection is the act of recognizing a framework, a test runner, a styling approach in someone else's repository. Those names appear here as signals to recognize, never as prescriptions — this skill never tells anyone which library to adopt. Intent mode holds the same line from the other end: the candidates are the product's own built-in stacks, quoted as they ship rather than composed here. Surfacing an option the product already offers is not prescribing a library; assembling a stack of your own would be.
Traverse for evidence, not for coverage. Read the few files that settle questions and stop.
| Signal | Where | What it settles |
|---|---|---|
| Declared dependencies | package.json dependencies / devDependencies (per workspace) | Which libraries this workspace actually claims |
| Resolved versions | The lockfile (pnpm-lock.yaml, package-lock.json, yarn.lock, ...) | The real MAJOR version — a manifest range does not settle this |
| Workspace declaration | pnpm-workspace.yaml, workspaces in the root manifest, build-orchestrator config | Whether this is a monorepo, and where the workspaces are |
| Framework wiring | The framework's own config file at the workspace root | Which framework is wired, not merely installed |
| Deploy/runtime target | The platform config file at the workspace root | Whether a workspace is a service, a worker, or a browser app |
Scripts in the manifest, directory layout, entry-point conventions, and the presence of a test directory. Use them to break a tie between two settled readings. Never let them originate a finding on their own — a test/ directory does not name a test runner.
@types/* packages. They mirror a runtime dependency; counting both double-counts one signal.node_modules, build output, coverage output, and generated directories.A library earns a MAPPED finding when it is named in a manifest and corroborated by a config file or real import. Manifest-only presence is a WEAK finding: record it, propose it if the category would otherwise be empty, and say in the report that it was manifest-only.
In a hosted conversation there is nothing to traverse. The user's description is the evidence, and its weaknesses are different: people name what they like rather than what they use, omit tooling entirely, and describe intentions as facts. Ask for the manifest if the user can paste one. Otherwise treat every finding as WEAK, propose conservatively, and say in the report that the proposal came from description rather than code.
When the user names nothing at all — no repository, no libraries, only the thing they want to build — there is no signal to weigh and traversal has nothing to do. Do not go looking for one in the phrasing: "a SaaS with billing" names an outcome, not a payments library, and reading a library out of it is invention with a detection's face on. That entry point is Pattern 3, and it starts by offering candidates rather than by mapping.
See examples/core.md for a full traversal walkthrough.
Never inline the catalog. Hundreds of skill ids written into reasoning are stale by the next marketplace commit, and a stale id produces a proposal that decodes to nothing. Acquire the catalog at run time, every run, in this order — and verify each route rather than assuming it.
| Priority | Route | How to acquire it | How to verify |
|---|---|---|---|
| 1 | Provided by the host | On a hosted surface the catalog is supplied with the invocation | Check the invocation context first. If a catalog is present, use it and stop here. |
| 2 | Machine-readable CLI output | The installed CLI may expose a JSON catalog flag (search --json, or a dedicated catalog --json) | Run the CLI's --help and read the flag list. Use the flag only if --help lists it. |
| 3 | Per-skill metadata.yaml | Read metadata.yaml from each skill directory in the fetched source cache or a marketplace checkout | Glob for metadata.yaml under the cache root or the checkout's skills directory. |
# Route 2 — verify, do not assume. The JSON flag is a filed prerequisite
# and may not have shipped in the installed version.
agents-inc search --help
Do not assume route 2 exists. It is tracked as a prerequisite and the command may still be flagless. A --help that does not list it means the route is unavailable; fall through to route 3.
What each route yields:
| Fact needed | Route 1 | Route 2 | Route 3 |
|---|---|---|---|
| Skill ids and categories | Yes | Yes | Yes (id is the directory name) |
displayName, usageGuidance | Yes | Yes | Yes |
Category exclusive / required | Yes | Yes | No — treat as unknown, say so |
| Matrix version for the payload | Yes | Yes | No — derive it, per the rule below |
Where matrixVersion comes from. Routes 1 and 2 supply it and it is used as given. Route 3 has none to read, so derive it from the marketplace checkout's package.json version field and record that origin in the report's assumptions. The field is diagnostics only and never gates a decode, so a derived value is honest as long as its origin travels with it — but never invent one and never leave it empty.
Record which route you used and which facts came from it. A proposal built on route 3 knows less about exclusivity than one built on route 1, and the report must not pretend otherwise.
If all three routes fail, stop. Report that the catalog could not be acquired. Do not proceed from memory — a proposal of remembered ids is worse than no proposal, because it looks like one.
The entry point with no signals in it. The user has said what they want to build, nothing in that sentence is a library, and the answer is not a mapping — it is a choice among the stacks the product already ships. Your part is to narrow that choice and explain it. Their part is to make it.
Stacks are data, not knowledge, and they go stale the same way: stacks are added, retired, and re-pointed at different skills between releases. Acquire them at run time through the Pattern 2 routes, in the same order and with the same verification — the host supplies them alongside the catalog where it supplies anything; the installed CLI is the next place to ask, and its --help is the only thing that says whether it can be asked; a source checkout carries its own stacks file, which may extend or override the built-ins. A remembered stack has remembered contents, and both are wrong before the name is.
If no route yields stacks, stop and say so. Offering candidates whose contents you cannot name is the same failure as guessing at catalog ids, one level up.
Two things are worth extracting, and only two.
| Read for | Sounds like | What it settles |
|---|---|---|
| Surfaces | "a web app", "an API my mobile app calls", "a command-line tool" | Which domains the proposal can touch at all |
| Concerns | "with auth", "and billing", "a live feed", "in three languages" | What each candidate either covers or visibly does not |
Everything else — team size, a deadline, a preference about a language — is context rather than evidence. It does not become a skill.
A stack ships its own name, description, philosophy, and the set of skills it names. That is the whole basis for a match, which is exactly why every match is explainable in one line. Matching against a remembered impression of "the Next.js one" is how a candidate arrives carrying something it does not contain.
Two to four candidates, best first, one line each saying which part of the intent it answers. Then stop.
SeedPayload before a pick. A payload is what a decision looks like.# ✅ Good — candidates, reasons, and the question left open
"a SaaS with auth and payments"
1. <stack-id-a> — declares auth, payments and analytics as what it is for
2. <stack-id-b> — same frontend, brings auth; names nothing for payments
3. <stack-id-c> — end-to-end type safety, auth included; payments by hand
Which is closest? Nothing is proposed until you say.
# ❌ Bad — the recommendation that arrived as a decision
"a SaaS with auth and payments"
→ SeedPayload for <stack-id-a>, 17 skills, ready to confirm
Why bad: the user's only remaining move is to notice a choice was made and undo it, and a payload that looks confirmed is precisely what nobody re-reads. The offer is the product of this pattern; the payload is the product of their answer.
Nothing about the rest is special. The stack names skill ids: verify each one against the acquired catalog, because a stack shipped by a different version may name a skill that has since been retired — a retired id is ABSENT and reported (Pattern 4), never carried. The stack also names which sub-agents carry which skills, and that is its data rather than a judgment to redo: Pattern 5 exists for evidence you gathered, and here there is none. Load states follow Pattern 6, conflicts Pattern 7, assembly Pattern 9. stackId in the payload is the stack the user picked — the one case where it is not null.
A picked stack routinely carries more than the intent asked for — a sub-agent for a surface the user never mentioned, a skill nobody described. Carry it as the stack ships it and name the surplus in the report. Trimming a pick to fit the sentence makes it mean something the user did not agree to, and an untick in the confirmation surface is cheaper than a silent edit.
A library the user did name that disagrees with the picked stack is not a gap but a conflict, and Pattern 7 has it: surface both, resolve neither.
Where the intent implies a category no candidate stack carries — a real-time feed, translations, background jobs — the gap belongs in the report, and it reads exactly like a detected library with no catalog skill: name what the user asked for, name that no candidate covers it, stop there. Do not invent a skill id to fill it, and do not pick one on their behalf. The confirmation surface lists that category's options, and choosing among them is the same decision the candidate list was.
A gap is no reason to withhold the pick. A stack that answers four concerns of five and says which one it missed beats a stack assembled here that answers all five and can be checked against nothing.
See examples/core.md for a worked intent-mode run.
Every detected library resolves to exactly one of three outcomes, and all three appear in the report.
| Outcome | Meaning | Where it goes |
|---|---|---|
| MAPPED | A catalog skill covers this library | The SeedPayload and the report |
| ABSENT | Detected, audited against the catalog, no skill exists | The report only, under "Detected, not in catalog" |
| AMBIGUOUS | Several catalog skills plausibly cover it | The payload carries the best-evidenced one; the report names the alternates |
The audited-vs-absent distinction is the point. "This library was checked against the catalog and has no skill" and "this library was never considered" look identical if you drop the finding. The first is information the user needs — it tells them the proposal is complete and where the gap is. Dropping it makes the proposal look like an oversight and hides a real marketplace gap. Report every ABSENT finding with its evidence.
Matching order: the slug is usually the library's own name, so match on slug first, then on the skill id, then on category plus display name. When nothing matches, the answer is ABSENT.
A library filed under one category but used for another still maps. A general-purpose library often earns its catalog place from one job — a schema library filed under forms — while the repository uses it for another, such as environment and wire-payload validation. Propose the catalog skill and note the observed usage in the report. Which category a skill sits in is the catalog's concern, not detection's: never drop the finding over the mismatch, and never invent an id in the category the usage suggests.
# ✅ Good — audited, and the gap is reported
Detected: a CSS framework in the web workspace manifest + its config file
Catalog: no skill with that slug in any styling category
Result: ABSENT → report row: "detected, no catalog skill (styling category left empty)"
# ❌ Bad — a plausible-looking id that the catalog does not contain
Result: web-styling-<guessed-name> → decodes to nothing, silently
Why bad: unknown ids are skipped by consumers rather than rejected, so a guessed id produces a proposal that is quietly smaller than it looked, with no error anywhere to explain it.
A required category with no signal is a gap, not a prompt to guess. If a domain is present but its required category detected nothing, leave it empty and say so. An empty required category is visible in the surface the user confirms, which is exactly the nudge that is wanted.
Workspaces map onto the sub-agents the roster carries. Report per workspace, then merge by judgment.
| Workspace shape | Domain | Informs |
|---|---|---|
| Browser application (UI framework wired, DOM entry) | web | web-developer, web-tester, web-pm, ... |
| HTTP service, API, or worker | api | api-developer, api-tester, api-pm, ... |
Terminal package (a bin entry) | cli | cli-developer, cli-tester, cli-pm, ... |
| Root tooling (formatter, type config, orchestrator) | shared | The domain agents the workspaces already justified |
Read the roster before you name an id. The table above is shaped by domain, but the roster is not uniformly per-domain — some roles are shared across every domain rather than duplicated inside each one, and which ones those are changes between releases. Take the ids from the agents the run acquired, exactly as Pattern 2 takes skill ids from the acquired catalog. An agent id remembered from an earlier roster fails the same way a retired skill id does: it is skipped rather than rejected, so its assignments quietly do not arrive.
Three rules that carry the weight:
web and api. Union them; do not force a single choice.Assignment granularity is per (sub-agent, skill), which is what the payload's assignments map expresses: one skill can be assigned to several agents, with a different load state for each.
Every assignment carries a load state, and not one of them is this skill's judgment to make. The product ships a preload mapping — one table, keyed by skill and by sub-agent role, read by the editor and the CLI alike — and it is the answer to "does this arrive preloaded?" for every pair nobody has explicitly decided. The proposal marks what that mapping has. Where the run cannot read it, the proposal marks lazy, which is the mapping's own word for a row it does not carry.
There is no budget here to hold, no slots to fill, and no count to keep.
The reason eagerness is rationed at all is real: a preloaded skill is paid for on every invocation whether the task touches it or not, so an agent that preloads everything begins every task with its context already spent. That reasoning is the mapping's, and it has already been spent on the user's behalf, per skill and per role. Re-deriving it here produces a second opinion for the machinery to disagree with.
Two things survive the rule that carried them:
assignments map is shaped to express.# ✅ Good — the mapping's answer, or its default, and the report says which
mapping readable → each (skill, sub-agent) pair marked as the mapping has it
mapping unreadable → every assignment `lazy`, recorded in the report as an
assumption rather than a finding
# ❌ Bad — a rule of one's own, applied over the top
"3-4 per agent, framework always in" → three preloads chosen here by hand
Why bad: a payload's load states travel as the user's own word, so a hand-made allocation overrides the mapping downstream instead of being corrected by it. Two surfaces that agreed about how a skill loads stop agreeing, and nothing errors. Marking lazy can only ever differ from the mapping in the direction of less resident context, and every one of them is visible in the surface for the user to flip.
Disagreement between workspaces is normal. What happens next depends entirely on whether the category is exclusive.
| Category is | Workspaces disagree | Do this |
|---|---|---|
| Non-exclusive | Two test runners, two styling approaches | Union them. Both go in the payload. Note it in the report. |
| Exclusive | Two workspaces on different frameworks | Surface a conflict. Never resolve it silently. |
The product model allows one selection per exclusive category per sub-agent, so the payload cannot hold both. That constraint is not permission to pick one quietly.
Resolve every workspace's frontend to its base framework before you compare. The category test alone misses this case: a meta-framework and a base framework are filed in different categories, so "do they disagree in the same category?" answers no, and two incompatible frontends union into one payload with nothing surfaced.
How to surface it:
Two frameworks inside one workspace is a different finding: usually a migration in flight. Report it as a migration, name both, and propose the one the config file wires.
In intent mode the disagreement is between the pick and something the user said. A stack picked after asking for Vue carries a React frontend and the exclusive category holds one of them — that is the same unresolved conflict, surfaced the same way, with the stack's choice and the user's own words as the two candidates. Do not quietly edit the picked stack to match the sentence: the stack is the thing they chose, and swapping a skill inside it makes the pick mean something they did not agree to.
Read the resolved MAJOR from the lockfile. A manifest range does not settle a version, and a major mismatch is exactly where a skill's guidance stops matching the code.
The rule is configure-and-warn:
SeedPayload stays schema-pure. It has no field for a warning, and adding one is a schema change.# ✅ Good — report row, payload untouched
| Skill | Repo major | Skill teaches | Note |
| ---------- | ---------- | ------------- | ----------------------------------------------- |
| <styling> | v3 | v4 | Configuration model differs; guidance may not apply |
# ❌ Bad — a warnings array bolted onto the payload
{ "v": 3, "warnings": ["version mismatch"], ... }
Why bad: the schema strips what it does not declare, so the warning silently disappears in transit and the decode still succeeds — the user gets the skill and never gets the caveat.
Two artifacts, always both.
SeedPayload contractSnapshot of packages/matrix/src/seed.ts at SEED_VERSION = 3. This snapshot is validated downstream by the editor's shared-import path and the CLI's --from path — if validation rejects a payload built to this shape, regenerate the snapshot from seed.ts rather than working around the rejection.
type SeedLoadState = "lazy" | "preloaded";
type SeedSkill = {
install: "plugin" | "eject";
scope: "project" | "global";
// Sub-agent id → load state. Presence IS the assignment.
assignments: Record<string, SeedLoadState>;
};
type SeedAgent = {
on?: boolean; // The only way a sub-agent holding no skills can travel.
model?: "opus" | "fable" | "sonnet" | "haiku";
effort?: "low" | "medium" | "high" | "xhigh" | "max";
scope?: "project" | "global"; // Absent means "project".
};
type SeedPayload = {
v: 3;
matrixVersion: string; // Diagnostics only — a mismatch must never fail a decode.
stackId: string | null; // null when detection proposed skills rather than a stack.
skills: Record<string, SeedSkill>; // Sparse — presence is selection.
agents: Record<string, SeedAgent>; // Sparse — an agent with nothing to say has no entry.
};
Rules for filling it:
stackId names the built-in stack the user picked in intent mode, and is null in every other case — proposing skills from signals is the normal one, and a stack that merely resembles the findings is not a match. It travels as a label: nothing downstream expands it, so every skill a picked stack names must also appear in skills or it does not arrive.install and scope are not detection findings. Emit "plugin" and "project" consistently and list them in the report as defaults the user can flip.lazy where it could not be read (Pattern 6) — never a per-agent allocation made here.agents entries are sparse. Include an entry only to say something — on: true for an agent that carries no skills of its own, or a model/effort/scope override the user asked for.| Section | Contents |
|---|---|
| What was detected | Per workspace: signals found, and the strength of each |
| Candidates and the pick | Intent mode: what was offered, the one line for each, and which the user picked |
| What mapped | Detected library → catalog skill id, with the agents it was assigned to |
| Detected, not in catalog | Every ABSENT finding, with its evidence |
| Intent not covered | Intent mode: what the user asked for that no candidate stack carries |
| Conflicts | Exclusive-category disagreements, both candidates, unresolved |
| Warnings | Version mismatches, manifest-only findings, route-3 unknowns |
| Assumptions | Defaults not derived from evidence (install, scope, catalog route) |
| Load states | Per agent: what the preload mapping answered, or that it could not be read at all |
Hand both artifacts to a surface where the user confirms before anything is written — a wizard pre-seed or the editor's import path. The skill itself writes no configuration, runs no install command, and never reports a configuration as applied. The payload loads exactly as if a shared link had arrived, and the user adjusts from there.
See examples/core.md for a complete payload and report.
<decision_framework>
Which way in is this?
Is there a repository to read?
├─ YES → Traverse it. Signals settle the proposal (Pattern 1).
└─ NO → Did the user name a stack, or libraries?
├─ YES → Their description is the evidence. Every finding is WEAK,
│ and the report says the proposal came from description.
└─ NO → They named an outcome, not a stack. Offer candidate built-in
stacks with one line each (Pattern 3), and wait for the pick.
Nothing below this line runs before they answer.
Does this signal earn a place in the payload?
Is the library named in a workspace manifest?
├─ NO → Not a finding. A lockfile-only entry is someone else's dependency.
└─ YES → Is it corroborated by a config file or a real import?
├─ NO → WEAK. Propose only if the category is otherwise empty; say "manifest-only".
└─ YES → Does the acquired catalog contain a skill for it?
├─ NO → ABSENT. Report row, no payload entry. Never guess an id.
└─ YES → Is it a frontend (framework OR meta-framework)?
│ Resolve to the base first: a meta-framework implies its base
│ (nextjs → react); a standalone one (astro) IS the frontend.
├─ YES, and another workspace resolves to a DIFFERENT frontend
│ → Surface a conflict. Stop here — do NOT ask the category
│ question. Different categories is not a union.
└─ Otherwise → Does another workspace disagree in the same category?
├─ NO → MAPPED. Add to the payload.
└─ YES → Is the category exclusive?
├─ NO → Union both. Note it in the report.
└─ YES → Surface a conflict. Better-evidenced candidate in
the payload (or neither, if evidence is even);
both named in the report as unresolved.
How does this assignment load?
Can this run read the product's preload mapping?
├─ YES → Mark what it says for this (skill, sub-agent) pair. That is the answer.
└─ NO → Mark `lazy` — the mapping's own word for a row it does not carry —
and record in the report that loads were not resolved here.
Never: choose a load state by hand, count preloads per agent, or hold a budget.
The mapping already spent that judgment, per skill and per role; a second
one written here overrides it downstream instead of deferring to it.
</decision_framework>
<red_flags>
High Priority Issues:
Medium Priority Issues:
SeedPayload to carry warnings — the schema strips what it does not declare, so the warning vanishes in transit while the decode still succeeds.Common Mistakes:
@types/* package as a second signal for the same library.stackId to a suggested stack that merely resembles the findings.Gotchas & Edge Cases:
matrixVersion is diagnostics only. A mismatch with the consumer's catalog must not fail the decode; it explains which ids were skipped. Never treat it as a gate.metadata.yaml route yields no category exclusive flags and no matrix version. A proposal built on it knows less about exclusivity — say so rather than assuming non-exclusive.stackId is a label, not an instruction. Nothing downstream expands it into skills, so a picked stack's skills must be enumerated in skills as well or they never arrive.</red_flags>
<critical_reminders>
All output must follow project conventions in CLAUDE.md
(You MUST acquire the catalog at run time and map only to ids it contains — never propose a skill id from memory, and never inline a copy of the catalog into your reasoning as if it were current)
(You MUST acquire the built-in stacks the same way when intent is all the user has given you, offer candidates with the reason each is one, and wait for the USER to pick before any mapping runs — recommending is still proposing, never deciding)
(You MUST emit the proposal as a SeedPayload for a surface the user confirms — never write config files, never run install commands, never report a configuration as applied)
(You MUST mark each assignment's load state as the product's preload mapping has it, and lazy where you cannot read the mapping — never allocate slots, count preloads, or hold a budget of your own)
(You MUST surface exclusive-category disagreement as an unresolved conflict naming both candidates and their evidence — never resolve one silently)
(You MUST report every detected library that has no catalog skill, every part of the intent no candidate stack covers, and every major-version mismatch, in the human-readable report — the SeedPayload stays schema-pure and carries none of them)
Failure to follow these rules produces a proposal that looks complete, installs less than it claimed, decides what was the user's to decide, and gives them no way to notice.
</critical_reminders>
Frequently asked questions
Quick Guide: Traverse what is in front of you — manifests, lockfiles, framework configs, one pass per workspace — or, where the user names nothing but the thing they want to build, offer candidate built-in stacks and wait for them to pick. Acquire the catalog and the stacks at r…
The source record exposes this install command: npx skills add https://github.com/agents-inc/skills --skill "src/skills/meta-config-stack-detect". Inspect the command and pinned source before running it.
Static rules flagged exec-script, read-files in the source; the page lists the matching lines and excerpts.
Alternatives
coreyhaines31/marketingskills
When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program
coreyhaines31/marketingskills
When the user wants to reduce churn, build cancellation flows, set up save offers, recover failed payments, or implement retention strategies. Also use when the user mentions 'churn,' 'cancel flow,' 'offboarding,' 'save offer,' 'dunning,' 'failed payment recovery,' 'win-back,' 'retention,' 'exit survey,' 'pause subscription,' 'involuntary churn,' 'people keep canceling,' 'churn rate is too high,' 'how do I keep users,' or 'customers are leaving.' Use this whenever someone is losing subscribers o
alirezarezvani/claude-skills
App Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklist
wanshuiyin/Auto-claude-code-research-in-sleep
Use it for operations and research tasks; the detail page covers purpose, installation, and practical steps.