PinAppAI

← All docs

AI-diff review (the /changes/ workflow)

Generate a /changes/ page from your latest git diff and let reviewers approve, reject, or rewrite each change one at a time — on the actual page where it lives.


After a content rewrite, redesign, or major copy refresh, you want reviewers to decide on every change individually — not skim a giant diff. The PinAppAI AI-diff review workflow turns your git history into a per-item review surface: generate a /changes/ page with Before/After cards, deploy, share the link, decide.

How it fits together

git diff (recent commits)

   │  AI prompt (Claude Code / Cursor / any agent)

/changes/ HTML page         ← generated, deployed alongside your site

   │  Widget on /changes/ posts items_detail to the API

PinAppAI populates change_items

   │  Reviewer visits /changes/ OR any source page

   • /changes/ → per-item Approve/Reject/Request-change bars + summary
   • source page → in-page review chip + decision panel + cross-page nav

1. Generate /changes/

Open your project in app.pinappai.com, open the Snippet modal, and click Copy AI diff prompt. Paste into Claude Code, Cursor, or any AI agent that has access to your repo.

The agent reads recent commits, summarises every meaningful change, and writes a single self-contained /changes/ page with:

  • A <div class="pp-change-item"> wrapper per atomic change
  • data-pp-page-url (the source page where the change lives) and data-pp-source-selector (a unique CSS selector to the element) on every item
  • BEFORE / AFTER text in red/green rows
  • All CSS inlined — one file to deploy, one file to delete

The AI generator never modifies your source files. The cardinal rule of its prompt is “you read source markup to understand it; you do not edit it.” /changes/ is the only artifact it writes.

2. Deploy + open

Commit and deploy /changes/ like any other page. Reviewers visit https://your.site/changes/ and see:

  • A header summary: 20 / 249 (8%) · ✓ 11 · ✗ 5 · ↻ 4 · 229 pending
  • Each item rendered as a card with Before/After + three buttons:
    • ✓ Approve — accept the AI’s proposed wording
    • ✗ Reject — reject without committing to alternative text
    • ↻ Request change — type the wording you actually want; that text is what the next AI iteration applies
  • A small black ↗ icon next to each item heading — opens the source page in a new tab with the in-page review panel pre-focused on that item

Decisions persist on PinAppAI’s servers, scoped to the reviewer’s verified email. Reload /changes/ and your decisions are still there.

3. Review on the actual page (in-page mode)

When a reviewer visits a source page (/pricing/, /tr/features/asset-management/, …) where some /changes/ items target it, a chip appears bottom-right:

16 changes to review on this page

Click → a draggable bottom panel opens with:

  • The actual rendered element framed in red on the page
  • BEFORE / AFTER rows for the current item
  • Approve / Reject / Request-change buttons (with inline edit on Request)
  • ◀ ▶ to walk through all items, even across pages — Next on the last item of this page seamlessly navigates to the first item of the next page
  • A 1/4 of 249 counter showing your position within the current page over the project total
  • The 249 is an underlined link back to /changes/ for the full card view

On pages without their own items, you still see a 249 changes to review on this site chip — click it to jump to the alphabetically first pending item project-wide.

4. Auto-discovery (cold start)

If a reviewer’s first visit is a source page (no /changes/ visit anywhere yet), the widget self-bootstraps: it fetches /changes/ same-origin, parses the items, and POSTs them to the API in the background. By the time the page finishes loading, the chip appears with the correct count. No manual warming step.

If your /changes/ lives at a non-default path (e.g., /tr/changes/), tell the widget via:

<script src="https://api.pinappai.com/widget.js"
        data-project="pk_..."
        data-changes-url="/tr/changes/" defer></script>

5. Hand decisions to the next AI iteration

Once reviewers are done, you have two paths to apply the queued decisions to source — pick whichever your team prefers:

  • MCP-native (recommended): in your AI client, run /pinappai:apply-decisions. The agent fetches the queued decisions, groups them by file, applies each one (rollbacks revert to the original; change-requests apply the reviewer’s literal wording), writes the iteration boundary marker, and asks before committing (a/b/c/d picker — see /docs/mcp/).
  • Export markdown: open the project’s Approvals view in admin and click Copy decisions for AI. Paste into Claude Code or any AI client without MCP installed; the markdown is self-contained and produces the same outcome.

Either path applies the literal text you asked for — no comment-prose to interpret.

Acknowledgment after apply (iteration-loop v2)

Once the changes are live and reviewers have weighed in, admins see every applied CR in the Approvals tab — one flat list across all iterations, tagged with each CR’s source iteration. The action you take on a CR depends on what the reviewers said:

Reviewer outcomeAdmin choices
Every reviewer approvedAcknowledge — closes the CR (closed_accepted).
Every reviewer rejectedRevert — sends the CR back to the current iteration so AI undoes it. Or Wontfix — closes without revert.
Every reviewer asked for a changeApply new change — closes the original, spawns a successor CR sourced from the reviewer’s wording, and routes it to the current iteration. Or Wontfix.
Mixed reviewer voicesAll four — Acknowledge / Revert / Apply new change / Wontfix. Optionally cite a reviewer (cited_reviewer_id) so the audit log records which voice you followed.

State-machine summary: accept / apply_new (on original) / wontfix are terminal (CRs surface in Closed). revert keeps the same CR; apply_new creates a successor. Both auto-attach to the open iteration (or open one), surfacing them in the Current iteration tab for the next AI run.

Three ways to acknowledge:

  • MCP: pinappai_acknowledge_change_request({ project, cr_id, outcome, cited_reviewer_id?, note? })
  • Iteration-first dashboard (app.pinappai.com/dashboard-v2, opt-in via your workspace settings): conditional action buttons per CR + a “Acknowledge all approved (N)” bulk action.
  • Legacy admin dashboard: the existing admin status PATCH still works (done → accept; wontfix → terminal); Phase 2 dual-writes emit the matching event automatically.

For the full state machine + coverage model see /docs/iteration-loop/.

5.5. The iteration boundary marker

Every apply run (whether apply-decisions or fix-changes) writes .pinappai/last-applied.json with the run’s ISO timestamp:

{
  "last_applied_at": "2026-05-06T21:05:00Z",
  "bundle_summary": "applied 8 decisions (3 rollbacks, 5 modifies)"
}

The next time you regenerate /changes/ (whether via /pinappai:generate-changes-page or by re-running the admin’s AI-diff prompt), the generator reads this marker and scopes the diff to “git log —since=.” Reviewers only see what’s drifted since the last apply — not the cumulative drift from your project’s beginning.

Commit .pinappai/last-applied.json along with the source changes from each apply. The marker file is in your “Affected files” list at the end of every applies-to-source slash command. If it ends up in a separate commit (or worse, uncommitted), your next /changes/ regen’s diff range becomes non-deterministic.

.pinappai/context.json (project-shape cache) lives next to it. Both are tiny — commit them.

Preparing for production

When you’re ready to ship the rewrite to production, you want /changes/ and all review markup gone from the customer-facing build. Two paths:

  • MCP-native: run /pinappai:remove in your AI client. The agent removes the widget script tag, deletes /changes/, cleans up any optional helpers, runs four git grep verification commands, and asks before committing.
  • Export markdown: open the Snippet modal in admin and click Copy remove prompt for AI. Same outcome.

Both paths preserve the .pinappai/ directory by design — your audit trail and project-shape cache survive the removal, so re-installing later (or branching off this state) drops you back into the same baseline. Removing .pinappai/ is a separate, explicit confirmation step.