{"_id":"@aevion-io/catalog-client","_rev":"2-285ef4ef6d01a2cff4ad68a33803c17d","name":"@aevion-io/catalog-client","dist-tags":{"latest":"0.8.1"},"versions":{"0.8.0":{"name":"@aevion-io/catalog-client","version":"0.8.0","keywords":["aevion","catalog","module-registry","discovery","typescript","sdk","qstore","qlearn","qevents","devhub","qcoreai","multichat","qmedia","coach","planet","client","api-client","zero-deps"],"author":{"name":"AEVION","email":"hello@aevion.app"},"license":"MIT","_id":"@aevion-io/catalog-client@0.8.0","maintainers":[{"name":"dosymbek","email":"yahiin1978@gmail.com"}],"homepage":"https://github.com/Dossymbek281078/AEVION/tree/main/packages/aevion-catalog-client#readme","bugs":{"url":"https://github.com/Dossymbek281078/AEVION/issues"},"dist":{"shasum":"e7f380c1b446a2d339b551514ee0710a8030cfeb","tarball":"https://registry.npmjs.org/@aevion-io/catalog-client/-/catalog-client-0.8.0.tgz","fileCount":5,"integrity":"sha512-OybpR7HYCKYwRw6VQLdATl4V3QSWBN8l0nxSTT389BKjO77VHYorBUeosp6Nvm6Og0HLiKUjOs8+cnTFQslYnA==","signatures":[{"sig":"MEUCIQC5/xL2u2YAcpPTBBSF7VilQYiV+kwp6HfqpAu6JW1v3wIgCOwDIZxW9Wmfj75Ig0qaC/nsLj6SXKHFIaGcZhLoXSQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":105737},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js","require":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"e2fe40c42b7b6cd27eb4a8abd679d616fb60029d","scripts":{"test":"vitest","build":"tsc","test:run":"vitest run","dry-publish":"npm publish --dry-run --access public","prepublishOnly":"npm run build && npm run test:run","verify-package":"npm pack --dry-run 2>&1 | tail -20 && echo '--- size estimate ---' && du -sh dist 2>/dev/null || true"},"_npmUser":{"name":"dosymbek","email":"yahiin1978@gmail.com"},"repository":{"url":"git+https://github.com/Dossymbek281078/AEVION.git","type":"git","directory":"packages/aevion-catalog-client"},"_npmVersion":"11.6.2","description":"TypeScript client for the AEVION Hub catalog API (/api/aevion/*) — module discovery, registry stats, status badges, plus typed sub-clients for QStore, QLearn, QEvents, DevHub, Planet, QCoreAI, Multichat, QMedia, Coach. Zero deps.","directories":{},"sideEffects":false,"_nodeVersion":"24.11.1","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.6.0","typescript":"^5.4.0"},"_npmOperationalInternal":{"tmp":"tmp/catalog-client_0.8.0_1779104704486_0.02376443054818833","host":"s3://npm-registry-packages-npm-production"}},"0.8.1":{"name":"@aevion-io/catalog-client","version":"0.8.1","description":"TypeScript client for the AEVION Hub catalog API (/api/aevion/*) — module discovery, registry stats, status badges, plus typed sub-clients for QStore, QLearn, QEvents, DevHub, Planet, QCoreAI, Multichat, QMedia, Coach. Zero deps.","main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","require":"./dist/index.js","import":"./dist/index.js","default":"./dist/index.js"},"./package.json":"./package.json"},"scripts":{"build":"tsc","prepublishOnly":"npm run build && npm run test:run","test":"vitest","test:run":"vitest run","dry-publish":"npm publish --dry-run --access public","verify-package":"npm pack --dry-run 2>&1 | tail -20 && echo '--- size estimate ---' && du -sh dist 2>/dev/null || true"},"keywords":["aevion","catalog","module-registry","discovery","typescript","sdk","qstore","qlearn","qevents","devhub","qcoreai","multichat","qmedia","coach","planet","client","api-client","zero-deps"],"author":{"name":"AEVION","email":"hello@aevion.app"},"license":"MIT","homepage":"https://github.com/Dossymbek281078/AEVION/tree/main/packages/aevion-catalog-client#readme","bugs":{"url":"https://github.com/Dossymbek281078/AEVION/issues"},"repository":{"type":"git","url":"git+https://github.com/Dossymbek281078/AEVION.git","directory":"packages/aevion-catalog-client"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"sideEffects":false,"engines":{"node":">=18"},"devDependencies":{"typescript":"^5.4.0","vitest":"^1.6.0"},"gitHead":"105d4e9bef79d05bca226526562d05478c0b423e","_id":"@aevion-io/catalog-client@0.8.1","_nodeVersion":"24.11.1","_npmVersion":"11.6.2","dist":{"integrity":"sha512-ATUVGp2FsA+k3mhTAUpIxj9U/+lHW1zLCy6Oq7nC0P3wmDUOOQfgi6jT65TZpQnA4jmAcgFDMEE0u0ArOE+MqA==","shasum":"d6fbba9700ca120654cf7c34edd59206fdd0a13e","tarball":"https://registry.npmjs.org/@aevion-io/catalog-client/-/catalog-client-0.8.1.tgz","fileCount":6,"unpackedSize":106836,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDoex5SzrMAwVP2mNEXWUpzxABQ1JFHlmBR7KFUizp5RgIgCqMd9fzP7dyGq9EvQbwaV3826qMSiRvHKBQ+2NKhh4w="}]},"_npmUser":{"name":"dosymbek","email":"yahiin1978@gmail.com"},"directories":{},"maintainers":[{"name":"dosymbek","email":"yahiin1978@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/catalog-client_0.8.1_1779107519003_0.04380590871749024"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-18T11:45:04.411Z","modified":"2026-05-18T12:31:59.342Z","0.8.0":"2026-05-18T11:45:04.701Z","0.8.1":"2026-05-18T12:31:59.213Z"},"bugs":{"url":"https://github.com/Dossymbek281078/AEVION/issues"},"author":{"name":"AEVION","email":"hello@aevion.app"},"license":"MIT","homepage":"https://github.com/Dossymbek281078/AEVION/tree/main/packages/aevion-catalog-client#readme","keywords":["aevion","catalog","module-registry","discovery","typescript","sdk","qstore","qlearn","qevents","devhub","qcoreai","multichat","qmedia","coach","planet","client","api-client","zero-deps"],"repository":{"type":"git","url":"git+https://github.com/Dossymbek281078/AEVION.git","directory":"packages/aevion-catalog-client"},"description":"TypeScript client for the AEVION Hub catalog API (/api/aevion/*) — module discovery, registry stats, status badges, plus typed sub-clients for QStore, QLearn, QEvents, DevHub, Planet, QCoreAI, Multichat, QMedia, Coach. Zero deps.","maintainers":[{"name":"dosymbek","email":"yahiin1978@gmail.com"}],"readme":"# @aevion-io/catalog-client\n\nTyped TypeScript client for the AEVION Hub catalog API. Zero dependencies. Node 18+ / modern browsers.\n\n## Install\n\n```bash\nnpm install @aevion-io/catalog-client\n# or\npnpm add @aevion-io/catalog-client\n# or\nyarn add @aevion-io/catalog-client\n```\n\nRequirements: Node.js `>=18` (native `fetch`) or a modern browser. TypeScript types are bundled — no `@types/...` needed.\n\n## Quick start\n\n```ts\nimport { AevionCatalog } from \"@aevion-io/catalog-client\";\n\nconst cat = new AevionCatalog();\n\n// List all modules with status=mvp\nconst { items } = await cat.list({ status: \"mvp\" });\nitems.forEach(m => console.log(m.code, m.name, m.frontend));\n\n// Single-module lookup\nconst qpersona = await cat.get(\"qpersona\");\nconsole.log(qpersona.relatedModules); // top-5 by tag overlap\n\n// Taxonomy stats\nconst { byStatus, byTag, total } = await cat.stats();\nconsole.log(`Total: ${total}, MVPs: ${byStatus.mvp}, top tag: ${byTag[0].tag}`);\n\n// Export URLs (no fetch — just URLs)\nconst csvUrl = cat.csvUrl({ status: \"mvp\", tag: \"ai\" });\nconst mdUrl = cat.markdownUrl({ kind: \"product\" });\nconst badgeUrl = cat.badgeUrl(\"qpersona\"); // shields.io-style SVG\n\n// Aggregate health\nconst { status, healthy, total: t } = await cat.health();\nconsole.log(`${status}: ${healthy}/${t} services up`);\n```\n\n## Examples\n\nEight runnable scripts under `examples/`:\n\n```bash\nnode examples/list-all.mjs              # registry dump grouped by status\nnode examples/get-module.mjs qsign      # single-module deep lookup\nnode examples/stats.mjs                 # by-status / by-kind / top tags\nnode examples/urls.mjs                  # CSV/MD/badge URLs (no network)\nnode examples/helpers.mjs               # v0.2 helpers: searchByTag/byStatus/...\nnode examples/openapi-sitemap.mjs       # v0.3 Hub aggregates: openapi() + sitemap()\nnode examples/graph.mjs                 # v0.4 graph helpers: graph() + neighbours()\nnode examples/search-diff.mjs           # v0.5 search + diff + fingerprint\n```\n\nSee [`examples/README.md`](./examples/README.md).\n\n## Helpers (v0.2)\n\nEach helper returns `CatalogItem[]` directly (skips the `{ items } =` destructure):\n\n```ts\nconst tagged = await cat.searchByTag(\"ai\");                    // any tag match\nconst inMvp  = await cat.byStatus([\"mvp\", \"launched\"]);        // status filter\nconst cores  = await cat.byKind(\"core\");                       // kind filter\nconst live   = await cat.mvpsAndLaunched();                    // sugar\nconst top    = await cat.topTags(5);                           // [{tag,count}]\n```\n\nSame names are exported as standalone functions against the default backend.\n\n## Hub aggregates (v0.3)\n\nTwo endpoints that aggregate across all AEVION modules:\n\n```ts\nconst idx = await cat.openapi();   // AEVION aggregate API index\nconsole.log(idx.modules, idx.services, idx.sdk);\n\nconst urls = await cat.sitemap();  // sitemap.xml parsed to SitemapEntry[]\nconsole.log(urls[0].loc, urls[0].priority);\n```\n\n## Graph helpers (v0.4)\n\nModule similarity via tag-Jaccard overlap, for \"you might also like\" widgets and\necosystem visualisations:\n\n```ts\n// Server-computed related modules for a single id (cheap, deep lookup)\nconst rel = await cat.relatedModules(\"qsign\");\n\n// Single-source neighbours, scored by Jaccard, with shared-tag breakdown\nconst near = await cat.neighbours(\"qsign\", { topK: 10 });\nnear.forEach(n => console.log(n.score, n.id, n.sharedTags));\n\n// Full registry tag-overlap graph — top-K edges per node\nconst edges = await cat.graph({ topK: 5, minOverlap: 1 });\n// edges: { from, to, overlap, score }[]\n```\n\n`graph()` is a single round-trip (uses `fields=id,name,tags` projection) and\nruns the K-NN locally — no extra backend endpoints required.\n\n## Search + diff + fingerprint (v0.5)\n\nClient-side compute on top of the catalog — no extra endpoints:\n\n```ts\n// Substring search across name + code + description + tags, with\n// simple relevance scoring (name > code > tags > description).\nconst hits = await cat.findByText(\"ai\", { limit: 10 });\nhits.forEach(m => console.log(m.score, m.id, m.name));\n\n// Pairwise compare two modules: field equality + tag-set Jaccard.\nconst d = await cat.diff(\"qsign\", \"qshield\");\nconsole.log(d.tags.jaccard, d.tags.shared, d.tags.onlyA, d.tags.onlyB);\nd.fields.forEach(f => console.log(f.key, f.equal, f.a, \"vs\", f.b));\n\n// Stable djb2 hash of identity-defining fields (id/code/status/kind/\n// priority/sorted-tags) — for cache-busting / change detection.\nconst fp = await cat.fingerprintModule(\"qsign\");\nconsole.log(fp.hash); // 8-char hex\n```\n\nAll three are single-round-trip (`findByText` + `fingerprintModule`) or two-round-trip\n(`diff`) calls. Zero crypto dependencies — djb2 is implemented inline.\n\n## New sub-clients in v0.7\n\n`v0.7.0` adds four more typed sub-clients on top of the v0.6 set. All four\nshare the parent `AevionCatalog` `baseUrl`, `fetch` and `headers` config.\n\n```ts\nconst cat = new AevionCatalog();\n\n// QCoreAI — LLM providers + chat\nconst provs = await cat.qcoreai.providers();        // GET  /api/qcoreai/providers\nconst ai    = await cat.qcoreai.health();           // GET  /api/qcoreai/health\nconst reply = await cat.qcoreai.chat({              // POST /api/qcoreai/chat\n  provider: \"openai\",\n  model: \"gpt-4o\",\n  messages: [{ role: \"user\", content: \"hello\" }],\n});\n\n// Multichat — multi-provider presets\nconst status  = await cat.multichat.providerStatus(); // GET  /api/multichat/provider-status\nconst presets = await cat.multichat.presets();        // GET  /api/multichat/presets\nconst session = await cat.multichat.launchPreset(\"brainstorm\");\n//                                                    // POST /api/multichat/presets/:id/launch\n\n// QMedia — recommendations + library\nconst rec   = await cat.qmedia.recommendations({ limit: 10 }); // GET /api/qmedia/recommendations\nconst hot   = await cat.qmedia.trending();                     // GET /api/qmedia/trending\nconst all   = await cat.qmedia.tracks();                       // GET /api/qmedia/tracks\n\n// Coach — sessions + goals\nconst sess  = await cat.coach.sessions();                      // GET  /api/coach/sessions\nconst open  = await cat.coach.goals({ completed: false });     // GET  /api/coach/goals\nconst done  = await cat.coach.goals({ completed: true });\nconst goal  = await cat.coach.createGoal({                     // POST /api/coach/goals\n  title: \"Ship SDK v0.7\",\n  description: \"Wire 4 new sub-clients\",\n  dueDate: \"2026-06-01\",\n});\nawait cat.coach.completeGoal(goal.id);                         // POST /api/coach/goals/:id/complete\n```\n\nAll methods are also exported as standalone convenience functions against\nthe default `https://api.aevion.app` backend: `getQCoreAIProviders`,\n`getQCoreAIHealth`, `qcoreaiChat`, `getMultichatPresets`,\n`getMultichatProviderStatus`, `launchMultichatPreset`,\n`getQMediaRecommendations`, `getQMediaTrending`, `getQMediaTracks`,\n`getMyCoachSessions`, `getMyCoachGoals`, `createCoachGoal`,\n`completeCoachGoal`.\n\n## Module sub-clients (v0.6)\n\n`AevionCatalog` exposes typed sub-clients for individual module APIs.\nThey share the parent's `baseUrl`, `fetch`, and `headers` config —\nconstruct the root client once and reuse every sub-client off it.\n\n```ts\nconst cat = new AevionCatalog({\n  headers: { Authorization: `Bearer ${token}` }, // forwarded to every sub-call\n});\n\n// QStore — marketplace\nconst top = await cat.qstore.products({ sort: \"popular\" });\nconst grid = await cat.qstore.featured({ limit: 8 });\n//        { popular, trending, newest, topRated }\n\n// QLearn — courses, bookmarks, streak, progress\nawait cat.qlearn.bookmark(\"smeta-101\");\nawait cat.qlearn.unbookmark(\"smeta-101\");\nconst marks = await cat.qlearn.bookmarks();\nconst streak = await cat.qlearn.streak();\n//             { current, longest, totalDays, activeToday, lastActiveAt }\nconst prog = await cat.qlearn.progress();\n//           { summary, continueLearning, notStarted, completed }\n\n// QEvents — event calendar + ICS export\nconst evts = await cat.qevents.list({ when: \"upcoming\" });\nconst ics  = await cat.qevents.ics(\"aevion-summit-2026\"); // text/calendar\nconst url  = cat.qevents.icsUrl(\"aevion-summit-2026\");    // direct URL (no fetch)\n\n// DevHub — snippets + stars\nconst snips = await cat.devhub.snippets({ limit: 20, tag: \"ts\" });\nconst s = await cat.devhub.createSnippet({\n  title: \"djb2 hash\",\n  content: \"function h(s){...}\",\n  language: \"ts\",\n  tags: [\"hash\", \"util\"],\n});\nconst one = await cat.devhub.getSnippet(s.id);\nawait cat.devhub.star(s.id);\n\n// Planet — cross-module activity feed\nconst feed = await cat.planet.activity({\n  limit: 50,\n  kinds: [\"release\", \"post\", \"module_update\"],\n});\n```\n\nAll sub-client methods are also exported as standalone convenience\nfunctions against the default `https://api.aevion.app` backend:\n`getQStoreProducts`, `getQStoreFeatured`, `bookmarkCourse`,\n`unbookmarkCourse`, `getMyBookmarks`, `getMyStreak`, `getMyProgress`,\n`getEvents`, `getEventIcs`, `getSnippets`, `createSnippet`, `getSnippet`,\n`starSnippet`, `getPlanetActivity`.\n\n## Convenience functions\n\nFor one-off calls against `https://api.aevion.app`:\n\n```ts\nimport {\n  listCatalog, getModule, getStats, getHealth,\n  searchByTag, byStatus, byKind, mvpsAndLaunched, topTags,\n  getRelatedModules, getGraph, getNeighbours,\n  findByText, diff, fingerprintModule,\n  // v0.6:\n  getQStoreProducts, getQStoreFeatured,\n  bookmarkCourse, unbookmarkCourse,\n  getMyBookmarks, getMyStreak, getMyProgress,\n  getEvents, getEventIcs,\n  getSnippets, createSnippet, getSnippet, starSnippet,\n  getPlanetActivity,\n  // v0.7:\n  getQCoreAIProviders, getQCoreAIHealth, qcoreaiChat,\n  getMultichatPresets, getMultichatProviderStatus, launchMultichatPreset,\n  getQMediaRecommendations, getQMediaTrending, getQMediaTracks,\n  getMyCoachSessions, getMyCoachGoals, createCoachGoal, completeCoachGoal,\n} from \"@aevion-io/catalog-client\";\n\nconst all   = await listCatalog();\nconst x     = await getModule(\"qfusionai\");\nconst s     = await getStats();\nconst h     = await getHealth();\nconst ai    = await searchByTag(\"ai\");\nconst live  = await mvpsAndLaunched();\nconst top5  = await topTags(5);\n```\n\n## Custom base URL\n\n```ts\nconst cat = new AevionCatalog({\n  baseUrl: \"https://api.aevion.app\",  // default\n  fetch: customFetch,                  // optional injection (e.g. for tests)\n});\n```\n\n## API\n\n### `class AevionCatalog`\n\n| Method | Returns | Description |\n|---|---|---|\n| `list(opts?)` | `CatalogResponse` | List modules with optional filters/projection |\n| `get(id)` | `CatalogItem` | Single-module deep lookup; throws on 404 |\n| `stats()` | `RegistryStats` | Taxonomy summary (byStatus, byKind, top-20 byTag) |\n| `health()` | `{ status, healthy, total, services, timestamp }` | Aggregate health |\n| `csvUrl(opts?)` | `string` | URL for `?format=csv` |\n| `markdownUrl(opts?)` | `string` | URL for `?format=md` |\n| `badgeUrl(id)` | `string` | URL for `/badges/<id>.svg` |\n\n### `CatalogListOptions`\n\n```ts\n{\n  status?: string | string[];   // filter, comma-joined\n  tag?: string | string[];      // filter, matches any\n  kind?: string | string[];     // filter\n  fields?: string[];            // projection — return only these keys\n}\n```\n\n### `CatalogItem`\n\n```ts\n{\n  id: string;\n  code: string;\n  name: string;\n  description: string;\n  kind: ModuleKind;\n  status: ModuleStatus;\n  priority: number;\n  tags: string[];\n  frontend: string;            // e.g. \"https://aevion.app/qpersona\"\n  ogImage: string;             // OpenGraph image URL\n  health: string | null;       // /api/<module>/health URL or null\n  openapi: string | null;      // OpenAPI 3.1 spec URL or null\n  waitlist: string | null;     // /api/<module>/waitlist URL or null\n  status_url: string | null;   // /api/<module>/status URL or null\n  relatedModules: { id: string; name: string; overlap: number }[];\n}\n```\n\n## Module statuses\n\n`launched` · `mvp` · `working` · `in_progress` · `research` · `planning` · `idea`\n\nStatus determines badge color: green (mvp/launched/working), amber (in_progress), violet (research), blue (planning), gray (idea).\n\n## Badges in README\n\nDrop into any `README.md` to track AEVION module status:\n\n```markdown\n![AEVION QPersona](https://api.aevion.app/api/aevion/badges/qpersona.svg)\n![AEVION QLife](https://api.aevion.app/api/aevion/badges/qlife.svg)\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}