{"_id":"@creezio/product-hub","_rev":"6-21b05bacf98f94bdd1e41a4c95ecf6dd","name":"@creezio/product-hub","dist-tags":{"latest":"0.26.0"},"versions":{"0.22.0":{"name":"@creezio/product-hub","version":"0.22.0","license":"UNLICENSED","_id":"@creezio/product-hub@0.22.0","maintainers":[{"name":"cedfiducia","email":"hello@creez.io"}],"homepage":"https://github.com/creezio/creezio#readme","bugs":{"url":"https://github.com/creezio/creezio/issues"},"dist":{"shasum":"ba108ec265a7d00fa5e9d1e0a4f1f69eeb54a746","tarball":"https://registry.npmjs.org/@creezio/product-hub/-/product-hub-0.22.0.tgz","fileCount":255,"integrity":"sha512-fCjs2kyfJV3UMK9nA9MOjSpCPciMXB6UXJpwxiJbKPFZsorjb6PdF91rvsTaJ9b6oCbDmAuFF+8u98U07WSV+w==","signatures":[{"sig":"MEUCIBZ0cepWHWA9QKcPR1xsJ/yg5mF3SvdFB9iINStubtmMAiEAo5Xu7z1fDvlBWvSobH+FXN1y9nHG3EiuY22lYqSRSJw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":990229},"main":"./dist-cjs/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=22.5"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js","require":"./dist-cjs/index.js"},"./ui":{"types":"./ui/index.ts","import":"./ui/index.ts","default":"./ui/index.ts"}},"gitHead":"544bc16fbe31e3a3721b24d2d17a377f1dc11e1c","scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"cedfiducia","email":"hello@creez.io"},"repository":{"url":"git+https://github.com/creezio/creezio.git","type":"git","directory":"packages/product-hub"},"_npmVersion":"10.9.8","description":"Product Hub / plugins — lifecycle, ACL, admin UI (N6)","directories":{},"_nodeVersion":"22.23.1","dependencies":{"zod":"^3.25.76","hono":"^4.12.32","@creezio/brand-config":"^0.22.0","@creezio/platform-core":"^0.22.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.3","@types/node":"^22.15.3","@types/react":"^18.3.12"},"peerDependencies":{"clsx":"^2.0.0","next":">=14.0.0","react":"^18.0.0 || ^19.0.0","sonner":">=1.0.0","lucide-react":">=0.400.0","tailwind-merge":"^2.0.0 || ^3.0.0","@radix-ui/react-slot":"^1.1.0","@radix-ui/react-tabs":"^1.1.0","class-variance-authority":"^0.7.0"},"peerDependenciesMeta":{"clsx":{"optional":true},"next":{"optional":true},"react":{"optional":true},"sonner":{"optional":true},"lucide-react":{"optional":true},"tailwind-merge":{"optional":true},"@radix-ui/react-slot":{"optional":true},"@radix-ui/react-tabs":{"optional":true},"class-variance-authority":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/product-hub_0.22.0_1788349931357_0.6608321867588818","host":"s3://npm-registry-packages-npm-production"}},"0.23.0":{"name":"@creezio/product-hub","version":"0.23.0","license":"UNLICENSED","_id":"@creezio/product-hub@0.23.0","maintainers":[{"name":"cedfiducia","email":"hello@creez.io"}],"homepage":"https://github.com/creezio/creezio#readme","bugs":{"url":"https://github.com/creezio/creezio/issues"},"dist":{"shasum":"59ed794e79aa86c55eefba007336e870db0c9cb8","tarball":"https://registry.npmjs.org/@creezio/product-hub/-/product-hub-0.23.0.tgz","fileCount":255,"integrity":"sha512-Q+D/d7AGVTf9vQjRu/atYVg7kCIUiyET46aP+U9fOpWe9I3Oeat/ii/fN0rCUiNG8v+nl/s3BbaY/WbZpqRx+A==","signatures":[{"sig":"MEQCID0ro0+kZ0HGUpWxgsYGFNLEUbt3rhc2LFZr6OJUv/T6AiB8OwUxqCz25JSQ3YpkvIRqZbE/VDzDSdaywVYM5LHHXQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":990121},"main":"./dist-cjs/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=22.5"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js","require":"./dist-cjs/index.js"},"./ui":{"types":"./ui/index.ts","import":"./ui/index.ts","default":"./ui/index.ts"}},"gitHead":"55f391b610619648ca8b633a0509ac2ce9d2d784","scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"cedfiducia","email":"hello@creez.io"},"repository":{"url":"git+https://github.com/creezio/creezio.git","type":"git","directory":"packages/product-hub"},"_npmVersion":"10.9.8","description":"Product Hub / plugins — lifecycle, ACL, admin UI (N6)","directories":{},"_nodeVersion":"22.23.2","dependencies":{"zod":"^3.25.76","hono":"^4.12.32","@creezio/brand-config":"^0.23.0","@creezio/platform-core":"^0.23.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.3","@types/node":"^22.15.3","@types/react":"^18.3.12"},"peerDependencies":{"clsx":"^2.0.0","next":">=14.0.0","react":"^18.0.0 || ^19.0.0","sonner":">=1.0.0","lucide-react":">=0.400.0","tailwind-merge":"^2.0.0 || ^3.0.0","@radix-ui/react-slot":"^1.1.0","@radix-ui/react-tabs":"^1.1.0","class-variance-authority":"^0.7.0"},"peerDependenciesMeta":{"clsx":{"optional":true},"next":{"optional":true},"react":{"optional":true},"sonner":{"optional":true},"lucide-react":{"optional":true},"tailwind-merge":{"optional":true},"@radix-ui/react-slot":{"optional":true},"@radix-ui/react-tabs":{"optional":true},"class-variance-authority":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/product-hub_0.23.0_1788353990877_0.1441248982935992","host":"s3://npm-registry-packages-npm-production"}},"0.24.0":{"name":"@creezio/product-hub","version":"0.24.0","license":"UNLICENSED","_id":"@creezio/product-hub@0.24.0","maintainers":[{"name":"cedfiducia","email":"hello@creez.io"}],"homepage":"https://github.com/creezio/creezio#readme","bugs":{"url":"https://github.com/creezio/creezio/issues"},"dist":{"shasum":"078f52115d0c02d4ced571f7ca82bf03438a2877","tarball":"https://registry.npmjs.org/@creezio/product-hub/-/product-hub-0.24.0.tgz","fileCount":255,"integrity":"sha512-JbIgZ9NQJD/PCS11Q+hYJroVt+UyhMy/w/WYhCxRO5tJNCNS9DeKBUHCVgG+cmO7EtmFKEm+ADwSezPjwdc1sw==","signatures":[{"sig":"MEUCIDsnX6uaGvdUN5YvPO4Q3TBdlWe1TdkUeeECOi2+2DwVAiEAzgzeNF2L5lzMsR1j1vgSMOFQAR4vXDLPHzotoXKxwuE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":990121},"main":"./dist-cjs/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=22.5"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js","require":"./dist-cjs/index.js"},"./ui":{"types":"./ui/index.ts","import":"./ui/index.ts","default":"./ui/index.ts"}},"gitHead":"55da99cacf142cd8af97487d70cc8dc54586db26","scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"cedfiducia","email":"hello@creez.io"},"repository":{"url":"git+https://github.com/creezio/creezio.git","type":"git","directory":"packages/product-hub"},"_npmVersion":"10.9.8","description":"Product Hub / plugins — lifecycle, ACL, admin UI (N6)","directories":{},"_nodeVersion":"22.23.2","dependencies":{"zod":"^3.25.76","hono":"^4.12.32","@creezio/brand-config":"^0.24.0","@creezio/platform-core":"^0.24.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.3","@types/node":"^22.15.3","@types/react":"^18.3.12"},"peerDependencies":{"clsx":"^2.0.0","next":">=14.0.0","react":"^18.0.0 || ^19.0.0","sonner":">=1.0.0","lucide-react":">=0.400.0","tailwind-merge":"^2.0.0 || ^3.0.0","@radix-ui/react-slot":"^1.1.0","@radix-ui/react-tabs":"^1.1.0","class-variance-authority":"^0.7.0"},"peerDependenciesMeta":{"clsx":{"optional":true},"next":{"optional":true},"react":{"optional":true},"sonner":{"optional":true},"lucide-react":{"optional":true},"tailwind-merge":{"optional":true},"@radix-ui/react-slot":{"optional":true},"@radix-ui/react-tabs":{"optional":true},"class-variance-authority":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/product-hub_0.24.0_1788360188728_0.5674947071240435","host":"s3://npm-registry-packages-npm-production"}},"0.24.1":{"name":"@creezio/product-hub","version":"0.24.1","license":"UNLICENSED","_id":"@creezio/product-hub@0.24.1","maintainers":[{"name":"cedfiducia","email":"hello@creez.io"}],"homepage":"https://github.com/creezio/creezio#readme","bugs":{"url":"https://github.com/creezio/creezio/issues"},"dist":{"shasum":"77906dfda214741759b768060b1ff7ec7649aa6c","tarball":"https://registry.npmjs.org/@creezio/product-hub/-/product-hub-0.24.1.tgz","fileCount":255,"integrity":"sha512-TGiCxvqcW5TYZx6iRcFmae3xmttcp6gsBf2V5Z44706JwLmpa5VGPYidOwXgHdF0+gb1Z+cY+XsXD8bl33ORRw==","signatures":[{"sig":"MEQCICccPMkOrMy3lSHhuLwwNHLAZZ2H/te/JNJ85Ajp52kuAiBadBmOccnl0b1EhMKVf4Z3sjt21ouQb/O3+ww0fLwbNg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":990121},"main":"./dist-cjs/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=22.5"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js","require":"./dist-cjs/index.js"},"./ui":{"types":"./ui/index.ts","import":"./ui/index.ts","default":"./ui/index.ts"}},"gitHead":"0b0add380e7244b9f1502eea4609dfda3fdca05d","scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"cedfiducia","email":"hello@creez.io"},"repository":{"url":"git+https://github.com/creezio/creezio.git","type":"git","directory":"packages/product-hub"},"_npmVersion":"10.9.8","description":"Product Hub / plugins — lifecycle, ACL, admin UI (N6)","directories":{},"_nodeVersion":"22.23.2","dependencies":{"zod":"^3.25.76","hono":"^4.12.32","@creezio/brand-config":"^0.24.1","@creezio/platform-core":"^0.24.1"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.3","@types/node":"^22.15.3","@types/react":"^18.3.12"},"peerDependencies":{"clsx":"^2.0.0","next":">=14.0.0","react":"^18.0.0 || ^19.0.0","sonner":">=1.0.0","lucide-react":">=0.400.0","tailwind-merge":"^2.0.0 || ^3.0.0","@radix-ui/react-slot":"^1.1.0","@radix-ui/react-tabs":"^1.1.0","class-variance-authority":"^0.7.0"},"peerDependenciesMeta":{"clsx":{"optional":true},"next":{"optional":true},"react":{"optional":true},"sonner":{"optional":true},"lucide-react":{"optional":true},"tailwind-merge":{"optional":true},"@radix-ui/react-slot":{"optional":true},"@radix-ui/react-tabs":{"optional":true},"class-variance-authority":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/product-hub_0.24.1_1788365358708_0.6282972743321273","host":"s3://npm-registry-packages-npm-production"}},"0.25.0":{"name":"@creezio/product-hub","version":"0.25.0","license":"UNLICENSED","_id":"@creezio/product-hub@0.25.0","maintainers":[{"name":"cedfiducia","email":"hello@creez.io"}],"homepage":"https://github.com/creezio/creezio#readme","bugs":{"url":"https://github.com/creezio/creezio/issues"},"dist":{"shasum":"6fcca60741e32deb94c468b92cc0e52106ea7543","tarball":"https://registry.npmjs.org/@creezio/product-hub/-/product-hub-0.25.0.tgz","fileCount":255,"integrity":"sha512-QrZ89hIiruV3pF3HlDUF42GMlFMVW9rkdH0t8/mezxnqqLl/MKl/JsVGSNk3oDoqEbNrqhs5bcTcvpIGldXlCA==","signatures":[{"sig":"MEQCIEZh2IDh5vB5RZY5MkNxBukGn5HulZuAVu2jJozvgiNcAiBjQT+ynU3rzb6TfpppI+BTiJeo1Zp/8IhJma7Ai4CBKA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":990047},"main":"./dist-cjs/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=22.5"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js","require":"./dist-cjs/index.js"},"./ui":{"types":"./ui/index.ts","import":"./ui/index.ts","default":"./ui/index.ts"}},"gitHead":"72ee394172d7a01bc0a51e0f8e4db3bbc5be8f31","scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"cedfiducia","email":"hello@creez.io"},"repository":{"url":"git+https://github.com/creezio/creezio.git","type":"git","directory":"packages/product-hub"},"_npmVersion":"10.9.8","description":"Product Hub / plugins — lifecycle, ACL, admin UI (N6)","directories":{},"_nodeVersion":"22.23.2","dependencies":{"zod":"^3.25.76","hono":"^4.12.32","@creezio/brand-config":"^0.25.0","@creezio/platform-core":"^0.25.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.3","@types/node":"^22.15.3","@types/react":"^18.3.12"},"peerDependencies":{"clsx":"^2.0.0","next":">=14.0.0","react":"^18.0.0 || ^19.0.0","sonner":">=1.0.0","lucide-react":">=0.400.0","tailwind-merge":"^2.0.0 || ^3.0.0","@radix-ui/react-slot":"^1.1.0","@radix-ui/react-tabs":"^1.1.0","class-variance-authority":"^0.7.0"},"peerDependenciesMeta":{"clsx":{"optional":true},"next":{"optional":true},"react":{"optional":true},"sonner":{"optional":true},"lucide-react":{"optional":true},"tailwind-merge":{"optional":true},"@radix-ui/react-slot":{"optional":true},"@radix-ui/react-tabs":{"optional":true},"class-variance-authority":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/product-hub_0.25.0_1788373643749_0.13268237482307876","host":"s3://npm-registry-packages-npm-production"}},"0.26.0":{"name":"@creezio/product-hub","version":"0.26.0","description":"Product Hub / plugins — lifecycle, ACL, admin UI (N6)","type":"module","main":"./dist-cjs/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist-cjs/index.js","default":"./dist/index.js"},"./ui":{"types":"./ui/index.ts","import":"./ui/index.ts","default":"./ui/index.ts"}},"scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit"},"dependencies":{"@creezio/brand-config":"^0.26.0","@creezio/platform-core":"^0.26.0","hono":"^4.12.32","zod":"^3.25.76"},"devDependencies":{"@types/node":"^22.15.3","@types/react":"^18.3.12","typescript":"^5.8.3"},"license":"UNLICENSED","module":"./dist/index.js","peerDependencies":{"@radix-ui/react-slot":"^1.1.0","@radix-ui/react-tabs":"^1.1.0","class-variance-authority":"^0.7.0","clsx":"^2.0.0","lucide-react":">=0.400.0","next":">=14.0.0","react":"^18.0.0 || ^19.0.0","sonner":">=1.0.0","tailwind-merge":"^2.0.0 || ^3.0.0"},"peerDependenciesMeta":{"@radix-ui/react-slot":{"optional":true},"@radix-ui/react-tabs":{"optional":true},"class-variance-authority":{"optional":true},"clsx":{"optional":true},"lucide-react":{"optional":true},"next":{"optional":true},"react":{"optional":true},"sonner":{"optional":true},"tailwind-merge":{"optional":true}},"publishConfig":{"registry":"https://registry.npmjs.org","access":"public"},"repository":{"type":"git","url":"git+https://github.com/creezio/creezio.git","directory":"packages/product-hub"},"engines":{"node":">=22.5"},"_id":"@creezio/product-hub@0.26.0","gitHead":"fef880ebe9665ef996cfbabbe551dbd2a823a875","bugs":{"url":"https://github.com/creezio/creezio/issues"},"homepage":"https://github.com/creezio/creezio#readme","_nodeVersion":"22.23.2","_npmVersion":"10.9.8","dist":{"integrity":"sha512-HMAySWSCDRBbWvje6KJqejs8Hnck/xnmyUSCaWrpCn5Ql1vzmxXpWw7IZM1a6rxWHG7ZebLdSGVTos5LQzfrrA==","shasum":"73212027c9f6242bc8ebf0ae62d718c41d159a03","tarball":"https://registry.npmjs.org/@creezio/product-hub/-/product-hub-0.26.0.tgz","fileCount":255,"unpackedSize":990047,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDwnrG4jx8CD8F9pus/pkUZ+y7FV0kjezb9D4csVONh8wIhAPA0FrA1ry5O20bO+DMNZ1r2gtreFa3TYZxbmOgE+5Ku"}]},"_npmUser":{"name":"cedfiducia","email":"hello@creez.io"},"directories":{},"maintainers":[{"name":"cedfiducia","email":"hello@creez.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/product-hub_0.26.0_1788381477117_0.1057465020714563"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-02T11:52:11.067Z","modified":"2026-09-02T20:37:57.458Z","0.22.0":"2026-09-02T11:52:11.504Z","0.23.0":"2026-09-02T12:59:51.033Z","0.24.0":"2026-09-02T14:43:08.925Z","0.24.1":"2026-09-02T16:09:18.853Z","0.25.0":"2026-09-02T18:27:23.909Z","0.26.0":"2026-09-02T20:37:57.283Z"},"bugs":{"url":"https://github.com/creezio/creezio/issues"},"license":"UNLICENSED","homepage":"https://github.com/creezio/creezio#readme","repository":{"type":"git","url":"git+https://github.com/creezio/creezio.git","directory":"packages/product-hub"},"description":"Product Hub / plugins — lifecycle, ACL, admin UI (N6)","maintainers":[{"name":"cedfiducia","email":"hello@creez.io"}],"readme":"# @creezio/product-hub\n\n## Rôle\n\n`@creezio/product-hub` est le socle kit des produits/plugins natifs Creezio. Il concentre les contrats purs, le store Product Hub, les routes HTTP Hono `/plugin-products`, l'ACL L3/L4, le control plane loopback, le provisioning n8n, la fabrique conversationnelle de plugins et l'UI d'administration.\n\nLe package est brand-agnostic : il expose des machines d'etat, des schemas SQL, des adapters et des factories. Les marques (TempoFlow, Certivan, Fidu, DemoBrand...) branchent leurs chemins, leur session, leur API key, leur DB SQLite et leurs integrations verticales.\n\nSurfaces publiees :\n\n| Import | Usage |\n|---|---|\n| `@creezio/product-hub` | lifecycle, ACL, store, routes Hono, n8n, control plane, factory, helpers UI/desktop |\n| `@creezio/product-hub/ui` | composants React admin plugins : `AdminPluginsList`, `AdminPluginDetail`, `HostManagedNotice` |\n\n## Périmètre (kit vs marque)\n\nCe qui appartient au kit :\n\n- lifecycle Product Hub (`request_received` -> `impact_analysis` -> `prd_draft` -> `released`, etc.) et statuts de taches ;\n- ACL plugins L3 organisation / L4 utilisateur avec fail-closed, capabilities `see`, `install`, `execute` et deny cross-org ;\n- contrats de store (`ProductHubStore`) et implementations memoire / SQLite core ;\n- DDL SQL Product Hub (`PRODUCT_HUB_CORE_SQL`, `PRODUCT_HUB_ACL_*_SQL`, `PRODUCT_HUB_RUNTIME_SQL`) ;\n- routes Hono `/plugin-products` et `/plugin-factory` ;\n- control plane HTTP loopback (`startPluginControlPlane`, `createPluginControlPlaneHandler`) ;\n- provisioning n8n generique par tokens marque ;\n- fabrique conversationnelle intention -> impact -> clarification -> PRD -> materialisation ;\n- UI admin reusable.\n\nCe qui reste dans la marque :\n\n- authentification externe au montage des routes (`requireSessionOrApiKey`, `getActor`, `getSession`) ;\n- choix des chemins (`pluginsDir`, `documentsDir`, `hermesContextDir`, `coreDbPath`) ;\n- ouverture DB concrete (`better-sqlite3` ou `node:sqlite`) et migrations verticales ;\n- resolution des credentials n8n, Hermes, API publique, env et secrets ;\n- modules encore verticaux listes par `PRODUCT_HUB_VERTICAL_REMAINING` : `plugin-git`, `plugin-data`, `plugin-accept-check`, `plugin-test-runner`, `plugin-crm-key` ;\n- UI metier autour des pages admin, navigation, ACL de routes, libelles de marque ;\n- decision fonctionnelle d'activer les plugins (`features.plugins`). Fidu peut garder `features.plugins: false` sans perdre la capacite kit.\n\n## Installation / build\n\nLe package est un workspace npm du monorepo.\n\n```bash\nnpm install\nnpm run build -w @creezio/product-hub\nnpm run typecheck -w @creezio/product-hub\n```\n\nDans le build global, il est compile apres `@creezio/brand-config`, `@creezio/shell` et `@creezio/platform-core`.\n\nArtefacts :\n\n- ESM : `dist/`\n- CJS Electron : `dist-cjs/`\n- UI source consommee par les apps Next : `ui/`\n\nDependances runtime directes : `@creezio/brand-config`, `@creezio/platform-core`, `hono`, `zod`. Les dependances React/UI sont des peer dependencies optionnelles car `./ui` n'est charge que par les apps qui l'utilisent.\n\n## Configuration\n\n### Tokens marque\n\nLes tokens Product Hub doivent venir du manifeste, pas de constantes `TEMPOFLOW_` / `CERTIVAN_` hardcodees.\n\n```ts\nimport { productHubTokensFromManifest } from \"@creezio/product-hub\";\nimport { appManifest } from \"@creezio/brand-config\";\n\nconst tokens = productHubTokensFromManifest(appManifest);\n```\n\nCes tokens alimentent notamment les tags n8n et les hints de process (`grantProcessHint`, `resolveN8nTagPrefix`).\n\n### Store SQLite core\n\nLe package expose le DDL et le store, mais le chemin DB et l'ouvreur concret restent injectes.\n\n```ts\nimport {\n  createSqliteProductHubStore,\n  openNodeSqliteDatabase,\n} from \"@creezio/product-hub\";\n\nconst store = createSqliteProductHubStore({\n  coreDbPath: \"/path/to/core.db\",\n  openDatabase: openNodeSqliteDatabase,\n});\n```\n\nPour tests et sandboxes, `createMemoryProductHubStore()` evite SQLite.\n\n### Routes `/plugin-products`\n\nL'authentification est volontairement externe : la marque protege le prefixe puis fournit acteur ACL et session.\n\n```ts\nimport {\n  createPluginProductsRoutes,\n  createPluginN8nProvisioning,\n  createProductHubHost,\n  productHubTokensFromManifest,\n} from \"@creezio/product-hub\";\n\nconst host = createProductHubHost({\n  requireStore,\n  getStore,\n  pluginsDir: () => process.env.MYBRAND_PLUGINS_DIR || \"\",\n});\n\nconst n8n = createPluginN8nProvisioning({\n  getDb: getProductHubBetterSqlite,\n  tokens: productHubTokensFromManifest(myManifest),\n  managedBy: \"mybrand\",\n  modeLabel: \"Tag dedie + registre MyBrand\",\n});\n\napi.use(\"/plugin-products\", requireSessionOrApiKey);\napi.use(\"/plugin-products/*\", requireSessionOrApiKey);\napi.route(\n  \"/plugin-products\",\n  createPluginProductsRoutes({\n    host,\n    store: requireStore,\n    getActor: (c) => resolvePluginAclActor(c),\n    getSession: (c) => getSessionFromContext(c),\n    pluginsDir: () => process.env.MYBRAND_PLUGINS_DIR || \"\",\n    documentsDir: () => resolvePluginDocumentsDir(),\n    hermesContextDir: () => process.env.MYBRAND_HERMES_CONTEXT_DIR || null,\n    apiUrlEnvHint: \"$MYBRAND_API_URL\",\n    n8n,\n    hermesCreateTask,\n    hermesSkills: [\"mybrand-plugins\"],\n    openReadonlyPluginDb,\n    defaultOwnerOrgId: \"org-mybrand\",\n  }),\n);\n```\n\n### Control plane\n\nLe control plane est un serveur HTTP local recommande en loopback. Le token Bearer et l'ACL viennent du host.\n\n```ts\nimport {\n  createPluginControlPlaneAclFromStore,\n  startPluginControlPlane,\n  withBearerServiceKeyFallback,\n} from \"@creezio/product-hub\";\n\nconst acl = withBearerServiceKeyFallback(\n  createPluginControlPlaneAclFromStore({ store }),\n);\n\nconst state = await startPluginControlPlane({\n  tokens,\n  controlToken: process.env.PLUGIN_CONTROL_TOKEN!,\n  pluginsDir,\n  adapters,\n  preferredPort: 0,\n  acl,\n});\n```\n\n## API publique (exports + exemples)\n\n### Lifecycle et PRD\n\nExports principaux :\n\n- `PLUGIN_LIFECYCLE_STATES`, `PLUGIN_LIFECYCLE_TRANSITIONS`, `PLUGIN_TASK_STATUSES`\n- `isPluginLifecycleState`, `canTransitionPluginLifecycle`, `assertPluginLifecycleTransition`\n- `PLUGIN_PRD_REQUIRED_SECTIONS`, `parsePluginPrdSections`, `missingPrdSections`, `missingPrdCoreFields`\n- `assertClarificationQuestions`\n\n```ts\nimport {\n  assertPluginLifecycleTransition,\n  missingPrdSections,\n  parsePluginPrdSections,\n} from \"@creezio/product-hub\";\n\nassertPluginLifecycleTransition(\"prd_draft\", \"awaiting_prd_approval\");\n\nconst sections = parsePluginPrdSections(revision.sections_json);\nif (missingPrdSections(sections).length > 0) {\n  throw new Error(\"PRD incomplet\");\n}\n```\n\n### ACL L3/L4\n\nExports principaux :\n\n- constantes : `PLUGIN_ACL_LEVEL_ORG`, `PLUGIN_ACL_LEVEL_USER`, `PLUGIN_ACL_DEFAULT_CAPABILITIES`\n- acteurs/policies : `PluginAclActor`, `PluginAclPolicy`, `PluginAclDecision`\n- decisions : `decidePluginAccess`, `canActorSeePlugin`, `canActorInstallPlugin`, `canActorExecutePlugin`, `filterVisiblePluginIds`\n- headers : `PLUGIN_ACL_ORG_HEADER`, `PLUGIN_ACL_USER_HEADER`, `PLUGIN_ACL_OWNER_HEADER`, `resolvePluginAclActorFromHeaders`, `buildPluginAclActorHeaders`\n\n```ts\nimport { decidePluginAccess, type PluginAclActor } from \"@creezio/product-hub\";\n\nconst actor: PluginAclActor = {\n  orgId: \"org-a\",\n  userId: \"user-1\",\n  isOwner: false,\n};\n\nconst decision = decidePluginAccess(policy, actor, \"execute\");\nif (!decision.allow) {\n  return c.json({ error: decision.reason }, 403);\n}\n```\n\nPar defaut, le modele est fail-closed : sans grant explicite, seul l'owner non impersonne ou une cle service voit/execute. `install` n'est pas dans les capabilities par defaut ; elle doit etre explicite ou admin.\n\n### Store et SQL\n\nExports principaux :\n\n- `ProductHubStore`, `PluginProductRecord`, `PluginPrdRevisionRecord`, `PluginTaskRecord`, `PluginClarificationRecord`\n- `createMemoryProductHubStore`, `createSqliteProductHubStore`, `createProductRequest`, `createSqliteProductRequest`\n- `PRODUCT_HUB_CORE_SQL`, `PRODUCT_HUB_ACL_USER_SQL`, `PRODUCT_HUB_ACL_ORG_SQL`, `PRODUCT_HUB_ACL_H5_SQL`, `PRODUCT_HUB_RUNTIME_SQL`\n- `migrateLegacyBrandProductHubOnce`, `createCachedSqliteProductHubAccessor`, `createBrandProductHubBindings`\n\n```ts\nimport { createMemoryProductHubStore, buildPluginImpactReport } from \"@creezio/product-hub\";\n\nconst store = createMemoryProductHubStore();\nconst { product } = store.createRequest({\n  name: \"Plugin scoring\",\n  description: \"Calculer un score depuis les donnees CRM\",\n  impact: buildPluginImpactReport({ intention: \"scoring\", evidence: [] }),\n});\n```\n\n### Routes HTTP Product Hub\n\n`createPluginProductsRoutes` couvre notamment :\n\n| Methode | Chemin |\n|---|---|\n| `GET` | `/visible` |\n| `GET` / `POST` | `/` |\n| `GET` | `/:id` |\n| `POST` | `/:id/transition` |\n| `POST` | `/:id/prd` |\n| `POST` | `/:id/clarifications` |\n| `POST` | `/:id/clarifications/:clarificationId/answers` |\n| `POST` | `/:id/prd/:revisionId/approve` |\n| `POST` / `PATCH` | `/:id/tasks`, `/:id/tasks/:taskId` |\n| `POST` | `/:id/tasks/:taskId/sync-hermes` |\n| `PATCH` | `/:id/runtime-link` |\n| `POST` / `GET` / `DELETE` | `/:id/documents...` |\n| `POST` | `/:id/test-runs`, `/:id/human-qa` |\n| `GET` | `/:id/data/tables...` |\n| `GET` / `POST` | `/:id/n8n...` |\n| `POST` | `/:id/archive` |\n\n### Fabrique conversationnelle\n\nExports principaux :\n\n- `createConversationalPluginFactory`\n- `createFsPluginScaffoldAdapters`\n- `createPluginFactoryRoutes`\n- `derivePluginIdentity`, `slugifyPluginId`\n- `draftPrdFromIntention`, `defaultClarificationQuestions`, `needsClarification`\n- `deterministicPrdDrafter`, `createOptionalLlmPrdDrafter`\n- `buildPluginScaffoldFiles`\n\n```ts\nimport {\n  createConversationalPluginFactory,\n  createFsPluginScaffoldAdapters,\n  createPluginFactoryRoutes,\n} from \"@creezio/product-hub\";\n\nconst factory = createConversationalPluginFactory({\n  store: requireStore(),\n  ...createFsPluginScaffoldAdapters(pluginsDir()),\n  installRuntime: async (pluginId, actor) => {\n    await ensurePluginMounted(pluginId, actor);\n    return { dbOpened: true };\n  },\n});\n\napi.route(\n  \"/plugin-factory\",\n  createPluginFactoryRoutes({\n    factory,\n    getActor,\n    enabled: () => process.env.PRODUCT_HUB_FACTORY === \"1\",\n  }),\n);\n```\n\nFlux de la factory : `submitIntention` -> impact -> clarification optionnelle -> PRD -> `approvePrd` -> `materialize` -> runtime installe.\n\n### n8n\n\nExports principaux :\n\n- `createPluginN8nProvisioning`, `resolveN8nTagPrefix`\n- `pluginN8nTag`, `isBrandPluginN8nTag`, `N8N_TAG_MAX_LENGTH`\n- types `PluginN8nProvisioning`, `PluginN8nSnapshot`, `N8nWorkflow`, `N8nExecution`\n\n```ts\nconst provisioning = createPluginN8nProvisioning({\n  getDb,\n  tokens,\n  managedBy: \"mybrand\",\n  modeLabel: \"Registre n8n marque\",\n});\n\nconst tag = provisioning.pluginN8nTag(\"mon-plugin\");\n```\n\n### UI admin\n\n```tsx\nimport {\n  AdminPluginDetail,\n  AdminPluginsList,\n  HostManagedNotice,\n} from \"@creezio/product-hub/ui\";\n```\n\nLa marque fournit la page, l'auth route et la navigation. Les composants consomment les endpoints kit.\n\n## Flux / fonctionnement\n\n1. Une intention plugin cree un `PluginProductRecord` dans le store.\n2. L'analyse d'impact produit une recommandation `create` ou `evolve`.\n3. Si l'intention est incomplete, une clarification ouverte est creee.\n4. Un PRD est sauvegarde puis valide par session utilisateur.\n5. Le produit passe en `planning`, puis `ready_for_execution`, `executing`, tests automatiques, QA humaine, release.\n6. Le runtime plugin est lie via `linkRuntime` et peut etre expose au control plane.\n7. Les ACL L3/L4 filtrent la visibilite, l'installation et l'execution cote API, MCP et control plane.\n8. n8n peut creer/associer workflows et tags par plugin.\n9. Les documents, tests, taches Hermes et donnees plugin sont accessibles via les routes dediees.\n\n## Intégration marques\n\nChecklist d'integration :\n\n1. Ajouter ou verifier `features.plugins` dans le manifeste marque.\n2. Executer les migrations SQLite core avec les SQL exportes par le package.\n3. Construire un singleton store (`createSqliteProductHubStore` ou accessor cache).\n4. Deriver les tokens via `productHubTokensFromManifest`.\n5. Brancher n8n avec `createPluginN8nProvisioning`.\n6. Creer `ProductHubHost` avec `createProductHubHost`.\n7. Monter `/plugin-products` derriere l'auth marque.\n8. Monter `/plugin-factory` seulement si la feature est active.\n9. Brancher le control plane loopback si la marque a un runtime plugin local.\n10. Remplacer les anciennes routes locales par des stubs minces deleguant au kit.\n11. Utiliser `@creezio/product-hub/ui` pour les pages admin.\n\nCas Fidu : `features.plugins: false` signifie \"pas d'UI plugins ni routes publiques activees par defaut\", pas \"le package ne fonctionne pas\". Le store et le control plane peuvent rester presents pour convergence technique.\n\n## Dépendances @creezio/*\n\n| Dependance | Rôle |\n|---|---|\n| `@creezio/brand-config` | source des tokens marque via manifeste |\n| `@creezio/platform-core` | constantes plateforme et helpers partages |\n\nLiens fonctionnels sans dependance directe obligatoire :\n\n- `@creezio/auth` protege les routes Hono cote marque.\n- `@creezio/shell-ui` et `@creezio/product-hub/ui` composent les pages admin dans les apps.\n- `@creezio/mcp-facade` peut reutiliser l'ACL Product Hub pour les tools plugin.\n- `@creezio/tasks` / Hermes restent injectes via adapters (`hermesCreateTask`).\n\n## Voir aussi → AGENTS.md + docs/FILES.md\n\n- [`AGENTS.md`](./AGENTS.md) : consignes de modification pour agents.\n- [`docs/FILES.md`](./docs/FILES.md) : inventaire fichier par fichier des exports et responsabilites.\n","readmeFilename":"README.md"}