[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6G9FV0R9BHHVDFW6CHABH15":3,"skill-same:01M6G9FV0R9BHHVDFW6CHABH15":65},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":43,"commitSha":44,"skillDirectory":45,"forksCount":46,"repositoryHtmlUrl":47,"repositoryHomepageUrl":6,"ownerHtmlUrl":48,"ownerBlogUrl":6,"ownerDescription":49,"updatedAt":50,"install":51,"resources":64},"01M6G9FV0R9BHHVDFW6CHABH15","nostics",null,"Structured diagnostic code library for JavaScript\u002FTypeScript. Turns errors and other conditions into typed, machine-readable `Diagnostic` instances with stable codes, docs URLs, and actionable fields. Use this skill whenever the project imports `nostics`, or works with `defineDiagnostics`\u002F`defineProdDiagnostics`, the `Diagnostic` class, diagnostic code registries, or structured error handling. Also covers reporters (`createConsoleReporter`, `createFetchReporter` from nostics\u002Freporters\u002Ffetch, `createFileReporter` from nostics\u002Freporters\u002Fnode, `createDevReporter` from nostics\u002Freporters\u002Fdev), formatters (`formatDiagnostic`, `ansiFormatter`, `jsonFormatter`), and Vite plugins (`nosticsStrip` from @nostics\u002Funplugin\u002Fstrip-transform, `nosticsCollector` from @nostics\u002Funplugin\u002Fdev-server-collector). Also use when migrating a library's existing `console.warn`\u002F`console.error`\u002F`warn()` helpers or thrown `Error`s to diagnostics: follow `references\u002Fmigration.md`.","zapabob\u002FSkills","zapabob","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F130830376?v=4","01M6DBMYZAGRTFQDSQYW3W764P","峯岸 亮","01M6DBMZ3GKDSJ01NZ9XTZD7JD",2,"MIT","https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Farchive\u002Fskill-md-reviewed\u002Fsha256\u002F78\u002F788f3b28602d93fdb9c51487e363eba13dd8466af5e90ac44ce0e9b0f597671d\u002FSKILL.md",[],[5,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"references","errors","with","actionable","codes","machine","error","project","instances","typescript","vite","use","fetch","node","server","dev","error handling","code","javascript","2026-11-10 10:12:30",false,"---\nname: nostics\ndescription: \"Structured diagnostic code library for JavaScript\u002FTypeScript. Turns errors and other conditions into typed, machine-readable `Diagnostic` instances with stable codes, docs URLs, and actionable fields. Use this skill whenever the project imports `nostics`, or works with `defineDiagnostics`\u002F`defineProdDiagnostics`, the `Diagnostic` class, diagnostic code registries, or structured error handling. Also covers reporters (`createConsoleReporter`, `createFetchReporter` from nostics\u002Freporters\u002Ffetch, `createFileReporter` from nostics\u002Freporters\u002Fnode, `createDevReporter` from nostics\u002Freporters\u002Fdev), formatters (`formatDiagnostic`, `ansiFormatter`, `jsonFormatter`), and Vite plugins (`nosticsStrip` from @nostics\u002Funplugin\u002Fstrip-transform, `nosticsCollector` from @nostics\u002Funplugin\u002Fdev-server-collector). Also use when migrating a library's existing `console.warn`\u002F`console.error`\u002F`warn()` helpers or thrown `Error`s to diagnostics: follow `references\u002Fmigration.md`.\"\nlicense: MIT\n---\n\n# nostics\n\nEvery error condition becomes a typed `Diagnostic` (extends `Error`) with a stable code, docs URL, and actionable `fix`. Serializable via `toJSON()`.\n\n`Diagnostic`: `name` (the code), `message`\u002F`why` (interpolated text), `fix?`, `docs?`, `sources?` (`'file:line:column'`), `cause?`, `toJSON()`. Throw it, catch it with `instanceof Diagnostic`, send `toJSON()` across process boundaries.\n\n## defineDiagnostics\n\nReturns one callable handle per code. Calling a handle builds a fresh `Diagnostic`, fires every reporter in order, and returns it. `throw` the return value to raise (reporters still run, so a thrown diagnostic also reports).\n\n```ts\nimport { createConsoleReporter, defineDiagnostics } from 'nostics'\n\nconst diagnostics = \u002F*#__PURE__*\u002F defineDiagnostics({\n  docsBase: (code) => `https:\u002F\u002Fnuxt.com\u002Fe\u002F${code.replace('NUXT_', '').toLowerCase()}`,\n  reporters: [\u002F*#__PURE__*\u002F createConsoleReporter()],\n  codes: {\n    NUXT_B1001: {\n      why: 'Could not compile template.',\n      fix: 'Check the template for syntax errors.',\n    },\n    NUXT_B2011: {\n      why: (p: { src: string }) => `Invalid plugin \"${p.src}\". src option is required.`,\n      fix: 'Pass a string path or an object with a `src` to `addPlugin()`.',\n    },\n    NUXT_W9001: { why: 'message', docs: false }, \u002F\u002F per-code: string overrides docsBase, false opts out\n  },\n})\n```\n\n- **`docsBase`** `string | (code) => string | undefined`: string appends `\u002F${code.toLowerCase()}`; function returns the full URL (or `undefined` to omit).\n- **`codes`**: each definition needs `why` (`string | (params) => string`, the only required field, becomes `Error.message`); optional `fix` (`string | (params) => string`) and `docs` (`string | false`).\n- **`reporters`**: fired on every call; optional. Their `options` types are intersected; required reporter options become required at the call site. Omit it (or pass `[]`) for a catalog whose codes are only ever `throw`n: the thrown `Diagnostic` already carries the message, so a console reporter would print it once and surface it again from the uncaught error, a visible duplicate. Keep report-only warnings and fatal throws in separate catalogs when one needs a reporter and the other does not.\n- **Param inference**: params from `why` and `fix` are intersected and required at the call site. If `why` needs `{ src }` and `fix` needs `{ date }`, the call requires `{ src, date }`.\n\n## Call sites\n\n```ts\ndiagnostics.NUXT_B1001() \u002F\u002F no params: report only\ndiagnostics.NUXT_B2011({ src: '\u002Fplugins\u002Fbad.ts' }) \u002F\u002F params first\ndiagnostics.NUXT_B2011({\n  src,\n  cause: originalError,\n  sources: ['nuxt.config.ts:42:3'],\n}) \u002F\u002F runtime fields merge in\ndiagnostics.NUXT_B2011({ src }, { method: 'error' }) \u002F\u002F reporter options second\nthrow diagnostics.NUXT_B2011({ src }) \u002F\u002F raise\n```\n\n`cause`\u002F`sources` go in the params object; `sources` matters most for build\u002Fconfig diagnostics where the JS stack points inside the library. Catch with `if (err instanceof Diagnostic)` then read `.name`, `.message`, `.fix`, `.docs`.\n\n## Reporters\n\n`(diagnostic: Diagnostic, options?: Opts) => void`. Declaring a required `options` type makes the second call-site argument required and typed.\n\n| Reporter                          | Import                    | Description                                                                                                                                                                            |\n| --------------------------------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `createConsoleReporter(options?)` | `nostics`                 | `console[method](formatter(d))`. `method` defaults `'warn'` (`'log'\\|'warn'\\|'error'`), `formatter` defaults `formatDiagnostic`; both via options, `method` also overridable per call. |\n| `createFetchReporter(url)`        | `nostics\u002Freporters\u002Ffetch` | POSTs diagnostic JSON to the URL; failures swallowed.                                                                                                                                  |\n| `createFileReporter(options?)`    | `nostics\u002Freporters\u002Fnode`  | Appends NDJSON to a local file (default `.nostics.log`).                                                                                                                               |\n| `createDevReporter()`             | `nostics\u002Freporters\u002Fdev`   | Sends `toJSON()` to the Vite dev server via `import.meta.hot.send()`.                                                                                                                  |\n\n```ts\nimport type { DiagnosticReporter } from 'nostics'\nconst sentryReporter: DiagnosticReporter = (d) =>\n  sentry.captureMessage(d.message, { tags: { code: d.name } })\nconst audited: DiagnosticReporter\u003C{ priority: number }> = (d, o) =>\n  audit.log({ name: d.name, priority: o.priority })\n\u002F\u002F → audited makes diagnostics.X({...}, { priority: 1 }) required and type-checked.\n```\n\n## Formatters\n\n| Formatter               | Import                    | Description                                                                                                |\n| ----------------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------- |\n| `formatDiagnostic`      | `nostics`                 | Plain unicode-decorated string (built-in reporters use it).                                                |\n| `ansiFormatter(colors)` | `nostics\u002Fformatters\u002Fansi` | Colorized; accepts a `Colors` interface (`red`\u002F`yellow`\u002F`cyan`\u002F`gray`\u002F`bold`\u002F`dim`, each `(s) => string`). |\n| `jsonFormatter`         | `nostics\u002Fformatters\u002Fjson` | `JSON.stringify(diagnostic)` via `toJSON()`.                                                               |\n\n`formatDiagnostic` output, detail order fixed `fix` → `sources` → `see`, missing fields omitted:\n\n```\n[NUXT_B2011] Invalid plugin `\u002Fplugins\u002Fbad.ts`. src option is required.\n├▶ fix: Pass a string path or an object with a `src` to `addPlugin()`.\n├▶ sources: nuxt.config.ts:42:3\n╰▶ see: https:\u002F\u002Fnuxt.com\u002Fe\u002Fb2011\n```\n\n## Vite plugins (`@nostics\u002Funplugin`, dev dependency)\n\n`@nostics\u002Funplugin\u002Fstrip-transform` (library authors, build optimization) and `@nostics\u002Funplugin\u002Fdev-server-collector` (app developers, dev-time collection). Both unplugin-based: `.vite()`, `.webpack()`, `.rollup()`, etc.\n\n- **`nosticsStrip`** marks `defineDiagnostics()` `\u002F*#__PURE__*\u002F` and wraps bare diagnostic expression statements with a `NODE_ENV` guard so they tree-shake out of production. Option `packageName?` (default `'nostics'`). Throws\u002Freturns\u002Fassignments stay (they are behavior). For tracking: relative imports, export the catalog directly, no factory wrappers or deep barrels.\n  - The plugin is optional. The same production output happens with no build transform if the catalog is annotated by hand: put `\u002F*#__PURE__*\u002F` before `defineDiagnostics(` and before each reporter factory call inside it (as in every example here), and dev-guard each report-only call site (`process.env.NODE_ENV !== 'production' && diagnostics.CODE(p)`). Always write the annotations in source; reach for the plugin when report-only call sites are unguarded and you want stripping without touching them.\n- **`nosticsCollector`** listens for `createDevReporter()` diagnostics over the Vite WebSocket and writes them as NDJSON via `createFileReporter`. Vite-only. Options `logFile?` (default `.nostics.log`), `debug?` (default `!!process.env.DEBUG`).\n\n```ts\n\u002F\u002F vite.config.ts\nimport { nosticsStrip } from '@nostics\u002Funplugin\u002Fstrip-transform'\nimport { nosticsCollector } from '@nostics\u002Funplugin\u002Fdev-server-collector'\nexport default defineConfig({\n  plugins: [nosticsStrip.vite(), nosticsCollector.vite()],\n})\n\n\u002F\u002F src\u002Fdiagnostics.ts — pair the collector with createDevReporter()\nimport { createConsoleReporter, defineDiagnostics } from 'nostics'\nimport { createDevReporter } from 'nostics\u002Freporters\u002Fdev'\nexport const diagnostics = \u002F*#__PURE__*\u002F defineDiagnostics({\n  reporters: [\u002F*#__PURE__*\u002F createConsoleReporter(), \u002F*#__PURE__*\u002F createDevReporter()],\n  codes: {\n    \u002F* ... *\u002F\n  },\n})\n```\n\n## Production builds\n\n- **Report-only** diagnostics (bare `diagnostics.X()`) should disappear: `nosticsStrip` or hand annotations drop them, then the unused catalog tree-shakes.\n- **Surviving** diagnostics (`throw`\u002F`return`\u002Fassigned\u002Fargument) stay, and each keeps the _whole_ catalog reachable, so every `why`\u002F`fix` ships. Not every library throws in production: if yours only reports, stripping is enough, stop here.\n\nWhen a library _does_ `throw` in production, pick `defineProdDiagnostics` at definition time with a `NODE_ENV` ternary, so a consumer bundler drops the dev branch (all catalog text):\n\n```ts\nimport { defineDiagnostics, defineProdDiagnostics } from 'nostics'\nexport const diagnostics =\n  process.env.NODE_ENV === 'production'\n    ? \u002F*#__PURE__*\u002F defineProdDiagnostics({ docsBase })\n    : \u002F*#__PURE__*\u002F defineDiagnostics({\n        docsBase,\n        reporters: [\n          \u002F* ... *\u002F\n        ],\n        codes: {\n          \u002F* text *\u002F\n        },\n      })\n```\n\nThe accessed code becomes the instance `name`, `docs` still derives from `docsBase`, `why` points to the docs URL when one exists (empty otherwise), no `why`\u002F`fix` text ships. No `reporters` by default (so a surviving `throw` doesn't also log and then resurface as the uncaught error); pass `reporters` to keep prod telemetry. `nosticsStrip` tracks this ternary like a direct catalog export.\n\n## Conventions\n\n- **Codes** are stable, fully-qualified `PREFIX_XNNNN` (`B` build, `R` runtime, `C` config, `D` deprecation). Never reuse or reassign a published code.\n- Always provide `why`; provide `fix` whenever the solution is known (the most actionable field for humans and agents). Use parameterized templates for runtime values, not string concatenation outside the factory.\n- **`why` is the diagnosis, `fix` is the remedy — split them, don't overlap them.** `why` states only what is wrong; `fix` states only what to do. The reporter prints both, so any wording that appears in both is dead weight. When a single source sentence carries both (`\"A hash must start with '#'. Prefix it with '#'.\"`), cut it in two — diagnosis to `why`, remedy to `fix` — rather than pasting the whole thing into `why` and echoing it in `fix`. `fix` accepts a param function too (`(p) => ...`), so move value-bearing remedies (`use \"#${p.hash}\"`) into it instead of leaving them in `why`.\n- Pass `cause` when re-raising; pass `sources` when the JS stack doesn't reflect the user's source.\n- Split large catalogs by domain (`diagnostics\u002Fbuild.ts`, `runtime.ts`, `config.ts`, re-exported from `index.ts`), each `defineDiagnostics()` sharing `docsBase` with its own code range.\n\n## References\n\n- **Migrating an existing library** to nostics (replacing `console.warn`\u002F`console.error`\u002F`warn()`\u002Fthrown `Error`s with diagnostic codes, without changing runtime behavior): follow `references\u002Fmigration.md` start to finish.\n- Building the error-code documentation site (page template, deployment, agent optimization): `references\u002Fdocumentation-site.md`.\n","# nostics\n\nEvery error condition becomes a typed `Diagnostic` (extends `Error`) with a stable code, docs URL, and actionable `fix`. Serializable via `toJSON()`.\n\n`Diagnostic`: `name` (the code), `message`\u002F`why` (interpolated text), `fix?`, `docs?`, `sources?` (`'file:line:column'`), `cause?`, `toJSON()`. Throw it, catch it with `instanceof Diagnostic`, send `toJSON()` across process boundaries.\n\n## defineDiagnostics\n\nReturns one callable handle per code. Calling a handle builds a fresh `Diagnostic`, fires every reporter in order, and returns it. `throw` the return value to raise (reporters still run, so a thrown diagnostic also reports).\n\n```ts\nimport { createConsoleReporter, defineDiagnostics } from 'nostics'\n\nconst diagnostics = \u002F*#__PURE__*\u002F defineDiagnostics({\n  docsBase: (code) => `https:\u002F\u002Fnuxt.com\u002Fe\u002F${code.replace('NUXT_', '').toLowerCase()}`,\n  reporters: [\u002F*#__PURE__*\u002F createConsoleReporter()],\n  codes: {\n    NUXT_B1001: {\n      why: 'Could not compile template.',\n      fix: 'Check the template for syntax errors.',\n    },\n    NUXT_B2011: {\n      why: (p: { src: string }) => `Invalid plugin \"${p.src}\". src option is required.`,\n      fix: 'Pass a string path or an object with a `src` to `addPlugin()`.',\n    },\n    NUXT_W9001: { why: 'message', docs: false }, \u002F\u002F per-code: string overrides docsBase, false opts out\n  },\n})\n```\n\n- **`docsBase`** `string | (code) => string | undefined`: string appends `\u002F${code.toLowerCase()}`; function returns the full URL (or `undefined` to omit).\n- **`codes`**: each definition needs `why` (`string | (params) => string`, the only required field, becomes `Error.message`); optional `fix` (`string | (params) => string`) and `docs` (`string | false`).\n- **`reporters`**: fired on every call; optional. Their `options` types are intersected; required reporter options become required at the call site. Omit it (or pass `[]`) for a catalog whose codes are only ever `throw`n: the thrown `Diagnostic` already carries the message, so a console reporter would print it once and surface it again from the uncaught error, a visible duplicate. Keep report-only warnings and fatal throws in separate catalogs when one needs a reporter and the other does not.\n- **Param inference**: params from `why` and `fix` are intersected and required at the call site. If `why` needs `{ src }` and `fix` needs `{ date }`, the call requires `{ src, date }`.\n\n## Call sites\n\n```ts\ndiagnostics.NUXT_B1001() \u002F\u002F no params: report only\ndiagnostics.NUXT_B2011({ src: '\u002Fplugins\u002Fbad.ts' }) \u002F\u002F params first\ndiagnostics.NUXT_B2011({\n  src,\n  cause: originalError,\n  sources: ['nuxt.config.ts:42:3'],\n}) \u002F\u002F runtime fields merge in\ndiagnostics.NUXT_B2011({ src }, { method: 'error' }) \u002F\u002F reporter options second\nthrow diagnostics.NUXT_B2011({ src }) \u002F\u002F raise\n```\n\n`cause`\u002F`sources` go in the params object; `sources` matters most for build\u002Fconfig diagnostics where the JS stack points inside the library. Catch with `if (err instanceof Diagnostic)` then read `.name`, `.message`, `.fix`, `.docs`.\n\n## Reporters\n\n`(diagnostic: Diagnostic, options?: Opts) => void`. Declaring a required `options` type makes the second call-site argument required and typed.\n\n| Reporter                          | Import                    | Description                                                                                                                                                                            |\n| --------------------------------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `createConsoleReporter(options?)` | `nostics`                 | `console[method](formatter(d))`. `method` defaults `'warn'` (`'log'\\|'warn'\\|'error'`), `formatter` defaults `formatDiagnostic`; both via options, `method` also overridable per call. |\n| `createFetchReporter(url)`        | `nostics\u002Freporters\u002Ffetch` | POSTs diagnostic JSON to the URL; failures swallowed.                                                                                                                                  |\n| `createFileReporter(options?)`    | `nostics\u002Freporters\u002Fnode`  | Appends NDJSON to a local file (default `.nostics.log`).                                                                                                                               |\n| `createDevReporter()`             | `nostics\u002Freporters\u002Fdev`   | Sends `toJSON()` to the Vite dev server via `import.meta.hot.send()`.                                                                                                                  |\n\n```ts\nimport type { DiagnosticReporter } from 'nostics'\nconst sentryReporter: DiagnosticReporter = (d) =>\n  sentry.captureMessage(d.message, { tags: { code: d.name } })\nconst audited: DiagnosticReporter\u003C{ priority: number }> = (d, o) =>\n  audit.log({ name: d.name, priority: o.priority })\n\u002F\u002F → audited makes diagnostics.X({...}, { priority: 1 }) required and type-checked.\n```\n\n## Formatters\n\n| Formatter               | Import                    | Description                                                                                                |\n| ----------------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------- |\n| `formatDiagnostic`      | `nostics`                 | Plain unicode-decorated string (built-in reporters use it).                                                |\n| `ansiFormatter(colors)` | `nostics\u002Fformatters\u002Fansi` | Colorized; accepts a `Colors` interface (`red`\u002F`yellow`\u002F`cyan`\u002F`gray`\u002F`bold`\u002F`dim`, each `(s) => string`). |\n| `jsonFormatter`         | `nostics\u002Fformatters\u002Fjson` | `JSON.stringify(diagnostic)` via `toJSON()`.                                                               |\n\n`formatDiagnostic` output, detail order fixed `fix` → `sources` → `see`, missing fields omitted:\n\n```\n[NUXT_B2011] Invalid plugin `\u002Fplugins\u002Fbad.ts`. src option is required.\n├▶ fix: Pass a string path or an object with a `src` to `addPlugin()`.\n├▶ sources: nuxt.config.ts:42:3\n╰▶ see: https:\u002F\u002Fnuxt.com\u002Fe\u002Fb2011\n```\n\n## Vite plugins (`@nostics\u002Funplugin`, dev dependency)\n\n`@nostics\u002Funplugin\u002Fstrip-transform` (library authors, build optimization) and `@nostics\u002Funplugin\u002Fdev-server-collector` (app developers, dev-time collection). Both unplugin-based: `.vite()`, `.webpack()`, `.rollup()`, etc.\n\n- **`nosticsStrip`** marks `defineDiagnostics()` `\u002F*#__PURE__*\u002F` and wraps bare diagnostic expression statements with a `NODE_ENV` guard so they tree-shake out of production. Option `packageName?` (default `'nostics'`). Throws\u002Freturns\u002Fassignments stay (they are behavior). For tracking: relative imports, export the catalog directly, no factory wrappers or deep barrels.\n  - The plugin is optional. The same production output happens with no build transform if the catalog is annotated by hand: put `\u002F*#__PURE__*\u002F` before `defineDiagnostics(` and before each reporter factory call inside it (as in every example here), and dev-guard each report-only call site (`process.env.NODE_ENV !== 'production' && diagnostics.CODE(p)`). Always write the annotations in source; reach for the plugin when report-only call sites are unguarded and you want stripping without touching them.\n- **`nosticsCollector`** listens for `createDevReporter()` diagnostics over the Vite WebSocket and writes them as NDJSON via `createFileReporter`. Vite-only. Options `logFile?` (default `.nostics.log`), `debug?` (default `!!process.env.DEBUG`).\n\n```ts\n\u002F\u002F vite.config.ts\nimport { nosticsStrip } from '@nostics\u002Funplugin\u002Fstrip-transform'\nimport { nosticsCollector } from '@nostics\u002Funplugin\u002Fdev-server-collector'\nexport default defineConfig({\n  plugins: [nosticsStrip.vite(), nosticsCollector.vite()],\n})\n\n\u002F\u002F src\u002Fdiagnostics.ts — pair the collector with createDevReporter()\nimport { createConsoleReporter, defineDiagnostics } from 'nostics'\nimport { createDevReporter } from 'nostics\u002Freporters\u002Fdev'\nexport const diagnostics = \u002F*#__PURE__*\u002F defineDiagnostics({\n  reporters: [\u002F*#__PURE__*\u002F createConsoleReporter(), \u002F*#__PURE__*\u002F createDevReporter()],\n  codes: {\n    \u002F* ... *\u002F\n  },\n})\n```\n\n## Production builds\n\n- **Report-only** diagnostics (bare `diagnostics.X()`) should disappear: `nosticsStrip` or hand annotations drop them, then the unused catalog tree-shakes.\n- **Surviving** diagnostics (`throw`\u002F`return`\u002Fassigned\u002Fargument) stay, and each keeps the _whole_ catalog reachable, so every `why`\u002F`fix` ships. Not every library throws in production: if yours only reports, stripping is enough, stop here.\n\nWhen a library _does_ `throw` in production, pick `defineProdDiagnostics` at definition time with a `NODE_ENV` ternary, so a consumer bundler drops the dev branch (all catalog text):\n\n```ts\nimport { defineDiagnostics, defineProdDiagnostics } from 'nostics'\nexport const diagnostics =\n  process.env.NODE_ENV === 'production'\n    ? \u002F*#__PURE__*\u002F defineProdDiagnostics({ docsBase })\n    : \u002F*#__PURE__*\u002F defineDiagnostics({\n        docsBase,\n        reporters: [\n          \u002F* ... *\u002F\n        ],\n        codes: {\n          \u002F* text *\u002F\n        },\n      })\n```\n\nThe accessed code becomes the instance `name`, `docs` still derives from `docsBase`, `why` points to the docs URL when one exists (empty otherwise), no `why`\u002F`fix` text ships. No `reporters` by default (so a surviving `throw` doesn't also log and then resurface as the uncaught error); pass `reporters` to keep prod telemetry. `nosticsStrip` tracks this ternary like a direct catalog export.\n\n## Conventions\n\n- **Codes** are stable, fully-qualified `PREFIX_XNNNN` (`B` build, `R` runtime, `C` config, `D` deprecation). Never reuse or reassign a published code.\n- Always provide `why`; provide `fix` whenever the solution is known (the most actionable field for humans and agents). Use parameterized templates for runtime values, not string concatenation outside the factory.\n- **`why` is the diagnosis, `fix` is the remedy — split them, don't overlap them.** `why` states only what is wrong; `fix` states only what to do. The reporter prints both, so any wording that appears in both is dead weight. When a single source sentence carries both (`\"A hash must start with '#'. Prefix it with '#'.\"`), cut it in two — diagnosis to `why`, remedy to `fix` — rather than pasting the whole thing into `why` and echoing it in `fix`. `fix` accepts a param function too (`(p) => ...`), so move value-bearing remedies (`use \"#${p.hash}\"`) into it instead of leaving them in `why`.\n- Pass `cause` when re-raising; pass `sources` when the JS stack doesn't reflect the user's source.\n- Split large catalogs by domain (`diagnostics\u002Fbuild.ts`, `runtime.ts`, `config.ts`, re-exported from `index.ts`), each `defineDiagnostics()` sharing `docsBase` with its own code range.\n\n## References\n\n- **Migrating an existing library** to nostics (replacing `console.warn`\u002F`console.error`\u002F`warn()`\u002Fthrown `Error`s with diagnostic codes, without changing runtime behavior): follow `references\u002Fmigration.md` start to finish.\n- Building the error-code documentation site (page template, deployment, agent optimization): `references\u002Fdocumentation-site.md`.\n",{"name":5,"license":15,"description":7},"main","0d1434f89f4bc6b07e9d272accd8c1013768820f","archive\u002Fskill-md-reviewed\u002Fsha256\u002F78\u002F788f3b28602d93fdb9c51487e363eba13dd8466af5e90ac44ce0e9b0f597671d",0,"https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills","https:\u002F\u002Fgithub.com\u002Fzapabob","The Open University of JAPAN　2019-now\r\n\r\nTokyo University of Science　2007-2010","2026-10-26 16:29:01",{"source":8,"skillName":5,"commands":52,"prompt":62,"zipAvailable":63},[53,56,59],{"tool":54,"command":55},"npx","npx skills add zapabob\u002FSkills --skill nostics",{"tool":57,"command":58},"bunx","bunx skills add zapabob\u002FSkills --skill nostics",{"tool":60,"command":61},"pnpm","pnpm dlx skills add zapabob\u002FSkills --skill nostics","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Farchive\u002Fskill-md-reviewed\u002Fsha256\u002F78\u002F788f3b28602d93fdb9c51487e363eba13dd8466af5e90ac44ce0e9b0f597671d\u002FSKILL.md",true,[],[66,104,138,164,191,207],{"skillNo":67,"name":68,"nameZh":6,"description":69,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":70,"categories":71,"keywords":85,"publishedAt":38},"01M6GJTE1GESGGF9K028Y7753E","xurl","X\u002FTwitter via xurl CLI: post, search, DM, media, v2 API.","https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Fregistry\u002Fskills\u002Fxurl\u002Fvariants\u002Fhermes-agent\u002FSKILL.md",[72,77,80],{"categoryNo":73,"categoryName":74,"taxonomyType":75,"taxonomyTypeDesc":76},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":78,"categoryName":79,"taxonomyType":75,"taxonomyTypeDesc":76},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":81,"categoryName":82,"taxonomyType":83,"taxonomyTypeDesc":84},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[68,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,43,101,102,103],"openclaw","macos","cli","github","linux","windows","official","search","https","social-media","api","Media","hermes","hermes agent","twitter","social","via","post",{"skillNo":105,"name":106,"nameZh":6,"description":107,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":108,"categories":109,"keywords":121,"publishedAt":38},"01M6GJT8S1PXQ8WPXT1HSNBWH2","writing-plans","Write implementation plans: bite-sized tasks, paths, code.","https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Fregistry\u002Fskills\u002Fwriting-plans\u002Fvariants\u002Fhermes-agent\u002FSKILL.md",[110,113,116,117,118],{"categoryNo":111,"categoryName":112,"taxonomyType":75,"taxonomyTypeDesc":76},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":114,"categoryName":115,"taxonomyType":75,"taxonomyTypeDesc":76},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":78,"categoryName":79,"taxonomyType":75,"taxonomyTypeDesc":76},{"categoryNo":81,"categoryName":82,"taxonomyType":83,"taxonomyTypeDesc":84},{"categoryNo":119,"categoryName":120,"taxonomyType":83,"taxonomyTypeDesc":84},"01JBSEEDCAT000000000000036","内容创作者",[122,123,124,125,87,126,90,127,91,128,129,130,36,131,132,133,134,135,136,137],"writing","writing plans","plans","design","review","workflow","documentation","tasks","development","planning","code-review","subagent","write","superpowers","paths","test-driven-development",{"skillNo":139,"name":140,"nameZh":6,"description":141,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":142,"categories":143,"keywords":147,"publishedAt":38},"01M6GJST0H5X7WHBJ3BZK0DVKH","whisper","OpenAI's general-purpose speech recognition model. Supports 99 languages, transcription, translation to English, and language identification. Six model sizes from tiny (39M params) to large (1550M params). Use for speech-to-text, podcast transcription, or multilingual audio processing. Best for robust, multilingual ASR.","https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Fregistry\u002Fskills\u002Fwhisper\u002Fvariants\u002Fhermes-agent-optional\u002FSKILL.md",[144],{"categoryNo":145,"categoryName":146,"taxonomyType":75,"taxonomyTypeDesc":76},"01JBSEEDCAT000000000000016","图像与多媒体",[140,87,90,148,149,150,151,152,153,154,155,156,30,157,158,159,160,161,162,163],"openai","speech","multimodal","Transformers","ASR","Audio","text","model","speech recognition","general","multilingual","translation","english","identification","processing","Audio Processing",{"skillNo":165,"name":166,"nameZh":6,"description":167,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":168,"categories":169,"keywords":173,"publishedAt":38},"01M6GJSMRQ8EETZTYMG72P70EA","weights-and-biases","W&B: log ML experiments, sweeps, model registry, dashboards.","https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Fregistry\u002Fskills\u002Fweights-and-biases\u002Fvariants\u002Fhermes-agent\u002FSKILL.md",[170],{"categoryNo":171,"categoryName":172,"taxonomyType":75,"taxonomyTypeDesc":76},"01JBSEEDCAT000000000000013","分析与可视化",[174,87,175,176,91,177,178,179,180,181,182,155,183,184,185,186,187,188,189,190],"weights and biases","tensorflow","experiments","pytorch","visualization","registry","real-time","tuning","dashboards","experiment","log","time","Experiment Tracking","Model Registry","Hyperparameter Tuning","WandB","Real-Time Visualization",{"skillNo":192,"name":193,"nameZh":6,"description":194,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":195,"categories":196,"keywords":198,"publishedAt":38},"01M6GJS19KDPRY112JTR326S06","watchers","Poll RSS, JSON APIs, and GitHub with watermark dedup.","https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Fregistry\u002Fskills\u002Fwatchers\u002Fvariants\u002Fhermes-agent-optional\u002FSKILL.md",[197],{"categoryNo":78,"categoryName":79,"taxonomyType":75,"taxonomyTypeDesc":76},[193,87,199,89,90,200,201,202,203,204,205,98,99,206,21],"terminal","automation","http","monitoring","cron","json","rss","devops",{"skillNo":208,"name":209,"nameZh":6,"description":210,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":211,"categories":212,"keywords":215,"publishedAt":38},"01M6GJRHJD2A6Q830SWF9W48BC","serving-llms-vllm","vLLM: high-throughput LLM serving, OpenAI API, quantization.","https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Fregistry\u002Fskills\u002Fvllm\u002Fvariants\u002Fhermes-agent\u002FSKILL.md",[213,214],{"categoryNo":73,"categoryName":74,"taxonomyType":75,"taxonomyTypeDesc":76},{"categoryNo":81,"categoryName":82,"taxonomyType":83,"taxonomyTypeDesc":84},[216,217,218,90,219,148,220,221,222,151,223,96,224,225,226,227,228,229,230,231],"llms","vLLM","serving llms vllm","research","openai api","tensor","Inference Serving","Production","llm serving","High Throughput","PagedAttention","Continuous Batching","Quantization","Tensor Parallelism","high-throughput","throughput"]