Registro público
Informe de salud del softwareesquema 0.27.0 · métricas 1.13.0 · 2026-07-27 20:22 UTC

ApparelHub-AI / apparelhub-mcp

TypeScriptMIT★ 0 estrellas⑂ 0 forksdesde jul 2026Ver en GitHub ↗

ApparelHub-AI/apparelhub-mcp tiene un índice de salud de 57 sobre 100, lo que lo sitúa en la banda Moderado. Su puntuación más alta es Vitality (73/100) y la más baja, Community & Adoption (33/100). Se actualizó por última vez hace 5 días. Una sola persona concentra la mayor parte del trabajo reciente.

57
global / 100
Moderado

Índice de salud del software

Las métricas se agrupan en categorías ponderadas sobre una escala de 1 a 100. El resultado global parte de su media; cuando la evidencia pública activa la Política de Jurisdicciones de Alto Riesgo, la calificación se ajusta y recibe el límite 49 (En riesgo). Preparación para IA queda fuera.

57
Excelente85-100Ejemplar; cumple prácticamente todos los criterios evaluados
Bueno70-84Saludable; carencias menores
Moderado50-69Aceptable con carencias notables; se recomienda revisión
En riesgo30-49Debilidades significativas; su adopción exige cautela
Crítico1-29Problemas graves (proyecto abandonado, un solo mantenedor, sin higiene)
VitalidadComunidad yAdopciónSostenibilidady GobernanzaCalidad deIngenieríaSeguridadPreparaciónpara IA

Perfil de puntuación

Cada eje es una categoría. La forma importa más que la media: un proyecto sano llena toda la figura, mientras que un perfil de picos y cráteres indica que la fortaleza en una dimensión enmascara el riesgo en otra.

Titularidad

ApparelHub-AIOrganización
1 seguidor5 repositorios públicosdesde may 2026

Este repositorio está respaldado por una organización: una custodia compartida y responsable que puede sobrevivir a cualquier mantenedor individual.

Ecosistemas de paquetes

RegistroPaqueteVersiónDescargas / mesVersionesÚltima publicaciónEtiquetas
npm@apparelhub/mcp-server0.5.12493539hace 6 díasmcpmodel-context-protocolapparelhubprint-on-demandecommerceai-agentsagentic-commerce

Métricas por categoría

Vitalidad

¿Está vivo el proyecto: se escribe código y se publican versiones?

73Bueno · 22% del índice global
Cómo se puntúa
36/36Recencia de push — último push hace 5 días
2.8/36Cadencia de commits — 4/52 semanas con commits
16.2/18Volumen de commits — 63 commits en el último año
0/10OpenSSF Scorecard: Maintained — project was created within the last 90 days. Please review its contents carefully
Datos de entrada utilizados
commits_last_year63
human_commit_share1
days_since_last_push5
active_weeks_last_year4
Cómo se puntúa
27/27Publica versiones — 38 versiones publicadas
36/36Recencia de las versiones — última versión hace 6 días
27/27Cadencia de publicación — una versión cada ~0,5 días
0/10OpenSSF Scorecard: Signed-Releases — sin datos
Datos de entrada utilizados
releases_count38
latest_release_tagv0.5.12
releases_from_tagsno
days_since_latest_release6
mean_days_between_releases0,5
Excluidos de la puntuación (sin datos o no aplicable): OpenSSF Scorecard: Signed-Releases. Los pesos restantes se han renormalizado.

Comunidad y Adopción

¿Tiene el proyecto usuarios, descargas, atención y unas condiciones acogedoras para quienes contribuyen?

33En riesgo · 18% del índice global
Cómo se puntúa
0/60Estrellas — 0 estrellas
0/25Forks — 0 forks
0/15Observadores — 0 observadores
Datos de entrada utilizados
forks0
stars0
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Cómo se puntúa
22.5/22.5README
22.5/22.5Licencia — licencia reconocida (MIT)
0/18Guía CONTRIBUTING
0/13.5Código de conducta
0/7.2Plantilla de issues
0/6.3Plantilla de PR
Datos de entrada utilizados
has_readme
has_license
has_contributingno
has_issue_templateno
has_code_of_conductno
has_pull_request_templateno
Cómo se puntúa
49.2/80Descargas mensuales — 4935 descargas/mes en npm
0/20Dependientes en el registro — no lo informa este ecosistema
Datos de entrada utilizados
packages@apparelhub/mcp-server
dependents
ecosystemsnpm
total_downloads
monthly_downloads4935
Excluidos de la puntuación (sin datos o no aplicable): Dependientes en el registro. Los pesos restantes se han renormalizado.

Sostenibilidad y Gobernanza

¿Sobrevivirá el proyecto a sus personas: factor bus, capacidad de respuesta, quién lo respalda y mantenimiento del paquete?

53Moderado · 24% del índice global
Cómo se puntúa
9/54Factor bus — la mitad de los commits recae en 1 contribuyente(s)
0.4/22.5Distribución de commits — el principal contribuyente firma el 98% de los commits
2.7/13.5Amplitud de contribuyentes — 2 contribuyentes
0/10OpenSSF Scorecard: Contributors — project has 0 contributing companies or organizations -- score normalized to 0
Datos de entrada utilizados
bus_factor1
contributors_sampled2
top_contributor_share0,984
Cómo se puntúa
42.9/46.8Resolución de issues — 92% de issues cerradas
36.9/38.3Aceptación de PR — 54/56 PR decididos fusionados
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Datos de entrada utilizados
merged_prs54
open_issues4
closed_issues45
issue_closed_ratio0,918
closed_unmerged_prs2
Cómo se puntúa
30/30Respaldo de la propiedad — propiedad de una organización
0/20Dominio verificado
2.2/25Alcance del propietario — 1 seguidores de ApparelHub-AI
6/25Trayectoria — 5 repos públicos, cuenta de ~0 años
Datos de entrada utilizados
followers1
owner_typeOrganization
is_verified
owner_loginApparelHub-AI
public_repos5
account_age_days59
Cómo se puntúa
25/25Publicado y resoluble — 1 paquete(s) en npm
35/35Recencia de publicación — última publicación hace 6 días
20/20Historial de versiones — 39 versiones en el registro
20/20No obsoleto — activo, ni obsoleto ni retirado
Datos de entrada utilizados
packages@apparelhub/mcp-server
ecosystemsnpm
any_deprecatedno
min_days_since_publish6

Calidad de Ingeniería

¿Existen unas prácticas mínimas de ingeniería y documentación?

72Bueno · 20% del índice global
Cómo se puntúa
24/24Flujos de trabajo de CI — 4 flujo(s) de trabajo
24/24Pruebas presentes
16/16Configuración de linter — eslint.config.js
0/9.6Hooks de pre-commit
0/6.4.editorconfig
20/20OpenSSF Scorecard: CI-Tests — 28 out of 28 merged PRs checked by a CI test -- score normalized to 10
Datos de entrada utilizados
has_ci
has_tests
has_editorconfigno
has_linter_config
has_precommit_configno

Documentación

55Moderado
Cómo se puntúa
30/30README
25/25Directorio de documentación
0/15Sitio de documentación / página del proyecto
0/10Descripción del repositorio
0/10Topics
0/10Wiki
Datos de entrada utilizados
topics
has_wikino
homepage
has_readme
has_docs_dir
has_descriptionno

Seguridad

¿Son sólidas las prácticas visibles de seguridad y de cadena de suministro, sin exposición jurisdiccional de alto riesgo sin resolver?

51Moderado · 16% del índice global
Cómo se puntúa
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
2.5/2.5CI-Tests — 28 out of 28 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
0/2.5Contributors — project has 0 contributing companies or organizations -- score normalized to 0
10/10Dangerous-Workflow — no dangerous workflow patterns detected
7.5/7.5Dependency-Update-Tool — update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5Licencia — license file detected
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
5/5Packaging — packaging workflow detected
1.5/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 3
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — sin datos
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
4.5/7.5Vulnerabilities — 4 existing vulnerabilities detected
Datos de entrada utilizados
sourceopenssf_scorecard
checks_evaluated17
scorecard_versionv5.5.0
checks_inconclusive1
scorecard_aggregate4,2
Excluidos de la puntuación (sin datos o no aplicable): signed_releases. Los pesos restantes se han renormalizado.
Cómo se puntúa
35/35Dependencias directas libres de avisos conocidos — ninguna dependencia directa tiene un aviso conocido
13.2/25Dependencias indirectas libres de avisos conocidos — 1 afectados: @hono/node-server 1.19.15 (moderate 5.9)
40/40Sin avisos pendientes — ningún aviso lleva público más de 90 días
Datos de entrada utilizados
sourceosv
advisories1
affected_packages1
assessed_packages95
unassessed_packages0
affected_by_severitymoderate 1
direct_affected_packages0
Se cotejó el cierre de dependencias en tiempo de ejecución de npm:@apparelhub/mcp-server@0.5.12 —lo que arrastra la instalación del paquete publicado—: 95 paquetes. No se analiza la alcanzabilidad.

Preparación para IA

¿Hasta qué punto está el repositorio preparado para desarrollarse y mantenerse con agentes de codificación de IA? Es una insignia independiente y experimental — peso 0,0, de modo que se presenta por separado y no afecta a la puntuación de salud global.

59Moderado · 0% del índice global
Cómo se puntúa
0/45Instrucciones para agentes — sin CLAUDE.md / AGENTS.md / reglas de editor
0/15Documentación legible por máquinas (llms.txt)
40/40Historial de commits legible — 63 de 63 commits humanos declaran su intención (asunto estructurado o cuerpo explicativo)
Datos de entrada utilizados
has_llms_txtno
legible_history_share1
agent_instruction_files
agent_instruction_max_bytes
Cómo se puntúa
0/18Arranque con un solo comando
22/22Pruebas automatizadas
11/11Configuración de lint / formato — eslint.config.js
11/11Verificación estática de tipos — tsconfig.json
10/10Entorno reproducible — Dockerfile, lockfile
10/10Práctica demostrada con agentes — 63 de los últimos 63 commits con autoría o crédito de agente
5/8Mantenimiento automatizado — automatización de dependencias configurada, no observada en los commits muestreados
3/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 3
Datos de entrada utilizados
has_nixno
has_tests
lockfilespackage-lock.json
has_dockerfile
typed_language
bootstrap_files
has_devcontainerno
has_linter_config
typecheck_configstsconfig.json
agent_commit_share1
toolchain_manifests
dependency_bot_commit_share0
Cómo se puntúa
45/45Código verificable por tipos — TypeScript (tipado estático)
55/55Tamaños de archivo manejables — 0/76 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languageTypeScript
largest_source_bytes43.434
source_files_sampled76
oversized_source_files0
Cómo se puntúa
0/40Esquema de API (OpenAPI/GraphQL/proto)
20/20Servidor MCP
0/40Ejemplos ejecutables
Datos de entrada utilizados
example_dirs
has_mcp_signal
api_schema_files

Datos clave

0estrellas de GitHub
2contribuidores
63commits en los últimos 12 meses
5días desde el último push
38versiones publicadas
1factor bus
4issues abiertas
npmecosistemas de paquetes

Advertencias de recopilación de datos

  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Más detalle

OpenSSF Scorecard 4.2 / 10
4.2agregado

Evaluación de seguridad independiente y agnóstica en cuanto a herramientas, procedente del proyecto de código abierto OpenSSF Scorecard. Cada comprobación premia una práctica de seguridad, no la herramienta de un proveedor concreto. Las comprobaciones que Scorecard no pudo determinar se marcan como n/d y se excluyen de la puntuación de seguridad (nunca se cuentan como cero).Scorecard v5.5.0 · 2026-07-27 20:21 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
10CI-Tests28 out of 28 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
10Dangerous-Workflowno dangerous workflow patterns detected
10Dependency-Update-Toolupdate tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
10Packagingpackaging workflow detected
3Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 3
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
n/dSigned-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
6Vulnerabilities4 existing vulnerabilities detected
Dependencias directas 2
RegistroPaqueteRestricción de versiónManifiesto
npm@modelcontextprotocol/sdk^1.29.0package.json
npmzod^4.4.3package.json
Todas las dependencias no recopilado

No fue posible recopilar el conjunto de dependencias resuelto para este informe: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Avisos de dependencias 1

Instalar npm:@apparelhub/mcp-server@0.5.12 arrastra 95 paquetes, directos y transitivos: 1 tienen avisos conocidos, de los cuales 0 son dependencias directas.

PaqueteVersiónRelaciónGravedadAvisosCorregido en
@hono/node-server1.19.15indirectamoderada12.0.5

Un aviso significa que la versión registrada en el grafo de dependencias cae dentro del rango afectado de un aviso. No se analiza la alcanzabilidad, y el grafo incluye fijaciones de desarrollo y prueba: un hallazgo puede referirse al utillaje y no al software distribuido.

Informe JSON sin procesar legible por máquina
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 462,
      "has_wiki": false,
      "homepage": null,
      "languages": {
        "Shell": 2343,
        "Python": 23590,
        "Dockerfile": 1230,
        "JavaScript": 2815,
        "TypeScript": 556111
      },
      "pushed_at": "2026-07-22T05:55:05Z",
      "created_at": "2026-07-01T00:44:00Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-21T01:36:08Z",
      "description": null,
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "TypeScript",
      "significant_languages": [
        "TypeScript"
      ]
    },
    "owner": {
      "blog": null,
      "name": null,
      "type": "Organization",
      "login": "ApparelHub-AI",
      "company": null,
      "location": null,
      "followers": 1,
      "avatar_url": "https://avatars.githubusercontent.com/u/289023539?v=4",
      "created_at": "2026-05-29T18:15:15Z",
      "is_verified": null,
      "public_repos": 5,
      "account_age_days": 59
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.5.12",
          "kind": "patch",
          "published_at": "2026-07-21T01:37:56Z"
        },
        {
          "tag": "v0.5.11",
          "kind": "patch",
          "published_at": "2026-07-20T21:27:31Z"
        },
        {
          "tag": "v0.5.10",
          "kind": "patch",
          "published_at": "2026-07-20T20:11:45Z"
        },
        {
          "tag": "v0.5.9",
          "kind": "patch",
          "published_at": "2026-07-20T03:32:40Z"
        },
        {
          "tag": "v0.5.8",
          "kind": "patch",
          "published_at": "2026-07-18T06:38:33Z"
        },
        {
          "tag": "v0.5.7",
          "kind": "patch",
          "published_at": "2026-07-18T01:02:46Z"
        },
        {
          "tag": "v0.5.6",
          "kind": "patch",
          "published_at": "2026-07-18T00:20:57Z"
        },
        {
          "tag": "v0.5.5",
          "kind": "patch",
          "published_at": "2026-07-17T22:57:19Z"
        },
        {
          "tag": "v0.5.4",
          "kind": "patch",
          "published_at": "2026-07-17T21:36:08Z"
        },
        {
          "tag": "v0.5.3",
          "kind": "patch",
          "published_at": "2026-07-16T16:07:27Z"
        },
        {
          "tag": "v0.5.2",
          "kind": "patch",
          "published_at": "2026-07-16T13:18:08Z"
        },
        {
          "tag": "v0.5.1",
          "kind": "patch",
          "published_at": "2026-07-16T00:57:30Z"
        },
        {
          "tag": "v0.5.0",
          "kind": "minor",
          "published_at": "2026-07-15T18:38:17Z"
        },
        {
          "tag": "v0.4.0",
          "kind": "minor",
          "published_at": "2026-07-11T01:50:49Z"
        },
        {
          "tag": "v0.3.14",
          "kind": "patch",
          "published_at": "2026-07-10T23:25:13Z"
        },
        {
          "tag": "v0.3.13",
          "kind": "patch",
          "published_at": "2026-07-10T06:24:31Z"
        },
        {
          "tag": "v0.3.12",
          "kind": "patch",
          "published_at": "2026-07-10T02:27:30Z"
        },
        {
          "tag": "v0.3.11",
          "kind": "patch",
          "published_at": "2026-07-09T19:36:41Z"
        },
        {
          "tag": "v0.3.10",
          "kind": "patch",
          "published_at": "2026-07-09T16:51:33Z"
        },
        {
          "tag": "v0.3.9",
          "kind": "patch",
          "published_at": "2026-07-09T15:57:02Z"
        },
        {
          "tag": "v0.3.8",
          "kind": "patch",
          "published_at": "2026-07-09T15:33:05Z"
        },
        {
          "tag": "v0.3.7",
          "kind": "patch",
          "published_at": "2026-07-09T15:06:18Z"
        },
        {
          "tag": "v0.3.6",
          "kind": "patch",
          "published_at": "2026-07-09T06:33:52Z"
        },
        {
          "tag": "v0.3.5",
          "kind": "patch",
          "published_at": "2026-07-09T03:51:01Z"
        },
        {
          "tag": "v0.3.4",
          "kind": "patch",
          "published_at": "2026-07-09T03:29:08Z"
        },
        {
          "tag": "v0.3.3",
          "kind": "patch",
          "published_at": "2026-07-09T01:27:48Z"
        },
        {
          "tag": "v0.3.2",
          "kind": "patch",
          "published_at": "2026-07-09T00:15:18Z"
        },
        {
          "tag": "v0.3.1",
          "kind": "patch",
          "published_at": "2026-07-08T22:39:18Z"
        },
        {
          "tag": "v0.3.0",
          "kind": "minor",
          "published_at": "2026-07-08T02:56:52Z"
        },
        {
          "tag": "v0.2.7",
          "kind": "patch",
          "published_at": "2026-07-07T23:34:24Z"
        },
        {
          "tag": "v0.2.6",
          "kind": "patch",
          "published_at": "2026-07-07T22:56:59Z"
        },
        {
          "tag": "v0.2.5",
          "kind": "patch",
          "published_at": "2026-07-07T22:29:09Z"
        },
        {
          "tag": "v0.2.4",
          "kind": "patch",
          "published_at": "2026-07-06T04:11:28Z"
        },
        {
          "tag": "v0.2.3",
          "kind": "patch",
          "published_at": "2026-07-06T03:05:21Z"
        },
        {
          "tag": "v0.2.2",
          "kind": "patch",
          "published_at": "2026-07-05T16:38:44Z"
        },
        {
          "tag": "v0.2.1",
          "kind": "patch",
          "published_at": "2026-07-05T08:59:10Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2026-07-05T07:54:58Z"
        },
        {
          "tag": "v0.1.1",
          "kind": "patch",
          "published_at": "2026-07-04T17:03:57Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "a8750b86de5f7362316fc069df6e6a8dd228f08c",
          "body": "…E_SOURCES (#122)\n\nFollow-up to v0.5.11. Flux 1.1 Pro's img2img is Flux Redux — a composition/style\nvariation, not an instruction-editor — so it is no longer offered for editing\n(the platform now returns a clean 400 for a Flux 1.1 Pro edit). Removed from\nEDIT_CAPABLE_SOURCES; iterate_design now reje\n[…]\nno tool description touched) -> should NOT reset Always-allow.\n324/324 vitest.\n\nCo-authored-by: ApparelHub Bot <bot-notifications@apparelhub.ai>\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v0.5.12: Flux 1.1 Pro is not an editor (Redux), drop from EDIT_CAPABL…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-21T01:36:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "65896033f52415798d8e590b97f2b8346907f8da",
          "body": "… (#121)\n\nRule-15 parity for apparelhub-ai#705 (per-model Replicate img2img editing).\n\n- EDIT_CAPABLE_SOURCES expands to every source EXCEPT Google Imagen 4 (the only\n  text-to-image-only source). The Replicate models — Seedream 4.0/4.5, Flux 1.1\n  Pro, Flux 2 Pro, Grok Imagine, Wan 2.7 — now suppor\n[…]\nthe next hosted deploy (re-grant if a scheduled\nrun stalls on iterate_design).\n\nCo-authored-by: ApparelHub Bot <bot-notifications@apparelhub.ai>\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v0.5.11: img2img edit works on almost every source (Replicate) (#705)…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-20T21:26:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "03bff2fbc9f0bcf349779e66225cd8f242755cba",
          "body": "…) (#120)\n\nRule-15 parity for apparelhub-ai epic #702 (config-driven OpenAI image sources,\nshipped to prod). Non-schema changes -> should NOT reset claude.ai Always-allow.\n\n- EDIT_CAPABLE_SOURCES adds 'GPT Image 2': it became a NATIVE gpt-image-2 source\n  (openai module) in #702, replacing the retir\n[…]\nplicit\nedit, kept out of the auto ladder). 324/324 vitest, tsc + eslint clean.\n\nCo-authored-by: ApparelHub Bot <bot-notifications@apparelhub.ai>\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v0.5.10: GPT Image 2 is edit-capable; OpenAI is async, not fast (#119…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-20T20:10:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9577d96ec9bfd899bf9c08e7a2615c03aaa0be8a",
          "body": "OpenAI's platform account is a shared billing surface and it's the least-\npreferred model; it should only ever be a last-resort fallback. Two spots still\ntried it first:\n  - pickSource(style:'abstract') returned 'OpenAI'\n  - ABSTRACT_LADDER started with 'OpenAI'\n\nNow pickSource always returns Nano B\n[…]\nsurfaces as model_rate_limited (429) instead of a 500 -> upstream_unavailable,\nso the fallback ladder cleanly skips it within a single request.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v0.5.9: OpenAI is never preferred first (operator directive) (#118)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-20T03:32:21Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "127900ceab8fbe32d8bab8b52bbc54c087a0846f",
          "body": "Agents previously had no way to see per-variant production COST or to\nprice to a target margin, so a flat price silently went negative on the\nbiggest sizes (costs tier by size). Two gaps closed:\n\n- ApiClient gains a put() method (mirrors patch) so the tool can drive\n  the per-variant PUT /product/{u\n[…]\n/ (1 - margin), then re-syncs connected channels. Skips variants\n  with no cost yet (not synced to fulfillment) and reports them.\n\nCloses #116.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v0.5.8: set_prices_by_margin tool + ApiClient.put() (#116) (#117)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-18T06:38:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0d9f152180dc3055fdddfdb8f25a5dc11d8abe59",
          "body": "…th (#115)\n\nGelato variant ids are strings (productUids like phonecase_apple_iphone-16_...),\nbut the MCP's variant handling assumed numeric ids. mapMatrix did\n`num(...) ?? 0`, so every Gelato variant became id 0 → mockupIdsCoveringColors\nderived nothing → create_product silently SKIPPED the mockup, \n[…]\nring productUid flows\nthrough end-to-end. 0.5.6 -> 0.5.7, 321 tests (1 new: Gelato create_product\nrenders a mockup with its string productUid).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Support string variant ids (Gelato productUids) across the product pa…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-18T01:02:30Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cabbf06fd2439255d86bf698fdb774dc77abdb47",
          "body": "…viders (#114)\n\nAfter #110 removed the hardcoded provider enum, there was no positive way for the\nmodel to answer \"what catalog providers do I have access to\" — it had to guess (and\nwould default to the two it knew). This adds a read-only list_catalog_providers tool\nthat returns the live, account-sc\n[…]\n.\n\nBumps 0.5.5 -> 0.5.6. 320 tests (1 new). Aligns with the #110 principle: the model\nasks the platform, it never assumes a fixed provider set.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add list_catalog_providers tool — discover the account's entitled pro…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-18T00:20:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f2f4fb1863f54de949a0a600426e606f2dba87a7",
          "body": "…onless (Gelato) (#113)\n\nGelato's product detail lists placements under top-level template_details with NO\narea/template dimensions — the real dims live on variants[].templates. The existing\nfallback to variant templates only fired when the top-level list was EMPTY, so for\nGelato it used the dimensi\n[…]\nintful (dimensioned top-level\nor empty+per-variant) is unaffected.\n\nBumps 0.5.4 -> 0.5.5. 319 tests pass (1 new). apparelhub-mcp#111 follow-up.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "get_garment_details: read variant templates when top-level is dimensi…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-17T22:57:03Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "bdb36b033a34415bb27b59aca7465424541e7a8c",
          "body": "…enum (#110) (#112)\n\nProvider access is an auth/entitlement decision that lives on the platform:\nGET /merchandise/providers is account-scoped + feature-flag-gated, returning\nexactly the providers THIS caller is entitled to. The browse_catalog /\nget_garment_details `provider` param was a static z.enu\n[…]\nes access.\n\nBumps 0.5.3 -> 0.5.4. 318 tests pass (2 new: accepts any entitled provider;\nunknown-provider error enumerates available providers).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Catalog tools: discover providers from the platform, not a hardcoded …",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-17T21:35:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "443e879548244d652241a1dd0dcc29063ef9ff6a",
          "body": "The add_order_item tool now forwards optional custom_price (the new item's\nper-unit retail price) and shipping_cost (order-level retail shipping the\ncustomer pays, not the provider cost) to POST /orders/<uuid>/items. Omitted ->\nthe variant price / existing shipping are preserved. Mirrors the platfor\n[…]\n clean, 316/316 vitest.\n\nBased off the released v0.5.2 tag (main is stale at 0.2.7 — the v0.3-0.5\nreleased line was never merged back to main).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v0.5.3: add_order_item accepts custom_price + shipping_cost (#656)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-16T16:04:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6a96e994565b21f4a0c761dfa63de278f5ad741b",
          "body": "New tools to add/remove items on a DRAFT order before confirm. Printful/Gelato\nedit the provider draft in place; Printify cancels + re-creates (edit_method\n\"recreated\" + new fulfillment_external_id — safe, drafts are uncharged). Relays\nedit_method/in_place/previous_external_id. Backend: apparelhub-ai#643.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v0.5.2: add_order_item / remove_order_item — edit a draft order (#643)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-16T13:18:04Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "4fe3ad6e7038330dd22f7f37f22661d33ed5a402",
          "body": "Agent-surface parity for the Gelato aspect-ratio feature (part of the\nGelato epic apparelhub-ai#526, Rule-15 agent-surface parity).\n\n- New `fit_aspect` tool: reshapes an EXISTING design to a target aspect\n  ratio via the platform route POST /images/generated/<uuid>/fit-aspect.\n  mode=\"pad\" letterbox\n[…]\nases (pad + nested-result mapping, background forwarding,\n  malformed aspect/background rejection). tsc build + eslint clean;\n  316 tests pass.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v0.5.1: fit_aspect tool + aspect-ratio guidance on generate_image (#107)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-16T00:57:24Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fdb214fc38c0fb6de78a8c3e27f817c6b8816e33",
          "body": "Mirror the new ApparelHub agent-API workspace/team routes so the connector\nreaches parity with the web UI for agency accounts. New src/tools/workspaces.ts\n(16 tools, wired into allTools):\n\n  workspaces  create_workspace / update_workspace / delete_workspace /\n              check_workspace_deletion /\n[…]\nsted MCP + npm client both call the PROD agent API, so these tools\nonly function once the backend routes are live on prod — release after that.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "tools: workspace & team management (v0.5.0) (#106)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-15T18:37:55Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6d23e1a77e551deaa481bcd2efdfb7fe3e92441a",
          "body": "…01) (#103)\n\nGarment Intelligence epic (apparelhub-ai#549) Phase 4. ship_product/create_product\nnow send the design + garment ref + print style to the platform's prepare-print-data\nservice (202 + poll) and receive the fully-composed per-placement print_data. The\nclient no longer holds the per-garmen\n[…]\nence-tested in apparelhub-ai). The\nprepare-print-data endpoint is live + verified on prod (apparelhub-ai#554).\n\nPart of epic apparelhub-ai#549.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v0.4.0: consume the platform print-data service; slim the package (#1…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-11T01:50:46Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "958906c56daf1a0ebc9849abb4b3c508dfe6bbd4",
          "body": "…#102)\n\n* feat(hosted): resolve garment layouts from the platform at runtime (mcp#100)\n\nGarment Intelligence epic (apparelhub-ai#549) Phase 2b. When the hosted server\nholds MCP_SERVICE_KEY, product composition resolves per-garment face layouts +\nprint-style routing + interior-surface blanking from t\n[…]\nease: v0.3.14 — hosted resolves garment layouts from the platform (mcp#100)\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "hosted: resolve garment layouts from the platform at runtime (#100) (…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-10T23:24:47Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ff1c8088b7ba0b0eea0306327abd282423ee9dfc",
          "body": "The scan used an extension allowlist (ts/js/mjs/cjs/md/json/yml/yaml)\nthat silently skipped python/*.py, deploy/*.sh, Dockerfile, and\nsamconfig.toml — the Python imaging helpers are exactly where a debug\nUUID or account reference could slip in. grep -I already skips\nbinaries, so the allowlist buys nothing; scan all tracked files except\nlockfiles. Verified the newly-covered files are clean before widening.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci: extend Rule 13 hygiene scan to every tracked file (#99)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-10T19:52:50Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "714133cfeb776fd8ddc0df04a49d38b6c729ec00",
          "body": "…-hat/mug) + interior-surface exclusion (#98)\n\nThe Merch QC discovery sweep (proactive probe-render + vision-grade across diverse garments)\nfound four new \"print area != visible FACE\" quirks. Each is grid-calibrated against the LIVE\nPrintful mockup and live-verified clip-free with a real subject+let\n[…]\n (outside_*, front/back/pocket)\nunaffected.\n\n360 vitest (7 new), tsc + eslint clean. Tool surface byte-identical (internal fill geometry only).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "v0.3.13: faceLayoutFor for 4 pilot-found quirks (tote/notebook/bucket…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-10T06:24:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4d3b3e234f4b22d3c509b57d696153a4f7722212",
          "body": "A stable-completion reconciler (self-delete only once the product set has been\nunchanged for a grace window) needs a \"last change\" timestamp, but\nlist_my_products dropped created/updated even though the list endpoint returns\nthem. A scheduled job hit this: all items reconciled, but it couldn't verif\n[…]\nductListItem now includes created + updated so a caller can measure\nrecency/stability. 353/353 vitest, tsc + eslint clean. Additive, read-only.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: expose created/updated on list_my_products (v0.3.12) (#91)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-10T02:27:27Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a60585701ff3cecf5c0c448a3c2975afe64cc6e4",
          "body": "…ket seam) (v0.3.11) (#90)\n\nThe SPAIN backpack split the goalkeeper's body and \"La Roja\" text across the\nfront-pocket seam. A Printful 279 All-Over Print Backpack has a front pocket\nwhose seam runs across the lower ~40% of the front face, so a design filling\nthe front area gets cut in half by it.\n\nf\n[…]\nll-over patterns that read fine when split can still be printed\nfull-bleed. 353/353 vitest (3 new), tsc + eslint clean. Tool surface unchanged.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: backpack designs favor the top half (no subject split by the poc…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-09T19:36:39Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "bf962e425a2c995ea169d65c775f476f1c27cec4",
          "body": "…10) (#89)\n\nThe MOROCCO water bottle clipped the flag star at the top and \"MOROCCO\" at\nthe base. A water bottle / tumbler / mug / glass print area WRAPS AROUND the\ntube — its top maps onto the shoulder/neck, its bottom onto the base, and its\nleft/right around the sides out of frontal view — so a des\n[…]\n Water Bottle (full crest: star + lion + MOROCCO all\nvisible with margin).\n\n350/350 vitest (2 new), tsc + eslint clean. Tool surface unchanged.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: inset designs on cylindrical drinkware so they don't clip (v0.3.…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-09T16:51:30Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6d5fe961d87edbd6cc19e19114eb64e11865d122",
          "body": "…9) (#88)\n\nAn hourly scheduled task skipped the NORWAY passport wallet every run and\ncould never finish: verify_design_quality returned a hard \"block\" on\nresolution (the 1024x1024 design keyed + tight-cropped to 847x396, min side\n< 600), and the task's algorithm skips any block-severity item — befor\n[…]\n (4 new), tsc + eslint clean. Repro-verified: NORWAY design\nkeys to 847x396 (BLOCK) -> upscales to 2000x935 (no block). Tool surface\nunchanged.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: low-res QC block auto-recovers instead of stranding a run (v0.3.…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-09T15:56:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "050b89295af42257e3ba1dcd00342f554ecbb9b4",
          "body": "…panels (v0.3.8) (#87)\n\nTwo refinements Tony flagged on the v0.3.7 renders:\n\n- Ear-cup lettering was clipped at the oval edge (the \"S\" in SPAIN). The\n  earcup art is now inset well within the oval safe area (56% width,\n  centered) so no lettering touches an edge. General rule: composed art on\n  an o\n[…]\nfixes\nlive-verified with real preview renders (SPAIN fully inside both ear cups;\nduffle fully covered, no white strip). Tool surface unchanged.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: no clipped lettering on ear cups + duffle hero-front with solid …",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-09T15:33:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2e18a01c6d55f2ea9e246f0d0c462303bc80141e",
          "body": "… (v0.3.7) (#86)\n\nThree more WC26 QC defects (headphones/wallet/duffle) + the passport-wallet\nresolution block. All grid-calibrated against the live providers.\n\nMulti-face / multi-piece — \"no blank faces\":\n- FaceLayout now carries faces: FaceRect[] (one rect per physical face, each\n  optionally rota\n[…]\nwallet logo upright\non BOTH faces, both headphone cups printed, duffle design on-face with no white\nstrip. Tool schemas/descriptions unchanged.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: no blank faces on multi-face/piece merch + resolution safety net…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-09T15:06:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "686bd9c26aa8325e7660d8fc5cc6c22ad493e44d",
          "body": "…nt coverage, single-dimension variants, centered non-apparel placed (v0.3.6) (#85)\n\nFour QC defects from the WC26 scheduled-task builds, all systemic:\n\n1. Print area != visible FACE (ENGLAND sock + drawstring incidents). Grid-file\n   preview calibration against the live providers established:\n   - \n[…]\nenter (back_center math).\n\n337/337 vitest (16 new), tsc clean. Tool schemas/descriptions unchanged (no\nclaude.ai Always-allow reset on deploy).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: face-aware fill (sock rotation, wrap face regions), full placeme…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-09T06:33:30Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1a21db3c79385d4a0242a89e41edfea8a36ff359",
          "body": "…eal (v0.3.5) (#84)\n\nLive E2E of v0.3.4 embroidery support surfaced Printful's option-id quirk:\nthe PLAIN embroidery_front placement (e.g. beanies) expects the BARE\n`thread_colors` option id, while embroidery_front_large (caps) and\nembroidery_chest_left take the placement-suffixed form. All three sh\n[…]\nuilds) surface the original error unchanged.\n- ship_product/sync_to_fulfillment report the correction when it happens.\n\n321 tests pass (4 new).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: thread-colors option id for plain embroidery_front + sync self-h…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-09T03:50:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "270cb7d993435281a051a0f6f1d9fd855abb2318",
          "body": "…ce goods (v0.3.4) (#83)\n\nTwo systemic pipeline fixes surfaced by automated runs:\n\n1. Embroidery garments (#81): fetchGarment read only top-level template keys,\n   which the raw garment endpoint never returns — so every garment fell back to\n   placement 'front' + 1800x2400 defaults. Correct for DTG,\n[…]\nront_large renders\nphotoreal first-poll; recompose output validated against the real artwork.\n318 tests pass (12 new).\n\nCloses #81. Closes #82.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: embroidery placements + thread colors, fill-face printing for fa…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-09T03:29:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "102c8b43a04eac5976bc0d8befbc196fbd4052b0",
          "body": "…(v0.3.3) (#80)\n\nship_product generated the mockup from the first 5 resolved variants, which for a\nmulti-color order (e.g. Black + White) are all one color (Black's sizes come first) —\nso the other colors shipped with no mockup and the gallery only showed black.\n\nNew mockupIdsCoveringColors() picks \n[…]\nship_product with Black+White requests a mockup for [firstBlack, firstWhite], not\ntwo blacks. 288 tests pass, typecheck + lint + build clean.\n\nCo-authored-by: Claude (for Tony) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(product): mockups cover every imported color, not just the first …",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-09T01:27:30Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "27b9f313fc6ac11b112b9634c6953e50739a7f36",
          "body": "…rix (v0.3.2) (#79)\n\nPrintify's variant matrix carries the variant id under `provider_ref_id` (a numeric\nstring) with no id/variant_id/provider_variant_id field. mapMatrix (used by\nship_product/create_product/add_variants) didn't read provider_ref_id, so every\nPrintify variant resolved to id 0 -> th\n[…]\nnts resolves a Printify-shaped variant (provider_ref_id) by color+size\nto the real id, not 0. 287 tests pass, typecheck + lint + build clean.\n\nCo-authored-by: Claude (for Tony) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(product): read Printify variant id from provider_ref_id in mapMat…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-09T00:15:03Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e3ea3d5f5083174048abece74a508fd0ecb4db00",
          "body": "…, variants, self-heal sync (v0.3.1) (#78)\n\n* fix(product): associate product with store in the split-primitive sync path + self-heal sync_to_channel (v0.3.1)\n\nA scheduled/automated agent that chained create_product -> add_variants ->\nsync_to_channel hit \"product not associated with store\" and left \n[…]\nriants throws on 0-resolved. 286 passing,\ntypecheck + lint + build clean.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude (for Tony) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: reliable automated product pipeline — store association, mockups…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-08T22:25:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "260fbf833d049c6d1e0750ef6045d534ca75e7f7",
          "body": "… (#77)\n\napparelhub-mcp is a public repo, so .github/workflows/*.yml is world-readable.\ndeploy-hosted.yml hardcoded all three AWS account ids (Hub/dev/prod) and the Hub\nIaCProvisioningRole ARN in plaintext. Move them to secrets:\n\n- HUB_ROLE_ARN      -> repo secret (shared across environments)\n- TARG\n[…]\nt_target` trigger or grant `id-token: write` to a PR-triggered\nworkflow in this public repo — a fork PR could otherwise assume the deploy role.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci: keep AWS account ids + Hub role ARN out of public workflow source…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-08T19:51:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9d0af861b6bbb962e29a8ddf83f87cb8e1c16c1a",
          "body": "…(epic apparelhub-ai#510) (#73)\n\nAdds the post-sale fulfillment-issue tool group (4 tools, surface 74 -> 78)\nover the new /agents/v1 issue endpoints. Providers accept problem reports\nonly in their own dashboards, within 30 days of delivery (free reprint or\nwallet refund), so the tools compute the wi\n[…]\n 0.3.0;\nversion bumped to 0.3.0 in package.json + src/version.ts (kept in sync for the\nversion unit test). Generic placeholders only (Rule 13).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: fulfillment-issue tools — report, list, check, resolve/replace …",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-08T02:39:42Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e19f44ec9a2dce31d506a44849682b76bd71f533",
          "body": "Version bump + changelog cut for #70 (#72): generate_image no longer fails for\nvalid models on a near-miss source name or a synchronous success response.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: v0.2.7 — source validation + synchronous-response parsing",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-07T23:34:06Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5518a274f5c96a9504289147df71c4ea4837d569",
          "body": "… response (#70) (#72)\n\nTwo fixes so image generation via the MCP tools stops failing for valid models:\n\nB1 - generate_image / design_apparel / iterate_design forwarded `source`\nverbatim (unvalidated). A near-miss name reached the platform, where the\nsource-name match is case-insensitive but the slo\n[…]\nerate_image rejecting an unknown source + never\ncalling the API. Full suite green (261). Companion platform hardening:\nantoniomercado/apparelhub-ai#508.\n\nCo-authored-by: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "generate_image: validate/normalize source + parse synchronous success…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-07T23:32:44Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "73c0f84836b56eab017b121561aa1b4397d49a04",
          "body": "Version bump + changelog cut for epic #66 Phase 2 (#68/#71). Completes the epic.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: v0.2.6 — honest structured error attribution",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-07T22:57:00Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1f9ccba1de3c2b093087b3b86222482d10167ab5",
          "body": "Make every failure carry an honest, structured cause so an agent can\nnever claim \"ApparelHub is rate-limited\" when ApparelHub returned no\nsuch error (the motivating incident: a harness-side 429 was confidently\nreported as an ApparelHub rate limit while ApparelHub had received no\nrequest at all).\n\n- \n[…]\nilure falls back\n  via the precise code; platform_rate_limited surfaces without\n  fallback; all-rungs-throttled keeps code model_rate_limited).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Phase 2: honest structured error attribution (#68) (#71)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-07T22:56:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cf1b13185175eed89d27657a2dfbcad5ca1350de",
          "body": "Version bump + changelog cut for the epic #66 Phase 1 ship (#67/#69).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: v0.2.5 — model-fallback ladder for image generation",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-07T22:28:52Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "3fff0339858f8a0bccc932ec6332de3d36fffbbc",
          "body": "An unattended agent got stuck when it hit a rate limit because every\ngeneration defaulted to the same model (Nano Banana) and never varied the\nsource. Add a model-fallback ladder so a genuine model/platform rate limit or\na transient failure transparently retries with a DIFFERENT model (on a\ndifferen\n[…]\navior (substitute on transient,\n  immediate throw on non-fallbackable, all-fail-with-trail, no_fallback).\n  236 tests pass; build + lint clean.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Phase 1: model-fallback ladder for image generation (#67) (#69)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-07T22:27:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "dc40ee0ba3abed364b847bdab980e84abef8b263",
          "body": "The hosted Lambda now emits one CloudWatch EMF metric line per request\n(namespace ApparelHub/MCP): Requests + LatencyMs, dimensioned by Outcome and\n(for tools/call) ToolName — no per-identity dimension (low cardinality, no\nuser data). CloudWatch auto-extracts the metrics; no PutMetricData call. The\n\n[…]\natus, parseRpc, buildEmf)\n- src/http/lambda.ts: emit per request (skip healthz)\n- deploy/hosted/template.yaml: ConnectorDashboard\n- 9 new tests\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(hosted): connector-traffic observability (epic #36, v0.2.4) (#65)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-06T04:11:22Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "87adcb91d970d153bd551a58032f8d023822a8f9",
          "body": "…2.3) (#64)\n\nThe platform store payload returns the fulfillment provider under `providers`\nand connected channels under `active_integrations`, but the mapper read\n`merchandise_providers`/`fulfillment_providers` + `ecommerce_integrations`/\n`integrations`. So every store surfaced \"no fulfillment provi\n[…]\ntest uses the exact live `providers`\nshape. Channels also need the platform list serializer to include\nactive_integrations (apparelhub-ai#502).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(read): list_my_stores reads the real provider/channel fields (v0.…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-06T03:05:15Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5d9cb56c05ef404de8f72d256d924b579e6d217f",
          "body": "…0.2.2) (#63)\n\nBelt-and-suspenders for unattended runs, on top of the 0.2.1 dominance\nauto-recovery. If keying still can't finish (missing toolchain, or a hard\nkeyer failure), design_apparel now keeps the raw design with\ntransparency_clean:false + a clear warning instead of throwing and killing\nthe \n[…]\nnkeyed design.\n\n- degrade set: local_tool_unavailable + transparency_failed\n- 2 new tests (keying hard-fail degrades; transient error surfaces)\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(design): design_apparel never aborts a good design over keying (v…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-05T16:38:12Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1760d3409ff2cdbbae880c4a64bf51498b7c8c1e",
          "body": "…split (#35) (#62)\n\nThe hosted Lambda hardcoded API_BASE_URL (prod), so the dev-account deploy\nintegrated with the prod platform — a second door to prod, not a dev env.\nAdd APPARELHUB_API_BASE_URL (SAM parameter ApparelhubApiBaseUrl -> Lambda\nenv), used for BOTH tool calls and OAuth token resolution\n[…]\ny-hosted.yml: pass it from the per-env GitHub var MCP_API_BASE_URL\n- test: asserts the dev base redirects resolve-token AND the downstream call\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(hosted): env-configurable platform base URL for a true dev/prod …",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-05T09:07:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1830182f2023efeb9b5b0d0b4555325244d0dcbf",
          "body": "…unds (v0.2.1) (#61)\n\nAI image models routinely render the \"solid #00FF00\" background as a\ntinted/muted green (e.g. #80E77B, #A6FB93). The box keyer's chroma sanity\ncheck refuses those (to protect warm design elements) and there was no\noverride exposed, so an unattended run got stuck regenerating a \n[…]\nminance auto-fallback (only when no mode/force pinned)\n- 3 new tests (recovery, explicit-mode-surfaces-error, box happy path)\n- v0.2.0 -> 0.2.1\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(design): auto-recover transparency keying on tinted green backgro…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-05T08:55:52Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6711dac8a319a9b181db51d15fb2b4720bac1b6d",
          "body": "…#59)\n\nREADME tool groups + docs/TOOLS.md sections for orders, analytics, collections,\ncross-workspace transfer, store/order management, and the api_request /\nget_api_reference escape hatch; list_my_workspaces added to Read. Bump to 0.2.0\n(SERVER_VERSION kept in sync) + CHANGELOG. Closes #55 (epic #47).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs + v0.2.0: document the capability-gap tools (surface 26 -> 74) (…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-05T07:54:53Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "0ddd8dd87050983b6cdcb487fa9bcad5fc445c66",
          "body": "…, management) + api_request escape hatch (#58)\n\nEpic #47. 47 new tools closing the read/act parity gaps found by the tool-vs-API\naudit, plus the generic escape hatch:\n- orders: approve/unapprove/hold/cancel/confirm/submit-fulfillment/check-status/reconcile + hold list/approve/request-changes (#48/#\n[…]\nainst the platform handlers; all tools carry MCP annotations\n(readOnlyHint/destructiveHint). tsc clean, 209 tests, eslint clean, Rule 13 clean.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "tools: capability-gap tools (orders, analytics, collections, transfer…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-05T07:12:06Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "867081f0880bdc5732f9b79226f6ce30bf0f1e9b",
          "body": "…e public repo (#57)\n\nThe previous guard hardcoded the real names it forbids into the workflow file,\nwhich (in a public repo) published the very terms it exists to keep out. Move\nthe name/account term list into the FORBIDDEN_TERMS repo secret and grep against\nthat. Every check now runs with grep -q \n[…]\n is never echoed into\nthe public build logs; errors name only the category. UUID + host patterns stay\ninline (they are generic, not sensitive).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "hygiene: move forbidden-term list into a secret; keep terms out of th…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-05T07:10:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2f09cc62664d1a5c5b71d12653928c6e4cc8641a",
          "body": "…rd (#56)\n\n* hygiene: scrub a real name from a tool description + add Rule 13 CI guard\n\nThis is a public repo. The list_my_workspaces description (#46) used a real\nperson's name as an example; replace it with a generic phrasing. Add a\nforbidden-patterns workflow that fails CI on real names / account\n[…]\nthe public repo again.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n* hygiene: guard must not scan its own pattern list\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "hygiene: scrub real name from a tool description + add Rule 13 CI gua…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-05T06:47:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cb0104849d22cdec4c88026e791e9effb40b824b",
          "body": "An agency/multi-brand account has more than one workspace (e.g. one per\nclient), and the store/product/order/design tools scope to the Default\nworkspace unless given workspace=<uuid>. There was no tool to enumerate\naccessible workspaces, so an agent couldn't resolve a workspace by name (e.g.\na clien\n[…]\nnot_found error hints to point at it. The connector key is already\naccount-wide, so this unlocks the workspaces the account can already act in.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "tools: add list_my_workspaces so agents can reach other workspaces (#46)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-05T06:18:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cff1633ea83923187dbc16feec1ecfae828d5a97",
          "body": "Behind CloudFront (mcp.apparelhub.ai), the Lambda Function URL requires its own\nHost, so CloudFront rewrites Host to the *.lambda-url origin. The server was\ncomputing its OAuth protected-resource metadata + WWW-Authenticate challenge\nfrom that Host, so it advertised the raw Function URL instead of the branded\ndomain. Prefer X-Forwarded-Host (set by CloudFront) with a Host fallback for\ndirect Function-URL hits.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "hosted: advertise the branded host via X-Forwarded-Host (#44/#35) (#45)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-04T22:31:39Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "eca09b2e97dd187b9afcfb1c9d6eac62fd7b27f8",
          "body": "…adata (#41) (#43)\n\n- GET /.well-known/oauth-protected-resource (RFC 9728) advertises the\n  authorization server when MCP_OAUTH_ISSUER is set — how surfaces\n  discover the OAuth flow.\n- Authorization: Bearer <opaque token> resolves via the platform's\n  service-authenticated resolve-token endpoint (h\n[…]\nbearer, fail-closed 503, static-path refused when flag off. Suite: 120.\n\nPlatform counterpart: antoniomercado/apparelhub-ai#497 (Phases 2A+2B).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Phase 2 server side: OAuth bearer resolution + protected-resource met…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-04T21:02:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7b4421bbf29c4e0b8e7d4839d5e5cdd8e39024b7",
          "body": "The handler was silent, which made the first connector-integration issue\nundiagnosable from CloudWatch. One JSON line per request (method, path,\nstatus, ms); any secret-length path segment is redacted to its length plus\na sha256 prefix so a wrong-bearer probe is diagnosable without ever logging\nsecret material.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "hosted: structured per-request logging with secret redaction",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-04T18:05:16Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "72ca3cde726e3f9dbf1b6aa6e29f31bb9c8910da",
          "body": "The Lambda node22 base image's python3 lacks a working ssl module, so pip\ncannot reach PyPI during docker build (CI run 28713648215). python3-pillow\nfrom the AL2023 repo provides PIL without touching pip.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "hosted: install Pillow from the distro repo, not pip",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-04T17:15:41Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "4b8e075db91fcf29f61fa95fc84e5636127840be",
          "body": "Graduates the Phase 0.5 prototype into the real hosted shape from the epic\ndecisions:\n\n- deploy/hosted/: SAM stack with PackageType Image. The Dockerfile layers\n  python3 + Pillow onto the Lambda node22 base so the imaging tools\n  (process_transparency, verify_design_quality stats) work hosted inste\n[…]\n Docker context is allowlisted to the prebuilt bundle + python helpers.\n\nSame handler, same static bearer interim auth; OAuth is Phase 2 (#34).\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Phase 1: container-packaged hosted server + CI deploy workflow (#40)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-04T17:12:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "973db38373000c138cf756fa333a5cc48672a030",
          "body": "Catalog fixes from the first hosted field test (#38) plus the streamable-HTTP\nLambda entry point. Also dates the 0.1.0 heading and rolls its content out of\nUnreleased.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release 0.1.1",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-04T17:03:55Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c5ea44d9c77991a2c6fc47d47bf40ad762c4b3f1",
          "body": "…t field test (#39)\n\n* Phase 0.5: stateless streamable-HTTP Lambda entry point (#38)\n\nServes the existing tool surface over MCP streamable HTTP from a Lambda\nFunction URL, per the epic #31 decisions comment:\n\n- WebStandardStreamableHTTPServerTransport in stateless mode with\n  enableJsonResponse: a f\n[…]\nyed\nprototype (browse -> ref ids -> details -> variant matrix + templates).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\n\n---------\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Phase 0.5: hosted streamable-HTTP prototype + catalog fixes from firs…",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-04T17:02:41Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6d1638c80ce0a235bff844b372382a18ac764212",
          "body": "- README: what it is, requirements, install + MCP config snippets for Claude\n  Code / Cursor / Aider / claude.ai, env vars, the full tool catalog, privacy,\n  the skill-vs-MCP relationship, and versioning/stability.\n- docs/TOOLS.md: the 26-tool reference, grouped, with conventions.\n- docs/RELEASING.m\n[…]\ng, and the /agents+/mcp funnel wait until\nthe repo is flipped public (per the ticket); the pipeline + docs are ready.\n\nCloses #20. Part of #11.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Distribution: full README, tool reference, release runbook (#20) (#30)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-01T21:53:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "feb330932564953749306cff09f25ecc9b6de357",
          "body": "Wire the privacy-bounded per-tool-call event signal: {tool, outcome,\nerror_code?, latency_ms, coarse_features}. Buffered + batched, fire-and-forget\n(a telemetry failure never affects a tool), off via APPARELHUB_MCP_TELEMETRY=off.\n\nPrivacy is enforced in code, two ways: a strict per-tool allowlist of\n[…]\ns/v1/telemetry) is a pending apparelhub-ai\nbackend workstream; until it ships, batched sends fail silently by design.\n\nCloses #19. Part of #11.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Minimal client-side telemetry signal (#19) (#29)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-01T21:48:57Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c274dc3923a3ae59f73e2ac4a35a4e0a9de010c9",
          "body": "verify_design_quality + check_design_compliance (tool spec §7).\n\n- verify_design_quality is the objective, local QC gate: alpha channel,\n  clean corners, white pre-multiply (Printful dark-halo guard), resolution,\n  and detected text -> a 0-100 score + issues. Uses a bundled image_stats.py;\n  degrade\n[…]\ncommon protected marks + prohibited terms, with\n  a clear \"not legal advice / not an image-content check\" disclaimer.\n\nCloses #18. Part of #11.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Safety / compliance tools (#18) (#28)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-01T21:43:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "25c2ddcac25a15a80bcd5706ba7b56e968f07a74",
          "body": "analyze_what_works, auto_optimize_listings, cascade_price_change,\nrecover_from_outage (tool spec §6). Multi-step, policy-bounded workflows\nover the merchant's own data.\n\n- analyze_what_works: own-account insights (best seller, top channel, AOV)\n  with honest confidence; cross-merchant intelligence i\n[…]\n_outage diagnoses failed fulfillment/channel syncs and retries\n  them only when explicitly applied with a store_uuid.\n\nCloses #17. Part of #11.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Systems of action (#17) (#27)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-01T21:37:26Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4dbb11bc52b1d2f11e270b1c61bda7384ada2fdf",
          "body": "ship_product + update_product / delete_product and the split primitives\ncreate_product, add_variants, sync_to_fulfillment, sync_to_channel\n(tool spec §3 + §3.5).\n\nEmbedded lessons: the create endpoint's field names (provider_uuid /\nproduct_ref_id / price / print_data) which differ from the mockup en\n[…]\npricing\nfloors enforced so a negative-margin price is refused; and the BC 3001\nAQUA-vs-Navy variant guard (Lesson 7).\n\nCloses #16. Part of #11.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Product workflows: the 7-phase pipeline (#16) (#26)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-01T21:31:42Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "076ae74dc6a7b17ab29c20e00e464a45f6ca5afc",
          "body": "design_apparel + iterate_design and the split primitives generate_image,\nprocess_transparency, verify_design_text (tool spec §2 + §3.5), plus the\nplacement-dimensions helper.\n\n- Async-generation contract: POST /images/generate, and for slow models\n  (Nano Banana etc.) poll /images/upload/{uuid}/stat\n[…]\nayer is injectable, so the orchestration is unit-tested with\n  a fake; the bundled script is smoke-tested end-to-end.\n\nCloses #15. Part of #11.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Design workflows + local image processing (#15) (#25)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-01T21:23:34Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a607ec145e03a0ecdb778a99b1458009fb45075c",
          "body": "browse_catalog, get_garment_details, recommend_garment (tool spec §4). These\nwrap the provider catalog endpoints (resolving the provider name to its uuid\nvia GET /merchandise) and add the garment-selection moat: positive-margin\npricing floors, quality-tier classification, and the BC 3001 AQUA-vs-Nav\n[…]\nrap surfaced on get_garment_details. recommend_garment is a\nknowledge-based advisory pick + rationale + alternatives.\n\nCloses #14. Part of #11.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Catalog tools with embedded garment knowledge (#14) (#24)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-01T21:09:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2e1bc2ff1f4281c569003945bcffcfa780c0fb86",
          "body": "Add the rest of the read surface (tool spec §5) alongside list_my_stores:\nlist_my_designs, list_my_products (per-store or all), list_my_orders, and\nget_order_details. Clean, agent-friendly projections with a view_url back\ninto apparelhub.ai; workspace-aware; tolerant field-name mappers.\n\nCloses #13. Part of #11.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Read tools: designs, products, orders, order details (#13) (#23)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-01T21:02:47Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2657ac4a9397d8379594495fd41bdfefb0647b56",
          "body": "Bootstrap @apparelhub/mcp-server, a stdio MCP server whose tools wrap the\nApparelHub Agent API at the workflow level.\n\n- MCP server over stdio (@modelcontextprotocol/sdk); tool registry with\n  zod-validated input schemas advertised to tools/list.\n- Connection-level auth: reads APPARELHUB_API_KEY, pi\n[…]\ned npm-publish workflow\n  (dry-run until an NPM_TOKEN secret is added). Dependabot for npm + actions.\n\nPart of ApparelHub-AI/apparelhub-mcp#11.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Foundation: MCP server scaffold, plumbing, and CI (#12)",
          "author_name": "Antonio Mercado",
          "author_login": "antoniomercado",
          "committed_at": "2026-07-01T20:56:15Z",
          "body_truncated": true,
          "is_coding_agent": true
        }
      ],
      "releases_count": 38,
      "commits_last_year": 63,
      "latest_release_at": "2026-07-21T01:37:56Z",
      "latest_release_tag": "v0.5.12",
      "releases_from_tags": false,
      "days_since_last_push": 5,
      "active_weeks_last_year": 4,
      "days_since_latest_release": 6,
      "mean_days_between_releases": 0.5
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": false,
      "has_contributing": false,
      "health_percentage": 25,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "@apparelhub/mcp-server",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "mcp",
            "model-context-protocol",
            "apparelhub",
            "print-on-demand",
            "ecommerce",
            "ai-agents",
            "agentic-commerce"
          ],
          "ecosystem": "npm",
          "matches_repo": true,
          "registry_url": "https://www.npmjs.com/package/@apparelhub/mcp-server",
          "is_deprecated": false,
          "latest_version": "0.5.12",
          "repository_url": "https://github.com/ApparelHub-AI/apparelhub-mcp",
          "versions_count": 39,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 4935,
          "first_published_at": "2026-07-02T22:19:14.620000Z",
          "latest_published_at": "2026-07-21T01:38:23.885000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 6
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 0,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_stars": 0,
        "collected_at": null
      },
      "open_issues_and_prs": 10
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": true,
      "has_mcp_signal": true,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 43434,
      "source_files_sampled": 76,
      "oversized_source_files": 0,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "package.json"
      ],
      "advisories": {
        "error": null,
        "scope": "published_package",
        "source": "osv",
        "findings": [
          {
            "name": "@hono/node-server",
            "direct": false,
            "version": "1.19.15",
            "severity": "moderate",
            "ecosystem": "npm",
            "cvss_score": 5.9,
            "advisory_ids": [
              "GHSA-frvp-7c67-39w9"
            ],
            "fixed_version": "2.0.5",
            "advisory_count": 1,
            "oldest_advisory_days": 6
          }
        ],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {
          "moderate": 1
        },
        "advisory_count": 1,
        "affected_count": 1,
        "assessed_count": 95,
        "malicious_count": 0,
        "assessed_package": "npm:@apparelhub/mcp-server@0.5.12",
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm"
      ],
      "dependencies": [
        {
          "name": "@modelcontextprotocol/sdk",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^1.29.0"
        },
        {
          "name": "zod",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "^4.4.3"
        }
      ],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 6,
        "merged_prs": 54,
        "open_issues": 4,
        "closed_ratio": 0.918,
        "closed_issues": 45,
        "closed_unmerged_prs": 2
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "antoniomercado",
          "commits": 62,
          "avatar_url": "https://avatars.githubusercontent.com/u/8753143?v=4"
        },
        {
          "type": "User",
          "login": "claude",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/81847?v=4"
        }
      ],
      "contributors_sampled": 2,
      "top_contributor_share": 0.984
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "deploy-hosted.yml",
        "forbidden-patterns.yml",
        "publish.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [
        "eslint.config.js"
      ],
      "has_editorconfig": false,
      "has_linter_config": true,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "package-lock.json"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "28 out of 28 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 0,
            "reason": "project has 0 contributing companies or organizations -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 10,
            "reason": "update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 0,
            "reason": "project was created within the last 90 days. Please review its contents carefully",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 3,
            "reason": "dependency not pinned by hash detected -- score normalized to 3",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 6,
            "reason": "4 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "a8750b86de5f7362316fc069df6e6a8dd228f08c",
        "ran_at": "2026-07-27T20:21:44Z",
        "aggregate_score": 4.2,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": true
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-22T05:55:10Z",
      "oldest_open_prs": [
        {
          "number": 22,
          "created_at": "2026-07-01T20:56:48Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 74,
          "created_at": "2026-07-08T05:53:55Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 75,
          "created_at": "2026-07-08T05:53:58Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 104,
          "created_at": "2026-07-15T05:53:58Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 105,
          "created_at": "2026-07-15T05:54:45Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 109,
          "created_at": "2026-07-16T16:23:13Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-07-21T01:36:04Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 92,
          "created_at": "2026-07-10T05:06:18Z",
          "last_comment_at": "2026-07-11T00:14:34Z",
          "last_comment_author": "antoniomercado"
        },
        {
          "number": 95,
          "created_at": "2026-07-10T05:06:48Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 96,
          "created_at": "2026-07-10T05:06:49Z",
          "last_comment_at": "2026-07-11T00:14:34Z",
          "last_comment_author": "antoniomercado"
        },
        {
          "number": 97,
          "created_at": "2026-07-10T05:06:50Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/ApparelHub-AI/apparelhub-mcp",
    "host": "github.com",
    "name": "apparelhub-mcp",
    "owner": "ApparelHub-AI"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 57,
      "inputs": {
        "security": 51,
        "vitality": 73,
        "community": 33,
        "governance": 53,
        "engineering": 72
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 73,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 55,
            "inputs": {
              "commits_last_year": 63,
              "human_commit_share": 1,
              "days_since_last_push": 5,
              "active_weeks_last_year": 4
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 5 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 5
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "4/52 weeks with commits",
                "points": 2.8,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 4
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "63 commits in the last year",
                "points": 16.2,
                "status": "partial",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 63
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 38,
              "latest_release_tag": "v0.5.12",
              "releases_from_tags": false,
              "days_since_latest_release": 6,
              "mean_days_between_releases": 0.5
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "38 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 38
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 6 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 6
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~0.5 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 0.5
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 33,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 0,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "0 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "moderate",
            "name": "Ecosystem adoption (downloads)",
            "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "registry_dependents"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 62,
            "inputs": {
              "packages": [
                "@apparelhub/mcp-server"
              ],
              "dependents": null,
              "ecosystems": "npm",
              "total_downloads": null,
              "monthly_downloads": 4935
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "4,935 downloads/month across npm",
                "points": 49.2,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 4935,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "not reported by this ecosystem",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_reported_by_this_ecosystem",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 53,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 12,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 2,
              "top_contributor_share": 0.984
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 98% of commits",
                "points": 0.4,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 98
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "2 contributors",
                "points": 2.7,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 80,
            "inputs": {
              "merged_prs": 54,
              "open_issues": 4,
              "closed_issues": 45,
              "issue_closed_ratio": 0.918,
              "closed_unmerged_prs": 2
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "92% of issues closed",
                "points": 42.9,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 92
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "54/56 decided PRs merged",
                "points": 36.9,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 54,
                      "decided": 56
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 38,
            "inputs": {
              "followers": 1,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "ApparelHub-AI",
              "public_repos": 5,
              "account_age_days": 59
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "1 followers of ApparelHub-AI",
                "points": 2.2,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 1,
                      "login": "ApparelHub-AI"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "5 public repos, account ~0 yr old",
                "points": 6,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 5
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 0
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "@apparelhub/mcp-server"
              ],
              "ecosystems": "npm",
              "any_deprecated": false,
              "min_days_since_publish": 6
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on npm",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 6 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 6
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "39 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 39
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "good",
        "name": "Engineering Quality",
        "value": 72,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "good",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 84,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": true,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "4 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 4
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": "eslint.config.js",
                "points": 16,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "eslint.config.js"
                    }
                  }
                ],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "28 out of 28 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 55,
            "inputs": {
              "topics": [],
              "has_wiki": false,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "moderate",
        "name": "Security",
        "value": 51,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 42,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 17,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 1,
              "scorecard_aggregate": 4.2
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "28 out of 28 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "update tool detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 3",
                "points": 1.5,
                "status": "partial",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "4 existing vulnerabilities detected",
                "points": 4.5,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "excellent",
            "name": "Dependency advisories",
            "note": "Matched the npm:@apparelhub/mcp-server@0.5.12 runtime dependency closure — what installing the published package pulls in — 95 packages. Reachability is not analyzed.",
            "notes": [
              {
                "code": "advisories_scope_published",
                "params": {
                  "package": "npm:@apparelhub/mcp-server@0.5.12",
                  "assessed": 95
                }
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 88,
            "inputs": {
              "source": "osv",
              "advisories": 1,
              "affected_packages": 1,
              "assessed_packages": 95,
              "unassessed_packages": 0,
              "affected_by_severity": "moderate 1",
              "direct_affected_packages": 0
            },
            "components": [
              {
                "key": "direct_dependencies_free_of_known_advisories",
                "name": "Direct dependencies free of known advisories",
                "detail": "no direct dependency carries a known advisory",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "no_direct_advisories",
                    "params": {}
                  }
                ],
                "max_points": 35
              },
              {
                "key": "indirect_dependencies_free_of_known_advisories",
                "name": "Indirect dependencies free of known advisories",
                "detail": "1 affected: @hono/node-server 1.19.15 (moderate 5.9)",
                "points": 13.2,
                "status": "partial",
                "details": [
                  {
                    "code": "advisories_affected",
                    "params": {
                      "count": 1,
                      "packages": "@hono/node-server 1.19.15 (moderate 5.9)"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "no advisory has been public longer than 90 days",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "advisories_none_stale",
                    "params": {
                      "days": 90
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "malicious_dependencies",
            "band": "excellent",
            "name": "Malicious dependencies",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "source": "osv",
              "meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
              "packages": [],
              "red_flag": false,
              "assessed_packages": 95,
              "malicious_packages": 0,
              "direct_malicious_packages": 0,
              "withdrawn_malicious_packages": 0,
              "installable_malicious_packages": 0
            },
            "components": [
              {
                "key": "no_dependency_reported_as_a_malicious_package",
                "name": "No dependency reported as a malicious package",
                "detail": "no dependency is reported as a malicious package",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "no_malicious_dependencies",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 59,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "at_risk",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 1,
              "agent_instruction_files": [],
              "agent_instruction_max_bytes": null
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "no CLAUDE.md / AGENTS.md / editor rules",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_instructions",
                    "params": {}
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "63 of 63 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 63,
                      "sampled": 63
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "good",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 72,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "package-lock.json"
              ],
              "has_dockerfile": true,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": true,
              "typecheck_configs": [
                "tsconfig.json"
              ],
              "agent_commit_share": 1,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": "eslint.config.js",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "eslint.config.js"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "tsconfig.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "Dockerfile, lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Dockerfile, lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "63 of the last 63 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 63,
                      "sampled": 63
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "dependency automation configured, none observed in the sampled commits",
                "points": 5,
                "status": "partial",
                "details": [
                  {
                    "code": "dependency_bot_config_only",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 3",
                "points": 3,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "primary_language": "TypeScript",
              "largest_source_bytes": 43434,
              "source_files_sampled": 76,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "TypeScript (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "TypeScript"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/76 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 76,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "critical",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 20,
            "inputs": {
              "example_dirs": [],
              "has_mcp_signal": true,
              "api_schema_files": []
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-27T20:22:02.065868Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/a/ApparelHub-AI/apparelhub-mcp.svg",
  "full_name": "ApparelHub-AI/apparelhub-mcp",
  "license_state": "standard",
  "license_spdx": "MIT"
}

Las puntuaciones son señales, no garantías. Reflejan prácticas públicamente visibles en GitHub; no son una auditoría de código ni una garantía de seguridad.

Los datos ausentes se excluyen y los pesos se renormalizan; nunca se puntúan como cero. La metodología es versionada y abierta: métricas v1.13.0, esquema v0.27.0 — metodología completa · wiki de métricas.

Cómo se sitúa un resultado dentro del registro general: estadísticas agregadasnpm.