reconstruct

agent
Guvenlik Denetimi
Uyari
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.

SUMMARY

Analyze any repo and generate reconstruction PRDs to rebuild it from scratch

README.md

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.

CI

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 --check gate.

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 in
inventory.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 material section (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
    an inventory.json that grows linearly with the repo. --summary only 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 in
references/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 applies
references/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 in
references/orchestration.md, and the loop
itself — rounds, stopping conditions, the known-gaps report — in
references/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 in
VERIFY.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 and
reconstruct_brainstorm. The scaffold is annotated destructive: with
force: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.1 and 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 a
BRAINSTORM.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 — see
references/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 in
references/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 and
REBUILD.md drive the build test-first (red → green → refactor).

How the rebuild works

  1. Read 00-overview/PRD.md, architecture/ARCHITECTURE.md, architecture/INTERFACES.md,
    architecture/DATA-MODEL.md, and — for a UI product — architecture/DESIGN-SYSTEM.md.
  2. Follow the dependency-tiered build order in REBUILD.md, implementing one
    features/<slug>/PRD.md at a time.
  3. Use data/ (and source/ 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 in
references/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 — see
references/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 containing
command 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 declared
expectedExitCode 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)

Sonuc bulunamadi