Skip to content
prod e051e98
Browse

3 · Extract & snapshot the vendor

Objective — get the vendor’s code onto disk and capture a pristine reference of exactly what shipped, so every future vendor update is a reviewable diff instead of an archaeology dig.

The code arrives now (or already landed during AI System setup). Capture a pristine reference of exactly what the vendor shipped and identify any patches the author baked into vendor/. This is the page that makes every future vendor update a reviewable diff.

flowchart LR
Z["CodeCanyon ZIP<br/>(👤 extract manually)"] --> R["verify the<br/>Laravel root"]
R --> D["capture vendor docs<br/>+ detect plugins"]
D --> B["back up pristine<br/>originals → Admin-Local"]
B --> P["compare shipped vendor/<br/>vs a fresh install"]
P --> C["document author patches<br/>in _CUSTOMIZATIONS.md"]

CodeCanyon ZIPs have unpredictable nesting — an outer ZIP wrapping inner ZIPs, docs mixed with source, sometimes multiple framework versions. Extract manually, then let the agent verify.

  1. Unpack and inspect. Double-click the ZIP in Finder (or use The Unarchiver) and look at what came out.

    • ✅ The archive is extracted and its top-level contents are visible.
  2. Find the Laravel root — the folder containing artisan, composer.json, app/, config/, routes/.

    What you seeWhat to do
    artisan directly in the extracted folderThat folder is the Laravel root
    A main-files/ or script/ subfolder holding artisanThe root is inside that subfolder
    Inner ZIPs (main-files.zip, documentation.zip)Extract the source ZIP — that contains the root
    vendor.zip / vendor/ inside the rootShipped vendor — extract it into the root if zipped
    documentation/, license/, readme/ foldersNot the root — move these to Admin-Local/2-Docs/
    • ✅ You can point to the one folder that contains artisan.
  3. Move (cut, don’t copy) the root into your workspace so nothing is left behind.

    Terminal window
    mv /path/to/extracted/laravel-root ~/MyWork/Projects/<ProjectName>
    # Expected: the root now lives under your workspace; the extraction folder is empty
    • ✅ The Laravel root is in your workspace and the source extraction folder is empty.

After the user has placed the files, the agent confirms the extraction is correct. Run from the project directory.

  1. Run the structure check.

    Terminal window
    echo "--- Essential files ---"
    for f in artisan composer.json .env.example; do
    [ -f "$f" ] && echo " ✅ $f" || echo " ❌ MISSING: $f"
    done
    echo "--- Essential directories ---"
    for d in app config database public resources routes storage bootstrap; do
    [ -d "$d" ] && echo " ✅ $d/" || echo " ❌ MISSING: $d/"
    done
    echo "--- Shipped (do NOT overwrite) ---"
    [ -d vendor ] && echo " 📦 vendor/ present ($(du -sh vendor | cut -f1)) — SHIPPED" || echo " ⬜ vendor/ absent — composer install later"
    [ -d public/build ] && echo " 📦 public/build/ present — pre-built assets" || echo " ⬜ public/build/ absent — npm run build later"
    echo "--- Nesting / leftover ZIPs ---"
    [ -f artisan ] && [ -d app ] || { echo " ❌ root is nested — find it:"; find . -maxdepth 3 -name artisan; }
    find . -maxdepth 2 -name "*.zip" | head -5
    # Expected: all ✅, vendor/ + public/build flagged 📦 if shipped, no ❌, no stray .zip
    • ✅ Every essential file/dir prints ✅, no nesting error, no unextracted inner ZIP.

Vendor docs carry context the listing page doesn’t — admin features, required cron jobs, API endpoints, server requirements. Mirror them in so later phases can grep them.

  1. Copy bundled docs into the docs vault.

    Terminal window
    mkdir -p Admin-Local/2-Docs/1-VendorDocs
    find . -maxdepth 2 \( -iname "*.pdf" -o -iname "readme*" -o -iname "install*" -o -iname "changelog*" \) \
    -exec cp {} Admin-Local/2-Docs/1-VendorDocs/ \; 2>/dev/null
    ls -lh Admin-Local/2-Docs/1-VendorDocs/
    # Expected: any shipped PDF/README/INSTALL/CHANGELOG files listed in the vault
    • ✅ Bundled docs are mirrored into Admin-Local/2-Docs/1-VendorDocs/.
  2. If the vendor docs are online-only (more than a handful of pages), mirror them locally so later phases can grep them instead of burning live fetches. Skip this when the vendor ships PDFs/README/docs in the archive.

    Terminal window
    # From the scraper tool's directory (see its README for the full contract):
    python3 -m venv .venv && source .venv/bin/activate
    pip install -r requirements.txt
    playwright install chromium # only needed for the JS-rendered scraper
    # Static HTML docs (interactive prompt):
    python3 simple_scraper.py
    # JS-rendered docs (positional args: <docs-url> <output-dir> <max-pages>):
    python3 docs_scraper.py "<VENDOR_DOCS_URL>" "Admin-Local/2-Docs/1-VendorDocs/scraped" 100
    # Expected: pages mirrored into Admin-Local/2-Docs/1-VendorDocs/scraped for later grep
    • ✅ The scraped docs land under a project-local Admin-Local/2-Docs/1-VendorDocs/scraped/ path.

    If you only have URLs and are not scraping yet, index them first:

    Terminal window
    mkdir -p Admin-Local/2-Docs/1-VendorDocs/online
    grep -RhoE 'https?://[^ )"]+' . | grep -Ei 'docs|documentation|help|support' \
    | sort -u > Admin-Local/2-Docs/1-VendorDocs/online/source-urls.txt
    # Expected: source-urls.txt lists docs URLs, or is empty if none were found
    • ✅ Online-only docs are indexed locally and scraped when the vendor docs are too large to grep live.
  3. Sweep for plugins and addons. Many CodeCanyon apps sell or bundle plugins separately — detect them now and defer installing any until the base app runs (Phase 6+).

    Terminal window
    echo "=== Plugin / Addon Detection ==="
    # Plugin directories shipped in the tree
    for d in plugins addons modules extensions packages Modules Plugins; do
    [ -d "$d" ] && echo " 📂 $d/ ($(ls -1 "$d" | wc -l | tr -d ' ') items):" && ls -1 "$d" | head -10
    done
    # Plugin-like Composer packages
    echo "--- composer.json plugin-like packages ---"
    grep -iE "plugin|addon|module|extension" composer.json 2>/dev/null | head -10
    # Plugin / marketplace routes
    echo "--- plugin routes ---"
    grep -iE "plugin|addon|module|marketplace|extension" routes/*.php 2>/dev/null | head -5
    # Separate plugin ZIPs in the source archive
    echo "--- plugin ZIPs in the source archive ---"
    find _source/ -maxdepth 2 -name "*.zip" 2>/dev/null | grep -iv "codecanyon\|main\|source" | head -10
    # Expected: any shipped/separate plugins surfaced for the action table below
    FindingAction
    Bundled pluginsNote which are included; they may need activation in the admin panel (Phase 6).
    Separate plugin ZIPsStage them under the source archive’s plugins/ for later install.
    Available for purchaseNote on the CodeCanyon listing; record in CLAUDE.md as “available but not purchased.”
    InstallationDefer to post-deploy (Phase 6+). Never install plugins before the base app runs.
    • ✅ Any plugins/addons are surfaced and slotted into the action table; none installed yet.
  4. Record the essentials in CLAUDE.md under a ## Vendor Documentation heading: source/version/author, server requirements, admin-panel features, cron jobs, API/webhooks, known gotchas, and any plugins/addons (bundled, for-purchase, or installed). Defer installing any plugin until the base app runs (Phase 6+).

    • CLAUDE.md has a ## Vendor Documentation section with version, requirements, and any plugins noted.

Before git, snapshot the untouched root files into a versioned vault — an offline record of “exactly as shipped,” independent of git history.

  1. Copy each top-level file with a version suffix.

    Terminal window
    export VERSION="x.y.z" # replace with the vendor's actual version, e.g. "10.4"
    mkdir -p "Admin-Local/3-Versions/1-v${VERSION}/1-Originals"
    for f in $(ls -A | while read x; do [ -f "$x" ] && echo "$x"; done); do
    cp "$f" "Admin-Local/3-Versions/1-v${VERSION}/1-Originals/${f}-v${VERSION}"
    done
    # Expected: every top-level file copied with a -v<VERSION> suffix into 1-Originals/
    • Admin-Local/3-Versions/1-v<VERSION>/1-Originals/ holds version-suffixed copies of the shipped root files.

5. Identify author vendor patches (the seam)

Section titled “5. Identify author vendor patches (the seam)”

CodeCanyon authors frequently modify third-party packages inside vendor/. You must find these before ever running composer install, which would silently overwrite them.

  1. If no vendor/ shipped, there’s nothing to compare — you’ll composer install in Phase 3. Skip to the gate.

    • ✅ Confirmed vendor/ absent → nothing to preserve.
  2. If vendor/ shipped, compare it against a fresh install in a temp directory (never the project root).

    Terminal window
    mkdir -p /tmp/vendor-compare
    cp composer.json composer.lock /tmp/vendor-compare/ 2>/dev/null
    ( cd /tmp/vendor-compare && composer install --no-scripts --no-autoloader 2>&1 | tail -3 )
    diff -rq vendor /tmp/vendor-compare/vendor 2>/dev/null \
    | grep -v "autoload\|installed.json\|installed.php\|.git" | tee /tmp/vendor-diff.txt
    echo "=== $(wc -l < /tmp/vendor-diff.txt | tr -d ' ') differing files ==="
    # Expected: a count of differing files (often 0)
    • ✅ A diff count printed — act on it per the table below.
    ResultMeaningAction
    0 differencesAuthor didn’t patch vendorSafe to composer install later; clean up /tmp
    1–5 differencesMinor author patchesDocument each in _CUSTOMIZATIONS.md; keep shipped vendor
    6+ differencesSignificant modificationsDocument all; never overwrite without reviewing each
  3. Preserve important patches into the tracked customization area, then clean up.

    Terminal window
    mkdir -p "resources/vendor-customizations/<vendor>/<package>"
    cp -r "vendor/<vendor>/<package>/src" "resources/vendor-customizations/<vendor>/<package>/"
    [ -d /tmp/vendor-compare ] && rm -rf /tmp/vendor-compare
    [ -f /tmp/vendor-diff.txt ] && rm -f /tmp/vendor-diff.txt
    # Expected: patched package copied to resources/vendor-customizations/; temp dirs removed
    • ✅ Each author patch is documented and copied into resources/vendor-customizations/; the shipped vendor/ is left in place.

The shipped vendor/ stays exactly where it is — it’s only ignored by git later, never deleted, until Phase 3 confirms the app boots.

Do not mark this step done until every box below is checked.

  • 🔀 Laravel root verified — all essential files/dirs present, no nesting, no unextracted inner ZIPs.
  • 🤖 Vendor docs captured — copied to Admin-Local/2-Docs/1-VendorDocs/; key facts in CLAUDE.md.
  • 🤖 Pristine backup taken — originals in Admin-Local/3-Versions/1-v<VERSION>/1-Originals/.
  • 🤖 Author patches identified — documented in _CUSTOMIZATIONS.md (or confirmed: 0 differences).
  • 🤖 Shipped vendor/ intact — no composer install run yet.