reconstruct
Health Uyari
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Uyari
- process.env — Environment variable access in assets/example-output/OBLIGATIONS.json
- process.env — Environment variable access in assets/example-output/VERIFY.json
- process.env — Environment variable access in assets/example-output/VERIFY.todo.json
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
Analyze any repo and generate reconstruction PRDs to rebuild it from scratch
reconstruct
Invocation
On request by default. reconstruct runs when you ask for it: the agent may call
it when you request a reconstruction or product specs, and you can invoke it
directly with $reconstruct in Codex, /reconstruct in Claude Code or OpenCode.
The agent does not pick it up on its own, and CLI commands are unchanged. One
setting per host makes it explicit-only — see Manual or automatic.
Turn any repository — or a greenfield idea — into reconstruction PRDs an AI agent can
rebuild the project from: faithful to the original (logic, routes, translations, schema,
config), optionally improved, and buildable enough that a fresh agent gets the contracts
right — enforced by a--checkgate.
reconstruct is an Agent Skill (the open agent-skills
ecosystem by Vercel). It pairs a thin deterministic scaffold with a thick AI
playbook: a bundled, dependency-free Node script extracts universal facts, resolves routes
(with their HTTP method) for the major frameworks, and surfaces candidate hints for
everything else; the AI agent that runs the skill supplies the deeper framework-aware
understanding — the full interface surface, the data model, and the real features — for
any stack.
📖 Full documentation:
DOCUMENTATION.md— concept, CLI
reference, the analyzer pipeline, how to extend it, and FAQ.
Install
# into the current project (committed, team-shared)
npx skills add maxgfr/reconstruct
# or globally for all your projects
npx skills add -g maxgfr/reconstruct
# optionally target specific agents (default: the ones detected)
npx skills add maxgfr/reconstruct -a codex opencode
This installs the skill into your agent (Codex, OpenCode, Claude Code, Cursor, …). Invoke it
explicitly — $reconstruct in Codex, /reconstruct in Claude Code or OpenCode, or just ask:
reconstruct this repo in redesign + complex mode.
What it produces
reconstruction/
├── REBUILD.md # master plan: build order + validation checklist
├── RECONSTRUCTION.md # (--merge) the whole tree in one markdown, WITH embedded source
├── SPECS.md # (--specs) the whole spec, code-free — the file to implement from
├── FEATURES.md # (--features) every feature PRD only, in build order
├── SUMMARY.md # one-page digest — written on EVERY run; read it to orient
├── 00-overview/PRD.md # product summary, stack, metrics, feature index
├── architecture/
│ ├── ARCHITECTURE.md # architecture + external services, cross-cutting policies, i18n message catalog
│ ├── INTERFACES.md # interface surface (method · path · kind · handler) + per-op input/output/side-effect contracts
│ ├── DATA-MODEL.md # entities, fields, relations, indexes + enums & domain types
│ ├── DESIGN-SYSTEM.md # design tokens, theming, typography, components & a11y (UI products)
│ └── diagram.md # mermaid module diagram
├── features/
│ └── NN-<slug>/PRD.md # one PRD per feature/module (build-order tiered)
├── data/ # ground truth, copied verbatim
│ ├── translations/ # i18n files
│ ├── schema/ # DB schema / models
│ └── config/ # build/lint/env config
├── source/ # (fidelity=mirror) copied real source, per feature
├── UNKNOWNS.json # (--unknowns) residual unknowns: revisioned, hash-chained, evidence-backed
├── OBLIGATIONS.json # (--verify --apply) every requirement: closed / open / failed + closure digest
└── inventory.json # machine-readable manifest + evidence[] (file · line · content hash)
Evidence model
Every route and env var the engine resolves gets a content-addressed record ininventory.json evidence[] — ev_<hash>, its file, line and content hash, plus two
independent axes: confidence (observed · derived · inferred) and authority (source ·
test · config · manifest · doc · plan · agent). Verdicts cite those ids; a supported verdict
resting on the agent's inference alone never closes an obligation; --check --repo flags
evidence whose file changed since generation; and what nobody could settle goes into a
fail-closed unknowns ledger instead of a confident guess. Details:references/evidence-model.md.
Two axes + fidelity
| Axis | Values | Effect |
|---|---|---|
| Mode | preserve | redesign | scratch |
Keep the current architecture, design a fresh one for the same features, or build greenfield from an interview (see From scratch). |
| Level | light | complex |
Faithful & concise, or also suggest improvements the agent folds in. |
| Fidelity | mirror | embed | describe |
Copy real files / inline key code / text-only. |
Fidelity defaults are derived (override with --fidelity):
| Mode + Level | Fidelity |
|---|---|
| preserve + light | mirror |
| preserve + complex | embed |
| redesign + light | embed |
| redesign + complex | describe |
Translations, schema, and config are always copied into
data/verbatim,
regardless of fidelity — you can't faithfully "rewrite" data.
Standalone CLI
The deterministic engine also runs on its own (no agent, no API key):
node scripts/analyze.mjs --repo ./my-app --out ./my-app/reconstruction \
--mode preserve --level light --fidelity mirror
# inspect the raw inventory without writing anything
node scripts/analyze.mjs --repo ./my-app --json
Run node scripts/analyze.mjs --help for all flags.
Bundling: one file or a digest
Four optional, combinable flags collapse the multi-file tree:
--merge→RECONSTRUCTION.md: the whole tree in one coherent markdown
(single H1, linked table of contents, headings demoted one level; ordered
overview → architecture → features → build order), with the embedded original
source. The complete archive.--specs→SPECS.md: the same whole tree as--merge— overview,
architecture (interfaces + data model), every feature PRD, build order — but
with each document's## Source materialsection (the embedded original source
code) stripped. Self-sufficient (it carries the contracts the feature PRDs
reference) yet code-free, so it's the single file you hand an agent to
(re)implement the project from.--features→FEATURES.md: every feature PRD only — the product
functionality — in build order, in one file (single H1 + table of contents).
The features-only counterpart to--merge.SUMMARY.md: a one-page digest from the inventory (stack, libraries, size,
features in build order, interface/data counts, locales, unknowns, next steps).
Written on every run — it is the cheap orientation document, a few KB against
aninventory.jsonthat grows linearly with the repo.--summaryonly selects it
for the standalone post-step below.
# inline: produce the tree and the bundles in one run
node scripts/analyze.mjs --repo ./my-app --out ./my-app/reconstruction --merge --specs --features
# standalone post-step: (re)build the bundles from an existing output, no --repo
node scripts/analyze.mjs --merge --specs --features --summary --out ./my-app/reconstruction
# just the code-free spec to implement from, from an existing reconstruction:
node scripts/analyze.mjs --specs --out ./my-app/reconstruction
The standalone form reads <OUT>/inventory.json + the .md files, is idempotent,
and errors clearly if the directory holds no inventory.json.
Validation: is it actually buildable?
A reconstruction is only useful if a fresh agent can rebuild each unit correctly from
the PRD + architecture docs alone. Once the PRDs are enriched, run the buildability gate:
node scripts/analyze.mjs --check --out ./my-app/reconstruction
It exits non-zero on the structural failures — unresolved 🧠 callouts or fill this in
placeholders, a feature that references an undocumented entity/operation, a feature PRD
missing its spine, an uncovered locale, and a gutted data model / interface surface /
feature PRD (an emptied contract fails too, not just a callout-laden one).
--check covers structure; the ten contract categories a PRD must actually carry —
field-level data model, fully-enumerated enums, operation & write contracts (a public write
can't require an owner foreign key), format validations, external services, quantified
policies, the i18n message catalog, shared/owned UI components, and — for UI products — the
design-system contract (tokens, theming, components, a11y) — are inreferences/buildability-checklist.md. In
greenfield mode the engine also validates the plan's consistency before rendering, so
dangling references and anonymous-write-to-owner-FK contradictions are caught up front.
Two validation layers: deterministic gate + AI review
--check is deterministic — it proves structure (no leftover callouts, the docs
declare entities/operations, every PRD keeps its spine). It can't judge substance: a PRD
can pass the gate and still be unbuildable (vague requirements, happy-path-only criteria, an
unsatisfiable write contract, an enum value that contradicts the data model). That second
judgement is the AI review — performed via the skill, not the script: there is no--ai flag and no API key, because the agent running the skill is the reviewer. After--check passes, the agent re-reads the tree and appliesreferences/ai-review-rubric.md (story completeness,
testable requirements, real Given/When/Then incl. failure paths, satisfiable write contracts,
enum fidelity, cross-doc consistency, faithfulness, i18n, and the rebuild self-test), fixing
every blocker in place. Layer 1 is fast and CI-friendly; layer 2 is where a smart model
earns its keep.
The layer-2 review is itself orchestrated by a review ledger so it terminates instead of
looping by feel. --review writes a per-feature worklist (REVIEW.todo.json), flagging only
the units whose content hash changed since the last round; an agent fans out one reviewer per
flagged unit plus one independent verifier per blocker, then --review --apply findings.json reduces the structured findings to REVIEW.json (ok, residual,noProgress/staleRounds):
node scripts/analyze.mjs --review --out ./my-app/reconstruction
node scripts/analyze.mjs --review --apply findings.json --out ./my-app/reconstruction
--check --semantic folds both semantic gates into the structural one — VERIFY.json
(requirements that don't trace to source) and REVIEW.json (unresolved blockers) — additively,
never relaxing --check. The gate is trustless and fail-closed: it re-reduces the persisted
verdicts/findings (never a stored ok), re-resolves every cited evidenceRef against the
inventory, and errors when a ledger is missing or unreadable (pass --allow-unverified to
downgrade that to a warning). For larger trees the enrichment and the review/fix loop both fan out
across subagents; the protocol (map-reduce + the ledger) is inreferences/orchestration.md, and the loop
itself — rounds, stopping conditions, the known-gaps report — inreferences/convergence-loop.md.
The third gate, --verify, checks faithfulness: it pairs every requirement with the evidence
the analyzer captured and makes you adjudicate each pair (supported · partial · refuted ·unsupported, stamped confirmed · inferred · gap). Its worklist is capped at 60 pairs
by default — the cap is reported on stdout, in VERIFY.md, and as coverage inVERIFY.todo.json, and --max-verify <n> raises it. Full contract:references/verify-playbook.md.
Re-running is guarded
A normal --repo/--scratch run re-renders every document, so pointing one at a tree you
have already enriched would destroy the prose. The CLI detects an enriched tree — a document
whose 🧠 callouts are all resolved, or a REVIEW.json/VERIFY.json ledger — and refuses:
<out> already holds an ENRICHED reconstruction — re-running the analyzer would overwrite it.
To continue an existing tree use --check/--review/--verify; to re-scaffold, point --out
at a new directory; --force overwrites and loses the enrichment.
Use it as an MCP server
The skill shells out to the CLI and parses its output. An MCP server skips both:
your agent calls reconstruct as typed tools, with JSON schemas in and structured
results out. Same engine, same tree, no wrapper.
Register it with any MCP client; the server command (node /abs/path/to/scripts/analyze.mjs --mcp)
is the same for every client. stdio is the default:
codex mcp add reconstruct -- node /abs/path/to/scripts/analyze.mjs --mcp # Codex
opencode mcp add reconstruct -- node /abs/path/to/scripts/analyze.mjs --mcp # OpenCode
claude mcp add reconstruct -- node /abs/path/to/scripts/analyze.mjs --mcp # Claude Code
Or over HTTP, on loopback — the server prints the URL and these same hints on start:
node scripts/analyze.mjs --mcp --transport http --port 7343 # → http://127.0.0.1:7343/mcp
codex mcp add reconstruct --url http://127.0.0.1:7343/mcp # Codex
opencode mcp add reconstruct --url http://127.0.0.1:7343/mcp # OpenCode
claude mcp add --transport http reconstruct http://127.0.0.1:7343/mcp # Claude Code
Clients configured through a JSON file take the same command or URL:
// stdio (Claude Desktop takes stdio servers only — a remote URL there will not work):
{ "mcpServers": { "reconstruct": { "command": "node", "args": ["/abs/path/to/scripts/analyze.mjs", "--mcp"] } } }
// Cursor, HTTP:
{ "mcpServers": { "reconstruct": { "url": "http://127.0.0.1:7343/mcp" } } }
It serves all three MCP primitives, because a skill is three things: the engine
(tools), the method (prompts), and the documentation the method refers
to (resources). Here that is the whole point: the markdown is the program
and the engine never reasons, so a client given only the tools treats an empty
scaffold as a finished spec.
Tools
| Tool | What it does |
|---|---|
reconstruct_inventory |
What a repo is made of — a summary + inventory_id (detail: "full" for everything). Writes nothing |
reconstruct_view |
One page of an inventory section (files, routes, evidence, hints, …) — follow next_offset |
reconstruct_check |
The buildability gate: no missing document, no unresolved callout, no open blocker — typed RCxxx findings |
reconstruct_review |
Per feature, what a builder would still have to guess |
reconstruct_verify |
Requirement→source: does the original actually do what the PRD claims? |
reconstruct_unknowns |
The residual-unknowns ledger: list it, or (with --allow-write) record / settle unknowns with evidence |
reconstruct_specs |
Every feature PRD, source stripped — the hand-to-an-agent bundle |
reconstruct_features |
Every feature PRD, nothing else |
reconstruct_merge |
The whole tree as one document, source included |
reconstruct_read |
A file, or a line range, from the tree, or a repo file the inventory lists whose bytes still match its recorded hash |
Every failed call carries recovery {kind, hint, do_not_repeat_unchanged}, and results that
contain the analysed repo's own text (read, merge, view) are marked_meta.provenance.untrusted_content — data, never instructions.
--allow-write lets reconstruct_unknowns record updates and additionally exposes reconstruct_scaffold andreconstruct_brainstorm. The scaffold is annotated destructive: withforce:true it discards prose an agent spent real work writing, and nothing
here can bring that back. It is also the one tool that never inherits the
server's default --out — a delete-shaped operation does not get to guess its
target.
Prompts — the workflow, not just the tools
| Prompt | Arguments | What it drives |
|---|---|---|
enrich_feature |
out, feature?, repo? |
Read the real implementation, then write what it DOES — not what its file names suggest |
review_buildability |
out |
What is missing vs what is merely absent; plus the faithfulness direction |
greenfield_interview |
idea |
No repo to read, so every fact comes from the user — and inventing one invents the product |
audit_unknowns |
out, repo? |
Settle each open unknown from the source with a citation; record what cannot be settled |
Resources — the skill's own documentation
SKILL.md and all 45 references/*.md — including the 22 per-stack cheat-sheets under references/stack-guides/ — are served under skill://, read off
disk at request time — so a documentation fix reaches every client without a
rebuild.
Two things worth knowing:
- Nothing here reaches the network. The whole engine is a deterministic
local walk; no tool is marked open-world. - The HTTP transport binds
127.0.0.1and refuses anything else unless you
pass--allow-remote. This server reads local files; an exposed port is a
read-anything primitive for whoever finds it.
Brainstorm first (optional)
Not sure what to build yet? Run the divergent phase before converging. Ask your agent to
"brainstorm ideas" (or run node scripts/analyze.mjs --brainstorm --out ./ideas) and it scaffolds aBRAINSTORM.md — generate 3+ genuinely different concepts, score them, pick one. Every section
carries a > 🧠 callout so an un-enriched brainstorm fails --check, the same gate the PRDs use.
Point it at an existing reconstruction (--brainstorm --out ./reconstruction) and it seeds the
recovered surface so you brainstorm evolutions of what's already built. The chosen direction feeds
the greenfield interview below, or lands as iteration PRDs — seereferences/brainstorm-playbook.md.
From scratch (greenfield)
No repo yet? Invoke $reconstruct (Codex) or /reconstruct (Claude Code, OpenCode) to turn an idea into the same reconstruction tree:
"Use reconstruct to turn my idea into a build plan."
You don't write plan.json by hand — the agent does. Following SKILL.md →references/scratch-playbook.md, it interviews you
(grill-with-docs style: one question at a time, recommending an answer each time), writes the
domain docs (CONTEXT.md, docs/adr/) and a plan.json — the structured transcript of the
interview — then runs the engine and enriches the PRDs:
# the agent runs this for you, once the interview has produced plan.json
node scripts/analyze.mjs --scratch --plan plan.json --out ./reconstruction --level complex --tdd
plan.json is an intermediate artifact the agent generates from your answers. You can
hand-write one if you prefer — the schema and a worked example are inreferences/scratch-plan-schema.md.
Greenfield collapses two axes — mode is always scratch, fidelity is forced to describe
(there is no source to mirror) — while --level still applies (complex = a deeper interview
that also proposes alternatives and more ADRs). On top of the usual tree it also writes the
interview's domain docs, and INTERFACES.md / DATA-MODEL.md / DESIGN-SYSTEM.md come
pre-filled from the plan — along with the enums, external services, cross-cutting policies,
and i18n message catalog the interview captures, so the from-scratch tree is as buildable as the
reverse-engineered one:
reconstruction/
├── … # the same REBUILD / overview / architecture / features tree
├── CONTEXT.md # the glossary (from plan.glossary + data-model relations)
└── docs/adr/NNNN-*.md # one terse ADR per recorded decision
CONTEXT.md and docs/adr/ are written if-absent, so a richer version you authored during
the interview is never clobbered. Add --tdd (here or in any mode) to make every feature PRD andREBUILD.md drive the build test-first (red → green → refactor).
- The interview:
references/scratch-playbook.md - The
plan.jsoncontract + example:references/scratch-plan-schema.md - A full worked plan:
tests/fixtures/scratch-plan/example.plan.json
(pnpm run parityrenders this plan and checks it is buildable-by-construction; pass-- --repo <repo>to also check the code path and the from-scratch path converge).
How the rebuild works
- Read
00-overview/PRD.md,architecture/ARCHITECTURE.md,architecture/INTERFACES.md,architecture/DATA-MODEL.md, and — for a UI product —architecture/DESIGN-SYSTEM.md. - Follow the dependency-tiered build order in
REBUILD.md, implementing onefeatures/<slug>/PRD.mdat a time. - Use
data/(andsource/when present) as ground truth.
Any stack. The deterministic scaffold is universal (tree, deps, env, i18n, stack/library
detection, plus candidate hints for routes/API/schema/entry points — so a stack without a
dedicated adapter is never invisible). On top of that, route adapters resolve the real
routes — with their HTTP method — for twelve framework families (Next.js, Express, Fastify,
Hono, Flask, FastAPI, NestJS, Django, Rails, Go, ASP.NET Core, and tRPC procedures as dot-paths) through a
small pluggable registry. The deeper
framework-aware depth — the full interface surface and data model — comes from the AI playbook
in SKILL.md + references/, with per-stack cheat-sheets inreferences/stack-guides/ (Next.js, Remix, Nuxt, SvelteKit,
Astro, Angular, Express/Fastify/Hono, NestJS, Django/Flask/FastAPI, Rails, Laravel, Go, Spring
Boot, .NET/ASP.NET, tRPC/gRPC, GraphQL, mobile, desktop Electron/Tauri, serverless/edge, and
libraries/CLIs/SDKs for repos with no web framework at all).stack-guides/INDEX.md maps every
label the engine emits onto its guide — the names are deliberately not one-to-one (Flask lives
in django-flask-fastapi.md). Adding agent guidance for a stack is just markdown; adding a
deterministic route adapter is a small, self-contained code PR — seereferences/adapters.md.
Monorepos too. Workspaces are detected across ecosystems (npm/yarn/pnpm — with Lerna and
Nx as fallbacks —, Cargo [workspace], go.work) and the analysis is attributed per
workspace: each entry of inventory.workspaces carries its own stack, dependencies, hints,
and the manifest-derived dependsOn graph; features group per workspace and the build order
follows the workspace topological order (shared packages before the apps that consume them).
See references/stack-guides/monorepo.md.
Compare original and rebuilt behavior
Use an explicit local cases.json with schemaVersion: 1 and nonempty cases:
each case has id, shared stdin, original and rebuilt objects containingcommand plus args, and optional timeoutMs (default 5000).
node scripts/analyze.mjs --compare cases.json --original ./original --rebuilt ./rebuilt --run-tests --json
Read the fixture and explicitly authorize execution first. Without --run-tests,
nothing executes and the result is not-tested/exit 1. A pass requires identical
stdout/stderr bytes and exit 0 for each case (or an explicitly declaredexpectedExitCode for negative cases). Timeout, missing commands, empty suites
and output overflow fail. The JSON includes current observations and fixture
SHA-256; it proves only the listed exercised cases, not whole-program equivalence
or source faithfulness. This is local code execution, not a sandbox. See the
fixture schema, limits and workflow.
Development
pnpm install
pnpm run build # bundles src/ -> scripts/analyze.mjs (committed, zero-dep)
pnpm test # vitest unit + integration over multi-stack fixtures
pnpm run typecheck
Security
The analyzer only reads the target repo's filesystem and copies files into the
output. Analysis never executes the analyzed project's code. The separate--compare --run-tests mode explicitly executes local fixture commands; read them
and authorize execution first. It is not sandboxed. Review scripts/ before
running on untrusted repositories.
License
MIT © maxgfr
See shared engine maintenance for pins, source adoption checks and the daily repin workflow.
Manual or automatic
reconstruct ships model-invocable, on request, and skills add installs it
that way: the agent may call it through its skill tool, but the description
restricts it to explicit requests, so it runs when you ask for it, not on its
own. You can still invoke it directly with $reconstruct in Codex, /reconstruct in
Claude Code or OpenCode, prefixing the plugin namespace when it is installed as a
Claude plugin.
Making it explicit-only again is one setting, read by Claude Code and OpenCode,
applied to the installed copy of the skill:
| Host | Shipped, on request | Explicit-only |
|---|---|---|
| Claude Code, OpenCode | no disable-model-invocation in SKILL.md |
add disable-model-invocation: true |
Claude Code can do it without touching the file:"skillOverrides": { "reconstruct": "user-invocable-only" } in settings.json
leaves /reconstruct working while hiding the skill from the model. Plugin installs
ignore skillOverrides, so edit the frontmatter there. Updating or reinstalling the
skill restores the shipped default, so reapply the change afterwards.
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi