🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@silverassist/agents-toolkit

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@silverassist/agents-toolkit - npm Package Compare versions

Comparing version
2.5.0
to
2.5.1
+1
-1
package.json
{
"name": "@silverassist/agents-toolkit",
"version": "2.5.0",
"version": "2.5.1",
"description": "Reusable AI agent prompts for development workflows with Jira integration — supports GitHub Copilot, Claude Code, and Codex",

@@ -5,0 +5,0 @@ "author": "Santiago Ramirez",

@@ -6,3 +6,3 @@ /**

export const VERSION = "2.5.0";
export const VERSION = "2.5.1";

@@ -9,0 +9,0 @@ export const PROMPTS = {

@@ -25,7 +25,23 @@ ---

2. **A `POST` IS cacheable cross-request — but only with explicit `next` options.**
Next.js does not cache `POST` by default. Any read `fetch` to CCDS or the WP GraphQL endpoint —
GET or POST — must set `next: { revalidate, tags }`. The request body is part of the cache key, so
different filter bodies cache independently.
2. **A `POST` read caches its DATA with `next` options — but the ROUTE still renders dynamically.**
Next.js does not cache `POST` by default; any read `fetch` (GET or POST) to CCDS or the WP GraphQL
endpoint must set `next: { revalidate, tags }` (the body is part of the cache key, so different
filter bodies cache independently). **However** (WEB-1069, Next 16) a page whose data comes from a
POST read still prerenders as `ƒ` (Dynamic) and serves `cache-control: private, no-store` even with
those options — the data-fetch cache and the route's static/dynamic classification are independent.
So `next: { revalidate, tags }` is **necessary but not sufficient** to make a POST-read page
CDN-cacheable; you must also apply a rendering/edge strategy (rule 2b). GET reads ISR natively and
need nothing extra.
2b. **Make a POST-read page cacheable at the rendering/edge layer.** Pick one (lowest risk first):
- **CDN edge override (current/default):** `src/proxy.ts` matches city/community paths and sets
`Cache-Control: public, s-maxage=2592000, stale-while-revalidate=2592000` — the same header ISR
pages emit (see rule 7 `expireTime`), so the CDN policy is uniform. Origin stays dynamic; the CDN
caches the deterministic-per-URL response. No build-time risk. This is what WEB-1069 shipped.
- **`export const dynamic = "force-static"` (interim):** prerenders the route as real ISR, but a
bad CCDS record/response at build time caches a blank page (the WEB-1058 regression) — use only
when the page is fully null-safe and reads throw on 5xx at runtime. Validate per repo.
- **`cacheComponents: true` + `use cache` (strategic):** PPR migration; do not mix ad hoc with
route-segment `export const revalidate`.
3. **Always pair `tags` with a `revalidate` duration.** `next: { tags }` alone either holds stale data

@@ -38,7 +54,9 @@ indefinitely or (Next 16 default) does not cache at runtime at all. Use a `CACHE_DURATIONS`-style

5. **Every cacheable route exports `revalidate`.** Suggested tiers: listing 24h–30d, detail/city 24h
(`86400`), state/landing 7d (`604800`), WP catch-all 7d. Do **not** add `revalidate` to
mutation/personalized routes (forms, thank-you, wizards). Prefer `export const revalidate` over
`dynamic = "force-static"` so a failed ISR revalidation preserves the last good cache instead of
overwriting it with a broken page.
5. **Every cacheable route exports `revalidate`.** CCDS/WP data changes rarely and is refreshed
on-demand (webhooks + tags), so the default is intentionally **long: `2592000` (30d)** for CCDS
reads, `WP_CACHE_DURATIONS`, and page segments alike (WEB-1069). Shorter tiers (24h/7d) are fine
per-route for volatile sources. Do **not** add `revalidate` to mutation/personalized routes (forms,
thank-you, wizards). Default to `export const revalidate` over `dynamic = "force-static"` so a
failed ISR revalidation preserves the last good cache instead of overwriting it with a broken page
(force-static is still a valid POST-read option per rule 2b once null-safety + throw-on-5xx exist).

@@ -49,4 +67,10 @@ 6. **On-demand revalidation dual-invalidates.** `/api/revalidate` must call `revalidateTag`/

7. **Image config** in `next.config`: set `minimumCacheTTL: 2592000` (30d), `qualities`, and
`formats: ["image/avif", "image/webp"]`. No malformed `remotePatterns` hostnames.
7. **`next.config` cache config.** `expireTime` sets the CDN stale window: Next emits
`s-maxage=<revalidate>, stale-while-revalidate=<expireTime − revalidate>` for ISR pages, so
`expireTime` **must be ≥ the largest page `revalidate`**. Set `expireTime: 5184000` (60d) so a 30d
page yields `s-maxage=2592000, stale-while-revalidate=2592000` — the same header the proxy sets on
dynamic pages (rule 2b). (WEB-1069 bug: `expireTime: 86400` under a 30d revalidate = invalid stale
window.) Also set image `minimumCacheTTL: 31536000` (1y — optimized images are content-hashed and
never change), `qualities`, and `formats: ["image/avif", "image/webp"]`. No malformed
`remotePatterns` hostnames.

@@ -73,3 +97,3 @@ 8. **Asset proxy TTLs** are type-keyed (image/css/font) at `365d + SWR 30d`.

revalidateTag,
revalidate = 86400, // 24h time-based fallback; pair with tags for surgical invalidation
revalidate = 2592000, // 30d time-based fallback; pair with tags for surgical invalidation
mutation = false,

@@ -98,3 +122,3 @@ }: FetchOptions): Promise<T | null> {

export const WP_CACHE_DURATIONS = {
pages: 86400, posts: 86400, menus: 86400, staticPages: 604800, default: 86400,
pages: 2592000, posts: 2592000, menus: 2592000, staticPages: 2592000, default: 2592000, // 30d
} as const;

@@ -101,0 +125,0 @@

@@ -21,5 +21,11 @@ ---

**Cache by intent (read vs. mutation), never by the HTTP method.** Some reads must use `POST` because
they take a body (e.g. CCDS `geo-search`). They still have to cache like a `GET`. Mutations must never
cache. Getting this wrong silently turns a static page into a per-request dynamic render.
they take a body (e.g. CCDS `geo-search`). Their *data* still has to cache like a `GET` — send
`next: { revalidate, tags }`, never `no-store`. Mutations must never cache.
**But caching the data is not the same as making the page static.** A POST read caches its response
cross-request, yet Next.js still renders the *route* dynamically (`private, no-store`). The data-fetch
cache (layer 2) and the route's static/dynamic classification (layers 1/5) are **independent** — see
the two sections below. This is the WEB-1069 gotcha and the reason city/community pages needed an edge
override even though their fetches were already cached.
---

@@ -45,17 +51,41 @@

## How Next.js 16 actually decides (the rule behind the rule)
## POST reads: the data caches, but the route stays dynamic (the key gotcha)
From `next/dist/server/lib/patch-fetch.js`:
Two independent facts, both true:
- `fetch` is **not cached by default**. A non-`GET` method is "uncacheable" **only when no explicit
cache config is provided**. Concretely, a POST is auto-no-cached only when it has no `next`/`cache`
options *and* the segment `revalidate` is `0`.
- Therefore **a `POST` IS cached cross-request when you pass an explicit `next: { revalidate }`** (and
the segment isn't `revalidate: 0`). This is why the WordPress GraphQL POST caches fine.
- The **request body is part of the cache key** (`incremental-cache` → `generateCacheKey` hashes
`init.body`), so different filter bodies cache independently and never collide.
1. **The data fetch caches.** From `next/dist/server/lib/patch-fetch.js`: a `fetch` is uncacheable
only when it has no `next`/`cache` options *and* the segment `revalidate` is `0`. So a POST **with**
`next: { revalidate }` IS cached cross-request — the **request body is part of the cache key**
(`generateCacheKey` hashes `init.body`), so different filter bodies cache independently. This is
real and bounds origin/CCDS load; it is why the WordPress GraphQL POST caches fine.
**Implication:** you do **not** need `unstable_cache` or a proxy header override to cache POST reads.
Just send `next: { revalidate, tags }`.
2. **The route still renders dynamically.** Empirically (WEB-1069, Next 16), a page whose data comes
from a POST read prerenders as `ƒ` (Dynamic) and serves `cache-control: private, no-store` — **even
with** `next: { revalidate, tags }` on the fetch. Next treats the POST as request-time data for
prerendering, so ISR (layer 1) never engages. GET reads do not have this problem — they ISR
natively (`s-maxage`, `x-nextjs-cache: HIT`).
**Implication:** `next: { revalidate, tags }` on a POST read is **necessary** (data cache) but **not
sufficient** to make the page CDN-cacheable. You must additionally pick a rendering/edge strategy
(next section). `revalidate` + `tags` alone will NOT flip a POST-read page from `private, no-store` to
`public`.
## Making a POST-read page cacheable (rendering / edge layer)
Pick one (ordered by risk, lowest first):
1. **CDN edge override (current, lowest risk).** `src/proxy.ts` matches the city/community paths and
sets `Cache-Control: public, s-maxage=2592000, stale-while-revalidate=2592000` — the **same**
header the ISR pages emit (see `expireTime` under ISR tiers), so the CDN policy is uniform across
static and dynamic routes. The origin stays dynamic; the CDN caches the deterministic-per-URL
response. Per-repo regex, no build-time risk — this is what WEB-1069 shipped.
2. **`export const dynamic = "force-static"` (interim).** Forces the POST read to `force-cache` and
prerenders the route as real ISR (confirmed via `prerender-manifest.json`). Removed in WEB-1058
because a CCDS failure at build time cached a **blank page**; safer now that reads throw on 5xx at
runtime (a failed revalidation keeps the last good cache), but full prerender is sensitive to
null/bad records — keep the page fully null-safe and validate per repo before adopting.
3. **`cacheComponents: true` + `use cache` (strategic).** Wrap the POST read in `use cache` so its data
lands in the static shell (PPR). Next-recommended long term; larger migration — do **not** mix ad
hoc with route-segment `export const revalidate`.
---

@@ -81,3 +111,3 @@

revalidateTag,
revalidate = 86400, // 24h time-based fallback; pair with tags for surgical invalidation
revalidate = 2592000, // 30d time-based fallback; pair with tags for surgical invalidation
mutation = false,

@@ -122,14 +152,27 @@ }: FetchOptions): Promise<T | null> {

| Route type | `export const revalidate` |
|------------|---------------------------|
| Listing / index | `2592000` (30d) — webhook handles freshness |
| Detail / city / community (`[slug]`) | `86400` (24h) |
| State / advisor landing | `604800` (7d) |
| WP catch-all (`[[...uri]]`) | `604800` (7d) |
CCDS/WP data changes rarely and is refreshed on-demand via webhooks + tags, so the time-based default
is intentionally **long** (WEB-1069):
| Route / config | Value |
|----------------|-------|
| CCDS reads (client default) | `2592000` (30d) |
| WordPress GraphQL reads (`WP_CACHE_DURATIONS`) | `2592000` (30d) |
| Listing / detail / city / community / state / landing / WP catch-all | `2592000` (30d) |
| `next.config` `expireTime` (CDN stale window) | `5184000` (60d) → emits `s-maxage=2592000, stale-while-revalidate=2592000` |
| `next.config` image `minimumCacheTTL` | `31536000` (1y) — optimized images are content-hashed, never change |
- Every cacheable route exports `revalidate`. Do **not** add it to form/personalized routes.
- Prefer `export const revalidate` over `dynamic = "force-static"`: a failed ISR revalidation then
- **`expireTime` sets the CDN stale window.** Next emits `s-maxage=<revalidate>,
stale-while-revalidate=<expireTime − revalidate>` for ISR pages, so `expireTime` **must be ≥ the
largest `revalidate`** or the stale window is invalid (the WEB-1069 bug: `expireTime: 86400` under a
30d revalidate). Set it to `5184000` (60d) so a 30d page yields the same header the proxy sets on
dynamic pages: `s-maxage=2592000, stale-while-revalidate=2592000`.
- The long default is safe because a missed webhook still self-heals within 30d; use `tags` for
immediate surgical invalidation. Shorter tiers (24h/7d) are fine per-route if a source is volatile.
- Default to `export const revalidate` over `dynamic = "force-static"`: a failed ISR revalidation then
preserves the last good cache instead of overwriting it with a broken page. Pair with a client that
**throws on 5xx at runtime** (so ISR keeps the previous version) but returns an error during the
build phase (so `generateStaticParams` can skip a bad entry without failing the build).
build phase (so `generateStaticParams` can skip a bad entry without failing the build). `force-static`
is still a valid POST-read option (see "Making a POST-read page cacheable") **once** the page is
fully null-safe and the throw-on-5xx guard is in place.

@@ -153,4 +196,5 @@ ---

- ❌ `next: method === "GET" ? {...} : { revalidate: 0 }` — leaves POST reads uncached → the route
renders dynamically (`private, no-store`). This is the exact regression that broke city pages.
- ❌ `next: method === "GET" ? {...} : { revalidate: 0 }` — leaves POST reads uncached (origin hit
every render). Note: even a *correctly* cached POST read still renders the route dynamically — that
needs an edge override, not just `next` options (see "Making a POST-read page cacheable").
- ❌ Bare `fetch(url, { method: "POST", body })` for a read — refetched from origin every render.

@@ -160,3 +204,5 @@ - ❌ `next: { tags }` with no `revalidate` — holds stale data or doesn't cache at runtime.

- ❌ Treating `React.cache()` as cross-request caching (it's request-scoped dedup only).
- ❌ `dynamic = "force-static"` on a page whose revalidation can fail (caches a broken page).
- ❌ `dynamic = "force-static"` on a page that is **not** fully null-safe or lacks throw-on-5xx — a bad
CCDS record/response at build time caches a broken/blank page (the WEB-1058 regression). It is a
valid option only once those guards exist.
- ❌ Mixing `cacheComponents: true` (`"use cache"`) with route-segment `export const revalidate` —

@@ -163,0 +209,0 @@ that is a separate, deliberate migration; do not introduce it ad hoc.