Sync third-party and MCP marketplace plugins
Constraint: Public skills are published only by explicit administrator action unless they are tracked third-party market sources. Confidence: high Scope-risk: narrow Directive: Keep private/internal skills out of the public marketplace and preserve normal incremental market Git history. Tested: Marketplace validation passed.
This commit is contained in:
@@ -33,8 +33,8 @@
|
|||||||
"repo": "https://github.com/nextlevelbuilder/ui-ux-pro-max-skill.git",
|
"repo": "https://github.com/nextlevelbuilder/ui-ux-pro-max-skill.git",
|
||||||
"ref": "main",
|
"ref": "main",
|
||||||
"adapter": "claude-skill",
|
"adapter": "claude-skill",
|
||||||
"commit": "8a1a6d857332da32252d77365da90c3f6293b47b",
|
"commit": "bc826e2267a36d98a2dcf5231e16c30ff546770f",
|
||||||
"syncedAt": "2026-08-19T16:00:01Z"
|
"syncedAt": "2026-08-20T16:00:00Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "caveman",
|
"id": "caveman",
|
||||||
@@ -42,8 +42,8 @@
|
|||||||
"repo": "https://github.com/JuliusBrussee/caveman.git",
|
"repo": "https://github.com/JuliusBrussee/caveman.git",
|
||||||
"ref": "main",
|
"ref": "main",
|
||||||
"adapter": "codex-plugin",
|
"adapter": "codex-plugin",
|
||||||
"commit": "99a9aa2f5a45097fc3563febea7d0baf64407441",
|
"commit": "a42ef766cedef6160407418a359a52939b2d20b9",
|
||||||
"syncedAt": "2026-08-19T16:00:01Z"
|
"syncedAt": "2026-08-20T16:00:00Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "taste-skill",
|
"id": "taste-skill",
|
||||||
@@ -60,8 +60,8 @@
|
|||||||
"repo": "https://github.com/shadcn-ui/ui.git",
|
"repo": "https://github.com/shadcn-ui/ui.git",
|
||||||
"ref": "main",
|
"ref": "main",
|
||||||
"adapter": "claude-skill",
|
"adapter": "claude-skill",
|
||||||
"commit": "25be24cca34d06eed29a4779c3f48c4816aa812c",
|
"commit": "4e88ab81ae1d1550165db949a903c691a04f699c",
|
||||||
"syncedAt": "2026-08-19T16:00:01Z"
|
"syncedAt": "2026-08-20T16:00:00Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "frontend-slides",
|
"id": "frontend-slides",
|
||||||
@@ -96,8 +96,8 @@
|
|||||||
"repo": "https://github.com/hugohe3/ppt-master.git",
|
"repo": "https://github.com/hugohe3/ppt-master.git",
|
||||||
"ref": "main",
|
"ref": "main",
|
||||||
"adapter": "claude-skill",
|
"adapter": "claude-skill",
|
||||||
"commit": "a160e776b7faff5d2227d180d0f31c6253056fae",
|
"commit": "fe9ae086ab33d5a384f691ffd432aeb04ba0f96f",
|
||||||
"syncedAt": "2026-08-19T16:00:01Z"
|
"syncedAt": "2026-08-20T16:00:00Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "grill-me",
|
"id": "grill-me",
|
||||||
@@ -105,8 +105,8 @@
|
|||||||
"repo": "https://github.com/mattpocock/skills.git",
|
"repo": "https://github.com/mattpocock/skills.git",
|
||||||
"ref": "main",
|
"ref": "main",
|
||||||
"adapter": "skill-collection",
|
"adapter": "skill-collection",
|
||||||
"commit": "885e2ca4d842d139e9aef4e48d366c63cb1b8013",
|
"commit": "0ab1b63a410a03d3627979a109c8695de27af954",
|
||||||
"syncedAt": "2026-08-19T16:00:01Z"
|
"syncedAt": "2026-08-20T16:00:00Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "next-skills",
|
"id": "next-skills",
|
||||||
@@ -114,8 +114,8 @@
|
|||||||
"repo": "https://github.com/vercel/next.js.git",
|
"repo": "https://github.com/vercel/next.js.git",
|
||||||
"ref": "canary",
|
"ref": "canary",
|
||||||
"adapter": "skill-collection",
|
"adapter": "skill-collection",
|
||||||
"commit": "5c5daffedd06d434263b1847257636149e36baf7",
|
"commit": "605425e139855c2664732bb814d0447512c05d00",
|
||||||
"syncedAt": "2026-08-19T16:00:01Z"
|
"syncedAt": "2026-08-20T16:00:00Z"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
"sourceId": "caveman",
|
"sourceId": "caveman",
|
||||||
"repo": "https://github.com/JuliusBrussee/caveman.git",
|
"repo": "https://github.com/JuliusBrussee/caveman.git",
|
||||||
"ref": "main",
|
"ref": "main",
|
||||||
"commit": "99a9aa2f5a45097fc3563febea7d0baf64407441",
|
"commit": "a42ef766cedef6160407418a359a52939b2d20b9",
|
||||||
"adapter": "codex-plugin",
|
"adapter": "codex-plugin",
|
||||||
"sourcePath": "plugins/caveman",
|
"sourcePath": "plugins/caveman",
|
||||||
"syncedAt": "2026-08-19T16:00:01Z"
|
"syncedAt": "2026-08-20T16:00:00Z"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
"sourceId": "grill-me",
|
"sourceId": "grill-me",
|
||||||
"repo": "https://github.com/mattpocock/skills.git",
|
"repo": "https://github.com/mattpocock/skills.git",
|
||||||
"ref": "main",
|
"ref": "main",
|
||||||
"commit": "885e2ca4d842d139e9aef4e48d366c63cb1b8013",
|
"commit": "0ab1b63a410a03d3627979a109c8695de27af954",
|
||||||
"adapter": "skill-collection",
|
"adapter": "skill-collection",
|
||||||
"sourcePath": "skills/productivity",
|
"sourcePath": "skills/productivity",
|
||||||
"syncedAt": "2026-08-19T16:00:01Z"
|
"syncedAt": "2026-08-20T16:00:00Z"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,17 @@ Interview the user relentlessly until you reach a shared understanding. Map this
|
|||||||
|
|
||||||
Work the tree in **rounds**. The **frontier** is every decision whose prerequisites are already settled: the questions you can ask _now_ without guessing at answers you haven't heard yet. Ask the whole frontier in one round: number each question and give your recommended answer. Then wait for the user's answers before the next round.
|
Work the tree in **rounds**. The **frontier** is every decision whose prerequisites are already settled: the questions you can ask _now_ without guessing at answers you haven't heard yet. Ask the whole frontier in one round: number each question and give your recommended answer. Then wait for the user's answers before the next round.
|
||||||
|
|
||||||
Each question should be formatted like so:
|
Format a round like so:
|
||||||
|
|
||||||
```
|
```
|
||||||
❓ **Q1** - **<question title>**: <question body, might be multiple paragraphs, including multiple choices>
|
❓ **Q1** - **<question title>**: <question body, might be multiple paragraphs, including multiple choices>
|
||||||
|
|
||||||
|
➡️ <your recommended answer>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
❓ **Q2** - **<question title>**: <question body, might be multiple paragraphs, including multiple choices>
|
||||||
|
|
||||||
➡️ <your recommended answer>
|
➡️ <your recommended answer>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -3,5 +3,5 @@
|
|||||||
"name": "playwright浏览器自动化操作",
|
"name": "playwright浏览器自动化操作",
|
||||||
"version": "20260605",
|
"version": "20260605",
|
||||||
"keySource": "none",
|
"keySource": "none",
|
||||||
"syncedAt": "2026-08-19T16:02:27Z"
|
"syncedAt": "2026-08-20T16:01:54Z"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
"sourceId": "next-skills",
|
"sourceId": "next-skills",
|
||||||
"repo": "https://github.com/vercel/next.js.git",
|
"repo": "https://github.com/vercel/next.js.git",
|
||||||
"ref": "canary",
|
"ref": "canary",
|
||||||
"commit": "5c5daffedd06d434263b1847257636149e36baf7",
|
"commit": "605425e139855c2664732bb814d0447512c05d00",
|
||||||
"adapter": "skill-collection",
|
"adapter": "skill-collection",
|
||||||
"sourcePath": "skills",
|
"sourcePath": "skills",
|
||||||
"syncedAt": "2026-08-19T16:00:01Z"
|
"syncedAt": "2026-08-20T16:00:00Z"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ In both, the per-route success bar is the same: **dev loop reports no errors AND
|
|||||||
Three classes of blocker come up, usually in this order:
|
Three classes of blocker come up, usually in this order:
|
||||||
|
|
||||||
1. **Request-time reads** (`cookies()`, `headers()`, `await params`, `await searchParams`). All four block when awaited at the top of a page or layout. `params` and `searchParams` often get missed because they're not framed as "request data" the way cookies and headers are. The fix is to push the read into a `<Suspense>`-wrapped child — and for `params`/`searchParams`, forward the promise into the child and await it there; don't `await` at the page top.
|
1. **Request-time reads** (`cookies()`, `headers()`, `await params`, `await searchParams`). All four block when awaited at the top of a page or layout. `params` and `searchParams` often get missed because they're not framed as "request data" the way cookies and headers are. The fix is to push the read into a `<Suspense>`-wrapped child — and for `params`/`searchParams`, forward the promise into the child and await it there; don't `await` at the page top.
|
||||||
2. **Sync-IO at module/render time** (`new Date()`, `Date.now()`, `Math.random()`, `crypto.randomUUID()`). These fail the build even with `instant = false` — the opt-out doesn't suppress them. If they're in a shared layout, they block every route under it. The codemod can't fix them; you have to translate each one by hand before the build can pass (see the [incremental pre-step](#incremental)). Grep the whole repo for these calls before running anything else.
|
2. **Sync-IO at module/render time** (`new Date()`, `Date.now()`, `Math.random()`, `crypto.randomUUID()`). These fail the build even with `instant = false` — the opt-out doesn't suppress them. If they're in a shared layout, they block every route under it. The codemod can't fix them; after running it, use the build errors to identify which calls to translate by hand (see the [incremental pre-step](#incremental)).
|
||||||
3. **`"use cache"` files that read request data.** A file with a top-level `"use cache"` directive can't export `instant`; combining the two errors with `Only async functions are allowed to be exported in a "use cache" file.`, which means the directive was wrong for that route. Remove it before running the codemod.
|
3. **`"use cache"` files that read request data.** A file with a top-level `"use cache"` directive can't export `instant`; combining the two errors with `Only async functions are allowed to be exported in a "use cache" file.`, which means the directive was wrong for that route. Remove it before running the codemod.
|
||||||
|
|
||||||
## working surfaces
|
## working surfaces
|
||||||
@@ -71,7 +71,7 @@ In preference order:
|
|||||||
|
|
||||||
1. **[`next-dev-loop`](https://github.com/vercel/next.js/tree/canary/skills/next-dev-loop) — strongly preferred.** Cross-checks `/_next/mcp` against the live browser via `agent-browser` and surfaces both compile and runtime issues in one pass. The diagnostics (React tree, suspense boundaries, console + network) are richer than poking at `next dev` by hand.
|
1. **[`next-dev-loop`](https://github.com/vercel/next.js/tree/canary/skills/next-dev-loop) — strongly preferred.** Cross-checks `/_next/mcp` against the live browser via `agent-browser` and surfaces both compile and runtime issues in one pass. The diagnostics (React tree, suspense boundaries, console + network) are richer than poking at `next dev` by hand.
|
||||||
|
|
||||||
Install it before starting the loop. Don't wait until you hit something `next dev` alone can't explain. Run:
|
Install it before starting the loop. Don't wait until you hit something `next dev` alone can't explain. It ships alongside this skill, so check whether it is already available first, and install it only if it is not:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx skills add https://github.com/vercel/next.js/tree/canary/skills/next-dev-loop
|
npx skills add https://github.com/vercel/next.js/tree/canary/skills/next-dev-loop
|
||||||
@@ -100,17 +100,9 @@ If there's no user to ask, default to **Incremental** and document the choice.
|
|||||||
|
|
||||||
### incremental
|
### incremental
|
||||||
|
|
||||||
Before invoking the codemod, fix the two classes of blocker it can't.
|
Before invoking the codemod, fix the blocker that does not require build feedback.
|
||||||
|
|
||||||
1. **Sync-IO at module/render time.** Grep the whole repo for `new Date()`, `Date.now()`, `Math.random()`, and `crypto.randomUUID()` (not only `app/**/layout.{js,jsx,ts,tsx}` — the read might live in any component imported by a layout). Unblock each match with the `await connection()` + `<Suspense>` fix from its `blocking-prerender-*` error card: it defers the value to request time, exactly as it behaved before the migration, so it needs no product decision. Add this exact comment on the line above the `await connection()`:
|
1. **Incompatible segment configs.** Grep for `^export const (revalidate|dynamic|fetchCache)` across the app directory and translate per the `requires` note above. The codemod does not touch them; leaving them in place fails the build after the codemod.
|
||||||
|
|
||||||
```tsx
|
|
||||||
// TODO: Cache Components adoption. Added to unblock the build: remove this connection() to re-trigger the error and review the fix options.
|
|
||||||
```
|
|
||||||
|
|
||||||
It shares the `TODO: Cache Components adoption` prefix with the comments the codemod writes, so the check-in grep finds both. Removing the `await connection()` makes the error fire again with its fix cards — the same motion as removing an opt-out in the loop.
|
|
||||||
|
|
||||||
2. **Incompatible segment configs.** Grep for `^export const (revalidate|dynamic|fetchCache)` across the app directory and translate per the `requires` note above. The codemod does not touch them; leaving them in place fails the build after the codemod.
|
|
||||||
|
|
||||||
The codemod refuses to run on a dirty working tree. Commit or stash unrelated work first, or pass `--force` to let its edits land alongside your WIP. Common false positive: if you recently upgraded Next.js, `package.json` and the lockfile will already be dirty — commit those first.
|
The codemod refuses to run on a dirty working tree. Commit or stash unrelated work first, or pass `--force` to let its edits land alongside your WIP. Common false positive: if you recently upgraded Next.js, `package.json` and the lockfile will already be dirty — commit those first.
|
||||||
|
|
||||||
@@ -134,7 +126,17 @@ The codemod opts every segment out, not only the root, on purpose. Resolution is
|
|||||||
|
|
||||||
Because the highest opt-out wins, remove them top-down (root layout first, then descend). Removing a leaf's opt-out does nothing while an ancestor still holds one.
|
Because the highest opt-out wins, remove them top-down (root layout first, then descend). Removing a leaf's opt-out does nothing while an ancestor still holds one.
|
||||||
|
|
||||||
Confirm the pre-step with `next build`. The build is the proof, not the codemod run — a shared layout that calls `new Date()` / `Math.random()` directly still fails regardless of the opt-out (see [background](#background)).
|
Next, run `next build` to surface blockers the codemod could not handle. The build is the proof, not the codemod run — a shared layout that calls `new Date()` / `Math.random()` directly still fails regardless of the opt-out (see [background](#background)). If the normal build reports a sync-IO error without locating the call, rerun that route with `next build --debug-prerender --debug-build-paths="app/path/to/page.tsx"`. For each sync-IO error it reports:
|
||||||
|
|
||||||
|
1. **Sync-IO at module/render time.** Use the route, originating file and line, and `/docs/messages/` link in the build output to locate the error. If needed, grep the whole repo for `new Date()`, `Date.now()`, `Math.random()`, and `crypto.randomUUID()` (not only `app/**/layout.{js,jsx,ts,tsx}` — the read might live in any component imported by a layout). Do not change unreported matches. Unblock the reported call with the `await connection()` + `<Suspense>` fix from its `blocking-prerender-*` error card: it defers the value to request time, exactly as it behaved before the migration, so it needs no product decision. Add this exact comment on the line above the `await connection()`:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// TODO: Cache Components adoption. Added to unblock the build: remove this connection() to re-trigger the error and review the fix options.
|
||||||
|
```
|
||||||
|
|
||||||
|
It shares the `TODO: Cache Components adoption` prefix with the comments the codemod writes, so the check-in grep finds both. Removing the `await connection()` makes the error fire again with its fix cards — the same motion as removing an opt-out in the loop.
|
||||||
|
|
||||||
|
After each fix, rerun the scoped build when available, then run `next build` again to find the next blocker. Repeat until the normal build passes.
|
||||||
|
|
||||||
After the build passes, confirm the root layout got an opt-out (`grep -n "export const instant" <app dir>/layout.*`). The root layout renders every route, including framework routes like `/_not-found`, so if it was missed, add `export const instant = false` to it by hand.
|
After the build passes, confirm the root layout got an opt-out (`grep -n "export const instant" <app dir>/layout.*`). The root layout renders every route, including framework routes like `/_not-found`, so if it was missed, add `export const instant = false` to it by hand.
|
||||||
|
|
||||||
@@ -228,6 +230,6 @@ When the loop has run on every feature — every remaining `instant = false` sit
|
|||||||
The work below is optional and lives in the docs — link the user to them and let them decide which to take on next. Don't walk these through inside this skill.
|
The work below is optional and lives in the docs — link the user to them and let them decide which to take on next. Don't walk these through inside this skill.
|
||||||
|
|
||||||
- [Sweep for more instant navigations](./references/dev-only-validations.md) — an optional follow-up once adoption is done, never required. A passing build is not the last word, because dev validates every route on each page load (simulating both page loads and client navigations) and catches what the build's first-error exit and descendant shadowing skipped. Offer it as the smaller path to instant navigation for a user who doesn't want to adopt Partial Prefetching. Adopting Partial Prefetching (below) runs the same kind of loop and meets these insights anyway, so recommend both and let the user pick which, or whether. The reference is the loop to execute.
|
- [Sweep for more instant navigations](./references/dev-only-validations.md) — an optional follow-up once adoption is done, never required. A passing build is not the last word, because dev validates every route on each page load (simulating both page loads and client navigations) and catches what the build's first-error exit and descendant shadowing skipped. Offer it as the smaller path to instant navigation for a user who doesn't want to adopt Partial Prefetching. Adopting Partial Prefetching (below) runs the same kind of loop and meets these insights anyway, so recommend both and let the user pick which, or whether. The reference is the loop to execute.
|
||||||
- [`next-partial-prefetching-adoption`](https://github.com/vercel/next.js/tree/canary/skills/next-partial-prefetching-adoption) — the follow-up skill that adopts Partial Prefetching: it enables `partialPrefetching` and audits every `<Link prefetch={true}>` against a decision table (or adopts incrementally with the flag off, driven by the `link-prefetch-partial` insight). It sequences this the same way this skill sequences Cache Components, but the insights are dev-only, so it's a browser click-through, not a build loop. Recommended after instant navigation, since those fixes feed directly into how much of each route the shell can prefetch. Concepts live in the [Adopting Partial Prefetching guide](https://nextjs.org/docs/app/guides/adopting-partial-prefetching).
|
- [`next-partial-prefetching-adoption`](https://github.com/vercel/next.js/tree/canary/skills/next-partial-prefetching-adoption) — the follow-up skill that adopts Partial Prefetching: it enables `partialPrefetching` and audits every `<Link prefetch={true}>` against a decision table (or adopts incrementally with the flag off, driven by the `instant-link-prefetch-partial` insight). It sequences this the same way this skill sequences Cache Components, but the insights are dev-only, so it's a browser click-through, not a build loop. Recommended after instant navigation, since those fixes feed directly into how much of each route the shell can prefetch. Concepts live in the [Adopting Partial Prefetching guide](https://nextjs.org/docs/app/guides/adopting-partial-prefetching).
|
||||||
- [Prevent regressions with e2e tests](https://nextjs.org/docs/app/guides/instant-navigation#prevent-regressions-with-e2e-tests) — the `@next/playwright` [`instant()`](https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config/instant#testing-instant-navigation) helper asserts on the UI that's available immediately on navigation, so regressions surface in CI. Recommend it once a route is instant: `next-dev-loop` confirms it _now_; an `instant()` test keeps it that way.
|
- [Prevent regressions with e2e tests](https://nextjs.org/docs/app/guides/instant-navigation#prevent-regressions-with-e2e-tests) — the `@next/playwright` [`instant()`](https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config/instant#testing-instant-navigation) helper asserts on the UI that's available immediately on navigation, so regressions surface in CI. Recommend it once a route is instant: `next-dev-loop` confirms it _now_; an `instant()` test keeps it that way.
|
||||||
- [`next-cache-components-optimizer`](https://github.com/vercel/next.js/tree/canary/skills/next-cache-components-optimizer) — a separate skill that grows each route's static shell so more of the page prerenders and less streams in. Pure optimization, not part of adoption.
|
- [`next-cache-components-optimizer`](https://github.com/vercel/next.js/tree/canary/skills/next-cache-components-optimizer) — a separate skill that grows each route's static shell so more of the page prerenders and less streams in. Pure optimization, not part of adoption.
|
||||||
|
|||||||
+1
-1
@@ -76,7 +76,7 @@ The shell prerenders as if authorized (the session read suspends before `redirec
|
|||||||
|
|
||||||
## Initial-load shell vs soft-navigation shell
|
## Initial-load shell vs soft-navigation shell
|
||||||
|
|
||||||
The `test-template.md` specs drive a `<Link>` click for soft navigations and `page.goto()` for initial loads. The two shells can differ for the same route:
|
The `../test-template.md` specs drive a `<Link>` click for soft navigations and `page.goto()` for initial loads. The two shells can differ for the same route:
|
||||||
|
|
||||||
> **The initial-load shell can show less than the soft-navigation shell when a layout above the shared boundary awaits un-enumerated `params`/`searchParams`.** An initial load re-runs every layout from the root; if a parent layout does `await props.params` and that segment has no `generateStaticParams`, the param suspends on the initial load and its whole subtree drops out of the shell. A soft navigation does not re-render that parent and already has the params. Symptom: an element present after a `<Link>` click is missing after `goto`.
|
> **The initial-load shell can show less than the soft-navigation shell when a layout above the shared boundary awaits un-enumerated `params`/`searchParams`.** An initial load re-runs every layout from the root; if a parent layout does `await props.params` and that segment has no `generateStaticParams`, the param suspends on the initial load and its whole subtree drops out of the shell. A soft navigation does not re-render that parent and already has the params. Symptom: an element present after a `<Link>` click is missing after `goto`.
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -139,7 +139,7 @@ Two defenses; use both:
|
|||||||
(SKILL.md phases 0 and A). Do not trust a pass from a build where it is not set.
|
(SKILL.md phases 0 and A). Do not trust a pass from a build where it is not set.
|
||||||
2. **Make the test self-validating**: for any route with deferred content, also assert that the
|
2. **Make the test self-validating**: for any route with deferred content, also assert that the
|
||||||
deferred content is gated under the lock, not only that the shell is present
|
deferred content is gated under the lock, not only that the shell is present
|
||||||
(`test-template.md`, self-validating variant). If the lock did not engage, the content is
|
(`../test-template.md`, self-validating variant). If the lock did not engage, the content is
|
||||||
already present and `toHaveCount(0)` fails.
|
already present and `toHaveCount(0)` fails.
|
||||||
|
|
||||||
The gated half holds under the lock for both navigation types regardless of warm state: the
|
The gated half holds under the lock for both navigation types regardless of warm state: the
|
||||||
|
|||||||
@@ -176,8 +176,3 @@ Close the session with the same session and restore context:
|
|||||||
`agent-browser --session "$SESSION" --restore close`. `close` saves
|
`agent-browser --session "$SESSION" --restore close`. `close` saves
|
||||||
that session's cookies and storage so the next loop's `--restore` open
|
that session's cookies and storage so the next loop's `--restore` open
|
||||||
keeps the user logged in. Leave `next dev` up for the next loop.
|
keeps the user logged in. Leave `next dev` up for the next loop.
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
`next-dev-loop-<topic>` siblings (e.g. `next-dev-loop-rsc`, `next-dev-loop-debug`)
|
|
||||||
assume this preflight already ran; they pick up at the loop.
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ description: >
|
|||||||
Partial Prefetching, flip the `partialPrefetching` flag, opt routes
|
Partial Prefetching, flip the `partialPrefetching` flag, opt routes
|
||||||
in with `export const prefetch = 'partial'`, audit
|
in with `export const prefetch = 'partial'`, audit
|
||||||
`<Link prefetch={true}>` calls, or resolve the
|
`<Link prefetch={true}>` calls, or resolve the
|
||||||
link-prefetch-partial and instant-shell-url-data insights.
|
instant-link-prefetch-partial and instant-shell-url-data insights.
|
||||||
---
|
---
|
||||||
|
|
||||||
# next-partial-prefetching-adoption
|
# next-partial-prefetching-adoption
|
||||||
@@ -23,7 +23,7 @@ Talk to the user in terms of what they'll see — PRs, features, and how the app
|
|||||||
|
|
||||||
- **Next.js 16.3 or later.** `partialPrefetching`, the `prefetch` route segment config, and the prefetch insights all land there.
|
- **Next.js 16.3 or later.** `partialPrefetching`, the `prefetch` route segment config, and the prefetch insights all land there.
|
||||||
|
|
||||||
- **A browser you can drive.** Install [`next-dev-loop`](https://github.com/vercel/next.js/tree/canary/skills/next-dev-loop) before starting (`npx skills add https://github.com/vercel/next.js/tree/canary/skills/next-dev-loop`). Install it without asking — it's a tool, not a product change — and don't assume it's blocked: verify a real blocker (no network, no npm, read-only filesystem) before falling back, and name it in your report. Link prefetches fire when a link renders and enters the viewport, and shell validation fires on navigation — neither is reachable from `curl` or the build. If the app is webpack-pinned, drive a browser directly (`agent-browser`, Playwright) — you lose the framework cross-checks, not the insights; they're still in the overlay and the dev log.
|
- **A browser you can drive.** Install [`next-dev-loop`](https://github.com/vercel/next.js/tree/canary/skills/next-dev-loop) before starting, unless it is already available — it ships alongside this skill (`npx skills add https://github.com/vercel/next.js/tree/canary/skills/next-dev-loop`). Install it without asking — it's a tool, not a product change — and don't assume it's blocked: verify a real blocker (no network, no npm, read-only filesystem) before falling back, and name it in your report. Link prefetches fire when a link renders and enters the viewport, and shell validation fires on navigation — neither is reachable from `curl` or the build. If the app is webpack-pinned, drive a browser directly (`agent-browser`, Playwright) — you lose the framework cross-checks, not the insights; they're still in the overlay and the dev log.
|
||||||
|
|
||||||
- **A runnable app.** Verification runs against `next dev` for the insight sweep and a production `next build`/`next start` for prefetching (prefetching is prod-only), so the app has to boot in both. If it reads a database or required env at import (e.g. an `env.ts` that throws on a missing `DATABASE_URL`), confirm it starts — with the real environment, or local data you stand up — before step 1. An app that won't run can't be swept or verified.
|
- **A runnable app.** Verification runs against `next dev` for the insight sweep and a production `next build`/`next start` for prefetching (prefetching is prod-only), so the app has to boot in both. If it reads a database or required env at import (e.g. an `env.ts` that throws on a missing `DATABASE_URL`), confirm it starts — with the real environment, or local data you stand up — before step 1. An app that won't run can't be swept or verified.
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ Every insight has a docs page — open it. Fetch the linked page for every disti
|
|||||||
|
|
||||||
## step 1: audit `<Link prefetch={true}>` (before enabling)
|
## step 1: audit `<Link prefetch={true}>` (before enabling)
|
||||||
|
|
||||||
If `partialPrefetching: true` is already set in `next.config.ts`, the app is adopted — skip to [step 3](#step-3-sweep-for-url-data-insights-after-enabling). Otherwise work the audit with the global flag **off**, adopting each destination with `export const prefetch = 'partial'` — enabling the flag first would mark every route adopted and silence the [`link-prefetch-partial`](https://nextjs.org/docs/messages/instant-link-prefetch-partial) insight this audit runs on. Ask the user how to ship it, in the language of PRs:
|
If `partialPrefetching: true` is already set in `next.config.ts`, the app is adopted — skip to [step 3](#step-3-sweep-for-url-data-insights-after-enabling). Otherwise work the audit with the global flag **off**, adopting each destination with `export const prefetch = 'partial'` — enabling the flag first would mark every route adopted and silence the [`instant-link-prefetch-partial`](https://nextjs.org/docs/messages/instant-link-prefetch-partial) insight this audit runs on. Ask the user how to ship it, in the language of PRs:
|
||||||
|
|
||||||
- **One branch** — the whole audit in one change, with the flag enabled and the codemod run at the end (step 2).
|
- **One branch** — the whole audit in one change, with the flag enabled and the codemod run at the end (step 2).
|
||||||
- **Route by route** — each adopted destination ships as its own PR. The insight still fires for the destinations you haven't reached, a live worklist, and step 2 comes after the last one.
|
- **Route by route** — each adopted destination ships as its own PR. The insight still fires for the destinations you haven't reached, a live worklist, and step 2 comes after the last one.
|
||||||
@@ -60,7 +60,7 @@ Enumerate the prefetch sites across the whole source tree, not only `app/` — t
|
|||||||
|
|
||||||
Then, for each one:
|
Then, for each one:
|
||||||
|
|
||||||
1. **Click each `<Link>` in `next dev`.** The insight fires at navigation time, not when the link prefetches, so a link sitting in the viewport won't trip it — you have to navigate through it. This click is _verification_: it confirms the insight fires before you adopt and clears after. Imperative `router.prefetch()` sites have no equivalent insight, so audit them from source and verify them in production ([step 4](#step-4-verify)). Without a browser, skip the click and adopt from [`link-prefetch-partial`](https://nextjs.org/docs/messages/instant-link-prefetch-partial) and the audit table below — the destination's structure tells you the row, and type-check gates the edit — then leave the live confirmation for the hand-off.
|
1. **Click each `<Link>` in `next dev`.** The insight fires at navigation time, not when the link prefetches, so a link sitting in the viewport won't trip it — you have to navigate through it. This click is _verification_: it confirms the insight fires before you adopt and clears after. Imperative `router.prefetch()` sites have no equivalent insight, so audit them from source and verify them in production ([step 4](#step-4-verify)). Without a browser, skip the click and adopt from [`instant-link-prefetch-partial`](https://nextjs.org/docs/messages/instant-link-prefetch-partial) and the audit table below — the destination's structure tells you the row, and type-check gates the edit — then leave the live confirmation for the hand-off.
|
||||||
2. **Adopt the destination.** Add the temporary route config with a link to the migration guide. That clears the insight for every link pointing at it:
|
2. **Adopt the destination.** Add the temporary route config with a link to the migration guide. That clears the insight for every link pointing at it:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
"sourceId": "ppt-master",
|
"sourceId": "ppt-master",
|
||||||
"repo": "https://github.com/hugohe3/ppt-master.git",
|
"repo": "https://github.com/hugohe3/ppt-master.git",
|
||||||
"ref": "main",
|
"ref": "main",
|
||||||
"commit": "a160e776b7faff5d2227d180d0f31c6253056fae",
|
"commit": "fe9ae086ab33d5a384f691ffd432aeb04ba0f96f",
|
||||||
"adapter": "claude-skill",
|
"adapter": "claude-skill",
|
||||||
"sourcePath": "skills/ppt-master",
|
"sourcePath": "skills/ppt-master",
|
||||||
"syncedAt": "2026-08-19T16:00:01Z"
|
"syncedAt": "2026-08-20T16:00:00Z"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ Before drawing each page, look up its entry in `page_rhythm` (key format `P<NN>`
|
|||||||
|
|
||||||
## 3. Execution Guidelines
|
## 3. Execution Guidelines
|
||||||
|
|
||||||
- **Element grouping (Mandatory)**: wrap each logical Slide-local body unit in a descriptive, page-unique top-level `<g id>`. Every visible direct root `<g>` declares root-coordinate `data-pptx-bounds="x y width height"`; frame/native coordinates do not replace it, and placeholder bounds also supply the slot frame. Nested groups need no bounds and any such values are ignored. Checker compares root bounds with the `viewBox`, recursively checks estimable text against its root module with DrawingML wrapping headroom, and independently checks every estimable visible text carrier against the page without that headroom: through `1px` is ignored; module overflow warns through `5%` and fails above it, while larger page overflow always fails. Unestimable visible text receives an advisory warning. Only a wholly off-canvas direct-root Morph endpoint may set `data-pptx-morph-staging="true"`; keep its text inside its own module bounds, use an explicit pair when Morph remains enabled, and never use the marker for partial overflow. Images, shapes, paths, `<use>`, effects, and object frames remain geometrically free. Flat pages use ordinary groups; structured slots already qualify, while titles, direct Master/Layout atoms, and canvas-level static framing may remain root primitives. On flat pages, give a root background image or full-canvas scrim/decoration rectangle a stable `id` plus `data-pptx-role="background"` / `"decoration"`; never wrap it only to silence the advisory.
|
- **Element grouping (Mandatory)**: wrap each logical Slide-local body unit in a descriptive, page-unique top-level `<g id>`. Every visible direct root `<g>` except a compact helper-authored preset atom declares root-coordinate `data-pptx-bounds="x y width height"`; that text-free atom stays top-level when standalone, uses `data-pptx-frame`, and never carries bounds. Frame/native coordinates do not replace bounds on any other group, and placeholder bounds also supply the slot frame. Nested groups need no bounds and any such values are ignored. Checker compares root bounds with the `viewBox`, recursively checks estimable text against its root module with DrawingML wrapping headroom, and independently checks every estimable visible text carrier against the page without that headroom: through `1px` is ignored; module overflow warns through `5%` and fails above it, while larger page overflow always fails. Unestimable visible text receives an advisory warning. Only a wholly off-canvas direct-root Morph endpoint may set `data-pptx-morph-staging="true"`; keep its text inside its own module bounds, use an explicit pair when Morph remains enabled, and never use the marker for partial overflow. Images, shapes, paths, `<use>`, effects, and object frames remain geometrically free. Flat pages use ordinary groups; structured slots already qualify, while titles, direct Master/Layout atoms, and canvas-level static framing may remain root primitives. On flat pages, give a root background image or full-canvas scrim/decoration rectangle a stable `id` plus `data-pptx-role="background"` / `"decoration"`; never wrap it only to silence the advisory.
|
||||||
- **Reference — not a constraint**: top-level groups set semantic and automatic-animation granularity, but they may contain descriptive nested `<g>` edit groups when the page has meaningful internal subunits. Nested groups need no bounds and create no automatic animation step; use or omit them from the page's actual editing semantics, with no default pattern, depth, or quota.
|
- **Reference — not a constraint**: top-level groups set semantic and automatic-animation granularity, but they may contain descriptive nested `<g>` edit groups when the page has meaningful internal subunits. Nested groups need no bounds and create no automatic animation step; use or omit them from the page's actual editing semantics, with no default pattern, depth, or quota.
|
||||||
- **Default — size `data-pptx-bounds` as the intended module zone, not a glyph box (may skip when no text is estimable)**: make the zone as generous as the canvas and sibling layout allow, without overlapping another module zone. An untransformed line spans `y - 0.85 × font_size` to `y + 0.35 × font_size`; width uses the shared SVG-to-PPTX per-run estimate and safety headroom. If text does not fit, first expand a zone that has unused non-overlapping space; otherwise reflow or adapt. Larger bounds do not repair off-canvas text.
|
- **Default — size `data-pptx-bounds` as the intended module zone, not a glyph box (may skip when no text is estimable)**: make the zone as generous as the canvas and sibling layout allow, without overlapping another module zone. An untransformed line spans `y - 0.85 × font_size` to `y + 0.35 × font_size`; width uses the shared SVG-to-PPTX per-run estimate and safety headroom. If text does not fit, first expand a zone that has unused non-overlapping space; otherwise reflow or adapt. Larger bounds do not repair off-canvas text.
|
||||||
- **Spec adherence**: follow binding color, canvas, typography, identity, resource, and template anchors; apply layout and other Reference directions under §2.1 without turning them into locks
|
- **Spec adherence**: follow binding color, canvas, typography, identity, resource, and template anchors; apply layout and other Reference directions under §2.1 without turning them into locks
|
||||||
@@ -179,7 +179,8 @@ Before drawing each page, look up its entry in `page_rhythm` (key format `P<NN>`
|
|||||||
factual `[CARRIERS]` summary and stores per-page detail under
|
factual `[CARRIERS]` summary and stores per-page detail under
|
||||||
`files[].info.carrier_receipt`. Compare the summary with the retained page jobs,
|
`files[].info.carrier_receipt`. Compare the summary with the retained page jobs,
|
||||||
chosen resource roles, and running geometry signatures before export. Counts
|
chosen resource roles, and running geometry signatures before export. Counts
|
||||||
and diversity never create a quota or prove quality; zero use remains valid.
|
and diversity never create a quota or prove quality; zero preset use alone
|
||||||
|
neither proves fit nor establishes a defect.
|
||||||
When the facts contradict an active decision—such as an adopted preset absent
|
When the facts contradict an active decision—such as an adopted preset absent
|
||||||
from output, a primary image reduced to a minor frame, or unrelated jobs
|
from output, a primary image reduced to a minor frame, or unrelated jobs
|
||||||
collapsing to one neutral construction—read only the affected receipt rows,
|
collapsing to one neutral construction—read only the affected receipt rows,
|
||||||
|
|||||||
+4
-4
@@ -280,11 +280,11 @@ the locked preset registry.
|
|||||||
| Deliberately absent transport fields | No hidden carrier, preview wrapper, `data-pptx-part`, or stored fingerprint belongs in project-authored SVG. Those fields remain part of expanded PPTX import/round-trip transport. |
|
| Deliberately absent transport fields | No hidden carrier, preview wrapper, `data-pptx-part`, or stored fingerprint belongs in project-authored SVG. Those fields remain part of expanded PPTX import/round-trip transport. |
|
||||||
|
|
||||||
**Hard rule**: treat the returned group as atomic. Keep it as the content group
|
**Hard rule**: treat the returned group as atomic. Keep it as the content group
|
||||||
when it stands alone. When it needs labels, icons, or other decorations, put
|
without `data-pptx-bounds` when it stands alone; `data-pptx-frame` owns its
|
||||||
the preset and those siblings in a separate parent content group; never put
|
object geometry. When it needs labels, icons, or other decorations, put the
|
||||||
|
preset and those siblings in a separate bounded parent content group; never put
|
||||||
them inside the preset group itself. Do not edit the direct paths; they are
|
them inside the preset group itself. Do not edit the direct paths; they are
|
||||||
validation evidence generated from the registry, not a freehand contour
|
validation evidence generated from the registry, not a freehand contour surface.
|
||||||
surface.
|
|
||||||
|
|
||||||
Canonical page/template authoring also keeps paint and opacity off ancestor
|
Canonical page/template authoring also keeps paint and opacity off ancestor
|
||||||
groups that contain the preset. Compatible ancestor paint still exports under
|
groups that contain the preset. Compatible ancestor paint still exports under
|
||||||
|
|||||||
+5
-4
@@ -626,7 +626,7 @@ These forms are needed only when the stated PPT behavior matters:
|
|||||||
|
|
||||||
### 4.3 Element Grouping (Mandatory)
|
### 4.3 Element Grouping (Mandatory)
|
||||||
|
|
||||||
**Hard rule — root groups protect body-text layout**: Every visible direct root `<g>` declares positive root-coordinate `data-pptx-bounds="x y width height"`. Keep it when frame/native coordinates size one PowerPoint object; placeholder bounds also supply the slot frame. On flat pages, make each module zone as generous as the canvas and sibling layout allow without overlapping another module zone. Checker validates this subcanvas against the root `viewBox`, then recursively validates only estimable `<text>` descendants against it using the shared SVG-to-PPTX per-run width estimate, inline-formula native-height envelope, and DrawingML wrapping headroom. It validates every estimable visible text carrier directly against the root `viewBox` with the same per-run estimate before that headroom. Nested groups and all shapes, images, paths, `<use>` instances, effects, and object frames are not module-boundary inputs. Per side, Checker ignores overflow through `1px`; module-boundary overflow warns through `5%` and fails above `5%`, while any larger root-`viewBox` text overflow fails. Bounds do not clip or reflow; unestimable visible text receives an advisory warning. The only page-boundary exception is a wholly off-canvas direct-root Morph endpoint marked `data-pptx-morph-staging="true"`; its own module bounds still apply, retained Morph uses an explicit pair, and the marker never excuses partial page overflow.
|
**Hard rule — root groups protect body-text layout**: Every visible direct root `<g>` except a compact helper-authored preset atom declares positive root-coordinate `data-pptx-bounds="x y width height"`. That text-free atom stays top-level when standalone, uses `data-pptx-frame`, and never carries bounds. Frame/native coordinates do not replace bounds on any other group; placeholder bounds also supply the slot frame. On flat pages, make each module zone as generous as the canvas and sibling layout allow without overlapping another module zone. Checker validates this subcanvas against the root `viewBox`, then recursively validates only estimable `<text>` descendants against it using the shared SVG-to-PPTX per-run width estimate, inline-formula native-height envelope, and DrawingML wrapping headroom. It validates every estimable visible text carrier directly against the root `viewBox` with the same per-run estimate before that headroom. Nested groups and all shapes, images, paths, `<use>` instances, effects, and object frames are not module-boundary inputs. Per side, Checker ignores overflow through `1px`; module-boundary overflow warns through `5%` and fails above `5%`, while any larger root-`viewBox` text overflow fails. Bounds do not clip or reflow; unestimable visible text receives an advisory warning. The only page-boundary exception is a wholly off-canvas direct-root Morph endpoint marked `data-pptx-morph-staging="true"`; its own module bounds still apply, retained Morph uses an explicit pair, and the marker never excuses partial page overflow.
|
||||||
|
|
||||||
Wrap each logical Slide-local body unit in one descriptive top-level `<g id>`; group count follows the page's semantic units, and each group becomes one stable animation target when animation is enabled. Generic deck-wide animation gives that target one step; an explicit animation sidecar may assign it several ordered effects. Nested implementation groups may remain anonymous and need no bounds; any nested bounds are ignored. Flat pages use ordinary groups; structured slots already qualify, while titles, direct atomic Master/Layout elements, and canvas-level static framing—including background images and full-canvas scrim/decoration rectangles—may remain root primitives. On flat pages, give such static framing a stable `id` plus `data-pptx-role="background"` / `"decoration"`; never add a `<g>` solely to silence an ungrouped-element advisory.
|
Wrap each logical Slide-local body unit in one descriptive top-level `<g id>`; group count follows the page's semantic units, and each group becomes one stable animation target when animation is enabled. Generic deck-wide animation gives that target one step; an explicit animation sidecar may assign it several ordered effects. Nested implementation groups may remain anonymous and need no bounds; any nested bounds are ignored. Flat pages use ordinary groups; structured slots already qualify, while titles, direct atomic Master/Layout elements, and canvas-level static framing—including background images and full-canvas scrim/decoration rectangles—may remain root primitives. On flat pages, give such static framing a stable `id` plus `data-pptx-role="background"` / `"decoration"`; never add a `<g>` solely to silence an ungrouped-element advisory.
|
||||||
|
|
||||||
@@ -653,9 +653,10 @@ nesting pattern, level, or quota.
|
|||||||
| Decorative cluster | Related decorative shapes (rings, dots, orbs) |
|
| Decorative cluster | Related decorative shapes (rings, dots, orbs) |
|
||||||
|
|
||||||
An authored native preset fragment (§1.5) is already an atomic `<g id>` and
|
An authored native preset fragment (§1.5) is already an atomic `<g id>` and
|
||||||
counts as one content group. Keep it top-level when it stands alone. When it
|
counts as one content group. Keep it top-level without `data-pptx-bounds` when
|
||||||
needs a label or decoration, place the preset and those siblings inside a
|
it stands alone. When it needs a label or decoration, place the preset and those
|
||||||
separate parent content group; never put them inside the preset group itself.
|
siblings inside a separate bounded parent content group; never put them inside
|
||||||
|
the preset group itself.
|
||||||
|
|
||||||
**Forbidden**:
|
**Forbidden**:
|
||||||
|
|
||||||
|
|||||||
@@ -89,6 +89,14 @@ communication job changes.
|
|||||||
| Typography character | The role editable type plays inside the composition, independent of exact font choice |
|
| Typography character | The role editable type plays inside the composition, independent of exact font choice |
|
||||||
| Delivery and afterlife | Viewing distance, projection/print behavior, reuse, and expected editing |
|
| Delivery and afterlife | Viewing distance, projection/print behavior, reuse, and expected editing |
|
||||||
|
|
||||||
|
**Default — derive shape language from project fit (may override when a generic
|
||||||
|
primitive system is itself the clearest identity or communication choice)**:
|
||||||
|
Before settling on lines, rectangles, circles, or ellipses as the deck's main
|
||||||
|
shape language, test whether the source material, identity, or communication
|
||||||
|
job offers a more specific edge, corner, opening, angle, contour, or layering
|
||||||
|
logic. Retain a primitive-led result when it deliberately fits; do not select
|
||||||
|
an exact authoring preset here.
|
||||||
|
|
||||||
> When the deck has AI images, the "Paired rendering" column exposes an
|
> When the deck has AI images, the "Paired rendering" column exposes an
|
||||||
> aesthetically related option. It does not select the rendering or create an
|
> aesthetically related option. It does not select the rendering or create an
|
||||||
> AI image job; compare it with the actual image roles before using it.
|
> AI image job; compare it with the actual image roles before using it.
|
||||||
|
|||||||
@@ -639,8 +639,8 @@ Behavior:
|
|||||||
- Native mode is strict about unsupported visual SVG elements: if a visual element cannot be represented or safely preserved, export fails with the SVG file, element tag, and position instead of silently dropping content.
|
- Native mode is strict about unsupported visual SVG elements: if a visual element cannot be represented or safely preserved, export fails with the SVG file, element tag, and position instead of silently dropping content.
|
||||||
- Omitting `--pptx-structure` reads `spec_lock.md`. Free-design, brand-only, and `template_reuse_scope: style` releases declare `mode: flat`, omit Master/Layout mappings and SVG structure metadata, and materialize one clean project-owned Master plus one Blank Layout from the current lock. Deck/layout templates use `mode: structured` only for `template_reuse_scope: mirror|layout`, with complete unique `pptx_masters` / `pptx_layouts` rosters and one `page_pptx_layouts` assignment per page. A template-backed Layout definition may remain unused by pages and still register in the final package.
|
- Omitting `--pptx-structure` reads `spec_lock.md`. Free-design, brand-only, and `template_reuse_scope: style` releases declare `mode: flat`, omit Master/Layout mappings and SVG structure metadata, and materialize one clean project-owned Master plus one Blank Layout from the current lock. Deck/layout templates use `mode: structured` only for `template_reuse_scope: mirror|layout`, with complete unique `pptx_masters` / `pptx_layouts` rosters and one `page_pptx_layouts` assignment per page. A template-backed Layout definition may remain unused by pages and still register in the final package.
|
||||||
- On structured template routes, every page root repeats Master/Layout keys and picker names. Master/Layout fixed visuals are direct semantic atoms. Ordinary layer `<g>` elements are invalid; one validated compact authored-preset `<g>` emitted by `preset_shape_svg.py` is the sole group exception because it compiles to one native shape.
|
- On structured template routes, every page root repeats Master/Layout keys and picker names. Master/Layout fixed visuals are direct semantic atoms. Ordinary layer `<g>` elements are invalid; one validated compact authored-preset `<g>` emitted by `preset_shape_svg.py` is the sole group exception because it compiles to one native shape.
|
||||||
- Every visible direct root `<g>` requires root-coordinate `data-pptx-bounds`; nested bounds are ignored. Frame/native metadata never replaces it; placeholder bounds also define the slot frame. Checker compares root bounds with `viewBox`, descendant text with its module using DrawingML wrapping headroom, and every estimable visible text carrier directly with the root `viewBox` before that headroom. Images, shapes, paths, `<use>`, effects, and object frames are excluded from module containment. Per side, ≤`1px` is ignored; module overflow ≤`5%` warns and >`5%` fails, while larger page text overflow always fails. Bounds never clip/reflow; unestimable visible text warns. A wholly off-canvas direct-root Morph endpoint may opt out of page containment with `data-pptx-morph-staging="true"`; it still needs valid module bounds, retained Morph uses an explicit pair, and partial overflow remains blocking.
|
- Every visible direct root `<g>` except a compact helper-authored preset atom requires root-coordinate `data-pptx-bounds`; nested bounds are ignored. The text-free preset atom remains top-level when standalone, uses `data-pptx-frame`, and never carries bounds. Frame/native metadata never replaces bounds on any other group; placeholder bounds also define the slot frame. Checker compares root bounds with `viewBox`, descendant text with its module using DrawingML wrapping headroom, and every estimable visible text carrier directly with the root `viewBox` before that headroom. Images, shapes, paths, `<use>`, effects, and object frames are excluded from module containment. Per side, ≤`1px` is ignored; module overflow ≤`5%` warns and >`5%` fails, while larger page text overflow always fails. Bounds never clip/reflow; unestimable visible text warns. A wholly off-canvas direct-root Morph endpoint may opt out of page containment with `data-pptx-morph-staging="true"`; it still needs valid module bounds, retained Morph uses an explicit pair, and partial overflow remains blocking.
|
||||||
- Missing root bounds fails on final pages/templates and under `--template-mode`; references warn until adapted.
|
- Missing required root bounds fails on final pages/templates and under `--template-mode`; references warn until adapted.
|
||||||
- On structured template routes, each normal slot is a direct root `<g id>` with semantic type, positive design-zone bounds, and exactly one compatible carrier. Composite `object` slots use explicit proxy binding; zero-slot Layouts are valid. Flat pages keep all SVG objects Slide-local.
|
- On structured template routes, each normal slot is a direct root `<g id>` with semantic type, positive design-zone bounds, and exactly one compatible carrier. Composite `object` slots use explicit proxy binding; zero-slot Layouts are valid. Flat pages keep all SVG objects Slide-local.
|
||||||
- Flat export maps locked typography/colors into a clean project-owned theme/Master, removes stock content placeholders and unused built-in Layouts, retains only the standard date/footer/slide-number capability hooks, and keeps one Blank Layout without promoting Slide content. Structured export additionally creates one reusable Layout per declared key and reopens the package to verify the full Presentation → Master → Layout → Slide graph, fixed-object order, placeholder identities/bounds, carrier bindings, hidden proxies, and zero-slot Layouts.
|
- Flat export maps locked typography/colors into a clean project-owned theme/Master, removes stock content placeholders and unused built-in Layouts, retains only the standard date/footer/slide-number capability hooks, and keeps one Blank Layout without promoting Slide content. Structured export additionally creates one reusable Layout per declared key and reopens the package to verify the full Presentation → Master → Layout → Slide graph, fixed-object order, placeholder identities/bounds, carrier bindings, hidden proxies, and zero-slot Layouts.
|
||||||
- Template `page_layouts` remains input provenance. Strict preserves the prototype contract; adaptive retains its Master and may use a new Layout identity only when Strategist declared it in the plan and lock. Construction cannot allocate or mutate Layout identity downstream.
|
- Template `page_layouts` remains input provenance. Strict preserves the prototype contract; adaptive retains its Master and may use a new Layout identity only when Strategist declared it in the plan and lock. Construction cannot allocate or mutate Layout identity downstream.
|
||||||
|
|||||||
@@ -2679,7 +2679,7 @@ class SVGQualityChecker:
|
|||||||
root: ET.Element,
|
root: ET.Element,
|
||||||
result: Dict,
|
result: Dict,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Validate direct root module boundaries in the SVG canvas."""
|
"""Validate ordinary direct-root module boundaries in the SVG canvas."""
|
||||||
parent_by_id = {
|
parent_by_id = {
|
||||||
id(child): parent
|
id(child): parent
|
||||||
for parent in root.iter()
|
for parent in root.iter()
|
||||||
@@ -2783,6 +2783,11 @@ class SVGQualityChecker:
|
|||||||
for group in root_groups:
|
for group in root_groups:
|
||||||
if self._is_hidden_element(group, parent_by_id):
|
if self._is_hidden_element(group, parent_by_id):
|
||||||
continue
|
continue
|
||||||
|
if (
|
||||||
|
_authored_preset_encoding is not None
|
||||||
|
and _authored_preset_encoding(group) == 'compact'
|
||||||
|
):
|
||||||
|
continue
|
||||||
raw_bounds = group.get(_BOUNDS_ATTR)
|
raw_bounds = group.get(_BOUNDS_ATTR)
|
||||||
if raw_bounds is None:
|
if raw_bounds is None:
|
||||||
missing.append(_element_label(group))
|
missing.append(_element_label(group))
|
||||||
@@ -2820,9 +2825,9 @@ class SVGQualityChecker:
|
|||||||
bucket.append(
|
bucket.append(
|
||||||
f'{prefix} {len(missing)} visible root-level <g> '
|
f'{prefix} {len(missing)} visible root-level <g> '
|
||||||
f'module(s) without explicit {_BOUNDS_ATTR} '
|
f'module(s) without explicit {_BOUNDS_ATTR} '
|
||||||
f'({sample}{suffix}); every final-page/template root <g> declares '
|
f'({sample}{suffix}); every final-page/template root <g> other '
|
||||||
'its root-coordinate layout subcanvas even when it also carries '
|
'than a compact authored-preset atom declares its root-coordinate '
|
||||||
'data-pptx-frame or native chart/table coordinates'
|
'layout subcanvas even when it also carries native coordinates'
|
||||||
)
|
)
|
||||||
|
|
||||||
def _check_text_bounds(
|
def _check_text_bounds(
|
||||||
|
|||||||
+19
-11
@@ -288,9 +288,16 @@ the roster after the whole-roster check:
|
|||||||
- an ordinary body-content frame and a density judgment for every page, adapted to the canvas and any user / template / style geometry; use `anchor`, `dense`, `breathing`, or an equivalent active-context distinction instead of one uniform fill level;
|
- an ordinary body-content frame and a density judgment for every page, adapted to the canvas and any user / template / style geometry; use `anchor`, `dense`, `breathing`, or an equivalent active-context distinction instead of one uniform fill level;
|
||||||
- for each page not bound to literal supplied geometry, a primary visual zone and one compact page-scale geometry job tied to its core message—what geometry must organize, without naming a preset or encoding form; keep it only in the transient roster for §3's authoring-time move;
|
- for each page not bound to literal supplied geometry, a primary visual zone and one compact page-scale geometry job tied to its core message—what geometry must organize, without naming a preset or encoding form; keep it only in the transient roster for §3's authoring-time move;
|
||||||
- for each page, preserve its semantic units, source-stated qualitative relationships, intended entry, and outcome so §3 can make the sole Structure decision before geometry;
|
- for each page, preserve its semantic units, source-stated qualitative relationships, intended entry, and outcome so §3 can make the sole Structure decision before geometry;
|
||||||
- when useful, a transient deck-level visual motif system with an identity or
|
- the resolved visual direction's deck-level shape language under
|
||||||
|
[`visual-styles/_index.md`](../../references/visual-styles/_index.md) §2,
|
||||||
|
retained for page-fit native geometry without selecting an exact preset here;
|
||||||
|
- when useful, an additional transient deck-level visual motif system with an identity or
|
||||||
communication job, a recognizable invariant, and a reuse mode: fixed chrome,
|
communication job, a recognizable invariant, and a reuse mode: fixed chrome,
|
||||||
adaptive variation, or both; omit it when restraint serves the deck better;
|
adaptive variation, or both; treat restraint as control of visual weight,
|
||||||
|
recurrence, and reuse, not as a reason by itself to omit an evidenced source,
|
||||||
|
identity, or communication motif; omit the system when no motif earns a
|
||||||
|
continuity job or when reuse would add false meaning, compete with the page
|
||||||
|
message, or reduce clarity;
|
||||||
- the resource decisions needed for immediate preparation. Required operational
|
- the resource decisions needed for immediate preparation. Required operational
|
||||||
image manifests may carry filenames, page relationship, status, and
|
image manifests may carry filenames, page relationship, status, and
|
||||||
generation/crop/focal cues. When page use depends on stable composition, also
|
generation/crop/focal cues. When page use depends on stable composition, also
|
||||||
@@ -572,9 +579,9 @@ capability menu, visualization recall, template geometry, or a later check.
|
|||||||
**Mandatory — independent per-page geometry move**: after the Structure result
|
**Mandatory — independent per-page geometry move**: after the Structure result
|
||||||
and any applicable topology resolve, apply
|
and any applicable topology resolve, apply
|
||||||
[`native-shape-authoring.md`](../../references/native-shape-authoring.md) §2.1
|
[`native-shape-authoring.md`](../../references/native-shape-authoring.md) §2.1
|
||||||
to the transient geometry job, actual content, resolved style, and complete
|
to the transient geometry job, actual content, retained deck shape language,
|
||||||
loaded native vocabulary before writing coordinates. Select through direct
|
resolved style, and complete loaded native vocabulary before writing
|
||||||
semantic comparison; use `describe --compact` only when objective geometry
|
coordinates. Select through direct semantic comparison; use `describe --compact` only when objective geometry
|
||||||
facts could change a serious candidate decision. This move owns the exact-fit
|
facts could change a serious candidate decision. This move owns the exact-fit
|
||||||
geometry gate, independent relationship / carrier fit,
|
geometry gate, independent relationship / carrier fit,
|
||||||
contour-family / exact-result choice, reader effect for a generic or undrawn
|
contour-family / exact-result choice, reader effect for a generic or undrawn
|
||||||
@@ -677,11 +684,12 @@ python3 ${SKILL_DIR}/scripts/svg_quality_checker.py <project_path> \
|
|||||||
Fix every blocking error and rerun the same command.
|
Fix every blocking error and rerun the same command.
|
||||||
|
|
||||||
**Mandatory — final carrier-receipt review**: Review the factual
|
**Mandatory — final carrier-receipt review**: Review the factual
|
||||||
`[CARRIERS]` summary against the retained page jobs, resource roles, and running
|
`[CARRIERS]` summary against the retained page jobs, deck shape language, any
|
||||||
geometry signatures before export. Counts and diversity are not quotas, and
|
adopted motif, resource roles, and running geometry signatures before export.
|
||||||
zero use is valid. When the summary contradicts an active decision, read only
|
Counts and diversity are not quotas; zero preset use alone neither proves fit
|
||||||
the affected `files[].info.carrier_receipt` rows from the current report, repair
|
nor establishes a defect. When the summary contradicts an active decision, read
|
||||||
those pages in one consolidated pass, and rerun the same final checker.
|
only the affected `files[].info.carrier_receipt` rows from the current report,
|
||||||
|
repair those pages in one consolidated pass, and rerun the same final checker.
|
||||||
|
|
||||||
Then export:
|
Then export:
|
||||||
|
|
||||||
@@ -752,7 +760,7 @@ or lock.
|
|||||||
- [x] The complete 187-name native preset vocabulary was read before P01; each page chose from that full capability surface, with objective candidate details inspected only when needed
|
- [x] The complete 187-name native preset vocabulary was read before P01; each page chose from that full capability surface, with objective candidate details inspected only when needed
|
||||||
- [x] Every page considered suitable carrier combinations without a coverage quota or single-carrier assumption
|
- [x] Every page considered suitable carrier combinations without a coverage quota or single-carrier assumption
|
||||||
- [x] The proactive decorative-lettering capability scan ran before carrier selection; every selected lettering job entered an AI item or lettering sheet/slice job, and zero selected jobs remained valid
|
- [x] The proactive decorative-lettering capability scan ran before carrier selection; every selected lettering job entered an AI item or lettering sheet/slice job, and zero selected jobs remained valid
|
||||||
- [x] Every page not bound to literal supplied geometry carried its geometry job into authoring, resolved each drawn contour from its exact family and job, retained the reader effect for any generic or undrawn result, and compared its actual geometry signature before the next page; repetition served the same page job / relationship or continuity motif
|
- [x] The deck shape language remained active independently of any optional motif; every page not bound to literal supplied geometry carried its geometry job into authoring, resolved each drawn contour from its exact family and job, retained the reader effect for any generic or undrawn result, and compared its actual geometry signature before the next page; repetition served the same page job / relationship or continuity motif
|
||||||
- [x] Image need was decided independently of credentials; any zero-image deck followed a complete roster review in which no image job improved communication or the selected non-image carriers fully carried it
|
- [x] Image need was decided independently of credentials; any zero-image deck followed a complete roster review in which no image job improved communication or the selected non-image carriers fully carried it
|
||||||
- [x] Every `slice_names` output exists after an exit-0 strict-alpha run, and no page whose chosen composition depends on a slice was authored or exported without it
|
- [x] Every `slice_names` output exists after an exit-0 strict-alpha run, and no page whose chosen composition depends on a slice was authored or exported without it
|
||||||
- [x] Every image-bearing page made its one pre-geometry composition decision
|
- [x] Every image-bearing page made its one pre-geometry composition decision
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
"sourceId": "shadcn",
|
"sourceId": "shadcn",
|
||||||
"repo": "https://github.com/shadcn-ui/ui.git",
|
"repo": "https://github.com/shadcn-ui/ui.git",
|
||||||
"ref": "main",
|
"ref": "main",
|
||||||
"commit": "25be24cca34d06eed29a4779c3f48c4816aa812c",
|
"commit": "4e88ab81ae1d1550165db949a903c691a04f699c",
|
||||||
"adapter": "claude-skill",
|
"adapter": "claude-skill",
|
||||||
"sourcePath": "skills/shadcn",
|
"sourcePath": "skills/shadcn",
|
||||||
"syncedAt": "2026-08-19T16:00:01Z"
|
"syncedAt": "2026-08-20T16:00:00Z"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
"sourceId": "ui-ux-pro-max",
|
"sourceId": "ui-ux-pro-max",
|
||||||
"repo": "https://github.com/nextlevelbuilder/ui-ux-pro-max-skill.git",
|
"repo": "https://github.com/nextlevelbuilder/ui-ux-pro-max-skill.git",
|
||||||
"ref": "main",
|
"ref": "main",
|
||||||
"commit": "8a1a6d857332da32252d77365da90c3f6293b47b",
|
"commit": "bc826e2267a36d98a2dcf5231e16c30ff546770f",
|
||||||
"adapter": "claude-skill",
|
"adapter": "claude-skill",
|
||||||
"sourcePath": ".claude/skills/ui-ux-pro-max",
|
"sourcePath": ".claude/skills/ui-ux-pro-max",
|
||||||
"syncedAt": "2026-08-19T16:00:01Z"
|
"syncedAt": "2026-08-20T16:00:00Z"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user