constella 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -0
- package/.next/app-path-routes-manifest.json +53 -0
- package/.next/build-manifest.json +20 -0
- package/.next/diagnostics/build-diagnostics.json +6 -0
- package/.next/diagnostics/framework.json +1 -0
- package/.next/export-marker.json +6 -0
- package/.next/images-manifest.json +68 -0
- package/.next/next-minimal-server.js.nft.json +1 -0
- package/.next/next-server.js.nft.json +1 -0
- package/.next/package.json +1 -0
- package/.next/prerender-manifest.json +36 -0
- package/.next/react-loadable-manifest.json +14 -0
- package/.next/required-server-files.js +343 -0
- package/.next/required-server-files.json +343 -0
- package/.next/routes-manifest.json +362 -0
- package/.next/server/app/(app)/activity/page.js +2 -0
- package/.next/server/app/(app)/activity/page.js.nft.json +1 -0
- package/.next/server/app/(app)/activity/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/agents/[handle]/page.js +18 -0
- package/.next/server/app/(app)/agents/[handle]/page.js.nft.json +1 -0
- package/.next/server/app/(app)/agents/[handle]/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/code/page.js +2 -0
- package/.next/server/app/(app)/code/page.js.nft.json +1 -0
- package/.next/server/app/(app)/code/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/config/page.js +2 -0
- package/.next/server/app/(app)/config/page.js.nft.json +1 -0
- package/.next/server/app/(app)/config/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/costs/page.js +2 -0
- package/.next/server/app/(app)/costs/page.js.nft.json +1 -0
- package/.next/server/app/(app)/costs/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/cron/page.js +2 -0
- package/.next/server/app/(app)/cron/page.js.nft.json +1 -0
- package/.next/server/app/(app)/cron/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/dashboard/page.js +2 -0
- package/.next/server/app/(app)/dashboard/page.js.nft.json +1 -0
- package/.next/server/app/(app)/dashboard/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/docs/[id]/page.js +2 -0
- package/.next/server/app/(app)/docs/[id]/page.js.nft.json +1 -0
- package/.next/server/app/(app)/docs/[id]/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/docs/page.js +2 -0
- package/.next/server/app/(app)/docs/page.js.nft.json +1 -0
- package/.next/server/app/(app)/docs/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/github/page.js +2 -0
- package/.next/server/app/(app)/github/page.js.nft.json +1 -0
- package/.next/server/app/(app)/github/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/goals/page.js +2 -0
- package/.next/server/app/(app)/goals/page.js.nft.json +1 -0
- package/.next/server/app/(app)/goals/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/inbox/page.js +2 -0
- package/.next/server/app/(app)/inbox/page.js.nft.json +1 -0
- package/.next/server/app/(app)/inbox/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/knowledge/page.js +3 -0
- package/.next/server/app/(app)/knowledge/page.js.nft.json +1 -0
- package/.next/server/app/(app)/knowledge/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/models/page.js +2 -0
- package/.next/server/app/(app)/models/page.js.nft.json +1 -0
- package/.next/server/app/(app)/models/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/notifications/page.js +2 -0
- package/.next/server/app/(app)/notifications/page.js.nft.json +1 -0
- package/.next/server/app/(app)/notifications/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/org/page.js +2 -0
- package/.next/server/app/(app)/org/page.js.nft.json +1 -0
- package/.next/server/app/(app)/org/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/organizations/page.js +2 -0
- package/.next/server/app/(app)/organizations/page.js.nft.json +1 -0
- package/.next/server/app/(app)/organizations/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/page.js +3 -0
- package/.next/server/app/(app)/page.js.nft.json +1 -0
- package/.next/server/app/(app)/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/planner/page.js +2 -0
- package/.next/server/app/(app)/planner/page.js.nft.json +1 -0
- package/.next/server/app/(app)/planner/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/plugins/page.js +2 -0
- package/.next/server/app/(app)/plugins/page.js.nft.json +1 -0
- package/.next/server/app/(app)/plugins/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/pm/page.js +2 -0
- package/.next/server/app/(app)/pm/page.js.nft.json +1 -0
- package/.next/server/app/(app)/pm/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/prepare-deploy/page.js +19 -0
- package/.next/server/app/(app)/prepare-deploy/page.js.nft.json +1 -0
- package/.next/server/app/(app)/prepare-deploy/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/profile/page.js +2 -0
- package/.next/server/app/(app)/profile/page.js.nft.json +1 -0
- package/.next/server/app/(app)/profile/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/pulse/page.js +2 -0
- package/.next/server/app/(app)/pulse/page.js.nft.json +1 -0
- package/.next/server/app/(app)/pulse/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/reports/[id]/page.js +3 -0
- package/.next/server/app/(app)/reports/[id]/page.js.nft.json +1 -0
- package/.next/server/app/(app)/reports/[id]/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/reports/page.js +5 -0
- package/.next/server/app/(app)/reports/page.js.nft.json +1 -0
- package/.next/server/app/(app)/reports/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/routines/page.js +2 -0
- package/.next/server/app/(app)/routines/page.js.nft.json +1 -0
- package/.next/server/app/(app)/routines/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/search/page.js +2 -0
- package/.next/server/app/(app)/search/page.js.nft.json +1 -0
- package/.next/server/app/(app)/search/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/security/page.js +2 -0
- package/.next/server/app/(app)/security/page.js.nft.json +1 -0
- package/.next/server/app/(app)/security/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/skills/page.js +18 -0
- package/.next/server/app/(app)/skills/page.js.nft.json +1 -0
- package/.next/server/app/(app)/skills/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/tasks/page.js +2 -0
- package/.next/server/app/(app)/tasks/page.js.nft.json +1 -0
- package/.next/server/app/(app)/tasks/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/test-dev/page.js +2 -0
- package/.next/server/app/(app)/test-dev/page.js.nft.json +1 -0
- package/.next/server/app/(app)/test-dev/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(app)/update/page.js +2 -0
- package/.next/server/app/(app)/update/page.js.nft.json +1 -0
- package/.next/server/app/(app)/update/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(auth)/login/page.js +2 -0
- package/.next/server/app/(auth)/login/page.js.nft.json +1 -0
- package/.next/server/app/(auth)/login/page_client-reference-manifest.js +1 -0
- package/.next/server/app/(auth)/onboarding/page.js +18 -0
- package/.next/server/app/(auth)/onboarding/page.js.nft.json +1 -0
- package/.next/server/app/(auth)/onboarding/page_client-reference-manifest.js +1 -0
- package/.next/server/app/_global-error/page.js +32 -0
- package/.next/server/app/_global-error/page.js.nft.json +1 -0
- package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -0
- package/.next/server/app/_global-error.html +1 -0
- package/.next/server/app/_global-error.meta +16 -0
- package/.next/server/app/_global-error.rsc +15 -0
- package/.next/server/app/_global-error.segments/_full.segment.rsc +15 -0
- package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +5 -0
- package/.next/server/app/_global-error.segments/_global-error.segment.rsc +5 -0
- package/.next/server/app/_global-error.segments/_head.segment.rsc +5 -0
- package/.next/server/app/_global-error.segments/_index.segment.rsc +6 -0
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -0
- package/.next/server/app/_not-found/page.js +2 -0
- package/.next/server/app/_not-found/page.js.nft.json +1 -0
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
- package/.next/server/app/api/auth/[...all]/route.js +1 -0
- package/.next/server/app/api/auth/[...all]/route.js.nft.json +1 -0
- package/.next/server/app/api/auth/[...all]/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/cron/tick/route.js +52 -0
- package/.next/server/app/api/cron/tick/route.js.nft.json +1 -0
- package/.next/server/app/api/cron/tick/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/dev-login/route.js +1 -0
- package/.next/server/app/api/dev-login/route.js.nft.json +1 -0
- package/.next/server/app/api/dev-login/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/locks/acquire/route.js +1 -0
- package/.next/server/app/api/locks/acquire/route.js.nft.json +1 -0
- package/.next/server/app/api/locks/acquire/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/models/progress/route.js +1 -0
- package/.next/server/app/api/models/progress/route.js.nft.json +1 -0
- package/.next/server/app/api/models/progress/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/passkey/authenticate/options/route.js +1 -0
- package/.next/server/app/api/passkey/authenticate/options/route.js.nft.json +1 -0
- package/.next/server/app/api/passkey/authenticate/options/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/passkey/authenticate/verify/route.js +1 -0
- package/.next/server/app/api/passkey/authenticate/verify/route.js.nft.json +1 -0
- package/.next/server/app/api/passkey/authenticate/verify/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/passkey/register/options/route.js +1 -0
- package/.next/server/app/api/passkey/register/options/route.js.nft.json +1 -0
- package/.next/server/app/api/passkey/register/options/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/passkey/register/verify/route.js +1 -0
- package/.next/server/app/api/passkey/register/verify/route.js.nft.json +1 -0
- package/.next/server/app/api/passkey/register/verify/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/stream/route.js +4 -0
- package/.next/server/app/api/stream/route.js.nft.json +1 -0
- package/.next/server/app/api/stream/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/sync/file/route.js +2 -0
- package/.next/server/app/api/sync/file/route.js.nft.json +1 -0
- package/.next/server/app/api/sync/file/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/telegram/poll/route.js +15 -0
- package/.next/server/app/api/telegram/poll/route.js.nft.json +1 -0
- package/.next/server/app/api/telegram/poll/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/upload/route.js +1 -0
- package/.next/server/app/api/upload/route.js.nft.json +1 -0
- package/.next/server/app/api/upload/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/v1/[[...path]]/route.js +1 -0
- package/.next/server/app/api/v1/[[...path]]/route.js.nft.json +1 -0
- package/.next/server/app/api/v1/[[...path]]/route_client-reference-manifest.js +1 -0
- package/.next/server/app-paths-manifest.json +53 -0
- package/.next/server/chunks/1003.js +1 -0
- package/.next/server/chunks/127.js +26 -0
- package/.next/server/chunks/1388.js +1 -0
- package/.next/server/chunks/1408.js +21 -0
- package/.next/server/chunks/1572.js +1 -0
- package/.next/server/chunks/1591.js +24 -0
- package/.next/server/chunks/1619.js +188 -0
- package/.next/server/chunks/162.js +1 -0
- package/.next/server/chunks/1881.js +1 -0
- package/.next/server/chunks/1968.js +1 -0
- package/.next/server/chunks/2297.js +348 -0
- package/.next/server/chunks/2341.js +1 -0
- package/.next/server/chunks/2517.js +1 -0
- package/.next/server/chunks/2549.js +1 -0
- package/.next/server/chunks/259.js +14 -0
- package/.next/server/chunks/2599.js +1 -0
- package/.next/server/chunks/260.js +1 -0
- package/.next/server/chunks/2867.js +147 -0
- package/.next/server/chunks/3018.js +1 -0
- package/.next/server/chunks/3050.js +18 -0
- package/.next/server/chunks/3085.js +12 -0
- package/.next/server/chunks/3131.js +1 -0
- package/.next/server/chunks/3242.js +1 -0
- package/.next/server/chunks/3266.js +15 -0
- package/.next/server/chunks/3524.js +1 -0
- package/.next/server/chunks/3527.js +479 -0
- package/.next/server/chunks/3533.js +869 -0
- package/.next/server/chunks/3550.js +1 -0
- package/.next/server/chunks/3609.js +2 -0
- package/.next/server/chunks/3667.js +462 -0
- package/.next/server/chunks/3760.js +4 -0
- package/.next/server/chunks/4679.js +1 -0
- package/.next/server/chunks/4804.js +1 -0
- package/.next/server/chunks/4832.js +2 -0
- package/.next/server/chunks/4853.js +1 -0
- package/.next/server/chunks/4979.js +67 -0
- package/.next/server/chunks/5060.js +1 -0
- package/.next/server/chunks/5278.js +1 -0
- package/.next/server/chunks/5614.js +1 -0
- package/.next/server/chunks/5818.js +1 -0
- package/.next/server/chunks/6479.js +1 -0
- package/.next/server/chunks/6658.js +1 -0
- package/.next/server/chunks/6706.js +1 -0
- package/.next/server/chunks/6719.js +1 -0
- package/.next/server/chunks/678.js +1 -0
- package/.next/server/chunks/683.js +1 -0
- package/.next/server/chunks/6862.js +1 -0
- package/.next/server/chunks/6882.js +1 -0
- package/.next/server/chunks/7037.js +1 -0
- package/.next/server/chunks/7107.js +741 -0
- package/.next/server/chunks/73.js +17 -0
- package/.next/server/chunks/7327.js +1 -0
- package/.next/server/chunks/7514.js +1 -0
- package/.next/server/chunks/7622.js +1 -0
- package/.next/server/chunks/7778.js +1 -0
- package/.next/server/chunks/7912.js +1 -0
- package/.next/server/chunks/7949.js +1 -0
- package/.next/server/chunks/7971.js +1 -0
- package/.next/server/chunks/7989.js +1 -0
- package/.next/server/chunks/842.js +22 -0
- package/.next/server/chunks/8762.js +15 -0
- package/.next/server/chunks/8823.js +77 -0
- package/.next/server/chunks/9146.js +4 -0
- package/.next/server/chunks/9676.js +1 -0
- package/.next/server/chunks/9783.js +22 -0
- package/.next/server/chunks/9969.js +3 -0
- package/.next/server/functions-config-manifest.json +18 -0
- package/.next/server/instrumentation.js +1 -0
- package/.next/server/instrumentation.js.nft.json +1 -0
- package/.next/server/interception-route-rewrite-manifest.js +1 -0
- package/.next/server/middleware-build-manifest.js +1 -0
- package/.next/server/middleware-manifest.json +6 -0
- package/.next/server/middleware-react-loadable-manifest.js +1 -0
- package/.next/server/middleware.js +18 -0
- package/.next/server/middleware.js.nft.json +1 -0
- package/.next/server/next-font-manifest.js +1 -0
- package/.next/server/next-font-manifest.json +1 -0
- package/.next/server/pages/500.html +1 -0
- package/.next/server/pages-manifest.json +3 -0
- package/.next/server/prefetch-hints.json +1 -0
- package/.next/server/server-reference-manifest.js +1 -0
- package/.next/server/server-reference-manifest.json +1 -0
- package/.next/server/webpack-runtime.js +1 -0
- package/.next/static/chunks/1858-339516f78a4b00da.js +1 -0
- package/.next/static/chunks/2320-fc8b39380e69d465.js +2 -0
- package/.next/static/chunks/23550918-ff694f70f4b0648c.js +1 -0
- package/.next/static/chunks/3219-ebb3c23be38c838d.js +1 -0
- package/.next/static/chunks/4263-adecb5b466380b6e.js +1 -0
- package/.next/static/chunks/5479-0cceab68cd0ca9c7.js +1 -0
- package/.next/static/chunks/5701-665b927b06158b76.js +1 -0
- package/.next/static/chunks/5920.6451a68b63918988.js +1 -0
- package/.next/static/chunks/6575-5c9139720bb0f5bf.js +4 -0
- package/.next/static/chunks/6834-4759af1ce7d95fb6.js +32 -0
- package/.next/static/chunks/7509.721cd47a931c5518.js +1 -0
- package/.next/static/chunks/8264-1ca011989ee2b231.js +1 -0
- package/.next/static/chunks/9219-4a39a98b5502d9d1.js +1 -0
- package/.next/static/chunks/9690-53d5222618cbeddb.js +1 -0
- package/.next/static/chunks/app/(app)/activity/page-3973534281ecea81.js +1 -0
- package/.next/static/chunks/app/(app)/agents/[handle]/page-83662a175c098282.js +1 -0
- package/.next/static/chunks/app/(app)/code/page-33979545192cd137.js +1 -0
- package/.next/static/chunks/app/(app)/config/page-9933aed1ca8a85c1.js +1 -0
- package/.next/static/chunks/app/(app)/costs/page-131c4dc580efcc19.js +1 -0
- package/.next/static/chunks/app/(app)/cron/page-53ea1aff998a87ca.js +1 -0
- package/.next/static/chunks/app/(app)/dashboard/page-deed83aaa9d0d447.js +1 -0
- package/.next/static/chunks/app/(app)/docs/[id]/page-38c993d73c0eab4f.js +1 -0
- package/.next/static/chunks/app/(app)/docs/page-bf463b55d0554e86.js +1 -0
- package/.next/static/chunks/app/(app)/error-988cd28480809861.js +1 -0
- package/.next/static/chunks/app/(app)/github/page-62678b4e82dfecb6.js +1 -0
- package/.next/static/chunks/app/(app)/goals/page-4adb426fe1c96106.js +1 -0
- package/.next/static/chunks/app/(app)/inbox/page-e347dc55ab467310.js +1 -0
- package/.next/static/chunks/app/(app)/knowledge/page-65393a045b4349be.js +1 -0
- package/.next/static/chunks/app/(app)/layout-7f65675705b011d8.js +1 -0
- package/.next/static/chunks/app/(app)/models/page-e01f1dd7e49a2951.js +1 -0
- package/.next/static/chunks/app/(app)/notifications/page-56548ac87aef00da.js +1 -0
- package/.next/static/chunks/app/(app)/org/page-699e6a6dc0db7d81.js +1 -0
- package/.next/static/chunks/app/(app)/organizations/page-36051a380a7e8eb7.js +1 -0
- package/.next/static/chunks/app/(app)/page-7d1011a566f81520.js +1 -0
- package/.next/static/chunks/app/(app)/planner/page-dab7ced94083373a.js +1 -0
- package/.next/static/chunks/app/(app)/plugins/page-5b5a1f53389be42e.js +1 -0
- package/.next/static/chunks/app/(app)/pm/page-0de5c08c0b227bb0.js +1 -0
- package/.next/static/chunks/app/(app)/prepare-deploy/page-e426038552df8d41.js +1 -0
- package/.next/static/chunks/app/(app)/profile/page-608dfcaf8aae0a69.js +1 -0
- package/.next/static/chunks/app/(app)/pulse/page-309ccaca91de1faa.js +1 -0
- package/.next/static/chunks/app/(app)/reports/[id]/page-53ea1aff998a87ca.js +1 -0
- package/.next/static/chunks/app/(app)/reports/page-68cdc6dcfa472d86.js +1 -0
- package/.next/static/chunks/app/(app)/routines/page-bcc55550b197a9fa.js +1 -0
- package/.next/static/chunks/app/(app)/search/page-5c5f67558d0dbf0d.js +1 -0
- package/.next/static/chunks/app/(app)/security/page-a7d41e36aa366b45.js +1 -0
- package/.next/static/chunks/app/(app)/skills/page-c5b21e89593b8336.js +1 -0
- package/.next/static/chunks/app/(app)/tasks/page-08ae079e3e54d2ce.js +1 -0
- package/.next/static/chunks/app/(app)/test-dev/page-633f82dfd9c3ce23.js +1 -0
- package/.next/static/chunks/app/(app)/update/page-4be019054351bfac.js +1 -0
- package/.next/static/chunks/app/(auth)/login/page-6e85d3377062acae.js +1 -0
- package/.next/static/chunks/app/(auth)/onboarding/page-ebb10c175abf3b85.js +1 -0
- package/.next/static/chunks/app/_global-error/page-23fe50a6bf589c97.js +1 -0
- package/.next/static/chunks/app/_not-found/page-dc38b02aebeab535.js +1 -0
- package/.next/static/chunks/app/api/auth/[...all]/route-23fe50a6bf589c97.js +1 -0
- package/.next/static/chunks/app/api/cron/tick/route-23fe50a6bf589c97.js +1 -0
- package/.next/static/chunks/app/api/dev-login/route-23fe50a6bf589c97.js +1 -0
- package/.next/static/chunks/app/api/locks/acquire/route-23fe50a6bf589c97.js +1 -0
- package/.next/static/chunks/app/api/models/progress/route-23fe50a6bf589c97.js +1 -0
- package/.next/static/chunks/app/api/passkey/authenticate/options/route-23fe50a6bf589c97.js +1 -0
- package/.next/static/chunks/app/api/passkey/authenticate/verify/route-23fe50a6bf589c97.js +1 -0
- package/.next/static/chunks/app/api/passkey/register/options/route-23fe50a6bf589c97.js +1 -0
- package/.next/static/chunks/app/api/passkey/register/verify/route-23fe50a6bf589c97.js +1 -0
- package/.next/static/chunks/app/api/stream/route-23fe50a6bf589c97.js +1 -0
- package/.next/static/chunks/app/api/sync/file/route-23fe50a6bf589c97.js +1 -0
- package/.next/static/chunks/app/api/telegram/poll/route-23fe50a6bf589c97.js +1 -0
- package/.next/static/chunks/app/api/upload/route-23fe50a6bf589c97.js +1 -0
- package/.next/static/chunks/app/api/v1/[[...path]]/route-23fe50a6bf589c97.js +1 -0
- package/.next/static/chunks/app/error-09899a13c38b6e89.js +1 -0
- package/.next/static/chunks/app/global-error-b8050d4d886f448c.js +1 -0
- package/.next/static/chunks/app/layout-ab9deed1e7e2e9df.js +1 -0
- package/.next/static/chunks/framework-4b2c6b6043dd203f.js +1 -0
- package/.next/static/chunks/main-722e16032e7764d1.js +5 -0
- package/.next/static/chunks/main-app-761880af2b6f1962.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/app-error-23fe50a6bf589c97.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/forbidden-23fe50a6bf589c97.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/not-found-23fe50a6bf589c97.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-23fe50a6bf589c97.js +1 -0
- package/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- package/.next/static/chunks/webpack-222e3894b78c67db.js +1 -0
- package/.next/static/css/0a9b5805594444e3.css +1 -0
- package/.next/static/yztMvBwyrWWkSqP6jfXoa/_buildManifest.js +1 -0
- package/.next/static/yztMvBwyrWWkSqP6jfXoa/_ssgManifest.js +1 -0
- package/.next/trace-build +1 -0
- package/.next/types/app/(app)/activity/page.ts +87 -0
- package/.next/types/app/(app)/agents/[handle]/page.ts +87 -0
- package/.next/types/app/(app)/code/page.ts +87 -0
- package/.next/types/app/(app)/config/page.ts +87 -0
- package/.next/types/app/(app)/costs/page.ts +87 -0
- package/.next/types/app/(app)/cron/page.ts +87 -0
- package/.next/types/app/(app)/dashboard/page.ts +87 -0
- package/.next/types/app/(app)/docs/[id]/page.ts +87 -0
- package/.next/types/app/(app)/docs/page.ts +87 -0
- package/.next/types/app/(app)/github/page.ts +87 -0
- package/.next/types/app/(app)/goals/page.ts +87 -0
- package/.next/types/app/(app)/inbox/page.ts +87 -0
- package/.next/types/app/(app)/knowledge/page.ts +87 -0
- package/.next/types/app/(app)/models/page.ts +87 -0
- package/.next/types/app/(app)/notifications/page.ts +87 -0
- package/.next/types/app/(app)/org/page.ts +87 -0
- package/.next/types/app/(app)/organizations/page.ts +87 -0
- package/.next/types/app/(app)/page.ts +87 -0
- package/.next/types/app/(app)/planner/page.ts +87 -0
- package/.next/types/app/(app)/plugins/page.ts +87 -0
- package/.next/types/app/(app)/pm/page.ts +87 -0
- package/.next/types/app/(app)/prepare-deploy/page.ts +87 -0
- package/.next/types/app/(app)/profile/page.ts +87 -0
- package/.next/types/app/(app)/pulse/page.ts +87 -0
- package/.next/types/app/(app)/reports/[id]/page.ts +87 -0
- package/.next/types/app/(app)/reports/page.ts +87 -0
- package/.next/types/app/(app)/routines/page.ts +87 -0
- package/.next/types/app/(app)/search/page.ts +87 -0
- package/.next/types/app/(app)/security/page.ts +87 -0
- package/.next/types/app/(app)/skills/page.ts +87 -0
- package/.next/types/app/(app)/tasks/page.ts +87 -0
- package/.next/types/app/(app)/test-dev/page.ts +87 -0
- package/.next/types/app/(app)/update/page.ts +87 -0
- package/.next/types/app/(auth)/login/page.ts +87 -0
- package/.next/types/app/(auth)/onboarding/page.ts +87 -0
- package/.next/types/app/api/auth/[...all]/route.ts +351 -0
- package/.next/types/app/api/cron/tick/route.ts +351 -0
- package/.next/types/app/api/dev-login/route.ts +351 -0
- package/.next/types/app/api/locks/acquire/route.ts +351 -0
- package/.next/types/app/api/models/progress/route.ts +351 -0
- package/.next/types/app/api/passkey/authenticate/options/route.ts +351 -0
- package/.next/types/app/api/passkey/authenticate/verify/route.ts +351 -0
- package/.next/types/app/api/passkey/register/options/route.ts +351 -0
- package/.next/types/app/api/passkey/register/verify/route.ts +351 -0
- package/.next/types/app/api/stream/route.ts +351 -0
- package/.next/types/app/api/sync/file/route.ts +351 -0
- package/.next/types/app/api/telegram/poll/route.ts +351 -0
- package/.next/types/app/api/upload/route.ts +351 -0
- package/.next/types/app/api/v1/[[...path]]/route.ts +351 -0
- package/.next/types/cache-life.d.ts +145 -0
- package/.next/types/link.d.ts +210 -0
- package/.next/types/package.json +1 -0
- package/.next/types/routes.d.ts +120 -0
- package/.next/types/validator.ts +511 -0
- package/CHANGELOG.md +312 -0
- package/LICENSE +21 -0
- package/README.md +382 -0
- package/README.pt-BR.md +391 -0
- package/bin/constella.mjs +329 -0
- package/bin/guard-hook.mjs +44 -0
- package/bin/lock-hook.mjs +49 -0
- package/bin/worker.mjs +142 -0
- package/docs/assets/arch-orbit.svg +56 -0
- package/docs/assets/blackhole.svg +37 -0
- package/docs/assets/divider-orbit.svg +23 -0
- package/docs/assets/hero-constella.svg +72 -0
- package/docs/en/AGENTS.md +279 -0
- package/docs/en/AI_ARCHITECTURE.md +373 -0
- package/docs/en/ARCHITECTURE.md +334 -0
- package/docs/en/AUTH_MODE.md +247 -0
- package/docs/en/CHAT_COMMANDS.md +305 -0
- package/docs/en/CONFIGURATION.md +340 -0
- package/docs/en/DEPLOY.md +331 -0
- package/docs/en/DM.md +297 -0
- package/docs/en/FAQ.md +258 -0
- package/docs/en/GITHUB.md +341 -0
- package/docs/en/GOALS_SPECS_ISSUES.md +303 -0
- package/docs/en/INBOX.md +340 -0
- package/docs/en/INSTALLATION.md +329 -0
- package/docs/en/KB_AGENT.md +305 -0
- package/docs/en/KB_RAG.md +356 -0
- package/docs/en/MCP.md +313 -0
- package/docs/en/MEMORY_RAG.md +289 -0
- package/docs/en/MODELS.md +341 -0
- package/docs/en/ONBOARDING.md +327 -0
- package/docs/en/PLUGINS.md +290 -0
- package/docs/en/PORTABLE_MODE.md +387 -0
- package/docs/en/PO_AGENT.md +379 -0
- package/docs/en/PREPARE_DEPLOY.md +308 -0
- package/docs/en/PROJECT_STACKS.md +258 -0
- package/docs/en/PUBLIC_API.md +315 -0
- package/docs/en/PUBLISHING.md +343 -0
- package/docs/en/README.md +95 -0
- package/docs/en/SECURITY.md +280 -0
- package/docs/en/SKILLS.md +349 -0
- package/docs/en/START_MODE.md +340 -0
- package/docs/en/SYNCED_BLOCKS.md +320 -0
- package/docs/en/TEAM_ROOM.md +285 -0
- package/docs/en/TELEGRAM.md +294 -0
- package/docs/en/TEST_DEV.md +321 -0
- package/docs/en/TROUBLESHOOTING.md +294 -0
- package/docs/en/UPDATE.md +301 -0
- package/docs/en/VPS_MODE.md +334 -0
- package/docs/en/WORKFLOW.md +321 -0
- package/docs/pt/AGENTS.md +279 -0
- package/docs/pt/AI_ARCHITECTURE.md +373 -0
- package/docs/pt/ARCHITECTURE.md +334 -0
- package/docs/pt/AUTH_MODE.md +247 -0
- package/docs/pt/CHAT_COMMANDS.md +307 -0
- package/docs/pt/CONFIGURATION.md +340 -0
- package/docs/pt/DEPLOY.md +331 -0
- package/docs/pt/DM.md +297 -0
- package/docs/pt/FAQ.md +258 -0
- package/docs/pt/GITHUB.md +341 -0
- package/docs/pt/GOALS_SPECS_ISSUES.md +303 -0
- package/docs/pt/INBOX.md +340 -0
- package/docs/pt/INSTALLATION.md +329 -0
- package/docs/pt/KB_AGENT.md +305 -0
- package/docs/pt/KB_RAG.md +356 -0
- package/docs/pt/MCP.md +313 -0
- package/docs/pt/MEMORY_RAG.md +289 -0
- package/docs/pt/MODELS.md +341 -0
- package/docs/pt/ONBOARDING.md +327 -0
- package/docs/pt/PLUGINS.md +290 -0
- package/docs/pt/PORTABLE_MODE.md +387 -0
- package/docs/pt/PO_AGENT.md +379 -0
- package/docs/pt/PREPARE_DEPLOY.md +308 -0
- package/docs/pt/PROJECT_STACKS.md +258 -0
- package/docs/pt/PUBLIC_API.md +315 -0
- package/docs/pt/PUBLISHING.md +343 -0
- package/docs/pt/README.md +95 -0
- package/docs/pt/SECURITY.md +280 -0
- package/docs/pt/SKILLS.md +349 -0
- package/docs/pt/START_MODE.md +340 -0
- package/docs/pt/SYNCED_BLOCKS.md +320 -0
- package/docs/pt/TEAM_ROOM.md +285 -0
- package/docs/pt/TELEGRAM.md +294 -0
- package/docs/pt/TEST_DEV.md +321 -0
- package/docs/pt/TROUBLESHOOTING.md +294 -0
- package/docs/pt/UPDATE.md +301 -0
- package/docs/pt/VPS_MODE.md +334 -0
- package/docs/pt/WORKFLOW.md +321 -0
- package/drizzle/0000_regular_nightshade.sql +644 -0
- package/drizzle/0001_mixed_zombie.sql +106 -0
- package/drizzle/meta/0000_snapshot.json +4650 -0
- package/drizzle/meta/0001_snapshot.json +5418 -0
- package/drizzle/meta/_journal.json +20 -0
- package/drizzle.config.mjs +16 -0
- package/next.config.mjs +18 -0
- package/package.json +130 -0
- package/scripts/clean-repo.mjs +20 -0
- package/scripts/dev-all.mjs +46 -0
- package/scripts/i18n-parity.mjs +57 -0
- package/scripts/mcp-server.mjs +100 -0
- package/scripts/postbuild.mjs +11 -0
- package/scripts/publish-public.mjs +116 -0
- package/scripts/start-all.mjs +45 -0
- package/scripts/trim-next.mjs +23 -0
- package/scripts/vps-install.sh +39 -0
- package/skills/CONTRIBUTING.md +122 -0
- package/skills/COVERAGE.md +129 -0
- package/skills/INDEX.json +3443 -0
- package/skills/README.md +57 -0
- package/skills/design/animation-motion/SKILL.md +60 -0
- package/skills/design/color-and-typography/SKILL.md +60 -0
- package/skills/design/css-techniques/SKILL.md +58 -0
- package/skills/design/design-systems/SKILL.md +60 -0
- package/skills/design/gradients/SKILL.md +59 -0
- package/skills/design/graphic-design-basics/SKILL.md +55 -0
- package/skills/design/microinteractions/SKILL.md +58 -0
- package/skills/design/responsive-layout/SKILL.md +59 -0
- package/skills/design/ui-ux-principles/SKILL.md +58 -0
- package/skills/engineering/architecture/api-design-rest-graphql/SKILL.md +67 -0
- package/skills/engineering/architecture/caching-strategies/SKILL.md +59 -0
- package/skills/engineering/architecture/data-modeling/SKILL.md +64 -0
- package/skills/engineering/architecture/message-queues-async/SKILL.md +58 -0
- package/skills/engineering/architecture/scalability-reliability/SKILL.md +62 -0
- package/skills/engineering/architecture/software-architecture-patterns/SKILL.md +56 -0
- package/skills/engineering/architecture/system-design-fundamentals/SKILL.md +56 -0
- package/skills/engineering/backend/auth-and-authorization/SKILL.md +62 -0
- package/skills/engineering/backend/backend-fundamentals/SKILL.md +65 -0
- package/skills/engineering/backend/observability-logging/SKILL.md +60 -0
- package/skills/engineering/frontend/accessibility-wcag/SKILL.md +57 -0
- package/skills/engineering/frontend/frontend-architecture/SKILL.md +65 -0
- package/skills/engineering/frontend/rendering-strategies-ssr-csr/SKILL.md +60 -0
- package/skills/engineering/frontend/state-management/SKILL.md +69 -0
- package/skills/engineering/performance/backend-performance/SKILL.md +69 -0
- package/skills/engineering/performance/database-query-optimization/SKILL.md +64 -0
- package/skills/engineering/performance/profiling-and-benchmarking/SKILL.md +60 -0
- package/skills/engineering/performance/web-performance-core-vitals/SKILL.md +72 -0
- package/skills/engineering/practices/clean-code/SKILL.md +61 -0
- package/skills/engineering/practices/code-optimization/SKILL.md +60 -0
- package/skills/engineering/practices/code-review-practices/SKILL.md +58 -0
- package/skills/engineering/practices/git-workflow/SKILL.md +62 -0
- package/skills/engineering/practices/refactoring/SKILL.md +58 -0
- package/skills/engineering/security/appsec-fundamentals/SKILL.md +70 -0
- package/skills/engineering/security/dependency-supply-chain/SKILL.md +77 -0
- package/skills/engineering/security/owasp-asvs/SKILL.md +54 -0
- package/skills/engineering/security/owasp-top-10/SKILL.md +63 -0
- package/skills/engineering/security/secrets-management/SKILL.md +58 -0
- package/skills/engineering/security/secure-auth-sessions/SKILL.md +56 -0
- package/skills/engineering/testing/tdd-and-coverage/SKILL.md +62 -0
- package/skills/engineering/testing/testing-strategy-pyramid/SKILL.md +56 -0
- package/skills/engineering/testing/unit-integration-e2e/SKILL.md +75 -0
- package/skills/languages/c/SKILL.md +74 -0
- package/skills/languages/clojure/SKILL.md +73 -0
- package/skills/languages/cpp/SKILL.md +75 -0
- package/skills/languages/csharp/SKILL.md +75 -0
- package/skills/languages/dart/SKILL.md +82 -0
- package/skills/languages/elixir/SKILL.md +74 -0
- package/skills/languages/erlang/SKILL.md +76 -0
- package/skills/languages/go/SKILL.md +83 -0
- package/skills/languages/haskell/SKILL.md +70 -0
- package/skills/languages/java/SKILL.md +71 -0
- package/skills/languages/javascript/SKILL.md +62 -0
- package/skills/languages/kotlin/SKILL.md +68 -0
- package/skills/languages/lua/SKILL.md +79 -0
- package/skills/languages/objectivec/SKILL.md +83 -0
- package/skills/languages/php/SKILL.md +74 -0
- package/skills/languages/python/SKILL.md +68 -0
- package/skills/languages/r/SKILL.md +70 -0
- package/skills/languages/ruby/SKILL.md +67 -0
- package/skills/languages/rust/SKILL.md +72 -0
- package/skills/languages/scala/SKILL.md +73 -0
- package/skills/languages/swift/SKILL.md +73 -0
- package/skills/languages/typescript/SKILL.md +69 -0
- package/skills/meta/authoring-agent-skills/SKILL.md +73 -0
- package/skills/meta/progressive-disclosure/SKILL.md +65 -0
- package/skills/meta/skill-frontmatter-spec/SKILL.md +65 -0
- package/skills/process/adr-technical-decisions/SKILL.md +59 -0
- package/skills/process/app-planning/SKILL.md +63 -0
- package/skills/process/architecture-before-code/SKILL.md +52 -0
- package/skills/process/breaking-work-into-sprints/SKILL.md +53 -0
- package/skills/process/idea-to-product/SKILL.md +50 -0
- package/skills/process/mocks-and-screen-flows/SKILL.md +52 -0
- package/skills/process/prioritization-moscow-rice/SKILL.md +64 -0
- package/skills/process/problem-framing/SKILL.md +51 -0
- package/skills/process/product-discovery/SKILL.md +53 -0
- package/skills/process/readme-generation/SKILL.md +90 -0
- package/skills/process/requirements-to-specs/SKILL.md +53 -0
- package/skills/process/research-official-docs/SKILL.md +58 -0
- package/skills/process/review-code-perf-security/SKILL.md +65 -0
- package/skills/process/security-by-design/SKILL.md +68 -0
- package/skills/process/specs-to-issues/SKILL.md +53 -0
- package/skills/process/testing-before-done/SKILL.md +61 -0
- package/skills/process/validating-ux-navigation/SKILL.md +63 -0
- package/skills/references/ai-attachments-ui/SKILL.md +66 -0
- package/skills/references/ai-in-browser-webllm/SKILL.md +74 -0
- package/skills/references/ai-tool-ui-patterns/SKILL.md +63 -0
- package/skills/references/component-patterns-gallery/SKILL.md +62 -0
- package/skills/references/gradient-resources/SKILL.md +66 -0
- package/skills/references/react-component-libraries/SKILL.md +61 -0
- package/skills/references/saas-landing-patterns/SKILL.md +67 -0
- package/skills/references/shadcn-tailwind-theming/SKILL.md +74 -0
- package/skills/references/vercel-ai-sdk-elements/SKILL.md +66 -0
- package/skills/references/web-animation-codrops/SKILL.md +68 -0
- package/skills/stacks/aiml/jupyter/SKILL.md +68 -0
- package/skills/stacks/aiml/keras/SKILL.md +77 -0
- package/skills/stacks/aiml/numpy/SKILL.md +69 -0
- package/skills/stacks/aiml/pandas/SKILL.md +72 -0
- package/skills/stacks/aiml/pytorch/SKILL.md +77 -0
- package/skills/stacks/aiml/scikit-learn/SKILL.md +74 -0
- package/skills/stacks/aiml/tensorflow/SKILL.md +79 -0
- package/skills/stacks/auth/auth0/SKILL.md +63 -0
- package/skills/stacks/auth/authjs/SKILL.md +69 -0
- package/skills/stacks/auth/clerk/SKILL.md +72 -0
- package/skills/stacks/auth/keycloak/SKILL.md +63 -0
- package/skills/stacks/auth/lucia/SKILL.md +56 -0
- package/skills/stacks/auth/passport/SKILL.md +70 -0
- package/skills/stacks/auth/supabase-auth/SKILL.md +66 -0
- package/skills/stacks/baas/amplify/SKILL.md +71 -0
- package/skills/stacks/baas/appwrite/SKILL.md +79 -0
- package/skills/stacks/baas/firebase/SKILL.md +73 -0
- package/skills/stacks/baas/heroku/SKILL.md +71 -0
- package/skills/stacks/backend/actix/SKILL.md +77 -0
- package/skills/stacks/backend/adonisjs/SKILL.md +65 -0
- package/skills/stacks/backend/aspnet-core/SKILL.md +75 -0
- package/skills/stacks/backend/codeigniter/SKILL.md +76 -0
- package/skills/stacks/backend/django/SKILL.md +62 -0
- package/skills/stacks/backend/express/SKILL.md +65 -0
- package/skills/stacks/backend/fastapi/SKILL.md +64 -0
- package/skills/stacks/backend/fastify/SKILL.md +64 -0
- package/skills/stacks/backend/fiber/SKILL.md +68 -0
- package/skills/stacks/backend/flask/SKILL.md +71 -0
- package/skills/stacks/backend/gin/SKILL.md +68 -0
- package/skills/stacks/backend/graphql/SKILL.md +70 -0
- package/skills/stacks/backend/hono/SKILL.md +64 -0
- package/skills/stacks/backend/koa/SKILL.md +63 -0
- package/skills/stacks/backend/laravel/SKILL.md +73 -0
- package/skills/stacks/backend/nestjs/SKILL.md +70 -0
- package/skills/stacks/backend/nginx/SKILL.md +77 -0
- package/skills/stacks/backend/phoenix/SKILL.md +68 -0
- package/skills/stacks/backend/rails/SKILL.md +67 -0
- package/skills/stacks/backend/spring/SKILL.md +70 -0
- package/skills/stacks/backend/spring-boot/SKILL.md +70 -0
- package/skills/stacks/backend/symfony/SKILL.md +77 -0
- package/skills/stacks/container/containerd/SKILL.md +75 -0
- package/skills/stacks/container/docker/SKILL.md +90 -0
- package/skills/stacks/container/podman/SKILL.md +93 -0
- package/skills/stacks/database/cassandra/SKILL.md +74 -0
- package/skills/stacks/database/cockroachdb/SKILL.md +69 -0
- package/skills/stacks/database/dynamodb/SKILL.md +62 -0
- package/skills/stacks/database/mariadb/SKILL.md +71 -0
- package/skills/stacks/database/mongodb/SKILL.md +71 -0
- package/skills/stacks/database/mysql/SKILL.md +72 -0
- package/skills/stacks/database/neon/SKILL.md +68 -0
- package/skills/stacks/database/planetscale/SKILL.md +70 -0
- package/skills/stacks/database/postgresql/SKILL.md +81 -0
- package/skills/stacks/database/redis/SKILL.md +78 -0
- package/skills/stacks/database/sqlite/SKILL.md +70 -0
- package/skills/stacks/database/supabase/SKILL.md +79 -0
- package/skills/stacks/dataviz/chart-js/SKILL.md +72 -0
- package/skills/stacks/dataviz/d3/SKILL.md +77 -0
- package/skills/stacks/dataviz/grafana/SKILL.md +69 -0
- package/skills/stacks/dataviz/plotly/SKILL.md +71 -0
- package/skills/stacks/frontend/alpine/SKILL.md +75 -0
- package/skills/stacks/frontend/angular/SKILL.md +75 -0
- package/skills/stacks/frontend/backbone/SKILL.md +82 -0
- package/skills/stacks/frontend/ember/SKILL.md +85 -0
- package/skills/stacks/frontend/htmx/SKILL.md +73 -0
- package/skills/stacks/frontend/lit/SKILL.md +76 -0
- package/skills/stacks/frontend/preact/SKILL.md +74 -0
- package/skills/stacks/frontend/qwik/SKILL.md +65 -0
- package/skills/stacks/frontend/react/SKILL.md +77 -0
- package/skills/stacks/frontend/solidjs/SKILL.md +75 -0
- package/skills/stacks/frontend/svelte/SKILL.md +70 -0
- package/skills/stacks/frontend/vue/SKILL.md +69 -0
- package/skills/stacks/infra/ansible/SKILL.md +76 -0
- package/skills/stacks/infra/aws/SKILL.md +66 -0
- package/skills/stacks/infra/azure/SKILL.md +72 -0
- package/skills/stacks/infra/circleci/SKILL.md +78 -0
- package/skills/stacks/infra/cloudflare/SKILL.md +65 -0
- package/skills/stacks/infra/fly-io/SKILL.md +63 -0
- package/skills/stacks/infra/gcp/SKILL.md +66 -0
- package/skills/stacks/infra/jenkins/SKILL.md +73 -0
- package/skills/stacks/infra/kubernetes/SKILL.md +64 -0
- package/skills/stacks/infra/netlify/SKILL.md +60 -0
- package/skills/stacks/infra/railway/SKILL.md +63 -0
- package/skills/stacks/infra/tailscale/SKILL.md +65 -0
- package/skills/stacks/infra/terraform/SKILL.md +75 -0
- package/skills/stacks/infra/vagrant/SKILL.md +70 -0
- package/skills/stacks/infra/vercel/SKILL.md +60 -0
- package/skills/stacks/meta/astro/SKILL.md +64 -0
- package/skills/stacks/meta/docusaurus/SKILL.md +71 -0
- package/skills/stacks/meta/eleventy/SKILL.md +69 -0
- package/skills/stacks/meta/gatsby/SKILL.md +63 -0
- package/skills/stacks/meta/hugo/SKILL.md +73 -0
- package/skills/stacks/meta/jekyll/SKILL.md +70 -0
- package/skills/stacks/meta/nextjs/SKILL.md +62 -0
- package/skills/stacks/meta/nuxt/SKILL.md +66 -0
- package/skills/stacks/meta/remix/SKILL.md +67 -0
- package/skills/stacks/meta/sveltekit/SKILL.md +70 -0
- package/skills/stacks/meta/vite/SKILL.md +63 -0
- package/skills/stacks/mobile/android/SKILL.md +77 -0
- package/skills/stacks/mobile/flutter/SKILL.md +77 -0
- package/skills/stacks/mobile/ionic/SKILL.md +72 -0
- package/skills/stacks/mobile/nativescript/SKILL.md +71 -0
- package/skills/stacks/mobile/react-native/SKILL.md +75 -0
- package/skills/stacks/mobile/xamarin/SKILL.md +73 -0
- package/skills/stacks/orm/diesel/SKILL.md +72 -0
- package/skills/stacks/orm/django-orm/SKILL.md +58 -0
- package/skills/stacks/orm/drizzle/SKILL.md +67 -0
- package/skills/stacks/orm/gorm/SKILL.md +73 -0
- package/skills/stacks/orm/knex/SKILL.md +64 -0
- package/skills/stacks/orm/mongoose/SKILL.md +64 -0
- package/skills/stacks/orm/prisma/SKILL.md +64 -0
- package/skills/stacks/orm/sequelize/SKILL.md +65 -0
- package/skills/stacks/orm/sqlalchemy/SKILL.md +71 -0
- package/skills/stacks/orm/typeorm/SKILL.md +70 -0
- package/skills/stacks/queue/bullmq/SKILL.md +69 -0
- package/skills/stacks/queue/celery/SKILL.md +68 -0
- package/skills/stacks/queue/kafka/SKILL.md +66 -0
- package/skills/stacks/queue/nats/SKILL.md +66 -0
- package/skills/stacks/queue/rabbitmq/SKILL.md +64 -0
- package/skills/stacks/queue/redis/SKILL.md +66 -0
- package/skills/stacks/runtime/beam/SKILL.md +72 -0
- package/skills/stacks/runtime/bun/SKILL.md +80 -0
- package/skills/stacks/runtime/deno/SKILL.md +74 -0
- package/skills/stacks/runtime/dotnet/SKILL.md +64 -0
- package/skills/stacks/runtime/jvm/SKILL.md +66 -0
- package/skills/stacks/runtime/node/SKILL.md +70 -0
- package/skills/stacks/runtime/pypy/SKILL.md +69 -0
- package/skills/stacks/runtime/python3/SKILL.md +70 -0
- package/skills/stacks/styling/bootstrap/SKILL.md +74 -0
- package/skills/stacks/styling/bulma/SKILL.md +80 -0
- package/skills/stacks/styling/chakra-ui/SKILL.md +61 -0
- package/skills/stacks/styling/css-modules/SKILL.md +54 -0
- package/skills/stacks/styling/mui/SKILL.md +60 -0
- package/skills/stacks/styling/sass/SKILL.md +63 -0
- package/skills/stacks/styling/shadcn-ui/SKILL.md +58 -0
- package/skills/stacks/styling/styled-components/SKILL.md +62 -0
- package/skills/stacks/styling/tailwind/SKILL.md +59 -0
- package/skills/stacks/styling/unocss/SKILL.md +64 -0
- package/skills/stacks/styling/vanilla-extract/SKILL.md +64 -0
- package/skills/stacks/styling/vuetify/SKILL.md +89 -0
- package/skills/stacks/testing/cypress/SKILL.md +68 -0
- package/skills/stacks/testing/jasmine/SKILL.md +67 -0
- package/skills/stacks/testing/jest/SKILL.md +67 -0
- package/skills/stacks/testing/mocha/SKILL.md +71 -0
- package/skills/stacks/testing/playwright/SKILL.md +68 -0
- package/skills/stacks/testing/puppeteer/SKILL.md +70 -0
- package/skills/stacks/testing/selenium/SKILL.md +70 -0
- package/skills/stacks/testing/vitest/SKILL.md +68 -0
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
[← Docs index](./README.md) · [🇧🇷 Português](../pt/KB_RAG.md) · [✦ Constella](../../README.md)
|
|
2
|
+
|
|
3
|
+
# Knowledge Base & RAG ✦ The Memory Nebula 🌌
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
> The control plane's long-term memory. Every decision, fix, pattern and finding agents accumulate condenses into a curated, classified, state-aware nebula — and gravity (semantic retrieval) pulls the right knowledge back into context when it's needed.
|
|
8
|
+
|
|
9
|
+
Constella runs **two cooperating layers** over the same store:
|
|
10
|
+
|
|
11
|
+
- **RAG** (`src/server/rag.ts`) — raw retrieval over workspace Markdown + chat transcripts. Embeddings when a local model is up; keyword heuristic otherwise.
|
|
12
|
+
- **KB** (`src/server/kb.ts`) — the curated layer the Knowledge agent (**Vannevar**) owns: typed entries, content-hash dedup, lifecycle (active → superseded → obsolete → archived), state-aware retrieval, a multi-hop knowledge graph, and budget-gated LLM curation.
|
|
13
|
+
|
|
14
|
+
Both write into one physical table — `rag_chunk` — and KB entries simply emit their own chunks (path `kb/<type>/<id>`) so a single retrieval pass spans docs, chat **and** curated knowledge.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 1. When to use 🪐
|
|
19
|
+
|
|
20
|
+
| You want to… | Layer / entry point |
|
|
21
|
+
|---|---|
|
|
22
|
+
| Let agents recall what was decided/built without re-reading every file | RAG `retrieve()` + KB `kbQuery()` |
|
|
23
|
+
| Capture a reusable learning deterministically (no LLM) | `ingestKnowledge()` |
|
|
24
|
+
| Have an agent self-record a fact mid-run | `[[REMEMBER type=<t>: <fact>]]` token |
|
|
25
|
+
| Have an agent ask the KB before acting | `[[CONSULT: <question>]]` token |
|
|
26
|
+
| Trigger reindex / chat re-index / embed health from a run | `[[KB: reindex|index-chat|health]]` token |
|
|
27
|
+
| Ask the KB a clean, curated question (chat / `/kb`) | `kbAnswer()` |
|
|
28
|
+
| Walk related knowledge from a goal/spec/issue | `relatedKnowledge()` |
|
|
29
|
+
| Dedupe, retire and tighten the KB | `runKbCuration()` (Vannevar) |
|
|
30
|
+
| Distill recurring learnings into new skills (P3) | `proposeSkillsFromLearnings()` |
|
|
31
|
+
|
|
32
|
+
See also [KB_AGENT.md](./KB_AGENT.md) (Vannevar's persona & ritual), [MEMORY_RAG.md](./MEMORY_RAG.md), [SYNCED_BLOCKS.md](./SYNCED_BLOCKS.md) (canonical blocks), and [MODELS.md](./MODELS.md) (the local embed/chat servers).
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 2. How it works 🛰️
|
|
37
|
+
|
|
38
|
+
### RAG store (`rag.ts`)
|
|
39
|
+
|
|
40
|
+
- **Indexed dirs** (`RAG_DIRS`): `.claude`, `DOCS`, `PO`, `Reports`, `specs`, `issues`. Plus the attached `mock/` prototype (text files: `.md .html .css .js/jsx .ts/tsx .txt .json`).
|
|
41
|
+
- **Excluded plumbing**: `.claude/kb/` (the KB agent's own prompt/taxonomy) and `.claude/skills/` are never indexed — a question would otherwise retrieve Constella's internals.
|
|
42
|
+
- **Chunking** (`chunksOf`): split on H1–H3 headers (`/\n(?=#{1,3}\s)/`); each part ≤ **1200 chars** (longer parts hard-split); **max 40 chunks** per document.
|
|
43
|
+
- **Embeddings** (`embed`): two backends, tried in order —
|
|
44
|
+
1. **Ollama** (`OLLAMA_URL`, default `http://127.0.0.1:11434`) with model `CONSTELLA_EMBED_MODEL` (default `nomic-embed-text`).
|
|
45
|
+
2. **Dedicated llama.cpp embed server** (`CONSTELLA_EMBED_URL`, default `http://127.0.0.1:8083`), OpenAI-compatible `/v1/embeddings`.
|
|
46
|
+
- Returns `null` if both are down → the caller falls back to keyword search.
|
|
47
|
+
- **Asymmetric nomic prefixes**: nomic-embed-text was trained with task prefixes and *requires* them. Documents are embedded as `search_document: …`, queries as `search_query: …`. Both index and query sides must use the same model + matching prefix or cosine similarity is meaningless.
|
|
48
|
+
- **Chat transcripts** (`indexChat`): the team room, DMs and Telegram are grouped per channel, the **last 400 lines** of each are embedded under path `chat/<channel>`, so agents recall what was *said*, not just what's in the docs.
|
|
49
|
+
|
|
50
|
+
### The local embed server (`local-models.ts`)
|
|
51
|
+
|
|
52
|
+
`ensureEmbedServer()` brings up a **separate** llama.cpp instance serving the local nomic GGUF with `--embeddings` on **:8083** (distinct from the chat server on **:8082**). It runs on boot and after an embedding model is downloaded, so retrieval is semantic with no manual setup:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
llama-server -m <nomic.gguf> --embeddings --host 127.0.0.1 --port 8083 -c 2048 --pooling mean [<gpu-offload args>]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`embedServerUp()` checks `GET <EMBED_URL>/health`; `llamaServerStatus()` checks the chat server's `/v1/models`.
|
|
59
|
+
|
|
60
|
+
### KB layer (`kb.ts`)
|
|
61
|
+
|
|
62
|
+
A `kb_entry` is **one unit of reusable knowledge** — a decision, code-change, finding, spec, fix, pattern… It is:
|
|
63
|
+
- **classified** by `type` + work/file refs,
|
|
64
|
+
- **deduped** by a SHA-256 content hash,
|
|
65
|
+
- **lifecycle-tracked** (`active → superseded → obsolete → archived`),
|
|
66
|
+
- and **emits its own `rag_chunk(s)`** under path `kb/<type>/<id>` for semantic retrieval.
|
|
67
|
+
|
|
68
|
+
All KB capture is **best-effort and fire-and-forget**: a bad item never aborts a batch, and KB work must never break a task run.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 3. Main flow 🌠
|
|
73
|
+
|
|
74
|
+
```mermaid
|
|
75
|
+
flowchart TD
|
|
76
|
+
subgraph Ingest["Ingest — deterministic, no LLM"]
|
|
77
|
+
A["Agent reply / task output"] -->|"[[REMEMBER type=…: fact]]"| EX["extractRemembered()"]
|
|
78
|
+
EX --> IK["ingestKnowledge(items)"]
|
|
79
|
+
DOC["Doc / spec / decision written"] --> IK
|
|
80
|
+
IK --> SCRUB{"scrubSecrets changes text?"}
|
|
81
|
+
SCRUB -- "yes (secret-shaped)" --> REFUSE["refuse · console.warn"]
|
|
82
|
+
SCRUB -- "no" --> HASH["sha256 hash"]
|
|
83
|
+
HASH --> DUP{"hash exists?"}
|
|
84
|
+
DUP -- "yes" --> TOUCH["touch updatedAt · skip"]
|
|
85
|
+
DUP -- "no" --> SLOT{"same type+source slot?"}
|
|
86
|
+
SLOT -- "yes" --> UPD["update-in-place"]
|
|
87
|
+
SLOT -- "no" --> INS["insert kb_entry"]
|
|
88
|
+
UPD --> EMB["embedEntry → rag_chunk kb/<type>/<id>"]
|
|
89
|
+
INS --> EMB
|
|
90
|
+
EMB --> CUR["scheduleKbCuration (debounced)"]
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
subgraph Query["Query — state-aware retrieval"]
|
|
94
|
+
Q["[[CONSULT]] · /kb · kbQuery()"] --> SEL["select rag_chunk WHERE obsolete=0"]
|
|
95
|
+
SEL --> QV{"embed(query) available?"}
|
|
96
|
+
QV -- "yes + vectors exist" --> COS["cosine top-k · mode=semantic"]
|
|
97
|
+
QV -- "no" --> KW["keyword overlap top-k · mode=heuristic"]
|
|
98
|
+
COS --> REFS["refsFor() → spec:/issue:/goal:/file:"]
|
|
99
|
+
KW --> REFS
|
|
100
|
+
REFS --> LOG["logQuery → kb_query_log"]
|
|
101
|
+
LOG --> ANS["KbAnswer{context, sources, refs, sufficient}"]
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
CUR -.->|"Vannevar (budget-gated)"| RUNCUR["runKbCuration() · merge/retire/tighten"]
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 4. Key concepts 🕳️
|
|
110
|
+
|
|
111
|
+
- **Deterministic capture, LLM curation** — the *hot path* (`ingestKnowledge`) never calls a model; the *cold path* (`runKbCuration`) does, off the critical path, budget-gated. The KB keeps working even if curation never runs.
|
|
112
|
+
- **Update-in-place vs insert** — an item with the same `(type, sourceKind, sourceRef)` slot is treated as an *update* of that knowledge (rewrites the row); a different slot inserts a new entry. Identical content (same hash) just touches `updatedAt`.
|
|
113
|
+
- **State-aware retrieval** — `kbQuery` only selects `rag_chunk WHERE obsolete = 0`. Superseded/obsolete entries and the chunks of cancelled/archived goals are flagged `obsolete = 1`, so stale knowledge stops surfacing automatically.
|
|
114
|
+
- **Insufficiency signal** — `KbAnswer.sufficient` is honest: when nothing relevant is found, the answer says so rather than inventing.
|
|
115
|
+
- **Knowledge graph** — `relatedKnowledge` walks the `goalId/specId/issueId` link columns + the `supersedesId` chain up to `hops` (default 2), grouping connected, *active* knowledge by type. Decisions are themselves `kb_entry` rows (`type="decision"`), so this naturally links decisions ↔ specs ↔ issues ↔ prior fixes.
|
|
116
|
+
- **Secrets never enter the KB** — before ingest, `scrubSecrets(blob)` runs; if the text changes (a secret shape was present), the item is **refused**. See [SECURITY.md](./SECURITY.md).
|
|
117
|
+
- **Local-first generation** — KB *answers* and *curation* prefer the local llama.cpp chat server (`LLAMACPP_URL`, default `:8082`); only if it's down does it fall back to the agent's (possibly paid) CLI. `<think>…</think>` blocks from reasoning GGUFs are stripped.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## 5. The knowledge taxonomy 🌌
|
|
122
|
+
|
|
123
|
+
`KbType` — the full set (from `kb.ts`). `note` is the catch-all.
|
|
124
|
+
|
|
125
|
+
| type | What it captures |
|
|
126
|
+
|---|---|
|
|
127
|
+
| `decision` | An architectural/product decision and its rationale |
|
|
128
|
+
| `spec` | A specification unit |
|
|
129
|
+
| `issue` | An issue/work item finding |
|
|
130
|
+
| `goal` | Goal-level knowledge |
|
|
131
|
+
| `plan` | Planning knowledge |
|
|
132
|
+
| `architecture` | System/structure knowledge |
|
|
133
|
+
| `business-rule` | A domain/business rule |
|
|
134
|
+
| `code-change` | A meaningful code change |
|
|
135
|
+
| `dependency` | A dependency / library fact |
|
|
136
|
+
| `integration` | An external integration detail |
|
|
137
|
+
| `bug` | A bug observed |
|
|
138
|
+
| `fix` | A fix applied |
|
|
139
|
+
| `test` | Test knowledge / coverage |
|
|
140
|
+
| `review` | A review finding |
|
|
141
|
+
| `vuln` | A security vulnerability |
|
|
142
|
+
| `doc` | Documentation knowledge |
|
|
143
|
+
| `user-context` | Operator/user context |
|
|
144
|
+
| `history` | Historical context |
|
|
145
|
+
| `command` | A useful command |
|
|
146
|
+
| `file-structure` | File/layout knowledge |
|
|
147
|
+
| `ui-pattern` | A reusable UI pattern |
|
|
148
|
+
| `stack` | Project-stack fact |
|
|
149
|
+
| `env-config` | Environment/config fact |
|
|
150
|
+
| `note` | Catch-all (default) |
|
|
151
|
+
|
|
152
|
+
**Agent self-capture** (`[[REMEMBER type=…]]`) accepts a narrower set — `KB_LEARN_TYPES` — and anything outside it falls back to `note`:
|
|
153
|
+
`decision, architecture, business-rule, integration, dependency, bug, fix, test, review, vuln, ui-pattern, stack, env-config, command, note`.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## 6. Agent tokens 🚀
|
|
158
|
+
|
|
159
|
+
Agents read/write the KB inline by emitting double-square-bracket tokens. The runner parses them out and strips them from the visible reply.
|
|
160
|
+
|
|
161
|
+
| Token | Direction | Handler | Effect |
|
|
162
|
+
|---|---|---|---|
|
|
163
|
+
| `[[REMEMBER type=<t>: <fact>]]` | producer | `extractRemembered()` | Becomes a typed `KbItem` (fact ≥ 8 chars), ingested via `ingestKnowledge` |
|
|
164
|
+
| `[[CONSULT: <question>]]` | consumer | `answerConsults()` | Runs `kbQuery` (k=6), posts the answer back into the thread so it's in context next turn (question ≥ 4 chars) |
|
|
165
|
+
| `[[KB: reindex]]` | maintenance | `runKbTools()` | `indexRag(orgId)` → reports chunk count |
|
|
166
|
+
| `[[KB: index-chat]]` | maintenance | `runKbTools()` | `indexChat(orgId)` → re-embeds conversations |
|
|
167
|
+
| `[[KB: health]]` | maintenance | `runKbTools()` | `llamaServerStatus()` → embed server up/down |
|
|
168
|
+
|
|
169
|
+
All three are **best-effort**: an unknown verb, a failed query or a too-short fact is silently skipped.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## 7. Tables 🪐
|
|
174
|
+
|
|
175
|
+
### `rag_chunk` — the physical store (RAG + KB share it)
|
|
176
|
+
|
|
177
|
+
| column | type | notes |
|
|
178
|
+
|---|---|---|
|
|
179
|
+
| `id` | text PK | |
|
|
180
|
+
| `workspace_id` | text → `workspace` | cascade delete |
|
|
181
|
+
| `path` | text | source path (`DOCS/…`, `chat/<channel>`, `kb/<type>/<id>`) |
|
|
182
|
+
| `chunk` | text | the chunk text |
|
|
183
|
+
| `vector` | text (JSON float[]) | `null` when not embedded (keyword fallback) |
|
|
184
|
+
| `kb_entry_id` | text | set when the chunk came from a `kb_entry` |
|
|
185
|
+
| `obsolete` | int(bool) | `1` → dropped by state-aware retrieval |
|
|
186
|
+
| `updated_at` | timestamp | |
|
|
187
|
+
|
|
188
|
+
### `kb_entry` — the curated knowledge unit
|
|
189
|
+
|
|
190
|
+
| column | type | notes |
|
|
191
|
+
|---|---|---|
|
|
192
|
+
| `id` | text PK | |
|
|
193
|
+
| `workspace_id` | text → `workspace` | cascade delete |
|
|
194
|
+
| `type` | text | one of `KbType` (default `note`) |
|
|
195
|
+
| `title` | text | ≤ 200 chars |
|
|
196
|
+
| `summary` | text | technical summary (Vannevar curates), ≤ 1200 chars |
|
|
197
|
+
| `body` | text | ≤ 8000 chars |
|
|
198
|
+
| `status` | text | `active \| superseded \| obsolete \| archived` |
|
|
199
|
+
| `goal_id` / `spec_id` / `issue_id` / `task_id` | text | nullable work refs |
|
|
200
|
+
| `module` | text | ≤ 120 chars |
|
|
201
|
+
| `paths` | JSON string[] | files this knowledge concerns (≤ 40) |
|
|
202
|
+
| `agent_handle` | text | who produced it |
|
|
203
|
+
| `source_kind` | text | `task \| goal \| review \| test \| decision \| spec \| issue \| note \| chat` |
|
|
204
|
+
| `source_ref` | text | origin id/key (jump-back); dedup slot key with `type`+`source_kind` |
|
|
205
|
+
| `supersedes_id` | text | the entry this one replaces |
|
|
206
|
+
| `hash` | text | SHA-256 content hash → dedup / update-in-place |
|
|
207
|
+
| `confidence` | int | 0..100 (default 70) |
|
|
208
|
+
| `created_at` / `updated_at` | timestamp | |
|
|
209
|
+
|
|
210
|
+
### `kb_query_log` — every consultation
|
|
211
|
+
|
|
212
|
+
| column | type | notes |
|
|
213
|
+
|---|---|---|
|
|
214
|
+
| `id` | text PK | |
|
|
215
|
+
| `workspace_id` | text → `workspace` | |
|
|
216
|
+
| `agent_handle` | text | who asked (`operator` for `/kb`) |
|
|
217
|
+
| `query` | text | ≤ 500 chars |
|
|
218
|
+
| `hits` | int | number of source paths returned |
|
|
219
|
+
| `mode` | text | `semantic \| heuristic \| none` |
|
|
220
|
+
| `refs` | JSON string[] | `kind:ref` jump-backs |
|
|
221
|
+
| `answered_at` | timestamp | indexed for the recent-recall view |
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## 8. Embedding & retrieval diagram 🛰️
|
|
226
|
+
|
|
227
|
+
```mermaid
|
|
228
|
+
flowchart LR
|
|
229
|
+
T["text chunk / query"] --> O{"Ollama up?\n(OLLAMA_URL :11434)"}
|
|
230
|
+
O -- "yes" --> OE["nomic prefix → /api/embeddings"]
|
|
231
|
+
O -- "no" --> L{"llama.cpp embed up?\n(CONSTELLA_EMBED_URL :8083)"}
|
|
232
|
+
L -- "yes" --> LE["nomic prefix → /v1/embeddings"]
|
|
233
|
+
L -- "no" --> NULL["return null"]
|
|
234
|
+
OE --> VEC["float[] vector"]
|
|
235
|
+
LE --> VEC
|
|
236
|
+
NULL --> KW["keyword heuristic (term overlap)"]
|
|
237
|
+
VEC --> COS["cosine() similarity"]
|
|
238
|
+
COS --> TOPK["top-k chunks"]
|
|
239
|
+
KW --> TOPK
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## 9. Step-by-step 🌠
|
|
245
|
+
|
|
246
|
+
### Capture a learning (deterministic)
|
|
247
|
+
1. A doc is written **or** an agent emits `[[REMEMBER type=decision: We chose SQLite WAL for the index]]`.
|
|
248
|
+
2. `extractRemembered` turns the token into a `KbItem`.
|
|
249
|
+
3. `ingestKnowledge` runs `scrubSecrets` (refuses secret-shaped content), hashes the content, and either touches a duplicate, updates the same slot, or inserts a new `kb_entry`.
|
|
250
|
+
4. `embedEntry` drops the old chunks for that path and re-embeds `# <title>\n<summary|body>` (≤ 6000 chars) into `rag_chunk` (path `kb/<type>/<id>`).
|
|
251
|
+
5. `scheduleKbCuration` arms a debounced curation pass.
|
|
252
|
+
|
|
253
|
+
### Consult before acting
|
|
254
|
+
1. An agent emits `[[CONSULT: how do we store secrets?]]`.
|
|
255
|
+
2. `answerConsults` calls `kbQuery(orgId, q, { k: 6 })`.
|
|
256
|
+
3. `kbQuery` selects active (`obsolete=0`) chunks, ranks by cosine (semantic) or term overlap (heuristic), builds internal refs, logs to `kb_query_log`.
|
|
257
|
+
4. The answer (context + sources + an explicit insufficiency flag) is posted back so it's in the agent's next-turn context.
|
|
258
|
+
|
|
259
|
+
### Curate (Vannevar)
|
|
260
|
+
1. After enough ingests (≥ 4 entries), the debounced (4 min) + cooldown'd (30 min) trigger fires `runKbCuration`.
|
|
261
|
+
2. Vannevar reviews ~60 recent active/superseded entries, returns JSON: `merges`, `obsolete`, `summaries`, `gaps`.
|
|
262
|
+
3. Merges → drops marked `superseded` (+ `supersedesId`); obsolete → `obsolete`; summaries rewritten + re-embedded; their chunks flagged `obsolete=1`.
|
|
263
|
+
4. A `Reports/kb-health.md` report is written (RAG-indexed) and the operator is notified.
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## 10. Examples 🪐
|
|
268
|
+
|
|
269
|
+
**Ask the KB from chat or `/kb`:**
|
|
270
|
+
|
|
271
|
+
```text
|
|
272
|
+
/kb how do we authenticate the worker process?
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
`kbAnswer` routes meta/status questions ("how is the KB?", "coverage", "gaps") to a deterministic **overview card**; content questions retrieve then get a short Vannevar-written answer with a tidy Sources line — it never dumps raw chunks.
|
|
276
|
+
|
|
277
|
+
**Self-capture + consult in one agent run:**
|
|
278
|
+
|
|
279
|
+
```text
|
|
280
|
+
[[CONSULT: what DB does this project use?]]
|
|
281
|
+
… work …
|
|
282
|
+
[[REMEMBER type=stack: Project uses Drizzle ORM over better-sqlite3]]
|
|
283
|
+
[[KB: reindex]]
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
**Cancel a goal → its knowledge retires automatically** (`markKbObsoleteForGoal`): the goal's `kb_entry` rows flip to `obsolete` and their `rag_chunk`s to `obsolete=1`, so retrieval stops surfacing them.
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## 11. Possible states 🕳️
|
|
291
|
+
|
|
292
|
+
**`kb_entry.status`**
|
|
293
|
+
|
|
294
|
+
| state | meaning |
|
|
295
|
+
|---|---|
|
|
296
|
+
| `active` | current, retrievable |
|
|
297
|
+
| `superseded` | merged into a canonical entry (`supersedesId` set); not retrieved |
|
|
298
|
+
| `obsolete` | contradicted / retired (also: goal cancelled/archived); not retrieved |
|
|
299
|
+
| `archived` | parked (counted separately in the lifecycle view) |
|
|
300
|
+
|
|
301
|
+
**`kbQuery` / `retrieve` mode**
|
|
302
|
+
|
|
303
|
+
| mode | meaning |
|
|
304
|
+
|---|---|
|
|
305
|
+
| `semantic` | cosine over real vectors (embed backend up) |
|
|
306
|
+
| `heuristic` | keyword term-overlap fallback (no embeddings) |
|
|
307
|
+
| `none` | index empty / nothing matched |
|
|
308
|
+
|
|
309
|
+
**`KbReply.mode`** (from `kbAnswer`): `overview` (the structured KB card), `answer` (model-written), `none` (insufficient knowledge).
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## 12. Related integrations 🛰️
|
|
314
|
+
|
|
315
|
+
- **Sync engine** — the watcher calls `scheduleRagReindex` / `indexRagFile` / `deindexRagFile` (debounced 2.5 s) so RAG tracks file changes; disk is truth. See [ARCHITECTURE.md](./ARCHITECTURE.md).
|
|
316
|
+
- **Chat** — every posted message arms `scheduleChatReindex` (debounced 6 s) → `indexChat`. See [TEAM_ROOM.md](./TEAM_ROOM.md), [DM.md](./DM.md), [TELEGRAM.md](./TELEGRAM.md).
|
|
317
|
+
- **Local models** — `ensureEmbedServer` (:8083) + `ensureLlamaServer` (:8082); GPU offload when it fits. See [MODELS.md](./MODELS.md).
|
|
318
|
+
- **Skills (P3)** — `proposeSkillsFromLearnings` distills strong recurring knowledge into **provisional** skills for operator approval. See [SKILLS.md](./SKILLS.md).
|
|
319
|
+
- **Synced blocks** — canonical named knowledge (`mission`, `official-stack`, `business-rules`) the overview card nudges you to create. See [SYNCED_BLOCKS.md](./SYNCED_BLOCKS.md).
|
|
320
|
+
- **Commands** — `/kb` (`/ask-kb`), `/reindex`, `/curate`, `/search`, `/graph`. See [CHAT_COMMANDS.md](./CHAT_COMMANDS.md).
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
## 13. Security 🕳️
|
|
325
|
+
|
|
326
|
+
- **Secret gate on ingest** — `scrubSecrets(blob) !== blob` ⇒ the item is refused and a `console.warn` is logged. No API key, token, PEM, bearer or credentialed DB URL ever lands in the KB.
|
|
327
|
+
- **Org isolation** — every query/index is scoped by `workspace_id` (resolved from `orgId`); only the active org's chunks are ever read or returned.
|
|
328
|
+
- **Internal plumbing hidden** — `.claude/kb/` and `.claude/skills/` are excluded from indexing so a question can't surface Constella's own prompts/skills.
|
|
329
|
+
- **Budget-gated LLM** — curation and skill-proposal runs check the agent's `dailyCapUsd` (`overCap`) before spending, and cost is booked to `cost_entry`.
|
|
330
|
+
- **Opt-outs** — `CONSTELLA_KB_CURATION=0` disables the automatic curation pass entirely.
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## 14. Troubleshooting 🚀
|
|
335
|
+
|
|
336
|
+
| Symptom | Likely cause | Fix |
|
|
337
|
+
|---|---|---|
|
|
338
|
+
| Retrieval is `heuristic`, never `semantic` | No embed backend up | Start Ollama with `nomic-embed-text`, or download a nomic GGUF so `ensureEmbedServer` brings up :8083. Check with `[[KB: health]]`. |
|
|
339
|
+
| `/kb` says "not enough in the Knowledge Base" | Empty/cold index | Run `/reindex` (or `[[KB: reindex]]`); knowledge also fills in as agents complete work. |
|
|
340
|
+
| New docs not retrieved | File outside `RAG_DIRS`, or watcher not running | Put docs under `.claude/DOCS/PO/Reports/specs/issues`; ensure the worker process is up. |
|
|
341
|
+
| Old/cancelled knowledge still surfacing | Chunks not flagged | Cancelling/archiving a goal calls `markKbObsoleteForGoal`; a manual `/curate` also retires contradicted entries. |
|
|
342
|
+
| Curation never runs | Cooldown / cap / opt-out | Needs ≥ 4 entries, respects 30-min cooldown + the agent's daily cap; check `CONSTELLA_KB_CURATION`. |
|
|
343
|
+
| Embeddings look wrong (poor matches) | Mismatched nomic prefixes or a non-nomic model | Keep `CONSTELLA_EMBED_MODEL` nomic, or ensure both index+query use the same model/prefix scheme. |
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## 15. Related links 🌌
|
|
348
|
+
|
|
349
|
+
- [KB_AGENT.md](./KB_AGENT.md) — Vannevar, the Knowledge agent
|
|
350
|
+
- [MEMORY_RAG.md](./MEMORY_RAG.md) — how memory feeds back into context
|
|
351
|
+
- [SYNCED_BLOCKS.md](./SYNCED_BLOCKS.md) — canonical knowledge blocks
|
|
352
|
+
- [SKILLS.md](./SKILLS.md) — learning → skills (P3)
|
|
353
|
+
- [MODELS.md](./MODELS.md) — local embed (:8083) & chat (:8082) servers
|
|
354
|
+
- [CHAT_COMMANDS.md](./CHAT_COMMANDS.md) — `/kb`, `/reindex`, `/curate`, `/graph`
|
|
355
|
+
- [ARCHITECTURE.md](./ARCHITECTURE.md) · [AI_ARCHITECTURE.md](./AI_ARCHITECTURE.md) — where KB/RAG sits in the ship
|
|
356
|
+
- [SECURITY.md](./SECURITY.md) — scrub, isolation, vault
|
package/docs/en/MCP.md
ADDED
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
[← Docs index](./README.md) · [🇧🇷 Português](../pt/MCP.md) · [✦ Constella](../../README.md)
|
|
2
|
+
|
|
3
|
+
# 🛰️ MCP Server — Driving the Central Ship from Orbit
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
A self-contained **Model Context Protocol** server (`scripts/mcp-server.mjs`) that exposes Constella's public REST API as MCP tools, so an external AI host — Claude Desktop, Cursor, or any MCP client — can pilot your Constella control plane through natural language.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
|
|
13
|
+
Reach for the MCP server when you want an **outside AI** to observe and steer Constella without opening the web UI:
|
|
14
|
+
|
|
15
|
+
- Ask Claude Desktop "what's the status of my agent-company?" and have it call `constella_status`.
|
|
16
|
+
- Approve a pending plan, flip 24/7 execution, or start new work from inside Cursor's chat.
|
|
17
|
+
- Wire Constella into any agentic host that speaks MCP, using a scoped Personal Access Token as the only credential.
|
|
18
|
+
|
|
19
|
+
This is the **outbound-to-Constella** direction: an AI host *drives* Constella. It is the mirror image of Constella's own constellation of agents *consuming* external MCP servers — see [Two MCP directions](#-two-mcp-directions-dont-confuse-them) below.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## How it works 🌌
|
|
24
|
+
|
|
25
|
+
The MCP server is a thin, dependency-free bridge. It speaks **JSON-RPC over stdio** to the MCP host, and each tool call is translated into a single HTTPS-style request against the Public REST API v1 (`/api/v1/...`), authenticated with a Personal Access Token (PAT).
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
MCP host (Claude Desktop / Cursor)
|
|
29
|
+
│ JSON-RPC over stdio
|
|
30
|
+
▼
|
|
31
|
+
scripts/mcp-server.mjs ──Bearer cn_…──► /api/v1/[[...path]] ──► Constella cores
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Key properties straight from the source:
|
|
35
|
+
|
|
36
|
+
- **Zero dependencies.** `scripts/mcp-server.mjs` imports only `node:readline` and uses the global `fetch` (Node 18+). It ships in the compiled distribution unchanged.
|
|
37
|
+
- **Hand-rolled MCP.** It implements the JSON-RPC methods `initialize`, `notifications/initialized`, `ping`, `tools/list` and `tools/call` directly — no SDK.
|
|
38
|
+
- **Thin mapping.** Every tool's `build(args)` returns `{ method, path, body? }`, which `callApi` sends to `${BASE}/api/v1${path}` with `Authorization: Bearer ${PAT}` (and `x-constella-org` when `CONSTELLA_ORG` is set).
|
|
39
|
+
- **One credential.** The REST layer (`authenticatePAT` in `src/server/api/pat-auth.ts`) is PAT-only; there is no session. Scope (`read` / `write`) is enforced server-side.
|
|
40
|
+
- **Request timeout.** Each REST call uses `AbortSignal.timeout(30_000)` — a 30-second ceiling per tool call.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Main flow 🚀
|
|
45
|
+
|
|
46
|
+
```mermaid
|
|
47
|
+
sequenceDiagram
|
|
48
|
+
participant Host as MCP host (Claude Desktop)
|
|
49
|
+
participant MCP as mcp-server.mjs
|
|
50
|
+
participant API as /api/v1 dispatcher
|
|
51
|
+
participant Core as plan-ops / work-ops / kb
|
|
52
|
+
|
|
53
|
+
Host->>MCP: initialize (stdio)
|
|
54
|
+
MCP-->>Host: serverInfo {name: constella}
|
|
55
|
+
Host->>MCP: tools/list
|
|
56
|
+
MCP-->>Host: 13 constella_* tools
|
|
57
|
+
Host->>MCP: tools/call constella_status
|
|
58
|
+
MCP->>API: GET /api/v1/status (Bearer cn_…)
|
|
59
|
+
API->>API: authenticatePAT + rate-limit
|
|
60
|
+
API->>Core: apiStatus(workspace)
|
|
61
|
+
Core-->>API: counts
|
|
62
|
+
API-->>MCP: {ok:true, data:{…}}
|
|
63
|
+
MCP-->>Host: content[text] (pretty JSON)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The lifecycle, step by step:
|
|
67
|
+
|
|
68
|
+
1. **Handshake.** The host sends `initialize`; the server replies with `protocolVersion` (echoing the host's, default `2024-11-05`), `capabilities: { tools: {} }`, and `serverInfo: { name: "constella", version: "1.0.0" }`.
|
|
69
|
+
2. **Discovery.** On `tools/list`, the server returns all tools (`name`, `description`, `inputSchema`).
|
|
70
|
+
3. **Invocation.** On `tools/call`, it looks up the tool by name, calls `build(arguments)`, fires the REST request via `callApi`, and wraps the JSON response as `{ content: [{ type: "text", text }], isError: data?.ok === false }`.
|
|
71
|
+
4. **Auth & scope.** The REST dispatcher authenticates the PAT, applies a sliding-window rate limit (120 req/min/token), and rejects write routes when the token has `read` scope.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Key concepts ✦
|
|
76
|
+
|
|
77
|
+
| Concept | Where | Meaning |
|
|
78
|
+
|---|---|---|
|
|
79
|
+
| **Outbound MCP** | `scripts/mcp-server.mjs` | An external AI host drives Constella through PAT-authenticated REST. |
|
|
80
|
+
| **PAT** | `personalAccessToken` table | `cn_…` token, SHA-256 hashed, scope `read` or `write`, plaintext shown once. |
|
|
81
|
+
| **Scope gate** | `route.ts` `needWrite()` | `write` tokens may mutate; `read` tokens get `403` on POST mutations. |
|
|
82
|
+
| **Org selection** | `CONSTELLA_ORG` → `x-constella-org` | Picks which org a multi-org user acts on (membership-validated). |
|
|
83
|
+
| **Rate limit** | `route.ts` `rateLimited()` | In-memory sliding 60s window, max 120 requests per token. |
|
|
84
|
+
| **Envelope** | `route.ts` `ok()` / `fail()` | Every response is `{ ok: true, data }` or `{ ok: false, error }`. |
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Environment variables 🪐
|
|
89
|
+
|
|
90
|
+
The MCP server is configured purely through env vars passed by the host:
|
|
91
|
+
|
|
92
|
+
| Variable | Default | Required | Purpose |
|
|
93
|
+
|---|---|---|---|
|
|
94
|
+
| `CONSTELLA_PAT` | — | **Yes** | The `cn_…` Personal Access Token. Use a **write** token to allow approve/execution/new-work; a **read** token for read-only. If unset, every tool returns `{ ok: false, error: "CONSTELLA_PAT is not set" }`. |
|
|
95
|
+
| `CONSTELLA_BASE_URL` | `http://localhost:3000` | No | Base URL of the running Constella server. Trailing slashes are stripped. |
|
|
96
|
+
| `CONSTELLA_ORG` | — | No | An `orgId` for multi-org users; sent as the `X-Constella-Org` header. |
|
|
97
|
+
|
|
98
|
+
> 🕳️ The token is **never logged** by either side. `pat-auth.ts` validates the bearer against the stored `tokenHash` and resolves the org/workspace through a membership join, so a token can't be pointed at a foreign tenant.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Tool catalog — every `constella_*` mapped to its REST route 🌠
|
|
103
|
+
|
|
104
|
+
All 13 tools are defined in the `TOOLS` array of `scripts/mcp-server.mjs`. Each maps 1:1 onto a v1 route.
|
|
105
|
+
|
|
106
|
+
| MCP tool | Scope | REST | Inputs | What it does |
|
|
107
|
+
|---|---|---|---|---|
|
|
108
|
+
| `constella_status` | read | `GET /status` | — | Counts of goals, issues, tasks and the plan state. |
|
|
109
|
+
| `constella_review` | read | `GET /review` | — | Readable text summary of plan, issues, tasks and next steps. |
|
|
110
|
+
| `constella_goals` | read | `GET /goals` | — | List goals. |
|
|
111
|
+
| `constella_issues` | read | `GET /issues` | — | List issues. |
|
|
112
|
+
| `constella_tasks` | read | `GET /tasks` | — | List tasks. |
|
|
113
|
+
| `constella_specs` | read | `GET /specs` | — | List specs. |
|
|
114
|
+
| `constella_kb` | read | `POST /kb` | `q` (required) | Ask the Knowledge Base a question. |
|
|
115
|
+
| `constella_approve_plan` | **write** | `POST /plan/approve` | — | Approve the pending plan and queue tasks. |
|
|
116
|
+
| `constella_reject_plan` | **write** | `POST /plan/reject` | `reason` (optional) | Send the plan back to the CEO for revision. |
|
|
117
|
+
| `constella_set_execution` | **write** | `POST /execution` | `on` (required, bool) | Turn 24/7 autonomous execution on or off. |
|
|
118
|
+
| `constella_new_work` | **write** | `POST /work` | `brief` (required), `title` (optional) | Start a new unit of work — the CEO drafts specs/issues for approval. |
|
|
119
|
+
| `constella_cancel_goal` | **write** | `POST /goals/{id}/cancel` | `id` (required) | Cancel a goal by id. |
|
|
120
|
+
| `constella_archive_goal` | **write** | `POST /goals/{id}/archive` | `id` (required) | Archive a goal by id. |
|
|
121
|
+
|
|
122
|
+
### Server-side handlers
|
|
123
|
+
|
|
124
|
+
Each route lands in the `dispatch()` switch of `src/app/api/v1/[[...path]]/route.ts`, which reuses the same session-less cores the Telegram remote control uses:
|
|
125
|
+
|
|
126
|
+
| REST route | Handler |
|
|
127
|
+
|---|---|
|
|
128
|
+
| `GET /status` | `apiStatus(ws)` |
|
|
129
|
+
| `GET /review` | `reviewSummaryFor(ws)` |
|
|
130
|
+
| `GET /goals` `/issues` `/tasks` `/specs` | `apiGoals` / `apiIssues` / `apiTasks` / `apiSpecs` |
|
|
131
|
+
| `POST /kb`, `GET /kb?q=` | `kbAnswer(org.id, q)` |
|
|
132
|
+
| `POST /plan/approve` | `approvePlanFor(org.id, ws)` |
|
|
133
|
+
| `POST /plan/reject` | `requestPlanChangesFor(ws.id, reason)` |
|
|
134
|
+
| `POST /execution` | `setAuto247For(ws.id, on)` |
|
|
135
|
+
| `POST /work` | `startNewWorkFor(org.id, ws, { brief, title })` |
|
|
136
|
+
| `POST /goals/{id}/cancel` | `cancelGoalFor(ws.id, id)` |
|
|
137
|
+
| `POST /goals/{id}/archive` | `archiveGoalFor(org.id, ws.id, id)` |
|
|
138
|
+
|
|
139
|
+
> Note: the host-side tool list does **not** include a `me` tool, but the REST API does expose `GET /api/v1` (or `/me`) returning the token's user, org, workspace and scope. Hosts can reach it through the [Public API](./PUBLIC_API.md) directly.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Step-by-step: configuring an MCP host
|
|
144
|
+
|
|
145
|
+
### 1. Mint a Personal Access Token
|
|
146
|
+
|
|
147
|
+
In the Constella web UI: **Profile → Personal access tokens → New token**. Choose a scope:
|
|
148
|
+
|
|
149
|
+
- **read** — for status/review/list/KB tools only.
|
|
150
|
+
- **write** — to also allow approve, reject, execution, new-work, cancel and archive.
|
|
151
|
+
|
|
152
|
+
The plaintext `cn_…` value is shown **once** (`createPAT` returns it; only the SHA-256 hash is persisted). Copy it immediately.
|
|
153
|
+
|
|
154
|
+
### 2. Make sure Constella is running
|
|
155
|
+
|
|
156
|
+
The MCP server talks to a live server at `CONSTELLA_BASE_URL` (default `http://localhost:3000`). Start Constella normally (`constella` / `npm start`).
|
|
157
|
+
|
|
158
|
+
### 3. Register the server in your host
|
|
159
|
+
|
|
160
|
+
**Claude Desktop** — edit `claude_desktop_config.json`:
|
|
161
|
+
|
|
162
|
+
```json
|
|
163
|
+
{
|
|
164
|
+
"mcpServers": {
|
|
165
|
+
"constella": {
|
|
166
|
+
"command": "node",
|
|
167
|
+
"args": ["C:/Users/Usuario/Documents/constella/scripts/mcp-server.mjs"],
|
|
168
|
+
"env": {
|
|
169
|
+
"CONSTELLA_PAT": "cn_your_write_token_here",
|
|
170
|
+
"CONSTELLA_BASE_URL": "http://localhost:3000"
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**Cursor** — add the same block under `mcpServers` in Cursor's MCP settings (`.cursor/mcp.json` or the global MCP config). For a multi-org user, add `"CONSTELLA_ORG": "<orgId>"` to `env`.
|
|
178
|
+
|
|
179
|
+
### 4. Use it
|
|
180
|
+
|
|
181
|
+
Restart the host, open a chat, and ask in plain language — the host will discover the 13 `constella_*` tools via `tools/list` and call them as needed:
|
|
182
|
+
|
|
183
|
+
> "Use Constella to show me the current status, then approve the pending plan."
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Examples 🌌
|
|
188
|
+
|
|
189
|
+
### Smoke-test the server by hand
|
|
190
|
+
|
|
191
|
+
You can drive the stdio protocol directly to confirm it's wired up:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
CONSTELLA_PAT=cn_xxx CONSTELLA_BASE_URL=http://localhost:3000 \
|
|
195
|
+
node scripts/mcp-server.mjs <<'EOF'
|
|
196
|
+
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05"}}
|
|
197
|
+
{"jsonrpc":"2.0","id":2,"method":"tools/list"}
|
|
198
|
+
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"constella_status","arguments":{}}}
|
|
199
|
+
EOF
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Each line is newline-delimited JSON-RPC; the server replies one JSON object per line.
|
|
203
|
+
|
|
204
|
+
### A `tools/call` request and response
|
|
205
|
+
|
|
206
|
+
Request from the host:
|
|
207
|
+
|
|
208
|
+
```json
|
|
209
|
+
{"jsonrpc":"2.0","id":7,"method":"tools/call",
|
|
210
|
+
"params":{"name":"constella_new_work",
|
|
211
|
+
"arguments":{"brief":"Add a dark-mode toggle to settings","title":"Dark mode"}}}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Server reply (the REST envelope is pretty-printed into a text content block):
|
|
215
|
+
|
|
216
|
+
```json
|
|
217
|
+
{"jsonrpc":"2.0","id":7,"result":{
|
|
218
|
+
"content":[{"type":"text","text":"{\n \"ok\": true,\n \"data\": { ... }\n}"}],
|
|
219
|
+
"isError":false}}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
If the PAT had `read` scope, the REST layer returns `403` and the content's `ok` is `false`, so `isError` becomes `true`.
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Possible states 🕳️
|
|
227
|
+
|
|
228
|
+
| Situation | Where it surfaces | Result |
|
|
229
|
+
|---|---|---|
|
|
230
|
+
| `CONSTELLA_PAT` unset | `callApi` | `{ ok: false, error: "CONSTELLA_PAT is not set" }` (no network call). |
|
|
231
|
+
| Malformed / missing bearer | `authenticatePAT` | HTTP `401` `"missing or malformed bearer token"`. |
|
|
232
|
+
| Unknown token hash | `authenticatePAT` | HTTP `401` `"invalid token"`. |
|
|
233
|
+
| No org / archived org | `authenticatePAT` | HTTP `404` / `409`. |
|
|
234
|
+
| Read token hits a write route | `needWrite()` | HTTP `403` `"this token has read scope; a write-scope token is required"`. |
|
|
235
|
+
| Over 120 req/min | `rateLimited()` | HTTP `429` `"rate limit exceeded (120 req/min)"`. |
|
|
236
|
+
| Unknown tool name | `tools/call` | JSON-RPC error `-32602` `unknown tool: …`. |
|
|
237
|
+
| Unknown JSON-RPC method | `handle()` | JSON-RPC error `-32601` `method not found: …`. |
|
|
238
|
+
| Handler throws | `rl.on("line")` | JSON-RPC error `-32603` (internal). |
|
|
239
|
+
| Non-JSON stdin line | `rl.on("line")` | Silently ignored. |
|
|
240
|
+
| REST returns non-JSON | `callApi` | `{ ok: false, error: "non-JSON response (http <status>)" }`. |
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## 🪐 Two MCP directions — don't confuse them
|
|
245
|
+
|
|
246
|
+
Constella touches MCP in **two opposite directions**:
|
|
247
|
+
|
|
248
|
+
| Direction | Who drives whom | Mechanism |
|
|
249
|
+
|---|---|---|
|
|
250
|
+
| **Outbound (this doc)** | An external AI host drives **Constella** | `scripts/mcp-server.mjs` → Public REST API v1, PAT-authenticated. |
|
|
251
|
+
| **Inbound (agents consume external MCPs)** | **Constella's agents** drive external MCP servers | Configured through the `claude` CLI's `~/.claude` config; **not** through Constella's `plugin` table. |
|
|
252
|
+
|
|
253
|
+
```mermaid
|
|
254
|
+
flowchart LR
|
|
255
|
+
subgraph Outbound
|
|
256
|
+
H["Claude Desktop / Cursor"] -->|stdio JSON-RPC| M["mcp-server.mjs"]
|
|
257
|
+
M -->|"Bearer cn_…"| R["/api/v1"]
|
|
258
|
+
R --> C["Constella cores"]
|
|
259
|
+
end
|
|
260
|
+
subgraph Inbound
|
|
261
|
+
A["Constella agent (claude CLI)"] -->|"~/.claude MCP config"| X["External MCP server"]
|
|
262
|
+
end
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
The inbound direction is operator-level configuration of the `claude` CLI and is unrelated to Constella's [Plugins](./PLUGINS.md) registry. See [Agents](./AGENTS.md) and [AI Architecture](./AI_ARCHITECTURE.md) for how agents run.
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Related integrations
|
|
270
|
+
|
|
271
|
+
- **[Public API](./PUBLIC_API.md)** — the REST v1 surface the MCP server wraps; same PATs and scopes.
|
|
272
|
+
- **[Telegram](./TELEGRAM.md)** — another remote-control surface reusing the same session-less cores (`plan-ops.ts` / `work-ops.ts`).
|
|
273
|
+
- **[Plugins](./PLUGINS.md)** — Constella's native plugin registry (GitHub, Telegram, Vault, Web Search); distinct from external MCP consumption.
|
|
274
|
+
- **[KB & RAG](./KB_RAG.md)** — what `constella_kb` queries under the hood.
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Security 🔒
|
|
279
|
+
|
|
280
|
+
- **PAT-only, hashed at rest.** Only the SHA-256 `tokenHash` is stored (`personalAccessToken` table). The plaintext `cn_…` appears once at creation and is never logged on either side.
|
|
281
|
+
- **Membership-secure org resolution.** `getActiveOrg(userId, orgHeader)` validates the requested org through a membership join — a token cannot be aimed at another tenant.
|
|
282
|
+
- **Scope enforcement.** Mutations require `write`; the `read` scope is locked to GET-style tools plus KB queries.
|
|
283
|
+
- **Rate limiting.** 120 requests/min/token (sliding 60s window), resetting on server restart.
|
|
284
|
+
- **Loopback by default.** With `CONSTELLA_BASE_URL` defaulting to `http://localhost:3000`, the MCP server reaches Constella on the loopback interface unless you deliberately point it elsewhere.
|
|
285
|
+
- **Bounded calls.** Each REST request is capped at 30 seconds (`AbortSignal.timeout(30_000)`).
|
|
286
|
+
- **Least privilege.** Prefer a **read** token for monitoring hosts; reserve **write** tokens for hosts you truly trust to approve plans and start work.
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Troubleshooting 🛠️
|
|
291
|
+
|
|
292
|
+
| Symptom | Likely cause | Fix |
|
|
293
|
+
|---|---|---|
|
|
294
|
+
| Every tool returns `"CONSTELLA_PAT is not set"` | Env var missing in the host's `env` block | Add `CONSTELLA_PAT` to the MCP server entry and restart the host. |
|
|
295
|
+
| `401 invalid token` | Token revoked, mistyped, or from another instance | Mint a fresh PAT; confirm `CONSTELLA_BASE_URL` points at the same instance. |
|
|
296
|
+
| `403 … write-scope token is required` | Using a read token for approve/execution/new-work | Create a **write**-scope token. |
|
|
297
|
+
| `429 rate limit exceeded` | More than 120 calls/min on one token | Slow down or use a second token. |
|
|
298
|
+
| Connection refused / non-JSON response | Constella not running or wrong base URL | Start Constella; verify `CONSTELLA_BASE_URL`. |
|
|
299
|
+
| Host shows no Constella tools | Server failed to launch | Check the host's MCP logs; verify the `node` command and absolute path to `scripts/mcp-server.mjs`. |
|
|
300
|
+
| `409 organization is archived` | The token's org was archived | Use a token whose org is active, or set a valid `CONSTELLA_ORG`. |
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## Related links
|
|
305
|
+
|
|
306
|
+
- [Public API](./PUBLIC_API.md)
|
|
307
|
+
- [Telegram](./TELEGRAM.md)
|
|
308
|
+
- [Plugins](./PLUGINS.md)
|
|
309
|
+
- [Agents](./AGENTS.md)
|
|
310
|
+
- [AI Architecture](./AI_ARCHITECTURE.md)
|
|
311
|
+
- [KB & RAG](./KB_RAG.md)
|
|
312
|
+
- [Security](./SECURITY.md)
|
|
313
|
+
- [Architecture](./ARCHITECTURE.md)
|