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,331 @@
|
|
|
1
|
+
[← Docs index](./README.md) · [🇧🇷 Português](../pt/DEPLOY.md) · [✦ Constella](../../README.md)
|
|
2
|
+
|
|
3
|
+
# Deploy (Production) 🚀
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
How to **launch the central ship itself** — getting the Constella control plane running in a durable, production-grade orbit. This page covers deploying *Constella the platform*: Docker on a VPS, the `vps-install.sh` bootstrap, Tailscale, supervised dual-process boot, and portable/global installs.
|
|
8
|
+
|
|
9
|
+
> **Not to be confused with [PREPARE_DEPLOY](./PREPARE_DEPLOY.md) / [DEPLOY of your project].** Those deploy the **user project** the agents build (a clean-tree export to a separate repo). *This* page deploys **Constella itself** — the ship, not the cargo.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## When to use 🌌
|
|
14
|
+
|
|
15
|
+
| You want to… | Use |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| Run Constella 24/7 on a remote server, private to your tailnet | **VPS / Docker** (`Dockerfile` + `docker-compose.yml`) |
|
|
18
|
+
| Bootstrap a fresh Ubuntu VPS in one command | **`scripts/vps-install.sh`** |
|
|
19
|
+
| Carry the whole control plane on a USB drive | **Portable** (`constella --portable`) |
|
|
20
|
+
| Install once on your own always-on machine | **Global npm** (`npm i -g constella`) |
|
|
21
|
+
| A quick ephemeral run | **`npx constella`** |
|
|
22
|
+
|
|
23
|
+
If you only want a local instance on your own laptop, see [START_MODE](./START_MODE.md) and [AUTH_MODE](./AUTH_MODE.md). For the tailnet specifics, see [VPS_MODE](./VPS_MODE.md); for the drive, [PORTABLE_MODE](./PORTABLE_MODE.md).
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## How it works 🪐
|
|
28
|
+
|
|
29
|
+
Every Constella launch — local, VPS, portable — goes through the same launcher, **`bin/constella.mjs`**. The launcher:
|
|
30
|
+
|
|
31
|
+
1. Resolves the **run mode** (`start | auth | vps | portable`) from the launch flag.
|
|
32
|
+
2. Resolves the **runtime root** `HOME` (`CONSTELLA_HOME` / `--path`, default `~/.constella`).
|
|
33
|
+
3. Generates + persists secrets into `<HOME>/.env` (`chmod 600`): `BETTER_AUTH_SECRET`, `CONSTELLA_VAULT_KEY`, `CONSTELLA_WORKER_SECRET`.
|
|
34
|
+
4. Pins `DATABASE_URL=file:<HOME>/constella.db` and applies the shipped Drizzle migrations (`drizzle-kit migrate`).
|
|
35
|
+
5. Boots **two supervised processes**: the **web** server (`next start`) and the **worker** (`bin/worker.mjs`).
|
|
36
|
+
|
|
37
|
+
A deploy is "the same launcher, in a more durable place" — inside a container, on a USB drive, or under a global install. The mode picks the bind host and the auth posture; the deploy target picks the durability.
|
|
38
|
+
|
|
39
|
+
```mermaid
|
|
40
|
+
flowchart TD
|
|
41
|
+
A["operator"] --> B["bin/constella.mjs (launcher)"]
|
|
42
|
+
B --> C{"run mode"}
|
|
43
|
+
C -->|"--vps"| D["Docker + Tailscale<br/>(0.0.0.0, tailnet only)"]
|
|
44
|
+
C -->|"--portable"| E["USB drive root<br/>(0.0.0.0)"]
|
|
45
|
+
C -->|"--start / --auth"| F["local host<br/>(127.0.0.1)"]
|
|
46
|
+
B --> G["next start (web :3000)"]
|
|
47
|
+
B --> H["bin/worker.mjs (cron + watcher + Telegram)"]
|
|
48
|
+
G -. "supervised, auto-restart" .- B
|
|
49
|
+
H -. "supervised, auto-restart" .- B
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Main flow — VPS via Docker + Tailscale 🛰️
|
|
55
|
+
|
|
56
|
+
The production-recommended deploy. Constella runs in a container, binds `0.0.0.0`, and is reachable **only** over your Tailscale tailnet — never the open internet.
|
|
57
|
+
|
|
58
|
+
### The image — `Dockerfile`
|
|
59
|
+
|
|
60
|
+
A multi-stage `node:22-bookworm-slim` build:
|
|
61
|
+
|
|
62
|
+
| Stage | Does |
|
|
63
|
+
| --- | --- |
|
|
64
|
+
| `base` | `corepack enable`; installs `git ca-certificates` |
|
|
65
|
+
| `deps` | `pnpm install --frozen-lockfile` |
|
|
66
|
+
| `build` | `pnpm build` (with `NEXT_TELEMETRY_DISABLED=1`) |
|
|
67
|
+
| `runtime` | sets `NODE_ENV=production`, `CONSTELLA_RUN_MODE=vps`, `CONSTELLA_PUBLIC=1`, `CONSTELLA_HOME=/data`; runs as the unprivileged `node` user; `VOLUME ["/data"]`; `EXPOSE 3000` |
|
|
68
|
+
|
|
69
|
+
Entrypoint:
|
|
70
|
+
|
|
71
|
+
```dockerfile
|
|
72
|
+
CMD ["node", "bin/constella.mjs", "--vps", "--host", "0.0.0.0", "--port", "3000"]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
> **Agent CLIs are NOT bundled in the image.** The Dockerfile note is explicit: for agents on a VPS, either add a `RUN` step that installs a CLI (`claude` / `codex`), or use **cloud API providers** configured in the [MODELS](./MODELS.md) module. See [Security](#security--).
|
|
76
|
+
|
|
77
|
+
### The stack — `docker-compose.yml`
|
|
78
|
+
|
|
79
|
+
Two services share one network namespace, so Constella never gets its own public port:
|
|
80
|
+
|
|
81
|
+
| Service | Image / build | Role |
|
|
82
|
+
| --- | --- | --- |
|
|
83
|
+
| `tailscale` | `tailscale/tailscale:latest` | Sidecar; joins your tailnet headlessly via `TS_AUTHKEY`; `hostname: constella`; persists state in the `tailscale-state` volume |
|
|
84
|
+
| `constella` | `build: .` | The app; `network_mode: service:tailscale` (shares the sidecar's net); persists `/data` in the `constella-data` volume |
|
|
85
|
+
|
|
86
|
+
`network_mode: service:tailscale` is the security pivot: Constella is reachable **at the Tailscale IP on port 3000** and nowhere else. Both services `restart: unless-stopped`.
|
|
87
|
+
|
|
88
|
+
```mermaid
|
|
89
|
+
flowchart LR
|
|
90
|
+
subgraph host["VPS host"]
|
|
91
|
+
subgraph ns["shared net namespace"]
|
|
92
|
+
TS["tailscale sidecar<br/>(joins tailnet)"]
|
|
93
|
+
CN["constella app<br/>:3000, 0.0.0.0"]
|
|
94
|
+
end
|
|
95
|
+
V1[("constella-data<br/>/data volume")]
|
|
96
|
+
V2[("tailscale-state")]
|
|
97
|
+
end
|
|
98
|
+
CN --- V1
|
|
99
|
+
TS --- V2
|
|
100
|
+
Dev["your device<br/>(same tailnet)"] -. "http://<ts-ip>:3000" .-> TS
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### One-command bootstrap — `scripts/vps-install.sh`
|
|
104
|
+
|
|
105
|
+
For a fresh Ubuntu Server. The script (`set -euo pipefail`) does, in order:
|
|
106
|
+
|
|
107
|
+
1. **Docker** — `curl -fsSL https://get.docker.com | sh` (only if `docker` is missing).
|
|
108
|
+
2. **Tailscale** — `curl -fsSL https://tailscale.com/install.sh | sh` (only if missing).
|
|
109
|
+
3. `sudo tailscale up` — joins your tailnet (prints a browser auth URL if needed).
|
|
110
|
+
4. **Auth key** — if `.env` lacks `TS_AUTHKEY=`, it prompts you to paste a `tskey-auth-…` key (created at `https://login.tailscale.com/admin/settings/keys`) and appends it to `.env`.
|
|
111
|
+
5. **Up** — `sudo docker compose up -d --build`.
|
|
112
|
+
6. Prints the reachable URL: `http://<tailscale-ip>:3000`.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Step-by-step
|
|
117
|
+
|
|
118
|
+
### A) VPS deploy from a clone
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
# on the VPS, with the repo cloned
|
|
122
|
+
bash scripts/vps-install.sh
|
|
123
|
+
# → installs Docker + Tailscale, prompts for TS_AUTHKEY, brings the stack up
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Or do it manually (mirrors the compose header):
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# 1. Get a Tailscale auth key:
|
|
130
|
+
# https://login.tailscale.com/admin/settings/keys
|
|
131
|
+
echo "TS_AUTHKEY=tskey-auth-..." > .env
|
|
132
|
+
# 2. Build + start
|
|
133
|
+
docker compose up -d --build
|
|
134
|
+
# 3. Reach Constella at the node's Tailscale IP:
|
|
135
|
+
# http://<this-node's-tailscale-ip>:3000
|
|
136
|
+
tailscale ip -4 # find the IP
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
On first boot the launcher generates and persists `BETTER_AUTH_SECRET` (and the vault + worker secrets) into `/data/.env`. Because `/data` is the `constella-data` named volume, those secrets — and login sessions and the encrypted vault — **survive restarts and rebuilds**.
|
|
140
|
+
|
|
141
|
+
### B) Portable deploy (USB)
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
npx constella --portable # auto-detect & pick a USB drive
|
|
145
|
+
npx constella --portable --path /Volumes/MYUSB # or name the drive
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
The launcher validates the drive **before** booting: it **refuses < 32 GB free** (fatal); `≥ 32 GB` boots. Binds `0.0.0.0`. The whole runtime root lives at `<drive>/.constella`. See [PORTABLE_MODE](./PORTABLE_MODE.md).
|
|
149
|
+
|
|
150
|
+
### C) Global install (own always-on box)
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
npm i -g constella
|
|
154
|
+
constella --auth # email+password, 127.0.0.1
|
|
155
|
+
# or --start for local auto-login, or --vps on a server you manage
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### D) Ephemeral
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
npx constella # default mode = start
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Supervised dual-process boot 🌠
|
|
167
|
+
|
|
168
|
+
A 24/7 control plane must survive a transient crash. `bin/constella.mjs` boots **two children** and supervises each:
|
|
169
|
+
|
|
170
|
+
| Process | Command | Hosts |
|
|
171
|
+
| --- | --- | --- |
|
|
172
|
+
| **web** | `next start -H <host> -p <port>` (from `PKG_ROOT`) | the dashboard + all API routes |
|
|
173
|
+
| **worker** | `node bin/worker.mjs` | cron tick (~60s → `POST /api/cron/tick`), chokidar file-watcher (debounce 400ms → `/api/sync/file`), Telegram long-poll |
|
|
174
|
+
|
|
175
|
+
Supervision rules (from `supervise()`):
|
|
176
|
+
|
|
177
|
+
- On an unexpected child exit, **auto-restart after 2s** — not a full shutdown.
|
|
178
|
+
- **Crash-loop guard:** at most **5 restarts within 60s** per child; beyond that it gives up and shuts down (so a real, repeated crash isn't masked forever).
|
|
179
|
+
- The web and worker are **independent**: a web crash restarts only the web; the worker self-retries its tick until the server answers.
|
|
180
|
+
- Optional heap bump: `CONSTELLA_WEB_HEAP_MB` adds `--max-old-space-size` to the web child (useful when an agent run causes a JS-heap OOM).
|
|
181
|
+
|
|
182
|
+
> There is **no systemd unit shipped in the repo** — *not found in current codebase*. The launcher's own supervisor + Docker's `restart: unless-stopped` are the durability layer. If you want OS-level supervision, wrap `constella --vps` (or `--auth`) in your own unit; the process is a normal long-lived foreground command and handles `SIGINT`/`SIGTERM` cleanly (it kills both children, then exits).
|
|
183
|
+
|
|
184
|
+
The worker carries the privileged `x-worker-secret` header, so it has an **SSRF guard**: it refuses to talk to any non-loopback `CONSTELLA_BASE_URL` unless `CONSTELLA_ALLOW_REMOTE_WORKER_BASE_URL=1`. The launcher always points it at `http://127.0.0.1:<port>` (loopback even in vps/portable), so this is invisible in normal deploys.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Run modes vs deploy targets
|
|
189
|
+
|
|
190
|
+
The **mode** (from `src/lib/run-mode.ts`) sets the bind host and login posture; the **deploy target** sets where it physically runs. They compose:
|
|
191
|
+
|
|
192
|
+
| Mode | `requiresLogin` | Bind host | Typical deploy target | Agent CLI permission |
|
|
193
|
+
| --- | --- | --- | --- | --- |
|
|
194
|
+
| `start` | false (auto-login `operator@constella.dev`) | `127.0.0.1` | local box / npx | `bypassPermissions` (full) |
|
|
195
|
+
| `auth` | true (email+password) | `127.0.0.1` | local always-on / global install | `acceptEdits` (jailed) |
|
|
196
|
+
| `vps` | true | `0.0.0.0` | **Docker + Tailscale** | `acceptEdits` (jailed) |
|
|
197
|
+
| `portable` | true | `0.0.0.0` | **USB drive** | `acceptEdits` (jailed) |
|
|
198
|
+
|
|
199
|
+
The mode is persisted in `organization.runMode`. In a published build `CONSTELLA_PUBLIC=1`, so the **UI never picks the mode** — the launch flag does.
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Key concepts
|
|
204
|
+
|
|
205
|
+
- **`CONSTELLA_HOME` / runtime root** — the single durable directory. In Docker it's `/data` (a named volume); on USB it's `<drive>/.constella`; otherwise `~/.constella`. Holds `constella.db`, `.env`, `organizations/<orgId>/workspace/`, `backups/`, `cache/`.
|
|
206
|
+
- **`PKG_ROOT`** — the *installed package* root (compiled `.next`, `drizzle/` migrations, configs). The launcher runs `next` and `drizzle-kit` from here, not from the launch CWD.
|
|
207
|
+
- **Secrets persistence** — every mode persists real secrets to `<HOME>/.env` (`mode 0600`). `next start` runs under `NODE_ENV=production`, where better-auth **throws on a default secret**, so a real `BETTER_AUTH_SECRET` is mandatory even locally.
|
|
208
|
+
- **Schema on first run** — `drizzle-kit migrate` is idempotent. A **fresh DB that fails to migrate aborts** (no tables = the app 500s); an existing DB tolerates a no-op re-run.
|
|
209
|
+
- **Build-on-first-run (fallback only)** — the published package ships a prebuilt `.next`, so building is skipped. From a source tree without a build it builds once; if the build fails it **refuses to fall back to `next dev`** in a public/network mode unless `CONSTELLA_DEV=1`.
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Launcher environment
|
|
214
|
+
|
|
215
|
+
The launcher exports these into both children:
|
|
216
|
+
|
|
217
|
+
| Variable | Value |
|
|
218
|
+
| --- | --- |
|
|
219
|
+
| `CONSTELLA_RUN_MODE` | `start \| auth \| vps \| portable` |
|
|
220
|
+
| `CONSTELLA_PUBLIC` | `1` (CLI launch is the public runtime) |
|
|
221
|
+
| `CONSTELLA_VERSION` | the installed package version |
|
|
222
|
+
| `CONSTELLA_HOME` | resolved runtime root |
|
|
223
|
+
| `DATABASE_URL` | `file:<HOME>/constella.db` |
|
|
224
|
+
| `CONSTELLA_PKG_ROOT` | the installed package root |
|
|
225
|
+
| `PORT` / `--port` | `3000` (default) |
|
|
226
|
+
| `--host` | `0.0.0.0` for vps/portable, else `127.0.0.1` |
|
|
227
|
+
|
|
228
|
+
Persisted in `<HOME>/.env` (`chmod 600`): `BETTER_AUTH_SECRET`, `CONSTELLA_VAULT_KEY`, `CONSTELLA_WORKER_SECRET`. Compose-only: `TS_AUTHKEY` (the Tailscale sidecar's join key) in the repo-root `.env`.
|
|
229
|
+
|
|
230
|
+
Opt-in tuning:
|
|
231
|
+
|
|
232
|
+
| Variable | Effect |
|
|
233
|
+
| --- | --- |
|
|
234
|
+
| `CONSTELLA_WEB_HEAP_MB` | `--max-old-space-size` for the web child (default: Node default) |
|
|
235
|
+
| `CONSTELLA_DEV=1` | allow a `next dev` fallback when there is no production build |
|
|
236
|
+
| `CONSTELLA_ALLOW_REMOTE_WORKER_BASE_URL=1` | let the worker talk to a non-loopback base URL (off by default) |
|
|
237
|
+
| `CONSTELLA_WORKER_INTERVAL_MS` | cron tick interval (default `60000`) |
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Updating a deployment 🛰️
|
|
242
|
+
|
|
243
|
+
`detectRunContext()` (`src/lib/run-context.ts`) classifies the running process so the **update method matches the deploy**:
|
|
244
|
+
|
|
245
|
+
| Context | Detected when | Update method |
|
|
246
|
+
| --- | --- | --- |
|
|
247
|
+
| `dev` | running from source (`isDevMode()`) | `git pull && pnpm install && pnpm build` |
|
|
248
|
+
| `vps` | `getRunMode() === "vps"` **or** `/.dockerenv` exists | `docker compose pull && docker compose up -d` |
|
|
249
|
+
| `portable` | `getRunMode() === "portable"` | ensure free space, back up the drive, then `npm install -g constella@latest` |
|
|
250
|
+
| `npx` | launch dir is npm's `_npx` cache | re-run `npx constella@latest` |
|
|
251
|
+
| `global` | none of the above | `npm install -g constella@latest` (auto-runs, detached) |
|
|
252
|
+
|
|
253
|
+
`startUpdate()` (`src/server/update-run.ts`) **always backs up first** — it copies `.env`, `constella.db`, `constella.db-wal`, `constella.db-shm` into `<HOME>/backups/<timestamp>/`. Only the `global` path auto-runs (a detached process writes `<HOME>/backups/last-update.json` that the UI polls); `vps` / `portable` / `dev` / `npx` return the **exact command** to run, because executing them from inside the web server is environment-specific. See [UPDATE](./UPDATE.md).
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
# on a VPS:
|
|
257
|
+
docker compose pull && docker compose up -d
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Because `/data` (or the USB `.constella`) is a persistent volume, the DB and secrets carry across the update; the launcher's idempotent `drizzle-kit migrate` brings the schema forward on the next boot.
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## Possible states
|
|
265
|
+
|
|
266
|
+
| Signal | Meaning |
|
|
267
|
+
| --- | --- |
|
|
268
|
+
| `• Secrets ready (stored in <HOME>/.env, never printed).` | first-boot secret generation/reuse OK |
|
|
269
|
+
| `✖ Portable needs at least 32 GB free …` | portable drive too small (fatal) |
|
|
270
|
+
| `• N GB free on the drive — good …` | portable drive has enough space, boots |
|
|
271
|
+
| `✖ Database schema migration failed on a fresh database — aborting` | fresh DB couldn't get its tables |
|
|
272
|
+
| `• schema migrate skipped/failed on an existing DB — continuing` | benign re-run on a built DB |
|
|
273
|
+
| `✖ No production build … Refusing to start a dev server in a public/network mode.` | no `.next` and no `CONSTELLA_DEV=1` |
|
|
274
|
+
| `• [web] exited (…) — auto-restarting in 2s (n/5 …)` | supervised restart within the window |
|
|
275
|
+
| `✖ [web] exited … crashed 5x within 60s — giving up.` | crash-loop cap hit; shutting down |
|
|
276
|
+
| `✓ Constella is starting. Reach it on your tailnet at: http://<ip>:3000` | `vps-install.sh` finished |
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Related integrations 🪐
|
|
281
|
+
|
|
282
|
+
- **Tailscale** — the private network plane for VPS mode (sidecar container + tailnet IP). See [VPS_MODE](./VPS_MODE.md).
|
|
283
|
+
- **Docker / docker compose** — the runtime + restart policy.
|
|
284
|
+
- **better-auth** — email+password (+ 2FA/passkeys) for every network mode; backed by `BETTER_AUTH_SECRET`. See [AUTH_MODE](./AUTH_MODE.md).
|
|
285
|
+
- **Vault** — provider keys encrypted with `CONSTELLA_VAULT_KEY`. See [SECURITY](./SECURITY.md).
|
|
286
|
+
- **Worker** — cron + watcher + Telegram, supervised alongside the web. See [TELEGRAM](./TELEGRAM.md), [ARCHITECTURE](./ARCHITECTURE.md).
|
|
287
|
+
- **Update** — context-aware self-update. See [UPDATE](./UPDATE.md).
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## Security 🕳️
|
|
292
|
+
|
|
293
|
+
- **Tailnet-only exposure.** With compose, Constella shares the Tailscale sidecar's network namespace, so the dashboard is reachable **only at the Tailscale IP on :3000**, never on the public internet. The host port is never published directly.
|
|
294
|
+
- **Unprivileged container user.** The `runtime` stage runs as the built-in `node` user (uid 1000), not root — an app-level RCE can't act as root over `/data`.
|
|
295
|
+
- **Login required on every network mode.** `vps`, `auth`, and `portable` all set `requiresLogin: true` (better-auth email+password, optional 2FA TOTP / WebAuthn passkeys, 30-day session).
|
|
296
|
+
- **Jailed agents off-local.** In `vps`/`auth`/`portable` the agent CLI runs in `acceptEdits` (edits confined to the workspace FS jail), not the `bypassPermissions` of local `start` mode.
|
|
297
|
+
- **Agent CLIs not bundled.** The image deliberately omits `claude`/`codex`. To run agents on a VPS, add a CLI in a `RUN` step or use cloud API providers in [MODELS](./MODELS.md). Without either, planning/Team-Room work, but agent execution has no runtime.
|
|
298
|
+
- **Secrets never printed.** `<HOME>/.env` is `chmod 600`; the launcher logs only its location. `scrubSecrets` strips secrets before KB ingest / Telegram / logs.
|
|
299
|
+
- **Worker SSRF guard.** The worker refuses to send its privileged secret to any non-loopback base URL unless explicitly opted in.
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Troubleshooting 🛰️
|
|
304
|
+
|
|
305
|
+
| Symptom | Cause / fix |
|
|
306
|
+
| --- | --- |
|
|
307
|
+
| Can't reach `http://<ip>:3000` from another device | the device isn't on the same tailnet; run `tailscale up` there, confirm with `tailscale status` |
|
|
308
|
+
| Sidecar won't join | bad/expired `TS_AUTHKEY`; mint a new key and `docker compose up -d` |
|
|
309
|
+
| App restarts in a loop | check the host's RAM — an agent run causing OS-level OOM kills `next start`; raise `CONSTELLA_WEB_HEAP_MB` for a JS-heap OOM, or cap concurrent agents |
|
|
310
|
+
| `✖ drizzle-kit not found …` | the install is incomplete; reinstall the package/rebuild the image |
|
|
311
|
+
| Fresh DB aborts on migrate | shipped `drizzle/` migrations missing or unwritable `/data`; confirm the volume is `node:node`-owned |
|
|
312
|
+
| Agents don't execute on the VPS | no agent CLI in the image and no cloud provider configured — add a CLI `RUN` step or set up [MODELS](./MODELS.md) |
|
|
313
|
+
| Lost sessions/vault after rebuild | `/data` (or USB `.constella`) wasn't a persistent volume; secrets regenerated. Keep the named volume |
|
|
314
|
+
| Portable refuses to boot | drive under 32 GB free — use a larger drive (`--path`) |
|
|
315
|
+
| Update did nothing on a VPS | by design: run `docker compose pull && docker compose up -d` yourself (the UI returns the command) |
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## Related links
|
|
320
|
+
|
|
321
|
+
- [VPS_MODE](./VPS_MODE.md) — the tailnet run mode in depth
|
|
322
|
+
- [PORTABLE_MODE](./PORTABLE_MODE.md) — USB-drive deploy
|
|
323
|
+
- [START_MODE](./START_MODE.md) · [AUTH_MODE](./AUTH_MODE.md) — local run modes
|
|
324
|
+
- [INSTALLATION](./INSTALLATION.md) — first install
|
|
325
|
+
- [CONFIGURATION](./CONFIGURATION.md) — env vars + runtime root
|
|
326
|
+
- [UPDATE](./UPDATE.md) — context-aware self-update
|
|
327
|
+
- [PREPARE_DEPLOY](./PREPARE_DEPLOY.md) — deploying the **user project** (clean-tree export), not Constella
|
|
328
|
+
- [ARCHITECTURE](./ARCHITECTURE.md) — web + worker, sync engine
|
|
329
|
+
- [SECURITY](./SECURITY.md) — FS jail, vault, scrubbing
|
|
330
|
+
- [MODELS](./MODELS.md) — cloud/local providers for agents on a server
|
|
331
|
+
- [TROUBLESHOOTING](./TROUBLESHOOTING.md) · [FAQ](./FAQ.md)
|
package/docs/en/DM.md
ADDED
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
[← Docs index](./README.md) · [🇧🇷 Português](../pt/DM.md) · [✦ Constella](../../README.md)
|
|
2
|
+
|
|
3
|
+
# Direct Messages — Private Orbits 🛰️✦
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
A **Direct Message** is a private 1:1 channel between you (the operator) and a single agent — its own little orbit, separate from the [Team Room](./TEAM_ROOM.md). DMs carry sessions (fresh contexts on demand), per-session compaction, attachments, Knowledge-Base capture, and — when you talk to a **planner** like Ada — the ability to turn a request into real, approval-gated work.
|
|
8
|
+
|
|
9
|
+
## When to use
|
|
10
|
+
|
|
11
|
+
- You want a **focused 1:1** with one agent (the CEO, the CTO, the QA lead, the Docs writer) without pinging the whole room.
|
|
12
|
+
- You want to **start new work** by simply describing it to **@ada** (or another planner) — no loose "new work" button.
|
|
13
|
+
- You want **multiple parallel threads** with the same agent, each with its own fresh context (DM **sessions**).
|
|
14
|
+
- You want to **attach files** (images / PDFs / docs) for one agent to read privately.
|
|
15
|
+
- You want to keep a conversation **out of the autonomous hand-off chain** — DMs never relay to teammates.
|
|
16
|
+
|
|
17
|
+
> 🪐 Channels at a glance: `room` (everyone, must @mention), `dm:<handle>` (private 1:1, this doc), `telegram` (isolated remote thread → Ada). See [Team Room](./TEAM_ROOM.md), [Chat Commands](./CHAT_COMMANDS.md) and [Telegram](./TELEGRAM.md).
|
|
18
|
+
|
|
19
|
+
## How it works
|
|
20
|
+
|
|
21
|
+
Every conversation in Constella lives in a **channel** — a plain string on the `message` table. A DM channel is the literal string `dm:<handle>`, e.g. `dm:ada`, `dm:linus`, `dm:edsger`. The handle after `dm:` is the agent's handle from the roster (see [Agents](./AGENTS.md)).
|
|
22
|
+
|
|
23
|
+
The DM machinery lives in three files:
|
|
24
|
+
|
|
25
|
+
| File | Responsibility |
|
|
26
|
+
| --- | --- |
|
|
27
|
+
| `src/server/chat.ts` | Operator-facing actions: `sendMessage`, `agentRespond`, DM **session** actions, clear/previews. |
|
|
28
|
+
| `src/server/collab.ts` | The real agent turn (`replyInChannel`): builds the prompt, runs the CLI, books cost, captures KB. |
|
|
29
|
+
| `src/server/sessions.ts` | DM-session lifecycle: `ensureActiveSession`, `sessionsFor`, `newSession`, `activateSession`, `renameSessionRow`, `deleteSessionRow`. |
|
|
30
|
+
| `src/server/compaction.ts` | `buildChannelContext` — folds older messages into a per-session summary when the channel outgrows the model window. |
|
|
31
|
+
|
|
32
|
+
### Routing a message to a responder
|
|
33
|
+
|
|
34
|
+
When you send to a `dm:<handle>` channel, `sendMessage` decides who answers (`src/server/chat.ts`):
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
if (channel.startsWith("dm:")) {
|
|
38
|
+
const h = channel.slice(3); if (handles.has(h)) responders = [h];
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
So a DM resolves to **exactly one responder** — the agent named by the channel. Contrast this with:
|
|
43
|
+
|
|
44
|
+
- **`room`** — the message must `@mention` a real teammate; up to **3** responders (`mentions(...).slice(0, 3)`); an un-mentioned room message is dropped (no dead-end post).
|
|
45
|
+
- **`telegram`** — always routes to **ada** (the CEO), falling back to the first agent if there is no `ada` handle.
|
|
46
|
+
|
|
47
|
+
After persisting your message, `sendMessage` also: wakes any open SSE stream (`wake`), schedules a RAG re-index of the conversation (`scheduleChatReindex`), and — **only in the `room`** for substantive text (≥15 chars) — logs an operator decision. (DMs do **not** log decisions.)
|
|
48
|
+
|
|
49
|
+
### The agent's real reply
|
|
50
|
+
|
|
51
|
+
`agentRespond(channel, handle)` flips the agent to `working`, then calls `replyInChannel` in `collab.ts`, which is where the real work happens:
|
|
52
|
+
|
|
53
|
+
1. Build a **chat-mode** instruction (DMs are always `mode: "chat"` — conversational, *no file edits*; only the team-room hand-off chain uses `mode: "work"`).
|
|
54
|
+
2. Append clause blocks: a **plan clause** (new-work token, below), an **attachments clause** (read uploaded files), a **language clause** (mirror the operator's language in chat only — everything written to the workspace stays English), plus **REMEMBER** / **CONSULT** / **KB** knowledge clauses, and a **Telegram security clause** (DM channels skip this — it's `telegram`-only).
|
|
55
|
+
3. Assemble ONE model-fitted context bundle (`assembleAgentPrompt`) — mission, project state, decisions, **this session's** conversation (compacted), RAG, memory.
|
|
56
|
+
4. Resolve the runtime (`resolveRuntime`) and run the CLI / HTTP API (`runAgentRuntime`, 180 s timeout), streaming live events to your view.
|
|
57
|
+
5. Strip the new-work token, extract `[[REMEMBER …]]` learnings into the KB, answer `[[CONSULT: …]]` queries (posted back as **Vannevar**), run `[[KB: …]]` tools, **scrub secrets**, and persist the reply on the **active session**.
|
|
58
|
+
6. Book real cost into `costEntry`.
|
|
59
|
+
|
|
60
|
+
> 🕳️ Crucial difference from the room: at the end, the room fans out the hand-off chain (`relayRoomMentions`), but **DMs stay 1:1** — `if (!channel.startsWith("dm:")) await relayRoomMentions(...)`. An `@mention` inside a DM reply does **not** wake another agent.
|
|
61
|
+
|
|
62
|
+
## Main flow
|
|
63
|
+
|
|
64
|
+
```mermaid
|
|
65
|
+
sequenceDiagram
|
|
66
|
+
actor Op as Operator
|
|
67
|
+
participant Chat as chat.ts
|
|
68
|
+
participant Sess as sessions.ts
|
|
69
|
+
participant Collab as collab.ts (replyInChannel)
|
|
70
|
+
participant CLI as Agent runtime (claude/codex)
|
|
71
|
+
participant DB as message / costEntry
|
|
72
|
+
|
|
73
|
+
Op->>Chat: sendMessage("dm:linus", text, attachments?)
|
|
74
|
+
Chat->>Chat: responder = "linus" (single)
|
|
75
|
+
Chat->>Sess: ensureActiveSession(ws, "dm:linus")
|
|
76
|
+
Chat->>DB: insert operator message (sessionId)
|
|
77
|
+
Chat-->>Op: { responders: ["linus"] }
|
|
78
|
+
Op->>Chat: agentRespond("dm:linus", "linus")
|
|
79
|
+
Chat->>Collab: replyInChannel(..., mode "chat")
|
|
80
|
+
Collab->>CLI: run with assembled context bundle
|
|
81
|
+
CLI-->>Collab: reply text (+ REMEMBER/CONSULT/KB tokens)
|
|
82
|
+
Collab->>DB: insert agent message (active session) + costEntry
|
|
83
|
+
Note over Collab: DM → NO relayRoomMentions (stays 1:1)
|
|
84
|
+
Collab-->>Op: streamed reply
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Key concepts
|
|
88
|
+
|
|
89
|
+
### DM sessions 🌠
|
|
90
|
+
|
|
91
|
+
A DM channel can hold **multiple sessions**. A session is a row in `chat_session` scoped to `(workspaceId, channel)`; exactly **one is active** per channel. Starting a new session gives the agent a **fresh context** while you keep every past message visible — you just switch which thread you're looking at.
|
|
92
|
+
|
|
93
|
+
- `ensureActiveSession(ws, channel)` returns the active session id, lazily creating **"Session 1"** the first time a DM is touched, and **adopting** any legacy null-session messages into it. Returns `null` for non-DM channels (the room and Telegram are single-thread and never get sessions).
|
|
94
|
+
- `newSession` deactivates the others and creates `Session N` (active).
|
|
95
|
+
- `activateSession` switches which session is active.
|
|
96
|
+
- `renameSessionRow` renames (≤60 chars).
|
|
97
|
+
- `deleteSessionRow` deletes the session **and its messages**; if it was active, it activates the newest remaining session (or none — `ensureActiveSession` recreates "Session 1" on the next touch).
|
|
98
|
+
|
|
99
|
+
`getMessages("dm:<handle>")` and `clearConversation` both scope to the **active session** for DMs, so a new session is a genuinely clean slate.
|
|
100
|
+
|
|
101
|
+
### Compaction (per session) 🌌
|
|
102
|
+
|
|
103
|
+
When a conversation outgrows the active model's context window, `buildChannelContext` (`compaction.ts`) folds the **older** messages into a structured summary and keeps only the most recent ones verbatim. For DMs this is **scoped to the active session** (`sessionId`), so each thread compacts independently:
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
const msgConds = [eq(message.workspaceId, workspaceId), eq(message.channel, channel)];
|
|
107
|
+
if (sessionId) msgConds.push(eq(message.sessionId, sessionId));
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
- The summary is **model-aware** — smaller models get a tighter (~150-word) summary, larger ones keep more detail (~350 words).
|
|
111
|
+
- Sections are fixed: `## Decisions`, `## Requirements`, `## Open issues`, `## Files`, `## Pending by agent`, `## Next steps`.
|
|
112
|
+
- Summarization runs on a **cheap model (`haiku`)** and books real cost.
|
|
113
|
+
- One `message_summary` row per `(workspace, channel, session)`; it stores `throughId` (last folded message) so an unchanged window is reused, not re-summarized.
|
|
114
|
+
- The compacted block is also linked into `.claude/memory.md` (one section per channel), best-effort.
|
|
115
|
+
|
|
116
|
+
### New work from a DM 🚀
|
|
117
|
+
|
|
118
|
+
This is the signature DM feature. **New work is born from the conversation with the CEO — not a loose button.** In **chat mode**, any agent's prompt includes a **plan clause**: if the operator is asking to **BUILD / IMPLEMENT / ADD / FIX / CHANGE** something (a new unit of work), the agent confirms in 1–2 sentences and emits, on a final separate line, the machine token:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
[[CREATE_WORK]]
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`collab.ts` defines this as `const CREATE_WORK = "[[CREATE_WORK]]"`. `replyInChannel` detects it (`planRequested`) and **strips it** before the reply is stored or shown. Back in `chat.ts`, `agentRespond` reacts:
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
if (planRequested) {
|
|
128
|
+
const r = await planFromConversation(channel);
|
|
129
|
+
// posts a short "registering this as new work…" confirmation back into the DM
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
`planFromConversation(channel)` (in `src/server/planner.ts`) takes the **last 30 messages** of the channel and runs the **same planning ritual as the first plan** — Ada (the CEO) drafts a Goal → specs → issues → TODOs, appended to the **CEO Planner** for your approval. (For the Telegram remote, the off-session twin is `planFromConversationFor` in `planner-core.ts`.)
|
|
134
|
+
|
|
135
|
+
> 🌠 Planner vs non-planner. The plan clause is offered to **every** agent, but the wording differs:
|
|
136
|
+
> - **Planners** (`isPlanner`: the CEO **ada**, the Product Owner **donald**, the CTO **linus** — or any role matching *product owner* / *CTO* / *chief tech*) get a direct "turn this into a spec + issues" instruction.
|
|
137
|
+
> - **Non-planners** get an extra reassurance: it *"runs through the CEO's planning ritual and waits for the operator's approval, so you're not committing anyone to build immediately."*
|
|
138
|
+
>
|
|
139
|
+
> Either way the request is **routed through the CEO's planner and gated by your approval** — no code is built directly from a DM. See [Goals, Specs & Issues](./GOALS_SPECS_ISSUES.md) and [Workflow](./WORKFLOW.md).
|
|
140
|
+
|
|
141
|
+
### Knowledge capture in a DM 🌌
|
|
142
|
+
|
|
143
|
+
Even in a private DM the agent can grow the shared brain (see [KB Agent](./KB_AGENT.md) and [KB & RAG](./KB_RAG.md)):
|
|
144
|
+
|
|
145
|
+
| Token (own line) | Effect |
|
|
146
|
+
| --- | --- |
|
|
147
|
+
| `[[REMEMBER type=<decision\|architecture\|business-rule\|integration\|fix\|note>: <fact>]]` | Auto-saved to the KB (deduped), token stripped from the shown reply. |
|
|
148
|
+
| `[[CONSULT: <question>]]` | Answered from the state-aware KB; the answer is posted back into the DM **as Vannevar**. |
|
|
149
|
+
| `[[KB: reindex \| index-chat \| health]]` | KB-agent maintenance (only the Knowledge role gets this clause); result reported back into the thread. |
|
|
150
|
+
|
|
151
|
+
You can also promote a single chat line into the KB with `sendMessageToKb(messageId)` (captured as a `note`), or pull KB context into the composer with `pullKbForComposer(query)` (draft only — never sends).
|
|
152
|
+
|
|
153
|
+
## Tables
|
|
154
|
+
|
|
155
|
+
### `chat_session` (`src/db/schema.ts`)
|
|
156
|
+
|
|
157
|
+
| Column | Type | Notes |
|
|
158
|
+
| --- | --- | --- |
|
|
159
|
+
| `id` | text PK | |
|
|
160
|
+
| `workspaceId` | text | FK → `workspace`, cascade delete. |
|
|
161
|
+
| `channel` | text | Always `dm:<handle>` (DM only). |
|
|
162
|
+
| `title` | text | Defaults to `Session N`; rename ≤60 chars. |
|
|
163
|
+
| `active` | boolean | Exactly one active per `(workspace, channel)`. |
|
|
164
|
+
| `createdAt` | timestamp | Newest-first ordering for the session list. |
|
|
165
|
+
|
|
166
|
+
### `message` (DM-relevant columns)
|
|
167
|
+
|
|
168
|
+
| Column | Notes |
|
|
169
|
+
| --- | --- |
|
|
170
|
+
| `channel` | `room` \| `dm:<handle>` \| `telegram`. |
|
|
171
|
+
| `fromKind` | `operator` \| `agent`. |
|
|
172
|
+
| `fromHandle` | The agent handle (null for operator). |
|
|
173
|
+
| `text` | Message body (agent replies stored ≤4000 chars). |
|
|
174
|
+
| `sessionId` | The `chat_session` this message belongs to. **NULL** for room/Telegram and legacy DM messages (backfilled to "Session 1"). |
|
|
175
|
+
| `sources` | RAG source chips for an agent reply. |
|
|
176
|
+
| `attachments` | Operator uploads (≤10/message): `{ name, type, size, path }`. |
|
|
177
|
+
| `taskId` / `kind` / `blocks` | Traceability chip / render hint / synced-block slugs. |
|
|
178
|
+
|
|
179
|
+
### `message_summary`
|
|
180
|
+
|
|
181
|
+
| Column | Notes |
|
|
182
|
+
| --- | --- |
|
|
183
|
+
| `channel` | The conversation summarized. |
|
|
184
|
+
| `sessionId` | DM session this summary covers; **NULL** for room/Telegram. |
|
|
185
|
+
| `summary` | Structured compacted context. |
|
|
186
|
+
| `throughId` | Last message folded in (reuse guard). |
|
|
187
|
+
| `msgCount` | Number of messages folded. |
|
|
188
|
+
|
|
189
|
+
## New-work-from-DM diagram
|
|
190
|
+
|
|
191
|
+
```mermaid
|
|
192
|
+
flowchart TD
|
|
193
|
+
A["Operator DMs @ada:\n'build a CSV export'"] --> B["sendMessage('dm:ada', …)\nresponder = ada"]
|
|
194
|
+
B --> C["agentRespond → replyInChannel\n(mode: chat, plan clause ON)"]
|
|
195
|
+
C --> D{"Operator asking to\nBUILD / FIX / CHANGE?"}
|
|
196
|
+
D -- "No" --> E["Normal 1:1 reply\n(stays in the DM)"]
|
|
197
|
+
D -- "Yes" --> F["Reply confirms + emits\n[[CREATE_WORK]] on last line"]
|
|
198
|
+
F --> G["token stripped\nplanRequested = true"]
|
|
199
|
+
G --> H["planFromConversation(channel)\nlast 30 messages → brief"]
|
|
200
|
+
H --> I["CEO planning ritual:\nGoal → specs → issues → TODOs"]
|
|
201
|
+
I --> J["Appended to CEO Planner\n(awaits operator approval)"]
|
|
202
|
+
J --> K["'Plan ready' streams back\ninto the DM"]
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Step-by-step
|
|
206
|
+
|
|
207
|
+
### Start new work from a DM
|
|
208
|
+
|
|
209
|
+
1. Open the DM with **@ada** (CEO) — or another planner like **@linus** / **@donald**.
|
|
210
|
+
2. Describe the work plainly: *"Build a settings page with a dark-mode toggle."*
|
|
211
|
+
3. Ada confirms ("registering this as new work…") and the heavy plan run starts detached.
|
|
212
|
+
4. A **"Plan ready"** message streams back into the DM when specs + issues are drafted.
|
|
213
|
+
5. Approve in the **CEO Planner** (or via `/approve` — see [Chat Commands](./CHAT_COMMANDS.md)). Approval is what authorizes the team to build.
|
|
214
|
+
|
|
215
|
+
### Manage DM sessions
|
|
216
|
+
|
|
217
|
+
1. In a DM, open the session list (newest first; one active).
|
|
218
|
+
2. **New session** → fresh agent context, old threads preserved (`createSession`).
|
|
219
|
+
3. **Switch** between sessions (`switchSession`); **rename** (`renameSession`); **delete** (`deleteSession`, confirmed by a modal).
|
|
220
|
+
4. **Clear conversation** in a DM wipes only the **active session's** messages + its summary — other sessions are untouched.
|
|
221
|
+
|
|
222
|
+
### Attach a file to a DM
|
|
223
|
+
|
|
224
|
+
1. Add up to 10 files to the composer; they are saved under `uploads/` in the workspace.
|
|
225
|
+
2. The agent's prompt gains an attachments clause pointing at the on-disk **paths**; it reads them with its file tools (images/PDFs supported).
|
|
226
|
+
3. Filenames are treated as **data, not instructions** (prompt-injection guard).
|
|
227
|
+
|
|
228
|
+
## Examples
|
|
229
|
+
|
|
230
|
+
```text
|
|
231
|
+
# DM with @ada — kicks off new work
|
|
232
|
+
You → @ada: We need a CSV export on the reports page.
|
|
233
|
+
Ada → Got it — I'll turn this into a spec + issues and register it for approval. [[CREATE_WORK]] (stripped)
|
|
234
|
+
Ada → Got it — registering this as new work. I'm drafting the plan now…
|
|
235
|
+
|
|
236
|
+
# DM with @edsger (QA lead) — a question, NOT new work → normal reply, no token
|
|
237
|
+
You → @edsger: What did the last test run flag on /login?
|
|
238
|
+
Edsger → The last run flagged 1 console error on /login (uncaught TypeError)…
|
|
239
|
+
|
|
240
|
+
# Non-planner routing a build request still goes through Ada's planner
|
|
241
|
+
You → @grace: Add a loading spinner to the dashboard.
|
|
242
|
+
Grace → I'll register this as new work — it runs through the CEO's planning ritual and waits for your approval. [[CREATE_WORK]] (stripped)
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Possible states
|
|
246
|
+
|
|
247
|
+
| State | Meaning |
|
|
248
|
+
| --- | --- |
|
|
249
|
+
| Responder resolved | DM channel `dm:<h>` → single responder `h` if the handle exists; otherwise `responders: []`. |
|
|
250
|
+
| `mode: "chat"` | DM replies are conversational — **no file edits**, no hand-off chain. |
|
|
251
|
+
| `planRequested = true` | Agent emitted `[[CREATE_WORK]]`; `planFromConversation` runs the ritual. |
|
|
252
|
+
| Active session | One `chat_session.active = true` per DM; drives reads, writes, compaction, clear. |
|
|
253
|
+
| Compacted | Older messages folded into `message_summary` for the active session. |
|
|
254
|
+
| Agent `working` / `idle` | `agentRespond` sets `working` during the turn, back to `idle` after. |
|
|
255
|
+
|
|
256
|
+
## Related integrations
|
|
257
|
+
|
|
258
|
+
- **[Team Room](./TEAM_ROOM.md)** — the shared channel; the `@mention` hand-off chain (which DMs deliberately avoid).
|
|
259
|
+
- **[Telegram](./TELEGRAM.md)** — the isolated remote thread that always talks to Ada; mirrors back from the in-app Telegram tab.
|
|
260
|
+
- **[Chat Commands](./CHAT_COMMANDS.md)** — slash commands work in DMs too (intercepted before the message path; not on Telegram).
|
|
261
|
+
- **[Goals, Specs & Issues](./GOALS_SPECS_ISSUES.md)** / **[Workflow](./WORKFLOW.md)** — where DM-born work lands and is approved.
|
|
262
|
+
- **[KB & RAG](./KB_RAG.md)** / **[Memory & RAG](./MEMORY_RAG.md)** — REMEMBER/CONSULT capture and conversation re-indexing.
|
|
263
|
+
- **[Inbox](./INBOX.md)** — operator pings raised when an agent addresses you (skipped on Telegram).
|
|
264
|
+
|
|
265
|
+
## Security
|
|
266
|
+
|
|
267
|
+
- **Secret scrubbing** — every reply (room, DM, Telegram) is passed through `scrubSecrets` before it is stored, shown or notified.
|
|
268
|
+
- **Attachments are data** — uploaded filenames/paths are wrapped as data; the prompt tells the model to ignore any directive embedded in a filename.
|
|
269
|
+
- **Prompt-injection hardening** is strongest on `telegram` (untrusted remote input); DMs are local operator input but still scrubbed and language-/workspace-jailed.
|
|
270
|
+
- **DMs don't fan out** — an `@mention` in a DM reply never wakes another agent, so a private thread can't spawn an autonomous chain.
|
|
271
|
+
- **No direct build from chat** — a DM can only *register* work; nothing executes until you approve the plan. See [Security](./SECURITY.md) and [AI Architecture](./AI_ARCHITECTURE.md) for the FS jail and permission modes.
|
|
272
|
+
|
|
273
|
+
## Troubleshooting
|
|
274
|
+
|
|
275
|
+
| Symptom | Likely cause / fix |
|
|
276
|
+
| --- | --- |
|
|
277
|
+
| The agent didn't reply in my DM | The handle after `dm:` must exist in the roster; a stray channel string yields `responders: []`. Check the handle in [Agents](./AGENTS.md). |
|
|
278
|
+
| I asked for a build but no plan appeared | The model judged it a question, not new work, so it didn't emit `[[CREATE_WORK]]`. Be explicit: *"Build/implement/fix …"*. The DM should then post a "registering this as new work…" line. |
|
|
279
|
+
| New session still shows old messages | You're viewing a previous session — switch to the active one. Reads are scoped to the active `chat_session`. |
|
|
280
|
+
| "Clear conversation" didn't clear everything | In a DM, clear only wipes the **active session**; other sessions persist by design. |
|
|
281
|
+
| An `@mention` in my DM did nothing | Correct — DMs are 1:1 and never relay. Use the [Team Room](./TEAM_ROOM.md) for hand-offs. |
|
|
282
|
+
| Old context keeps coming back | That's the per-session compacted summary (`message_summary`) being injected. Start a fresh session for a clean context. |
|
|
283
|
+
| Reply timed out | The runtime cap is 180 s; very heavy single turns may hit it. |
|
|
284
|
+
|
|
285
|
+
## Related links
|
|
286
|
+
|
|
287
|
+
- [Team Room](./TEAM_ROOM.md)
|
|
288
|
+
- [Chat Commands](./CHAT_COMMANDS.md)
|
|
289
|
+
- [Telegram](./TELEGRAM.md)
|
|
290
|
+
- [Agents](./AGENTS.md)
|
|
291
|
+
- [Goals, Specs & Issues](./GOALS_SPECS_ISSUES.md)
|
|
292
|
+
- [Workflow](./WORKFLOW.md)
|
|
293
|
+
- [KB & RAG](./KB_RAG.md)
|
|
294
|
+
- [Memory & RAG](./MEMORY_RAG.md)
|
|
295
|
+
- [Inbox](./INBOX.md)
|
|
296
|
+
- [AI Architecture](./AI_ARCHITECTURE.md)
|
|
297
|
+
- [Security](./SECURITY.md)
|