constellai 0.3.5 → 0.3.6
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 -1
- package/.next/app-path-routes-manifest.json +3 -3
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +3 -3
- package/.next/server/app/(app)/activity/page.js +2 -2
- package/.next/server/app/(app)/activity/page.js.nft.json +1 -1
- package/.next/server/app/(app)/activity/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/agents/[handle]/page.js +2 -2
- package/.next/server/app/(app)/agents/[handle]/page.js.nft.json +1 -1
- package/.next/server/app/(app)/agents/[handle]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/code/page.js +2 -2
- package/.next/server/app/(app)/code/page.js.nft.json +1 -1
- package/.next/server/app/(app)/code/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/config/page.js +2 -2
- package/.next/server/app/(app)/config/page.js.nft.json +1 -1
- package/.next/server/app/(app)/config/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/costs/page.js +2 -2
- package/.next/server/app/(app)/costs/page.js.nft.json +1 -1
- package/.next/server/app/(app)/costs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/cron/page.js +2 -2
- package/.next/server/app/(app)/cron/page.js.nft.json +1 -1
- package/.next/server/app/(app)/cron/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/dashboard/page.js +2 -2
- package/.next/server/app/(app)/dashboard/page.js.nft.json +1 -1
- package/.next/server/app/(app)/dashboard/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/design/page.js +5 -5
- package/.next/server/app/(app)/design/page.js.nft.json +1 -1
- package/.next/server/app/(app)/design/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/docs/[id]/page.js +2 -2
- package/.next/server/app/(app)/docs/[id]/page.js.nft.json +1 -1
- package/.next/server/app/(app)/docs/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/docs/page.js +2 -2
- package/.next/server/app/(app)/docs/page.js.nft.json +1 -1
- package/.next/server/app/(app)/docs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/github/page.js +2 -2
- package/.next/server/app/(app)/github/page.js.nft.json +1 -1
- package/.next/server/app/(app)/github/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/goals/page.js +2 -2
- package/.next/server/app/(app)/goals/page.js.nft.json +1 -1
- package/.next/server/app/(app)/goals/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/inbox/page.js +2 -2
- package/.next/server/app/(app)/inbox/page.js.nft.json +1 -1
- package/.next/server/app/(app)/inbox/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/knowledge/page.js +3 -3
- package/.next/server/app/(app)/knowledge/page.js.nft.json +1 -1
- package/.next/server/app/(app)/knowledge/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/models/page.js +2 -2
- package/.next/server/app/(app)/models/page.js.nft.json +1 -1
- package/.next/server/app/(app)/models/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/notifications/page.js +2 -2
- package/.next/server/app/(app)/notifications/page.js.nft.json +1 -1
- package/.next/server/app/(app)/notifications/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/org/page.js +3 -3
- package/.next/server/app/(app)/org/page.js.nft.json +1 -1
- package/.next/server/app/(app)/org/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/organizations/page.js +2 -2
- package/.next/server/app/(app)/organizations/page.js.nft.json +1 -1
- package/.next/server/app/(app)/organizations/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/page.js +3 -3
- package/.next/server/app/(app)/page.js.nft.json +1 -1
- package/.next/server/app/(app)/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/planner/page.js +3 -3
- package/.next/server/app/(app)/planner/page.js.nft.json +1 -1
- package/.next/server/app/(app)/planner/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/plugins/page.js +2 -2
- package/.next/server/app/(app)/plugins/page.js.nft.json +1 -1
- package/.next/server/app/(app)/plugins/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/pm/page.js +2 -2
- package/.next/server/app/(app)/pm/page.js.nft.json +1 -1
- package/.next/server/app/(app)/pm/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/prepare-deploy/page.js +6 -6
- package/.next/server/app/(app)/prepare-deploy/page.js.nft.json +1 -1
- package/.next/server/app/(app)/prepare-deploy/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/profile/page.js +2 -2
- package/.next/server/app/(app)/profile/page.js.nft.json +1 -1
- package/.next/server/app/(app)/profile/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/pulse/page.js +2 -2
- package/.next/server/app/(app)/pulse/page.js.nft.json +1 -1
- package/.next/server/app/(app)/pulse/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/reports/[id]/page.js +3 -3
- package/.next/server/app/(app)/reports/[id]/page.js.nft.json +1 -1
- package/.next/server/app/(app)/reports/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/reports/page.js +2 -2
- package/.next/server/app/(app)/reports/page.js.nft.json +1 -1
- package/.next/server/app/(app)/reports/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/routines/page.js +2 -2
- package/.next/server/app/(app)/routines/page.js.nft.json +1 -1
- package/.next/server/app/(app)/routines/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/search/page.js +2 -2
- package/.next/server/app/(app)/search/page.js.nft.json +1 -1
- package/.next/server/app/(app)/search/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/security/page.js +2 -2
- package/.next/server/app/(app)/security/page.js.nft.json +1 -1
- package/.next/server/app/(app)/security/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/skills/page.js +2 -2
- package/.next/server/app/(app)/skills/page.js.nft.json +1 -1
- package/.next/server/app/(app)/skills/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/tasks/page.js +2 -2
- package/.next/server/app/(app)/tasks/page.js.nft.json +1 -1
- package/.next/server/app/(app)/tasks/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/test-dev/page.js +2 -2
- package/.next/server/app/(app)/test-dev/page.js.nft.json +1 -1
- package/.next/server/app/(app)/test-dev/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/update/page.js +3 -3
- package/.next/server/app/(app)/update/page.js.nft.json +1 -1
- package/.next/server/app/(app)/update/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(auth)/login/page.js +2 -2
- package/.next/server/app/(auth)/login/page.js.nft.json +1 -1
- package/.next/server/app/(auth)/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(auth)/onboarding/page.js +2 -2
- package/.next/server/app/(auth)/onboarding/page.js.nft.json +1 -1
- package/.next/server/app/(auth)/onboarding/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_global-error/page.js +1 -1
- package/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +3 -3
- package/.next/server/app/_global-error.segments/_full.segment.rsc +3 -3
- package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +2 -2
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page.js +1 -1
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/api/cron/tick/route.js +16 -16
- package/.next/server/app/api/locks/acquire/route.js +1 -1
- package/.next/server/app/api/sync/file/route.js +2 -2
- package/.next/server/app/api/telegram/poll/route.js +10 -10
- package/.next/server/app/api/upload/route.js +1 -1
- package/.next/server/app/api/v1/[[...path]]/route.js +1 -1
- package/.next/server/app-paths-manifest.json +3 -3
- package/.next/server/chunks/1249.js +14 -14
- package/.next/server/chunks/158.js +21 -0
- package/.next/server/chunks/1765.js +1 -0
- package/.next/server/chunks/1845.js +1 -1
- package/.next/server/chunks/2495.js +1 -0
- package/.next/server/chunks/2517.js +1 -1
- package/.next/server/chunks/259.js +9 -9
- package/.next/server/chunks/260.js +1 -1
- package/.next/server/chunks/2867.js +2 -2
- package/.next/server/chunks/2960.js +1 -1
- package/.next/server/chunks/3131.js +1 -1
- package/.next/server/chunks/3234.js +4 -4
- package/.next/server/chunks/4467.js +12 -0
- package/.next/server/chunks/4619.js +1 -1
- package/.next/server/chunks/4979.js +12 -12
- package/.next/server/chunks/535.js +1 -0
- package/.next/server/chunks/6431.js +1 -1
- package/.next/server/chunks/7225.js +4 -0
- package/.next/server/chunks/7336.js +1 -1
- package/.next/server/chunks/7589.js +3 -3
- package/.next/server/chunks/7989.js +1 -1
- package/.next/server/chunks/850.js +1 -1
- package/.next/server/chunks/8561.js +3 -3
- package/.next/server/chunks/8623.js +1 -1
- package/.next/server/chunks/8719.js +417 -0
- package/.next/server/chunks/8762.js +15 -417
- package/.next/server/chunks/8823.js +1 -1
- package/.next/server/chunks/9783.js +3 -3
- package/.next/server/chunks/9969.js +1 -1
- package/.next/server/instrumentation.js +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/2831-d7f6495bf43f4f9d.js +4 -0
- package/.next/static/chunks/{3219-b4941c7ff967e904.js → 3219-486bddbf87074d04.js} +1 -1
- package/.next/static/chunks/3775-82dcdf23109aa5bf.js +1 -0
- package/.next/static/chunks/6836-341614c5418e2aa4.js +1 -0
- package/.next/static/chunks/8306-7418693cd7fd5861.js +1 -0
- package/.next/static/chunks/{8370-2733742abf5f3ddf.js → 8370-8b3e7106703024ce.js} +2 -2
- package/.next/static/chunks/9690-ea874aec65263b9d.js +1 -0
- package/.next/static/chunks/app/(app)/activity/{page-29e80a32c02f376b.js → page-cf8d67941440bdce.js} +1 -1
- package/.next/static/chunks/app/(app)/agents/[handle]/page-7baa24f1ae8bc400.js +1 -0
- package/.next/static/chunks/app/(app)/code/page-b342d74807e8b914.js +1 -0
- package/.next/static/chunks/app/(app)/config/page-1e68ba8d20215d67.js +1 -0
- package/.next/static/chunks/app/(app)/costs/page-a58d759eec6048df.js +1 -0
- package/.next/static/chunks/app/(app)/cron/page-cc7f4e3d8ab5618f.js +1 -0
- package/.next/static/chunks/app/(app)/dashboard/page-7757c33acf751c4c.js +1 -0
- package/.next/static/chunks/app/(app)/design/{page-238be90d78d22780.js → page-f48c0487d240248e.js} +3 -3
- package/.next/static/chunks/app/(app)/docs/[id]/page-95c52cf457d869ef.js +1 -0
- package/.next/static/chunks/app/(app)/docs/page-fbc50cd357d5e2ca.js +1 -0
- package/.next/static/chunks/app/(app)/github/page-dac138256ed91e65.js +1 -0
- package/.next/static/chunks/app/(app)/goals/page-f87d40f6832d63b3.js +1 -0
- package/.next/static/chunks/app/(app)/inbox/page-49c1293e0d98874f.js +12 -0
- package/.next/static/chunks/app/(app)/knowledge/page-18fca436883ed5cc.js +1 -0
- package/.next/static/chunks/app/(app)/layout-c9778f98c0103f74.js +1 -0
- package/.next/static/chunks/app/(app)/models/page-030c085cd7767495.js +1 -0
- package/.next/static/chunks/app/(app)/notifications/page-12af3fee8b36a00e.js +12 -0
- package/.next/static/chunks/app/(app)/org/page-576001ff4a820744.js +12 -0
- package/.next/static/chunks/app/(app)/organizations/page-b973e1eee6e56baf.js +1 -0
- package/.next/static/chunks/app/(app)/page-cef52fc5f4fd4418.js +1 -0
- package/.next/static/chunks/app/(app)/planner/page-da2db56914346192.js +1 -0
- package/.next/static/chunks/app/(app)/plugins/{page-d10239fcbabdf4fa.js → page-3b78b76ecb21d616.js} +1 -1
- package/.next/static/chunks/app/(app)/pm/{page-61ad11558f241cf1.js → page-78303379c1ea5dc5.js} +1 -1
- package/.next/static/chunks/app/(app)/prepare-deploy/page-98b1bd3bf712bb60.js +1 -0
- package/.next/static/chunks/app/(app)/profile/page-de24af53de0ef2b2.js +1 -0
- package/.next/static/chunks/app/(app)/pulse/page-db7fd63369c01fa2.js +1 -0
- package/.next/static/chunks/app/(app)/reports/[id]/page-cc7f4e3d8ab5618f.js +1 -0
- package/.next/static/chunks/app/(app)/reports/page-97ab95e6f8b77b62.js +1 -0
- package/.next/static/chunks/app/(app)/routines/page-cf6a3331775ca11b.js +1 -0
- package/.next/static/chunks/app/(app)/search/page-3960825f66b05606.js +1 -0
- package/.next/static/chunks/app/(app)/security/page-53b0770355cf7aa4.js +1 -0
- package/.next/static/chunks/app/(app)/skills/{page-72691864856c9906.js → page-809a73b94861f8b8.js} +1 -1
- package/.next/static/chunks/app/(app)/tasks/page-b2497927d127f7aa.js +1 -0
- package/.next/static/chunks/app/(app)/test-dev/page-93ec5d89e2afb612.js +1 -0
- package/.next/static/chunks/app/(app)/update/page-a23322af4e59a93c.js +1 -0
- package/.next/static/chunks/app/(auth)/login/page-446681bfb762cb05.js +1 -0
- package/.next/static/chunks/app/(auth)/onboarding/page-2b8cb3e0b024c995.js +1 -0
- package/.next/trace-build +1 -1
- package/CHANGELOG.md +37 -0
- package/README.md +7 -1
- package/README.pt-BR.md +7 -1
- package/bin/constella-update.mjs +19 -7
- package/bin/constella.mjs +1 -1
- package/bin/worker.mjs +1 -0
- package/docs/UPDATE.md +11 -2
- package/docs/roadmap.md +36 -0
- package/package.json +1 -1
- package/scripts/i18n-parity.mjs +1 -1
- package/scripts/install.sh +4 -2
- package/scripts/publish-public.mjs +12 -3
- package/scripts/vps-clean.sh +1 -1
- package/scripts/vps-install.sh +19 -5
- package/scripts/vps-update.sh +26 -17
- package/.next/server/chunks/212.js +0 -1
- package/.next/server/chunks/6381.js +0 -15
- package/.next/server/chunks/6853.js +0 -12
- package/.next/server/chunks/6954.js +0 -1
- package/.next/server/chunks/9215.js +0 -4
- package/.next/server/chunks/9229.js +0 -1
- package/.next/server/chunks/9310.js +0 -21
- package/.next/static/chunks/2692-7fee6e06b3c93940.js +0 -1
- package/.next/static/chunks/2997-ec8b18227849683e.js +0 -1
- package/.next/static/chunks/6602-f26d109fd94cee1d.js +0 -4
- package/.next/static/chunks/9112-c37628abc8a164cd.js +0 -1
- package/.next/static/chunks/9690-53d5222618cbeddb.js +0 -1
- package/.next/static/chunks/app/(app)/agents/[handle]/page-83277413debb3b25.js +0 -1
- package/.next/static/chunks/app/(app)/code/page-1f954f7688bc24e4.js +0 -1
- package/.next/static/chunks/app/(app)/config/page-eee4f8736608afa5.js +0 -1
- package/.next/static/chunks/app/(app)/costs/page-0beac688917eaa30.js +0 -1
- package/.next/static/chunks/app/(app)/cron/page-a4dd65c78173b872.js +0 -1
- package/.next/static/chunks/app/(app)/dashboard/page-519a934ccfcce6fa.js +0 -1
- package/.next/static/chunks/app/(app)/docs/[id]/page-e29afa1ba1a086e1.js +0 -1
- package/.next/static/chunks/app/(app)/docs/page-b4462f9ca2118f8b.js +0 -1
- package/.next/static/chunks/app/(app)/github/page-cf8501e45fe38663.js +0 -1
- package/.next/static/chunks/app/(app)/goals/page-75c36155c162df5b.js +0 -1
- package/.next/static/chunks/app/(app)/inbox/page-f40bdb457609ddad.js +0 -12
- package/.next/static/chunks/app/(app)/knowledge/page-dc5dd15e4f0ad22e.js +0 -1
- package/.next/static/chunks/app/(app)/layout-408976a4d35f06a8.js +0 -1
- package/.next/static/chunks/app/(app)/models/page-a54e0b8ffed0085c.js +0 -1
- package/.next/static/chunks/app/(app)/notifications/page-1f84d74bc53c2c6c.js +0 -12
- package/.next/static/chunks/app/(app)/org/page-d17c62b7a668b399.js +0 -12
- package/.next/static/chunks/app/(app)/organizations/page-b55445f226cf8c61.js +0 -1
- package/.next/static/chunks/app/(app)/page-c7dd52ecc2da529d.js +0 -1
- package/.next/static/chunks/app/(app)/planner/page-920e439e6f88c238.js +0 -1
- package/.next/static/chunks/app/(app)/prepare-deploy/page-8d25f86b26ab0d2e.js +0 -1
- package/.next/static/chunks/app/(app)/profile/page-236673e1a8c1e6c6.js +0 -1
- package/.next/static/chunks/app/(app)/pulse/page-f2c6049a967b93a3.js +0 -1
- package/.next/static/chunks/app/(app)/reports/[id]/page-a4dd65c78173b872.js +0 -1
- package/.next/static/chunks/app/(app)/reports/page-5c07fa3a8b5ba553.js +0 -1
- package/.next/static/chunks/app/(app)/routines/page-0193e84e6a60a06a.js +0 -1
- package/.next/static/chunks/app/(app)/search/page-07e037c487f14c35.js +0 -1
- package/.next/static/chunks/app/(app)/security/page-71e5d992b5ddf79a.js +0 -1
- package/.next/static/chunks/app/(app)/tasks/page-5c9ca8f83d4c904f.js +0 -1
- package/.next/static/chunks/app/(app)/test-dev/page-5aee630d9bc73a0b.js +0 -1
- package/.next/static/chunks/app/(app)/update/page-2c9bcdb65bd2f597.js +0 -1
- package/.next/static/chunks/app/(auth)/login/page-50033813b56469ee.js +0 -1
- package/.next/static/chunks/app/(auth)/onboarding/page-075fd9673f7ab241.js +0 -1
- /package/.next/static/{vaEtsAmUuKf_DngRqwRUn → fb-rRThu8P8AXEQQBbLgT}/_buildManifest.js +0 -0
- /package/.next/static/{vaEtsAmUuKf_DngRqwRUn → fb-rRThu8P8AXEQQBbLgT}/_ssgManifest.js +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[72],{1171:(e,n,t)=>{Promise.resolve().then(t.bind(t,9173))},4055:(e,n,t)=>{"use strict";t.d(n,{Jv:()=>s,yK:()=>i});var a=t(5138),r=t(8618);let i=(0,a.M)({baseURL:window.location.origin,plugins:[(0,r.N)()]}),{signIn:s,signUp:l,signOut:o,useSession:c,twoFactor:d}=i},6816:(e,n,t)=>{"use strict";t.d(n,{J:()=>r});var a=t(5076);function r({size:e=34,rx:n=9}){return(0,a.jsxs)("svg",{width:e,height:e,viewBox:"0 0 100 100",style:{display:"block",flex:`0 0 ${e}px`},"aria-label":"Constella",children:[(0,a.jsx)("rect",{x:"1",y:"1",width:"98",height:"98",rx:n,fill:"var(--cs-bg)",stroke:"var(--cs-border)",strokeWidth:"1.5"}),(0,a.jsx)("path",{d:"M66.06 27.06 L42.75 22.95 L24.62 38.17 L24.62 61.83 L42.75 77.05 L66.06 72.94",fill:"none",stroke:"var(--cs-line)",strokeWidth:"2.1",strokeLinecap:"round",strokeLinejoin:"round"}),(0,a.jsx)("path",{d:"M48 50 L42.75 22.95 M48 50 L24.62 50 M48 50 L42.75 77.05",fill:"none",stroke:"var(--cs-line)",strokeWidth:"1.2",strokeLinecap:"round",opacity:"0.55"}),[[66.06,27.06],[42.75,22.95],[24.62,38.17],[24.62,61.83],[42.75,77.05],[66.06,72.94]].map((e,n)=>(0,a.jsx)("circle",{cx:e[0],cy:e[1],r:"3.1",fill:"var(--cs-node)"},n)),(0,a.jsx)("circle",{cx:"48",cy:"50",r:"8.5",fill:"var(--cs-glow)",opacity:"0.4"}),(0,a.jsx)("circle",{cx:"48",cy:"50",r:"4.3",fill:"var(--cs-core)"})]})}},7814:(e,n,t)=>{"use strict";Object.defineProperty(n,"__esModule",{value:!0});var a={callServer:function(){return i.callServer},createServerReference:function(){return l.createServerReference},findSourceMapURL:function(){return s.findSourceMapURL}};for(var r in a)Object.defineProperty(n,r,{enumerable:!0,get:a[r]});let i=t(3825),s=t(2617),l=t(5986)},9173:(e,n,t)=>{"use strict";t.d(n,{LoginForm:()=>f});var a=t(5076),r=t(8488),i=t(9860),s=t(2320),l=t(4055),o=t(7814);let c=(0,o.createServerReference)("400d7461b3ca3fd6964ccfe68c70dc7f79d72dba29",o.callServer,void 0,o.findSourceMapURL,"signupAction");var d=t(6816),u=t(8576),g=t(181),p=t(6824),h=t(5629);function f({screen:e,operatorEmail:n}){let t=(0,i.useRouter)(),o=(0,h.k)(),[m,y]=(0,r.useState)(e),[x,v]=(0,r.useState)(n),[j,b]=(0,r.useState)(""),[w,S]=(0,r.useState)(""),[k,N]=(0,r.useState)(""),[C,L]=(0,r.useState)(!1),[R,T]=(0,r.useState)(""),[z,E]=(0,r.useState)(""),[M,O]=(0,r.useState)(!1),[F,P]=(0,r.useState)("");function J(e){e?.twoFactorRedirect?O(!0):t.push("/")}async function _(){L(!0),T("");let e=await l.Jv.email({email:x,password:w});if(e.error){L(!1),T(o("login.invalidCredentials"));return}J(e.data),L(!1)}async function I(){if(T(""),w!==k)return void T(o("login.passwordMismatch"));L(!0);let e=await c({email:x,name:j,password:w});if(!e.ok){if(L(!1),"alreadyConfigured"===e.error){y("signin"),S(""),N(""),E(o("login.alreadyConfigured"));return}T(o("login.failed"));return}let n=await l.Jv.email({email:e.email,password:w});if(n.error){L(!1),T(o("login.failed"));return}J(n.data),L(!1)}async function B(){L(!0),T("");let e=await l.yK.twoFactor.verifyTotp({code:F});(L(!1),e.error)?T(e.error.message??o("login.invalidCode")):t.push("/")}async function K(){L(!0),T("");try{let e=await fetch("/api/passkey/authenticate/options",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({email:x})}).then(e=>e.json());if(e.error)throw Error(e.error);let n=await (0,s.HS)({optionsJSON:e}),a=await fetch("/api/passkey/authenticate/verify",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({response:n})}).then(e=>e.json());if(!a.ok)throw Error(a.error??o("login.passkeyFailed"));t.push("/")}catch(e){L(!1),T(e instanceof Error?e.message:o("login.passkeyFailed"))}}let W="signup"===m?o("login.signup.title"):o("login.title"),U="signup"===m?o("login.signup.sub"):o("login.sub.continue");return(0,a.jsxs)("div",{className:"login-wrap",children:[(0,a.jsx)("div",{className:"login-aurora","aria-hidden":!0,style:{position:"fixed",inset:0,zIndex:-1,pointerEvents:"none",background:"radial-gradient(60% 50% at 70% 20%, color-mix(in srgb, var(--accent) 18%, transparent), transparent 70%), radial-gradient(50% 40% at 20% 80%, color-mix(in srgb, #7c5cff 16%, transparent), transparent 70%)"}}),(0,a.jsxs)("div",{className:"login-card",children:[(0,a.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:12,marginBottom:18},children:[(0,a.jsx)(d.J,{size:46,rx:13}),(0,a.jsx)("span",{style:{fontSize:18,fontWeight:800},children:"Constella"}),(0,a.jsxs)("div",{style:{marginLeft:"auto",display:"flex",gap:8,alignItems:"center"},children:[(0,a.jsx)(p.LangSwitch,{}),(0,a.jsx)(g.AnimToggle,{})]})]}),(0,a.jsx)("h1",{style:{fontSize:24,fontWeight:800,marginBottom:6},children:W}),(0,a.jsx)("p",{className:"muted",style:{fontSize:13,marginBottom:16},children:U}),z&&(0,a.jsx)("p",{style:{color:"var(--accent)",fontSize:12.5,marginBottom:10},children:z}),M?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("label",{className:"form-label",children:o("login.authCode")}),(0,a.jsx)("input",{className:"form-input",placeholder:"123456",autoFocus:!0,value:F,onChange:e=>P(e.target.value),onKeyDown:e=>{"Enter"===e.key&&F.length>=6&&B()}}),R&&(0,a.jsx)("p",{style:{color:"var(--sx-keyword)",fontSize:12.5,marginTop:8},children:R}),(0,a.jsx)("button",{className:"btn-accent",style:{width:"100%",justifyContent:"center",marginTop:16,padding:11},disabled:C||F.length<6,onClick:B,children:C?o("login.verifying"):o("login.verify")})]}):"signup"===m?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("label",{className:"form-label",children:o("login.name")}),(0,a.jsx)("input",{className:"form-input",value:j,onChange:e=>b(e.target.value),placeholder:"Operator"}),(0,a.jsx)("label",{className:"form-label",children:o("login.email")}),(0,a.jsx)("input",{className:"form-input",value:x,onChange:e=>v(e.target.value)}),(0,a.jsx)("label",{className:"form-label",children:o("login.password")}),(0,a.jsx)("input",{className:"form-input",type:"password",value:w,onChange:e=>S(e.target.value),placeholder:"••••••••"}),(0,a.jsx)("label",{className:"form-label",children:o("login.confirmPassword")}),(0,a.jsx)("input",{className:"form-input",type:"password",value:k,onChange:e=>N(e.target.value),placeholder:"••••••••",onKeyDown:e=>{"Enter"===e.key&&w.length>=8&&k.length>=8&&I()}}),R&&(0,a.jsx)("p",{style:{color:"var(--sx-keyword)",fontSize:12.5,marginTop:8},children:R}),(0,a.jsx)("button",{className:"btn-accent",style:{width:"100%",justifyContent:"center",marginTop:12,padding:11},disabled:C||w.length<8||k.length<8,onClick:I,children:C?o("login.signingIn"):o("login.signup.button")})]}):(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("label",{className:"form-label",children:o("login.email")}),(0,a.jsx)("input",{className:"form-input",value:x,onChange:e=>v(e.target.value)}),(0,a.jsx)("label",{className:"form-label",children:o("login.password")}),(0,a.jsx)("input",{className:"form-input",type:"password",value:w,onChange:e=>S(e.target.value),onKeyDown:e=>{"Enter"===e.key&&w.length>=8&&_()}}),R&&(0,a.jsx)("p",{style:{color:"var(--sx-keyword)",fontSize:12.5,marginTop:8},children:R}),(0,a.jsx)("button",{className:"btn-accent",style:{width:"100%",justifyContent:"center",marginTop:12,padding:11},disabled:C||w.length<8,onClick:_,children:C?o("login.signingIn"):o("login.signin")}),(0,a.jsx)("button",{className:"btn-ghost",style:{width:"100%",justifyContent:"center",marginTop:8,padding:10},disabled:C,onClick:K,type:"button",children:o("login.passkey")})]}),(0,a.jsxs)("div",{className:"login-note",style:{display:"flex",alignItems:"center",gap:8,marginTop:16,fontSize:11.5,color:"var(--text-faint)"},children:[(0,a.jsx)(u.I,{name:"shield",size:13})," ",o("login.note")]})]})]})}},9860:(e,n,t)=>{"use strict";var a=t(2004);t.o(a,"usePathname")&&t.d(n,{usePathname:function(){return a.usePathname}}),t.o(a,"useRouter")&&t.d(n,{useRouter:function(){return a.useRouter}})}},e=>{e.O(0,[7555,2320,3219,6836,6646,6834,7358],()=>e(e.s=1171)),_N_E=e.O()}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[5134],{5629:(e,s,a)=>{"use strict";a.d(s,{LangProvider:()=>i,k:()=>c});var r=a(5076),t=a(8488),n=a(3219);let l=(0,t.createContext)("en");function i({lang:e,children:s}){return(0,r.jsx)(l.Provider,{value:e,children:s})}function c(){let e=(0,t.useContext)(l);return(s,a)=>(0,n.t)(e,s,a)}},6816:(e,s,a)=>{"use strict";a.d(s,{J:()=>t});var r=a(5076);function t({size:e=34,rx:s=9}){return(0,r.jsxs)("svg",{width:e,height:e,viewBox:"0 0 100 100",style:{display:"block",flex:`0 0 ${e}px`},"aria-label":"Constella",children:[(0,r.jsx)("rect",{x:"1",y:"1",width:"98",height:"98",rx:s,fill:"var(--cs-bg)",stroke:"var(--cs-border)",strokeWidth:"1.5"}),(0,r.jsx)("path",{d:"M66.06 27.06 L42.75 22.95 L24.62 38.17 L24.62 61.83 L42.75 77.05 L66.06 72.94",fill:"none",stroke:"var(--cs-line)",strokeWidth:"2.1",strokeLinecap:"round",strokeLinejoin:"round"}),(0,r.jsx)("path",{d:"M48 50 L42.75 22.95 M48 50 L24.62 50 M48 50 L42.75 77.05",fill:"none",stroke:"var(--cs-line)",strokeWidth:"1.2",strokeLinecap:"round",opacity:"0.55"}),[[66.06,27.06],[42.75,22.95],[24.62,38.17],[24.62,61.83],[42.75,77.05],[66.06,72.94]].map((e,s)=>(0,r.jsx)("circle",{cx:e[0],cy:e[1],r:"3.1",fill:"var(--cs-node)"},s)),(0,r.jsx)("circle",{cx:"48",cy:"50",r:"8.5",fill:"var(--cs-glow)",opacity:"0.4"}),(0,r.jsx)("circle",{cx:"48",cy:"50",r:"4.3",fill:"var(--cs-core)"})]})}},7111:(e,s,a)=>{"use strict";a.r(s),a.d(s,{default:()=>I});var r=a(5076),t=a(8488),n=a(9860),l=a(7814);let i=(0,l.createServerReference)("00536887303acc0e3e97ebf762573d54c8b90c22ac",l.callServer,void 0,l.findSourceMapURL,"operatorHasOrg"),c=(0,l.createServerReference)("40634c805da9328a750493c980590c2cc920b3c463",l.callServer,void 0,l.findSourceMapURL,"completeOnboarding"),o=new Set(["node_modules",".git",".next",".turbo","dist","build","out","coverage",".cache",".pnpm-store",".vercel","vendor",".parcel-cache",".svelte-kit",".nuxt",".astro",".angular",".venv","venv","env","__pycache__",".mypy_cache",".pytest_cache",".ruff_cache",".tox",".nox","htmlcov","site-packages",".eggs",".ipynb_checkpoints","target",".gradle","bin","obj","Pods",".cargo","Carthage",".cxx","DerivedData",".idea",".vscode",".svn",".hg",".vs",".fleet","logs","tmp","temp",".terraform","archives",".testdev"]),d=/\.(py|pyi|pyw|js|jsx|ts|tsx|mjs|cjs|mts|cts|json|jsonc|html?|css|scss|sass|less|styl|md|markdown|mdx|txt|rst|yml|yaml|toml|ini|cfg|conf|env|example|sample|sh|bash|zsh|bat|cmd|ps1|sql|graphql|gql|prisma|xml|svg|vue|svelte|astro|go|rs|java|kt|kts|scala|clj|rb|erb|php|blade|c|h|cpp|cc|hpp|cs|fs|swift|m|mm|dart|lua|r|ex|exs|erl|hrl|gradle|properties|lock|proto|tf|tfvars|dockerfile|dockerignore|gitignore|gitattributes|editorconfig|prettierrc|eslintrc|babelrc|npmrc|nvmrc|browserslistrc)$/i,h=new Set(["dockerfile","makefile","procfile","rakefile","gemfile","brewfile","vagrantfile","license","licence","readme","changelog","authors","contributors","notice","codeowners"]),g=(0,l.createServerReference)("404920b51041e53b84201a4d0bd807d856749255dc",l.callServer,void 0,l.findSourceMapURL,"githubReposForToken"),x=(0,l.createServerReference)("00e5057490125e95f92cedacb91e5b099809903a5e",l.callServer,void 0,l.findSourceMapURL,"checkSetupEnv"),u=(0,l.createServerReference)("40f0ba4e8fc146f8d07c593b31cf3f0d2abc34ae89",l.callServer,void 0,l.findSourceMapURL,"checkAdapter"),m=(0,l.createServerReference)("40ac5945bee33a412fb41ae16eed87dfe54514519f",l.callServer,void 0,l.findSourceMapURL,"testConnection"),p=(0,l.createServerReference)("60b95a553e80554da66940990613b1c1dc80001c4c",l.callServer,void 0,l.findSourceMapURL,"probeModel"),j=(0,l.createServerReference)("009dd80a9ca45e3c95bbf131e7c42bd29936283bab",l.callServer,void 0,l.findSourceMapURL,"detectProviders");var b=a(8088),v=a(3730);let f={TypeScript:{slug:"typescript"},JavaScript:{slug:"javascript"},Python:{slug:"python"},Go:{slug:"go",variant:"original-wordmark"},Rust:{slug:"rust"},Java:{slug:"java"},Kotlin:{slug:"kotlin"},"C#":{slug:"csharp"},Ruby:{slug:"ruby"},PHP:{slug:"php"},Elixir:{slug:"elixir"},Swift:{slug:"swift"},"C++":{slug:"cplusplus"},Scala:{slug:"scala"},Dart:{slug:"dart"},C:{slug:"c"},Clojure:{slug:"clojure"},Haskell:{slug:"haskell"},Lua:{slug:"lua"},R:{slug:"r"},"Objective-C":{slug:"objectivec"},Erlang:{slug:"erlang",variant:"plain"},"Node.js":{slug:"nodejs"},Bun:{slug:"bun"},Deno:{slug:"denojs"},"Python 3":{slug:"python"},JVM:{slug:"java"},".NET":{slug:"dotnetcore"},"BEAM (Erlang VM)":{slug:"erlang",variant:"plain"},React:{slug:"react"},Vue:{slug:"vuejs"},Svelte:{slug:"svelte"},Angular:{slug:"angular"},SolidJS:{slug:"solidjs"},"Alpine.js":{slug:"alpinejs"},Ember:{slug:"ember"},Backbone:{slug:"backbonejs"},"HTML/CSS":{slug:"html5"},"Vanilla JS":{slug:"javascript"},"Plain CSS":{slug:"css3"},"Next.js":{slug:"nextjs"},Nuxt:{slug:"nuxtjs"},Remix:{slug:"remix"},SvelteKit:{slug:"svelte"},Astro:{slug:"astro"},Gatsby:{slug:"gatsby"},"Vite (SPA)":{slug:"vitejs"},Hugo:{slug:"hugo"},Jekyll:{slug:"jekyll",variant:"original-wordmark"},NestJS:{slug:"nestjs"},Fastify:{slug:"fastify"},Express:{slug:"express"},Koa:{slug:"koa"},Django:{slug:"django",variant:"plain"},Flask:{slug:"flask"},FastAPI:{slug:"fastapi"},"Spring Boot":{slug:"spring"},Spring:{slug:"spring"},Laravel:{slug:"laravel"},"Ruby on Rails":{slug:"rails"},Gin:{slug:"go",variant:"original-wordmark"},Phoenix:{slug:"phoenix"},"ASP.NET Core":{slug:"dotnetcore"},Nginx:{slug:"nginx"},GraphQL:{slug:"graphql"},Symfony:{slug:"symfony"},CodeIgniter:{slug:"codeigniter"},PostgreSQL:{slug:"postgresql"},MySQL:{slug:"mysql"},MariaDB:{slug:"mariadb"},SQLite:{slug:"sqlite"},MongoDB:{slug:"mongodb"},Redis:{slug:"redis"},Cassandra:{slug:"cassandra"},DynamoDB:{slug:"dynamodb"},Supabase:{slug:"supabase"},Prisma:{slug:"prisma"},Sequelize:{slug:"sequelize"},SQLAlchemy:{slug:"sqlalchemy"},"Tailwind CSS":{slug:"tailwindcss"},"CSS Modules":{slug:"css3"},Sass:{slug:"sass"},MUI:{slug:"materialui"},Bootstrap:{slug:"bootstrap"},Bulma:{slug:"bulma"},Vuetify:{slug:"vuetify"},Docker:{slug:"docker"},Podman:{slug:"podman"},Vercel:{slug:"vercel"},Netlify:{slug:"netlify"},AWS:{slug:"amazonwebservices",variant:"original-wordmark"},GCP:{slug:"googlecloud"},Kubernetes:{slug:"kubernetes"},Azure:{slug:"azure"},Jenkins:{slug:"jenkins"},CircleCI:{slug:"circleci",variant:"plain"},Terraform:{slug:"terraform"},Ansible:{slug:"ansible"},Vagrant:{slug:"vagrant"},RabbitMQ:{slug:"rabbitmq"},Kafka:{slug:"apachekafka"},Auth0:{slug:"auth0",variant:"plain"},Keycloak:{slug:"keycloak"},"React Native":{slug:"react"},Flutter:{slug:"flutter"},Android:{slug:"android"},Ionic:{slug:"ionic"},Xamarin:{slug:"xamarin"},NativeScript:{slug:"nativescript"},TensorFlow:{slug:"tensorflow"},PyTorch:{slug:"pytorch"},"scikit-learn":{slug:"scikitlearn"},Pandas:{slug:"pandas"},NumPy:{slug:"numpy"},Jupyter:{slug:"jupyter"},Jest:{slug:"jest"},Vitest:{slug:"vitest"},Cypress:{slug:"cypressio"},Playwright:{slug:"playwright"},Selenium:{slug:"selenium"},Mocha:{slug:"mocha"},Jasmine:{slug:"jasmine"},Puppeteer:{slug:"puppeteer"},D3:{slug:"d3js"},Grafana:{slug:"grafana"},Firebase:{slug:"firebase"},Appwrite:{slug:"appwrite"},Heroku:{slug:"heroku"}};var y=a(9562),k=a(973),M=a(6816),N=a(8576),S=a(3728),w=a(9265),C=a(5629);let z=["company","ceoModel","connection","stack","brief"];function L({name:e}){let s,a=(s=f[e])?`https://cdn.jsdelivr.net/gh/devicons/devicon/icons/${s.slug}/${s.slug}-${s.variant??"original"}.svg`:null,[n,l]=(0,t.useState)(!1);return!a||n?(0,r.jsx)("span",{className:"sc-mono",children:e.replace(/[^A-Za-z0-9]/g,"").slice(0,2)}):(0,r.jsx)("img",{className:"sc-ico",src:a,alt:"",loading:"lazy",onError:()=>l(!0)})}function F({stack:e,onPick:s,query:a,setQuery:t}){let n=(0,C.k)(),l=a.trim().toLowerCase(),i=l?v.z.flatMap(s=>s.opts.filter(e=>"None"!==e&&(e.toLowerCase().includes(l)||s.label.toLowerCase().includes(l))).map(a=>({cat:s,o:a,bad:(0,y.YL)(e,s.key,a)}))).slice(0,16):[];return(0,r.jsxs)("div",{className:"stack-search-wrap",children:[(0,r.jsxs)("div",{className:"stack-search",children:[(0,r.jsx)(N.I,{name:"search",size:15}),(0,r.jsx)("input",{placeholder:n("onboarding.stackSearchPh"),value:a,onChange:e=>t(e.target.value)}),a&&(0,r.jsx)("button",{className:"ss-clear",onClick:()=>t(""),children:(0,r.jsx)(N.I,{name:"close",size:13})})]}),l&&i.length>0&&(0,r.jsx)("div",{className:"stack-find scroll",children:i.map(({cat:a,o:t,bad:n})=>(0,r.jsxs)("button",{type:"button",className:"stack-find-row"+(n?" disabled":""),disabled:!!n,title:n||(0,v.f)(a.key,t),onClick:()=>{n||s(a.key,t)},children:[(0,r.jsx)(L,{name:t}),(0,r.jsx)("span",{className:"sf-name",children:t}),(0,r.jsx)("span",{className:"sf-cat",children:a.label}),(0,k.Hn)(e[a.key],t)&&(0,r.jsx)(N.I,{name:"check",size:13})]},a.key+t))}),l&&0===i.length&&(0,r.jsx)("div",{className:"stack-find sf-empty",children:n("onboarding.stackNoMatch",{query:a})})]})}function P({step:e}){let s=(0,C.k)();return(0,r.jsx)("div",{className:"onb-steps",children:z.map((a,t)=>(0,r.jsxs)("span",{style:{display:"contents"},children:[t>0&&(0,r.jsx)("span",{className:"onb-sep"}),(0,r.jsxs)("div",{className:"onb-stepdot"+(e===t?" on":e>t?" done":""),children:[(0,r.jsx)("span",{className:"num",children:e>t?"✓":t+1}),(0,r.jsx)("span",{children:s(`onboarding.step.${a}`)})]})]},a))})}function R({adapter:e,model:s,cached:a,onDone:n}){let l=(0,C.k)(),i=[{t:l("onboarding.test.prepare"),d:l("onboarding.test.prepareDesc")},{t:l("onboarding.test.adapter"),d:l("onboarding.test.adapterDesc",{adapter:e})},{t:l("onboarding.test.connection"),d:l("onboarding.test.connectionDesc")},{t:l("onboarding.test.model",{model:s}),d:l("onboarding.test.modelDesc")},{t:l("onboarding.test.ready"),d:l("onboarding.test.readyDesc")}],[c,o]=(0,t.useState)(a?i.length:0),[d,h]=(0,t.useState)(null),[g,j]=(0,t.useState)(null);return(0,t.useEffect)(()=>{if(a)return void o(i.length);let r=!0;return h(null),j(null),(async()=>{let a=[()=>x(),()=>u(e),()=>m(e),()=>p(e,s)];for(let e=0;e<a.length;e++){if(!r)return;o(e);let s=await a[e]();if(!r)return;if(!s.ok){h(e),j(s.error??l("onboarding.test.failed")),n(!1);return}o(e+1)}r&&(o(i.length),n(!0))})(),()=>{r=!1}},[a]),(0,r.jsx)("div",{className:"track",children:i.map((e,s)=>{let a=d===s,t=a?"":s<c?"done":s===c?"on":"todo";return(0,r.jsxs)("div",{className:"track-step "+t,children:[(0,r.jsx)("div",{className:"track-ico",children:a?(0,r.jsx)(N.I,{name:"close",size:15}):"done"===t?(0,r.jsx)(N.I,{name:"check",size:16}):"on"===t?(0,r.jsx)("span",{className:"spin",children:(0,r.jsx)(N.I,{name:"refresh",size:15})}):(0,r.jsx)(N.I,{name:"dot",size:8})}),(0,r.jsxs)("div",{className:"track-main",children:[(0,r.jsx)("div",{className:"track-t",children:e.t}),(0,r.jsx)("div",{className:"track-d",children:a?g:e.d})]})]},s)})})}function I(){let e=(0,n.useRouter)(),s=(0,C.k)(),[a,l]=(0,t.useState)(0),[x,u]=(0,t.useState)(!1);(0,t.useEffect)(()=>{i().then(u).catch(()=>{})},[]);let[m,p]=(0,t.useState)(""),[f,z]=(0,t.useState)(""),[I,H]=(0,t.useState)(""),[A,V]=(0,t.useState)([]),[T,D]=(0,t.useState)(""),[$,q]=(0,t.useState)(""),[_,E]=(0,t.useState)({}),[J,U]=(0,t.useState)(""),[B,W]=(0,t.useState)(""),[O,Q]=(0,t.useState)("You are Ada, the CEO of this company. Plan before building: analyse the brief, design the architecture and rituals, then organise the team."),[K,G]=(0,t.useState)(""),[Y,X]=(0,t.useState)(""),[Z,ee]=(0,t.useState)([]),[es,ea]=(0,t.useState)(!1),[er,et]=(0,t.useState)(""),[en,el]=(0,t.useState)("new"),[ei,ec]=(0,t.useState)(""),[eo,ed]=(0,t.useState)(""),[eh,eg]=(0,t.useState)([]),[ex,eu]=(0,t.useState)(""),[em,ep]=(0,t.useState)(!1),[ej,eb]=(0,t.useState)(""),[ev,ef]=(0,t.useState)([]),[ey,ek]=(0,t.useState)(""),[eM,eN]=(0,t.useState)(""),[eS,ew]=(0,t.useState)(!1),[eC,ez]=(0,t.useState)(0),[eL,eF]=(0,t.useState)(0),[eP,eR]=(0,t.useState)("");async function eI(){ep(!0),eb("");try{let e=await g(ei);if(!e.ok){eb(e.error??s("onboarding.src.listReposFailed")),eg([]);return}ed(e.login??""),eg(e.repos??[]),e.repos?.[0]&&eu(e.repos[0].full)}finally{ep(!1)}}async function eH(e){var a;let r;if(!e||!e.length)return;ew(!0),ez(0),eb(""),ef([]),eN("");let t=Array.from(e),n=(t[0].webkitRelativePath||t[0].name).split("/")[0]||"project",l=t.filter(e=>{var s;let a=(e.webkitRelativePath||e.name).split("/");for(let e=1;e<a.length-1;e++)if(s=a[e],o.has(s))return!1;let r=a[a.length-1];return!/^\.env(\.local|\.development|\.production)?$/i.test(r)&&".DS_Store"!==r&&!!(d.test(r)||h.has(r.toLowerCase()))&&!(e.size>524288)});if(!l.length){ew(!1),eb(s("onboarding.src.noFiles"));return}let i=[];for(let e=0;e<l.length;e++){let s=l[e],a=(s.webkitRelativePath||s.name).split("/").slice(1).join("/");if(a)try{i.push({path:a,content:await s.text()})}catch{}(e%5==0||e===l.length-1)&&ez(Math.round((e+1)/l.length*100))}ef(i),ek(n),eN((a=i.map(e=>e.path),(r=e=>a.some(s=>e.test(s)))(/(^|\/)manage\.py$/)?"Django (Python)":r(/(^|\/)next\.config\.(js|mjs|ts)$/)?"Next.js":r(/\.vue$/)?"Vue":r(/(^|\/)go\.mod$/)?"Go":r(/(^|\/)Cargo\.toml$/i)?"Rust":r(/(^|\/)pom\.xml$/)||r(/(^|\/)build\.gradle/)?"JVM":r(/(^|\/)composer\.json$/)?"PHP":r(/\.py$/)?"Python":r(/(^|\/)package\.json$/)?"Node":"")),ew(!1)}let eA="new"===en||"github"===en&&!!ex||"local"===en&&ev.length>0;async function eV(e){if(!e)return;let s=/\.(html?|css|jsx?|tsx?|md|txt|json|svg)$/i,a=[];for(let r of Array.from(e).slice(0,120)){let e=(r.webkitRelativePath||r.name).replace(/^\/+/,"");if(s.test(e)&&!(r.size>262144))try{a.push({path:e,content:await r.text()})}catch{}}ee(a)}let[eT,eD]=(0,t.useState)(!1),[e$,eq]=(0,t.useState)(""),[e_,eE]=(0,t.useState)(""),[eJ,eU]=(0,t.useState)(""),[eB,eW]=(0,t.useTransition)();(0,t.useEffect)(()=>{j().then(({detected:e})=>{V(e),e[0]&&(D(e[0].id),q(e[0].models[0]??""))})},[]),(0,t.useEffect)(()=>{if(!eB)return void eF(0);eF(8);let e=setInterval(()=>eF(e=>e<92?e+Math.max(1,Math.round((92-e)/12)):e),400);return()=>clearInterval(e)},[eB]);let eO=A.find(e=>e.id===T),eQ=eO?.adapter??"",eK=eQ+":"+$,eG=es&&er===eK,eY=(0,y.hP)(_);function eX(e,s){let a=(0,y.T1)({..._,[e]:(0,k.P_)(_[e],s)});E(a.stack),W(a.removed.map(e=>`${e.opt} was unselected automatically — ${e.reason}.`).join(" "))}return(0,r.jsxs)("div",{className:"onb",children:[(0,r.jsxs)("div",{className:"onb-top",children:[(0,r.jsxs)("div",{className:"onb-brand",children:[(0,r.jsx)(M.J,{size:34,rx:9}),(0,r.jsx)("div",{className:"bw",children:"Constella"})]}),(0,r.jsx)(P,{step:a}),x&&(0,r.jsx)("button",{className:"onb-close",title:s("onboarding.closeSetup"),"aria-label":s("onboarding.closeSetup"),onClick:()=>e.push("/"),children:(0,r.jsx)(N.I,{name:"close",size:16})})]}),(0,r.jsx)("div",{className:"onb-body",children:(0,r.jsxs)("div",{className:"onb-card"+(3===a?" onb-card-wide":""),children:[0===a&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("div",{className:"onb-h",children:s("onboarding.company.h")}),(0,r.jsx)("div",{className:"onb-sub",style:{marginBottom:14},children:s("onboarding.company.sub")}),(0,r.jsxs)("div",{className:"persona-field",children:[(0,r.jsxs)("label",{className:"form-label",children:[s("onboarding.company.nameLabel")," ",(0,r.jsx)("span",{className:"req",children:"*"})]}),(0,r.jsx)("input",{className:"form-input",required:!0,autoFocus:!0,value:m,onChange:e=>p(e.target.value),placeholder:s("onboarding.company.namePh")})]}),(0,r.jsxs)("div",{className:"persona-field",children:[(0,r.jsxs)("label",{className:"form-label",children:[s("onboarding.company.missionLabel")," ",(0,r.jsx)("span",{className:"req",children:"*"})]}),(0,r.jsx)("textarea",{className:"persona-ta",required:!0,value:f,onChange:e=>z(e.target.value),placeholder:s("onboarding.company.missionPh")})]}),(0,r.jsxs)("div",{className:"persona-field",children:[(0,r.jsxs)("label",{className:"form-label",children:[s("onboarding.company.objectiveLabel")," ",(0,r.jsx)("span",{className:"req",children:"*"})]}),(0,r.jsx)("textarea",{className:"persona-ta",required:!0,value:I,onChange:e=>H(e.target.value),placeholder:s("onboarding.company.objectivePh")})]}),(0,r.jsx)("div",{className:"onb-foot",children:(0,r.jsxs)("button",{className:"btn-accent",disabled:!m.trim()||!f.trim()||!I.trim(),onClick:()=>l(1),children:[s("common.next")," ",(0,r.jsx)(N.I,{name:"chevronRight",size:13})]})})]}),1===a&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("div",{className:"onb-h",children:s("onboarding.brain.h")}),(0,r.jsx)("div",{className:"onb-sub",children:s("onboarding.brain.sub")}),(0,r.jsxs)("div",{className:"onb-secrow",children:[(0,r.jsx)("span",{className:"osr-t",children:s("onboarding.brain.detected")}),(0,r.jsx)("span",{className:"osr-line"})]}),(0,r.jsxs)("div",{className:"prov-cards",children:[A.map(e=>(0,r.jsxs)("div",{className:"prov-card "+("local"===e.kind?"local-card":"cloud-card")+(T===e.id?" on":""),onClick:()=>{D(e.id),q(e.models[0]??"")},children:[(0,r.jsx)("span",{className:"pc-badge",children:s(`onboarding.kind.${e.kind}`)}),(0,r.jsx)(w.W,{id:e.id,size:42}),(0,r.jsx)("div",{className:"pc-name",children:e.name}),(0,r.jsx)("div",{className:"pc-sub",children:e.adapter})]},e.id)),0===A.length&&(0,r.jsx)("div",{className:"muted",style:{fontSize:12.5,padding:12},children:s("onboarding.brain.detecting")})]}),(0,r.jsxs)("button",{className:"btn-ghost",style:{marginTop:10},onClick:()=>eD(e=>!e),children:[(0,r.jsx)(N.I,{name:"add",size:13})," ",s("onboarding.brain.registerToggle")]}),eT&&(0,r.jsxs)("div",{className:"card",style:{marginTop:10},children:[(0,r.jsx)("div",{className:"detail-label",children:s("onboarding.brain.registerTitle")}),(0,r.jsx)(S.m,{value:e$,placeholder:s("onboarding.brain.chooseProvider"),options:b.WQ.filter(e=>"unsupported"!==e.status).map(e=>({value:e.id,label:e.displayName,glyphId:e.id})),onChange:eq,glyph:!0}),(0,r.jsxs)("div",{className:"set-grid",style:{marginTop:8},children:[(0,r.jsx)("input",{className:"form-input mono",placeholder:s("onboarding.brain.modelIdPh"),value:eJ,onChange:e=>eU(e.target.value)}),(0,r.jsx)("input",{className:"form-input mono",type:"password",placeholder:s("onboarding.brain.apiKeyPh"),value:e_,onChange:e=>eE(e.target.value)})]}),(0,r.jsxs)("div",{style:{display:"flex",justifyContent:"flex-end",gap:8,marginTop:10},children:[(0,r.jsx)("button",{className:"btn-ghost",onClick:()=>eD(!1),children:s("common.cancel")}),(0,r.jsxs)("button",{className:"btn-accent",disabled:!e$,onClick:function(){let e=b.WQ.find(e=>e.id===e$);if(!e)return;let s={id:e.id,name:e.displayName,adapter:e.defaultAdapter,kind:"cli"===e.category?"cli":"local_runtime"===e.category?"local":"cloud",models:eJ.trim()?[eJ.trim()]:[]};V(e=>e.find(e=>e.id===s.id)?e:[...e,s]),D(s.id),q(eJ.trim()||""),eD(!1)},children:[(0,r.jsx)(N.I,{name:"check",size:13})," ",s("onboarding.brain.addSelect")]})]})]}),eO&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{className:"onb-secrow",children:[(0,r.jsx)("span",{className:"osr-t",children:s("onboarding.brain.modelFor",{name:eO.name})}),(0,r.jsx)("span",{className:"osr-line"})]}),(0,r.jsx)(S.m,{mono:!0,value:$,options:eO.models.map(e=>({value:e,label:e})),onChange:q})]}),(0,r.jsxs)("div",{className:"onb-foot",children:[(0,r.jsxs)("button",{className:"btn-ghost",onClick:()=>l(0),children:[(0,r.jsx)(N.I,{name:"chevronLeft",size:13})," ",s("common.back")]}),(0,r.jsxs)("button",{className:"btn-accent",disabled:!eO||!$,onClick:()=>l(2),children:[s("common.next")," ",(0,r.jsx)(N.I,{name:"chevronRight",size:13})]})]})]}),2===a&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("div",{className:"onb-h",children:s("onboarding.setup.h")}),(0,r.jsxs)("div",{className:"onb-sub",children:[s("onboarding.setup.sub")," ",(0,r.jsx)("b",{style:{color:"var(--text)"},children:eQ})," \xb7 ",(0,r.jsx)("b",{style:{color:"var(--text)"},children:$}),"."]}),(0,r.jsx)(R,{adapter:eQ,model:$,cached:eG,onDone:e=>{ea(e),et(eK)}}),(0,r.jsxs)("div",{className:"onb-foot",children:[(0,r.jsxs)("button",{className:"btn-ghost",onClick:()=>l(1),children:[(0,r.jsx)(N.I,{name:"chevronLeft",size:13})," ",s("common.back")]}),(0,r.jsx)("button",{className:"btn-accent",disabled:!eG,onClick:()=>l(3),children:eG?(0,r.jsxs)(r.Fragment,{children:[s("onboarding.setup.continue")," ",(0,r.jsx)(N.I,{name:"chevronRight",size:13})]}):s("onboarding.setup.testing")})]})]}),3===a&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("div",{className:"onb-h",children:s("onboarding.stack.h")}),(0,r.jsx)("div",{className:"onb-sub",children:s("onboarding.stack.sub")}),eY&&(0,r.jsxs)("div",{className:"modal-hint",style:{color:"var(--sx-number)"},children:[(0,r.jsx)(N.I,{name:"pulse",size:12})," ",eY]}),B&&(0,r.jsxs)("div",{className:"modal-hint",style:{color:"var(--sx-keyword)"},children:[(0,r.jsx)(N.I,{name:"warn",size:12})," ",B]}),(0,r.jsx)(F,{stack:_,onPick:eX,query:J,setQuery:U}),v.z.map(e=>(0,r.jsxs)("div",{className:"stack-cat",children:[(0,r.jsxs)("div",{className:"onb-secrow",children:[(0,r.jsx)("span",{className:"osr-t",children:e.label}),(0,r.jsx)("span",{className:"osr-pick",children:_[e.key]||"—"}),(0,r.jsx)("span",{className:"osr-line"})]}),(0,r.jsx)("div",{className:"stack-cards",children:e.opts.map(s=>{let a=(0,y.YL)(_,e.key,s),t=(0,k.Hn)(_[e.key],s);return(0,r.jsxs)("button",{className:"stack-card"+(t?" on":"")+(a?" disabled":""),disabled:!!a&&!t,title:a||(0,v.f)(e.key,s),onClick:()=>!a&&eX(e.key,s),children:[(0,r.jsx)(L,{name:s}),(0,r.jsx)("span",{className:"sc-name",children:s}),t&&(0,r.jsx)("span",{className:"sc-check",children:(0,r.jsx)(N.I,{name:"check",size:12})})]},s)})})]},e.key)),(0,r.jsxs)("div",{className:"onb-foot",children:[(0,r.jsxs)("button",{className:"btn-ghost",onClick:()=>l(2),children:[(0,r.jsx)(N.I,{name:"chevronLeft",size:13})," ",s("common.back")]}),(0,r.jsxs)("button",{className:"btn-accent",onClick:()=>l(4),children:[s("common.next")," ",(0,r.jsx)(N.I,{name:"chevronRight",size:13})]})]})]}),4===a&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("div",{className:"onb-h",children:s("onboarding.brief.h")}),(0,r.jsx)("div",{className:"onb-sub",children:s("onboarding.brief.sub")}),(0,r.jsxs)("div",{className:"persona-field",children:[(0,r.jsx)("label",{className:"form-label",children:s("onboarding.brief.sourceLabel")}),(0,r.jsx)("div",{className:"src-cards",children:["new","github","local"].map(e=>(0,r.jsxs)("button",{type:"button",className:"src-card"+(en===e?" on":""),onClick:()=>{el(e),eb("")},children:[(0,r.jsx)(N.I,{name:"new"===e?"add":"github"===e?"git":"files",size:18}),(0,r.jsx)("div",{className:"src-t",children:s(`onboarding.src.${e}.t`)}),(0,r.jsx)("div",{className:"src-d",children:s(`onboarding.src.${e}.d`)})]},e))}),"github"===en&&(0,r.jsxs)("div",{className:"card",style:{marginTop:10,display:"grid",gap:8},children:[(0,r.jsxs)("div",{style:{display:"flex",gap:8},children:[(0,r.jsx)("input",{className:"form-input mono",type:"password",placeholder:s("onboarding.src.tokenPh"),value:ei,onChange:e=>ec(e.target.value)}),(0,r.jsx)("button",{className:"btn-ghost",disabled:em||ei.trim().length<7,onClick:eI,children:em?"…":s("onboarding.src.listRepos")})]}),eh.length>0&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{className:"form-hint",children:[eo&&(0,r.jsxs)(r.Fragment,{children:[s("onboarding.src.signedInAs")," ",(0,r.jsx)("b",{children:eo})," \xb7 "]}),s("onboarding.src.pickRepo")]}),(0,r.jsx)(S.m,{value:ex,options:eh.map(e=>({value:e.full,label:e.full,tag:e.private?s("onboarding.src.private"):s("onboarding.src.public")})),onChange:eu})]})]}),"local"===en&&(0,r.jsxs)("div",{className:"card",style:{marginTop:10,display:"grid",gap:8},children:[(0,r.jsxs)("label",{className:"btn-ghost",style:{cursor:eS?"default":"pointer",justifyContent:"center"},children:[(0,r.jsx)(N.I,{name:"grid",size:14})," ",eS?s("onboarding.src.reading"):ev.length>0?s("onboarding.src.chooseAnother"):s("onboarding.src.chooseFolder"),(0,r.jsx)("input",{type:"file",hidden:!0,webkitdirectory:"",directory:"",multiple:!0,disabled:eS,onChange:e=>eH(e.target.files)})]}),eS&&(0,r.jsxs)("div",{children:[(0,r.jsx)("div",{style:{height:6,borderRadius:999,background:"var(--bg-active)",overflow:"hidden"},children:(0,r.jsx)("div",{style:{height:"100%",width:eC+"%",background:"var(--accent)",transition:"width .2s"}})}),(0,r.jsx)("div",{className:"form-hint",children:s("onboarding.src.readingPct",{pct:eC})})]}),!eS&&ev.length>0&&(0,r.jsxs)("div",{className:"form-hint",style:{color:"var(--sx-string)"},children:[(0,r.jsx)(N.I,{name:"check",size:12})," ",s(1===ev.length?"onboarding.src.imported.one":"onboarding.src.imported.other",{n:ev.length,name:ey}),eM&&(0,r.jsxs)(r.Fragment,{children:[" \xb7 ",(0,r.jsx)("b",{style:{color:"var(--text)"},children:eM})]})]})]}),ej&&(0,r.jsx)("div",{style:{fontSize:11.5,color:"#e8688f",marginTop:6},children:ej}),(0,r.jsxs)("div",{className:"form-hint",children:[(0,r.jsx)(N.I,{name:"bot",size:12})," ",s("onboarding.src.analyseHint")]})]}),(0,r.jsxs)("div",{className:"persona-field",children:[(0,r.jsxs)("label",{className:"form-label",children:[s("onboarding.brief.systemPrompt")," ",(0,r.jsx)("span",{className:"req",children:"*"})]}),(0,r.jsx)("textarea",{className:"persona-ta mono",required:!0,value:O,onChange:e=>Q(e.target.value)})]}),(0,r.jsxs)("div",{className:"persona-field",children:[(0,r.jsxs)("label",{className:"form-label",children:[s("onboarding.brief.projectBrief")," ",(0,r.jsxs)("span",{style:{color:"var(--text-faint)",fontWeight:400},children:["\xb7 ",s("onboarding.brief.optional")]})]}),(0,r.jsx)("textarea",{className:"persona-ta mono",style:{minHeight:110},placeholder:s("onboarding.brief.briefPh"),value:Y,onChange:e=>{X(e.target.value),!K&&e.target.value&&G("project-brief.md")}})]}),(0,r.jsxs)("div",{className:"persona-field",children:[(0,r.jsxs)("label",{className:"form-label",children:[s("onboarding.brief.attachMock")," ",(0,r.jsxs)("span",{style:{color:"var(--text-faint)",fontWeight:400},children:["\xb7 ",s("onboarding.brief.optional")," \xb7 HTML, CSS, JS, MD"]})]}),(0,r.jsxs)("div",{style:{display:"flex",gap:8,flexWrap:"wrap",alignItems:"center"},children:[(0,r.jsxs)("label",{className:"btn-ghost",style:{cursor:"pointer"},children:[(0,r.jsx)(N.I,{name:"doc",size:13})," ",s("onboarding.brief.files"),(0,r.jsx)("input",{type:"file",multiple:!0,hidden:!0,onChange:e=>eV(e.target.files)})]}),(0,r.jsxs)("label",{className:"btn-ghost",style:{cursor:"pointer"},children:[(0,r.jsx)(N.I,{name:"grid",size:13})," ",s("onboarding.brief.folder"),(0,r.jsx)("input",{type:"file",hidden:!0,webkitdirectory:"",directory:"",multiple:!0,onChange:e=>eV(e.target.files)})]}),Z.length>0&&(0,r.jsxs)("span",{className:"chip-sm",style:{display:"inline-flex",alignItems:"center",gap:6},children:[(0,r.jsx)(N.I,{name:"check",size:12})," ",s(1===Z.length?"onboarding.brief.filesAttached.one":"onboarding.brief.filesAttached.other",{n:Z.length}),(0,r.jsx)("button",{className:"link-btn",style:{marginLeft:4},onClick:()=>ee([]),children:(0,r.jsx)(N.I,{name:"close",size:11})})]})]}),(0,r.jsxs)("div",{className:"form-hint",children:[(0,r.jsx)(N.I,{name:"bot",size:12})," ",s("onboarding.brief.mockHintPre")," ",(0,r.jsx)("span",{className:"mono",children:"mock/"})," ",s("onboarding.brief.mockHintPost")]})]}),eB&&(0,r.jsxs)("div",{style:{marginTop:12},children:[(0,r.jsx)("div",{style:{height:6,borderRadius:999,background:"var(--bg-active)",overflow:"hidden"},children:(0,r.jsx)("div",{style:{height:"100%",width:eL+"%",background:"var(--accent)",transition:"width .3s"}})}),(0,r.jsxs)("div",{className:"form-hint",children:[s("onboarding.src.settingUp")," ",eL,"%"]})]}),eP&&(0,r.jsxs)("div",{className:"form-hint",style:{color:"var(--sx-keyword)",marginTop:10},children:[(0,r.jsx)(N.I,{name:"close",size:12})," ",eP]}),(0,r.jsxs)("div",{className:"onb-foot",children:[(0,r.jsxs)("button",{className:"btn-ghost",disabled:eB,onClick:()=>l(3),children:[(0,r.jsx)(N.I,{name:"chevronLeft",size:13})," ",s("common.back")]}),(0,r.jsxs)("button",{className:"btn-accent",disabled:eB||!O.trim()||!eA,onClick:function(){let e="github"===en?{type:"github",pat:ei,repoFull:ex,branch:eh.find(e=>e.full===ex)?.branch,login:eo||void 0}:"local"===en?{type:"local",rootName:ey,files:ev}:{type:"new"};eR(""),eW(async()=>{try{let s=await c({company:m,mission:f,objective:I,stack:_,provider:eQ,model:$,systemPrompt:O,briefText:Y,briefName:K,mockFiles:Z,source:e,providerCatalogId:T||void 0,providerKey:e$&&e$===T&&e_?e_:void 0});if(s&&!s.ok)return void eR(s.error||"Setup didn't complete — please try again.");eF(100),window.location.assign("/planner")}catch{eR("Setup didn't complete — please try again. If it keeps failing, reload the page.")}})},children:[(0,r.jsx)(N.I,{name:"bot",size:14})," ",eB?s("onboarding.brief.settingUp"):s("onboarding.brief.handOff")]})]})]})]})})]})}},7814:(e,s,a)=>{"use strict";Object.defineProperty(s,"__esModule",{value:!0});var r={callServer:function(){return n.callServer},createServerReference:function(){return i.createServerReference},findSourceMapURL:function(){return l.findSourceMapURL}};for(var t in r)Object.defineProperty(s,t,{enumerable:!0,get:r[t]});let n=a(3825),l=a(2617),i=a(5986)},8576:(e,s,a)=>{"use strict";a.d(s,{I:()=>n});var r=a(5076);let t={files:(0,r.jsx)("path",{d:"M3 3.5h5l1.5 2H13a1 1 0 0 1 1 1V12a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4.5a1 1 0 0 1 1-1z"}),search:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("circle",{cx:"7",cy:"7",r:"4.2"}),(0,r.jsx)("path",{d:"M10.2 10.2 14 14"})]}),git:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("circle",{cx:"4",cy:"4",r:"1.8"}),(0,r.jsx)("circle",{cx:"4",cy:"12",r:"1.8"}),(0,r.jsx)("circle",{cx:"12",cy:"9.5",r:"1.8"}),(0,r.jsx)("path",{d:"M4 5.8v4.4M5.8 4H9a2 2 0 0 1 2 2v1.6"})]}),debug:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("circle",{cx:"8",cy:"8.5",r:"3.5"}),(0,r.jsx)("path",{d:"M8 5V3M4.5 8.5H2m12 0h-2.5M4.8 11.8 3.4 13M11.2 11.8l1.4 1.2M5.2 5 3.8 3.6M10.8 5l1.4-1.4"})]}),ext:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("rect",{x:"2.5",y:"2.5",width:"4.5",height:"4.5",rx:"1"}),(0,r.jsx)("rect",{x:"9",y:"2.5",width:"4.5",height:"4.5",rx:"1"}),(0,r.jsx)("rect",{x:"2.5",y:"9",width:"4.5",height:"4.5",rx:"1"}),(0,r.jsx)("path",{d:"M9 11.2h4.5M11.2 9v4.5"})]}),settings:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("circle",{cx:"8",cy:"8",r:"2.2"}),(0,r.jsx)("path",{d:"M8 1.5v2M8 12.5v2M14.5 8h-2M3.5 8h-2M12.6 3.4l-1.4 1.4M4.8 11.2l-1.4 1.4M12.6 12.6l-1.4-1.4M4.8 4.8 3.4 3.4"})]}),account:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("circle",{cx:"8",cy:"5.5",r:"2.8"}),(0,r.jsx)("path",{d:"M2.8 14c0-2.8 2.3-4.5 5.2-4.5s5.2 1.7 5.2 4.5"})]}),chevronRight:(0,r.jsx)("path",{d:"M6 4l4 4-4 4"}),chevronDown:(0,r.jsx)("path",{d:"M4 6l4 4 4-4"}),chevronUp:(0,r.jsx)("path",{d:"M4 10l4-4 4 4"}),close:(0,r.jsx)("path",{d:"M4 4l8 8M12 4l-8 8"}),add:(0,r.jsx)("path",{d:"M8 3v10M3 8h10"}),newFile:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("path",{d:"M9 2H4a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V6L9 2z"}),(0,r.jsx)("path",{d:"M9 2v4h4M8 8v4M6 10h4"})]}),newFolder:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("path",{d:"M2 5.5a1 1 0 0 1 1-1h3l1.2 1.5H13a1 1 0 0 1 1 1V12a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5.5z"}),(0,r.jsx)("path",{d:"M8 8v3M6.5 9.5h3"})]}),refresh:(0,r.jsx)("path",{d:"M13 8a5 5 0 1 1-1.5-3.5M13 2.5V5h-2.5"}),collapse:(0,r.jsx)("path",{d:"M3 5h6M3 8h6M3 11h6M12 6l-1.5 1.5L12 9"}),more:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("circle",{cx:"3.5",cy:"8",r:"1"}),(0,r.jsx)("circle",{cx:"8",cy:"8",r:"1"}),(0,r.jsx)("circle",{cx:"12.5",cy:"8",r:"1"})]}),split:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("rect",{x:"2",y:"3",width:"12",height:"10",rx:"1"}),(0,r.jsx)("path",{d:"M8 3v10"})]}),terminal:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("rect",{x:"2",y:"3",width:"12",height:"10",rx:"1.5"}),(0,r.jsx)("path",{d:"M4.5 6.5 6.5 8l-2 1.5M8 10h3.5"})]}),panelBottom:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("rect",{x:"2",y:"3",width:"12",height:"10",rx:"1.5"}),(0,r.jsx)("path",{d:"M2 10h12"})]}),sidebarIcon:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("rect",{x:"2",y:"3",width:"12",height:"10",rx:"1.5"}),(0,r.jsx)("path",{d:"M6 3v10"})]}),bell:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("path",{d:"M8 2a3.5 3.5 0 0 0-3.5 3.5c0 3-1.3 4-1.3 4h9.6s-1.3-1-1.3-4A3.5 3.5 0 0 0 8 2z"}),(0,r.jsx)("path",{d:"M6.7 12a1.4 1.4 0 0 0 2.6 0"})]}),check:(0,r.jsx)("path",{d:"M3 8.5 6.5 12 13 4"}),error:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("circle",{cx:"8",cy:"8",r:"6"}),(0,r.jsx)("path",{d:"M8 5v4M8 11h.01"})]}),warn:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("path",{d:"M8 2.5 14.5 13.5h-13z"}),(0,r.jsx)("path",{d:"M8 7v3M8 12h.01"})]}),branch:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("circle",{cx:"4",cy:"4",r:"1.6"}),(0,r.jsx)("circle",{cx:"4",cy:"12",r:"1.6"}),(0,r.jsx)("circle",{cx:"12",cy:"9",r:"1.6"}),(0,r.jsx)("path",{d:"M4 5.6v4.8M5.6 4H9a1.8 1.8 0 0 1 1.8 1.8v1.6"})]}),sync:(0,r.jsx)("path",{d:"M3 6a5 5 0 0 1 8.5-2M13 10a5 5 0 0 1-8.5 2M11.5 2.5V4h-1.5M4.5 13.5V12h1.5"}),command:(0,r.jsx)("path",{d:"M5.5 3.5A1.5 1.5 0 1 1 4 5h8a1.5 1.5 0 1 1-1.5 1.5v3A1.5 1.5 0 1 1 12 11H4a1.5 1.5 0 1 1 1.5-1.5v-3z"}),goto:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("path",{d:"M3 8h8M7.5 4.5 11 8l-3.5 3.5"}),(0,r.jsx)("path",{d:"M13 3v10"})]}),sun:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("circle",{cx:"8",cy:"8",r:"3"}),(0,r.jsx)("path",{d:"M8 1.5v1.5M8 13v1.5M14.5 8H13M3 8H1.5M12.6 3.4l-1 1M4.4 11.6l-1 1M12.6 12.6l-1-1M4.4 4.4l-1-1"})]}),moon:(0,r.jsx)("path",{d:"M13 9.2A5.5 5.5 0 0 1 6.8 3 5.5 5.5 0 1 0 13 9.2z"}),play:(0,r.jsx)("path",{d:"M5 3.5v9l7-4.5z"}),trash:(0,r.jsx)("path",{d:"M3.5 4.5h9M6 4.5V3h4v1.5M5 4.5l.5 8.5h5l.5-8.5"}),dot:(0,r.jsx)("circle",{cx:"8",cy:"8",r:"3"}),fileTs:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("path",{d:"M9 2H4a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V6L9 2z"}),(0,r.jsx)("path",{d:"M9 2v4h4"})]}),arrowUp:(0,r.jsx)("path",{d:"M8 13V3M4 7l4-4 4 4"}),arrowDown:(0,r.jsx)("path",{d:"M8 3v10M4 9l4 4 4-4"}),agents:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("circle",{cx:"5.5",cy:"6",r:"2.2"}),(0,r.jsx)("circle",{cx:"11",cy:"6.5",r:"1.8"}),(0,r.jsx)("path",{d:"M2 13c0-2 1.6-3.2 3.5-3.2S9 11 9 13M9.5 12.5c.2-1.6 1.3-2.5 2.8-2.5 1.3 0 2.4.8 2.4 2.3"})]}),bot:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("rect",{x:"3",y:"5.5",width:"10",height:"7",rx:"2"}),(0,r.jsx)("path",{d:"M8 3v2.5M5.8 9h.01M10.2 9h.01M6 12h4"}),(0,r.jsx)("circle",{cx:"8",cy:"3",r:"1"})]}),send:(0,r.jsx)("path",{d:"M14 2 7 9M14 2l-4.5 12-2.5-5L2 6.5z"}),at:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("circle",{cx:"8",cy:"8",r:"3"}),(0,r.jsx)("path",{d:"M11 8v1.2a1.8 1.8 0 0 0 3.5.6A6.5 6.5 0 1 0 11 13.2"})]}),chevronLeft:(0,r.jsx)("path",{d:"M10 4 6 8l4 4"}),dockRight:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("rect",{x:"2",y:"3",width:"12",height:"10",rx:"1.5"}),(0,r.jsx)("path",{d:"M10 3v10"}),(0,r.jsx)("rect",{x:"10.5",y:"3.5",width:"3",height:"9",rx:"1",fill:"currentColor",stroke:"none",opacity:"0.25"})]}),dockLeft:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("rect",{x:"2",y:"3",width:"12",height:"10",rx:"1.5"}),(0,r.jsx)("path",{d:"M6 3v10"}),(0,r.jsx)("rect",{x:"2.5",y:"3.5",width:"3",height:"9",rx:"1",fill:"currentColor",stroke:"none",opacity:"0.25"})]}),chat:(0,r.jsx)("path",{d:"M3 4.5h10a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1H7l-3 2.5V11.5H3a1 1 0 0 1-1-1v-5a1 1 0 0 1 1-1z"}),grid:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("rect",{x:"2.5",y:"2.5",width:"4.5",height:"4.5",rx:"1"}),(0,r.jsx)("rect",{x:"9",y:"2.5",width:"4.5",height:"4.5",rx:"1"}),(0,r.jsx)("rect",{x:"2.5",y:"9",width:"4.5",height:"4.5",rx:"1"}),(0,r.jsx)("rect",{x:"9",y:"9",width:"4.5",height:"4.5",rx:"1"})]}),inbox:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("path",{d:"M2 9h3l1 2h4l1-2h3"}),(0,r.jsx)("path",{d:"M2.5 9 4 3.5h8L13.5 9v3.5a1 1 0 0 1-1 1h-9a1 1 0 0 1-1-1z"})]}),calendar:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("rect",{x:"2.5",y:"3.5",width:"11",height:"10",rx:"1.5"}),(0,r.jsx)("path",{d:"M2.5 6.5h11M5.5 2v3M10.5 2v3"})]}),repeat:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("path",{d:"M3 6a4 4 0 0 1 7-2.5L12 5M13 10a4 4 0 0 1-7 2.5L4 11"}),(0,r.jsx)("path",{d:"M12 2v3H9M4 14v-3h3"})]}),doc:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("path",{d:"M9 2H4.5a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1V5.5L9 2z"}),(0,r.jsx)("path",{d:"M9 2v3.5h3.5M6 8.5h4M6 11h4"})]}),skill:(0,r.jsx)("path",{d:"M8 2.5l1.4 3.1 3.4.4-2.5 2.3.7 3.3L8 9.9 5 11.6l.7-3.3L3.2 6l3.4-.4z"}),pulse:(0,r.jsx)("path",{d:"M2 8h3l1.5-4 2.5 8 1.5-4H14"}),coins:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("ellipse",{cx:"6",cy:"4.5",rx:"3.5",ry:"1.8"}),(0,r.jsx)("path",{d:"M2.5 4.5v3c0 1 1.6 1.8 3.5 1.8s3.5-.8 3.5-1.8v-3"}),(0,r.jsx)("ellipse",{cx:"10",cy:"9.5",rx:"3.5",ry:"1.8"}),(0,r.jsx)("path",{d:"M6.5 9.5c.4.9 1.8 1.5 3.5 1.5s3.5-.8 3.5-1.8v-1.2"})]}),cpu:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("rect",{x:"4",y:"4",width:"8",height:"8",rx:"1.5"}),(0,r.jsx)("rect",{x:"6.3",y:"6.3",width:"3.4",height:"3.4",rx:".5"}),(0,r.jsx)("path",{d:"M6 2v2M10 2v2M6 12v2M10 12v2M2 6h2M2 10h2M12 6h2M12 10h2"})]}),shield:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("path",{d:"M8 2 3 4v4c0 3 2.2 5 5 6 2.8-1 5-3 5-6V4z"}),(0,r.jsx)("path",{d:"M5.8 8 7.3 9.5 10.4 6.3"})]}),target:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("circle",{cx:"8",cy:"8",r:"5.5"}),(0,r.jsx)("circle",{cx:"8",cy:"8",r:"2.4"})]}),selectParent:(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("rect",{x:"2",y:"2.5",width:"12",height:"11",rx:"1.5"}),(0,r.jsx)("path",{d:"M8 11V6.5M5.5 9 8 6.5l2.5 2.5"})]})};function n({name:e,size:s=16,className:a="",strokeWidth:l=1.4,style:i}){let c=t[e];return c?(0,r.jsx)("svg",{width:s,height:s,viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:l,strokeLinecap:"round",strokeLinejoin:"round",className:a,style:i,children:"play"===e||"dot"===e?(0,r.jsx)("g",{fill:"currentColor",stroke:"none",children:c}):c}):null}},9177:(e,s,a)=>{Promise.resolve().then(a.bind(a,7111))},9860:(e,s,a)=>{"use strict";var r=a(2004);a.o(r,"usePathname")&&a.d(s,{usePathname:function(){return r.usePathname}}),a.o(r,"useRouter")&&a.d(s,{useRouter:function(){return r.useRouter}})}},e=>{e.O(0,[3219,4263,9562,6646,6834,7358],()=>e(e.s=9177)),_N_E=e.O()}]);
|
package/.next/trace-build
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
[{"name":"run-webpack","duration":
|
|
1
|
+
[{"name":"run-webpack","duration":30718826,"timestamp":219493746896,"id":14,"parentId":1,"tags":{},"startTime":1782539196897,"traceId":"6891e50d0d0197c6"},{"name":"run-typescript","duration":11653241,"timestamp":219524471329,"id":7670,"parentId":1,"tags":{},"startTime":1782539227622,"traceId":"6891e50d0d0197c6"},{"name":"static-check","duration":1572906,"timestamp":219536313659,"id":7673,"parentId":1,"tags":{},"startTime":1782539239464,"traceId":"6891e50d0d0197c6"},{"name":"static-generation","duration":2933518,"timestamp":219538704732,"id":7783,"parentId":1,"tags":{},"startTime":1782539241855,"traceId":"6891e50d0d0197c6"},{"name":"collect-build-traces","duration":10927581,"timestamp":219537891628,"id":7780,"parentId":1,"tags":{},"startTime":1782539241042,"traceId":"6891e50d0d0197c6"},{"name":"telemetry-flush","duration":59,"timestamp":219548824263,"id":7792,"parentId":1,"tags":{},"startTime":1782539251974,"traceId":"6891e50d0d0197c6"},{"name":"next-build","duration":55405744,"timestamp":219493418584,"id":1,"tags":{"buildMode":"default","version":"16.2.9","bundler":"webpack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1782539196569,"traceId":"6891e50d0d0197c6"}]
|
package/CHANGELOG.md
CHANGED
|
@@ -12,6 +12,43 @@ may still introduce breaking changes while the platform stabilises.
|
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
|
+
## [0.3.6] — 2026-06-26 — "Hardening pass"
|
|
16
|
+
|
|
17
|
+
A whole-project code review — **security, correctness and robustness**. Highlights:
|
|
18
|
+
|
|
19
|
+
### Security
|
|
20
|
+
- **Operator-account takeover closed.** The signup takeover guard keyed off the `.env` flag ALONE; a
|
|
21
|
+
restored/copied `constella.db` (flag absent, credential present) let an unauthenticated caller reset the
|
|
22
|
+
operator's password. The DB credential is now the source of truth (signup action **and** login screen).
|
|
23
|
+
- **Secret scanning hardened.** The commit/export scan now catches GitHub fine-grained PATs (`github_pat_…`);
|
|
24
|
+
the public-publish scan covers `.cjs/.cts` files and iterates ALL matches of validated patterns (a
|
|
25
|
+
placeholder no longer hides a real secret later in a file).
|
|
26
|
+
- **Web-research allowlist** re-validates the FINAL url host after redirects (and matches port-bearing hosts).
|
|
27
|
+
- **Live-inspect spoofing closed** — the canvas only trusts a `live:select` message from its own iframe.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
- **RAG reindex** no longer wipes curated KB-entry chunks (scoped to non-KB chunks).
|
|
31
|
+
- **Runner:** a null-assignee task can't deadlock the queue; an agent isn't left stuck "working" after a throw;
|
|
32
|
+
a relay failure can't abort a task's own bookkeeping; the "update available" notice stops re-appearing after
|
|
33
|
+
you dismiss it.
|
|
34
|
+
- **Telegram:** a failed ingest no longer drops the operator's message (offset advances only on success); the
|
|
35
|
+
inline-button allowlist is default-deny.
|
|
36
|
+
- **Dev server:** detached process group (a clean stop no longer orphans the real server) + an in-flight boot
|
|
37
|
+
lock (no second server spawned on a concurrent start).
|
|
38
|
+
- **Local models:** stopping the chat server (:8082) no longer also kills the RAG embedding server (:8083).
|
|
39
|
+
- **Dates:** report + profile no longer render far-future (year-57000) timestamps.
|
|
40
|
+
- Plus markdown-patch `$`-escaping, prerelease-aware update checks, a stdin-EPIPE crash guard, and a long tail
|
|
41
|
+
of data/UI/script fixes.
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
- **VPS one-click self-update hardened:** invoke the SAME absolute npm/systemctl the sudoers rule uses, scope
|
|
45
|
+
the rule to `constellai@latest` (drop the `@*` wildcard), and always (re)write the drop-in so a stale one
|
|
46
|
+
self-heals.
|
|
47
|
+
- **Docs:** an honest **compatibility status** in the README (Windows primary · Linux experimental · macOS
|
|
48
|
+
untested · portable in validation) + a **[roadmap](docs/roadmap.md)** skeleton.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
15
52
|
## [0.3.5] — 2026-06-26 — "VPS update polish"
|
|
16
53
|
|
|
17
54
|
### Fixed
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
<p align="center">
|
|
7
7
|
<a href="#-quickstart"><img alt="npx constella" src="https://img.shields.io/badge/npx-constellai-7c3aed?style=for-the-badge&logo=npm&logoColor=white"></a>
|
|
8
|
-
<img alt="version" src="https://img.shields.io/badge/version-0.3.
|
|
8
|
+
<img alt="version" src="https://img.shields.io/badge/version-0.3.6-22d3ee?style=for-the-badge">
|
|
9
9
|
<img alt="node" src="https://img.shields.io/badge/node-%E2%89%A520-3fb950?style=for-the-badge&logo=node.js&logoColor=white">
|
|
10
10
|
<img alt="license" src="https://img.shields.io/badge/license-MIT-a78bfa?style=for-the-badge">
|
|
11
11
|
<img alt="agent CLIs" src="https://img.shields.io/badge/agent%20CLIs-claude%20%C2%B7%20codex%20%C2%B7%20%2B8-e879f9?style=for-the-badge">
|
|
@@ -32,6 +32,12 @@ Real `claude` / `codex` agents that plan, build, review and ship — on your mac
|
|
|
32
32
|
> 24/7 — writing real code in a real workspace, using local or cloud models, with budgets, skills,
|
|
33
33
|
> RAG memory, GitHub/Telegram integration and a deploy pipeline. **Nothing is faked.**
|
|
34
34
|
|
|
35
|
+
> ⚙️ **Compatibility status** — Constella is young and not yet tested in every environment:
|
|
36
|
+
> - **Windows** — primary platform (developed + tested here)
|
|
37
|
+
> - **Linux** — experimental; works normally, still in active testing
|
|
38
|
+
> - **macOS** — not tested yet (no Mac on hand 😅)
|
|
39
|
+
> - **Portable (USB) mode** — in validation
|
|
40
|
+
|
|
35
41
|
<p align="center"><img src="docs/assets/divider-orbit.svg" alt="" width="100%"/></p>
|
|
36
42
|
|
|
37
43
|
## 🪐 What is Constella?
|
package/README.pt-BR.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
<p align="center">
|
|
7
7
|
<a href="#-início-rápido"><img alt="npx constella" src="https://img.shields.io/badge/npx-constellai-7c3aed?style=for-the-badge&logo=npm&logoColor=white"></a>
|
|
8
|
-
<img alt="version" src="https://img.shields.io/badge/version-0.3.
|
|
8
|
+
<img alt="version" src="https://img.shields.io/badge/version-0.3.6-22d3ee?style=for-the-badge">
|
|
9
9
|
<img alt="node" src="https://img.shields.io/badge/node-%E2%89%A520-3fb950?style=for-the-badge&logo=node.js&logoColor=white">
|
|
10
10
|
<img alt="license" src="https://img.shields.io/badge/license-MIT-a78bfa?style=for-the-badge">
|
|
11
11
|
<img alt="agent CLIs" src="https://img.shields.io/badge/CLIs%20de%20agente-claude%20%C2%B7%20codex%20%C2%B7%20%2B8-e879f9?style=for-the-badge">
|
|
@@ -33,6 +33,12 @@ Agentes `claude` / `codex` reais que planejam, constroem, revisam e entregam —
|
|
|
33
33
|
> com orçamentos, skills, memória RAG, integração com GitHub/Telegram e um pipeline de deploy. **Nada é
|
|
34
34
|
> falso.**
|
|
35
35
|
|
|
36
|
+
> ⚙️ **Status de compatibilidade** — a Constella é nova e ainda não foi testada em todos os ambientes:
|
|
37
|
+
> - **Windows** — plataforma principal (desenvolvida + testada aqui)
|
|
38
|
+
> - **Linux** — experimental; funciona normalmente, em fase de testes
|
|
39
|
+
> - **macOS** — não testado (não tenho um Mac 😅)
|
|
40
|
+
> - **Modo pen-drive (portátil)** — em validação
|
|
41
|
+
|
|
36
42
|
<p align="center"><img src="docs/assets/divider-orbit.svg" alt="" width="100%"/></p>
|
|
37
43
|
|
|
38
44
|
## 🪐 O que é a Constella?
|
package/bin/constella-update.mjs
CHANGED
|
@@ -55,7 +55,13 @@ const PORT = String(arg("--port") || process.env.PORT || state.port || "3000");
|
|
|
55
55
|
let LAUNCHER = Number(arg("--pid") || process.env.CONSTELLA_LAUNCHER_PID || state.launcherPid || 0);
|
|
56
56
|
|
|
57
57
|
const log = (...a) => { if (!QUIET) console.log(...a); };
|
|
58
|
-
const sleep = (ms) => {
|
|
58
|
+
const sleep = (ms) => {
|
|
59
|
+
try { Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms); return; } catch { /* no SAB → busy-wait */ }
|
|
60
|
+
// Fallback when SharedArrayBuffer is unavailable (sandbox / hardened runtime): a real blocking wait. The old
|
|
61
|
+
// no-op return made the graceful-shutdown loops spin instantly → an immediate SIGKILL that skipped run.json
|
|
62
|
+
// cleanup + the child-kill cascade.
|
|
63
|
+
const end = Date.now() + ms; while (Date.now() < end) { /* block */ }
|
|
64
|
+
};
|
|
59
65
|
const alive = (p) => { try { process.kill(p, 0); return true; } catch { return false; } };
|
|
60
66
|
const psout = (s) => { try { return execFileSync("powershell", ["-NoProfile", "-Command", s], { timeout: 9000, windowsHide: true }).toString(); } catch { return ""; } };
|
|
61
67
|
const ints = (s) => s.split(/\r?\n/).map((x) => +x.trim()).filter((n) => n > 0);
|
|
@@ -116,16 +122,21 @@ function relaunch() {
|
|
|
116
122
|
// So here we update via `sudo -n` and then let systemd cycle the unit (it stops this whole cgroup — us
|
|
117
123
|
// included — and starts fresh on the new code). No kill-by-pid, no relaunch: systemd owns the process.
|
|
118
124
|
const SERVICE = process.env.CONSTELLA_SERVICE || "constella";
|
|
125
|
+
// Invoke the SAME absolute npm/systemctl the sudoers rule was written with (vps-install.sh passes them via the
|
|
126
|
+
// service env), so `sudo -n` matches the NOPASSWD entry even when sudo's secure_path resolves a bare `npm`/
|
|
127
|
+
// `systemctl` to a different path. Falls back to the bare name (unchanged behavior) when the env isn't set.
|
|
128
|
+
const NPM = process.env.CONSTELLA_NPM_PATH || "npm";
|
|
129
|
+
const SYSTEMCTL = process.env.CONSTELLA_SYSTEMCTL_PATH || "systemctl";
|
|
119
130
|
|
|
120
131
|
function vpsInstall(target) {
|
|
121
132
|
const opt = { stdio: QUIET ? "ignore" : "inherit", windowsHide: true, cwd: SAFE_CWD };
|
|
122
133
|
for (let i = 0; i < 4; i++) {
|
|
123
|
-
log(`• sudo
|
|
134
|
+
log(`• sudo ${NPM} install -g ${target} (attempt ${i + 1}/4)…`);
|
|
124
135
|
// Prefer passwordless sudo (root-owned global prefix). Fall back to plain npm in case the prefix is
|
|
125
136
|
// already user-writable (a user-level npm prefix) — then no sudo is needed at all.
|
|
126
|
-
let r = spawnSync("sudo", ["-n",
|
|
137
|
+
let r = spawnSync("sudo", ["-n", NPM, "install", "-g", target], opt);
|
|
127
138
|
if (r.status === 0) return true;
|
|
128
|
-
r = spawnSync(
|
|
139
|
+
r = spawnSync(NPM, ["install", "-g", target], { ...opt, shell: true });
|
|
129
140
|
if (r.status === 0) return true;
|
|
130
141
|
sleep(3000);
|
|
131
142
|
}
|
|
@@ -138,14 +149,15 @@ function restartUnit() {
|
|
|
138
149
|
// code. The result file is already "done", so the reconnecting UI sees success. If sudo/systemctl isn't
|
|
139
150
|
// available (a non-systemd container), this no-ops and the host keeps running the old code until a manual
|
|
140
151
|
// restart — `Restart=always` does NOT help here because we didn't crash.
|
|
141
|
-
try { spawnSync("sudo", ["-n",
|
|
152
|
+
try { spawnSync("sudo", ["-n", SYSTEMCTL, "restart", SERVICE], { stdio: QUIET ? "ignore" : "inherit" }); } catch { /* manual restart needed */ }
|
|
142
153
|
}
|
|
143
154
|
|
|
144
155
|
if (MODE === "vps") {
|
|
145
156
|
result({ status: "running" });
|
|
146
157
|
if (QUIET) sleep(1200); // let the UI receive the response + start polling
|
|
147
|
-
|
|
148
|
-
|
|
158
|
+
// Always @latest on a VPS: the NOPASSWD sudoers rule is scoped to EXACTLY `constellai@latest` (no `@*`
|
|
159
|
+
// wildcard that could span into extra args), and the button only ever wants the newest release.
|
|
160
|
+
const target = `${PKG}@latest`;
|
|
149
161
|
const okv = vpsInstall(target);
|
|
150
162
|
result({ status: okv ? "done" : "error" });
|
|
151
163
|
log(okv ? "✓ Installed — restarting the service." : "✖ Update failed — run by hand: sudo npm i -g constellai@latest && sudo systemctl restart constella");
|
package/bin/constella.mjs
CHANGED
|
@@ -153,7 +153,7 @@ async function pickUsbHome() {
|
|
|
153
153
|
const PKG = "constellai"; // npm package name (the CLI command/bin stays `constella`)
|
|
154
154
|
const args = process.argv.slice(2);
|
|
155
155
|
const has = (f) => args.includes(f);
|
|
156
|
-
const flag = (f) => { const i = args.indexOf(f);
|
|
156
|
+
const flag = (f) => { const i = args.indexOf(f); if (i < 0) return undefined; const v = args[i + 1]; return v && !v.startsWith("-") ? v : undefined; }; // a value-less option (e.g. `--port --onboarding`) must not swallow the next flag as its value
|
|
157
157
|
const rawCmd = args.find((a) => !a.startsWith("-")); // the bare subcommand the user typed (if any)
|
|
158
158
|
const cmd = rawCmd ?? "";
|
|
159
159
|
|
package/bin/worker.mjs
CHANGED
|
@@ -41,6 +41,7 @@ if (!isLoopback && !ALLOW_REMOTE) {
|
|
|
41
41
|
if (!isLoopback && ALLOW_REMOTE && new URL(BASE).protocol !== "https:") {
|
|
42
42
|
console.warn(`• CONSTELLA_BASE_URL is a remote http:// host (${baseHost}) — the worker secret will travel in cleartext. Use https://.`);
|
|
43
43
|
}
|
|
44
|
+
if (!SECRET) console.error("✖ CONSTELLA_WORKER_SECRET is empty — every privileged worker call (tick · sync · telegram) will be rejected (401) and nothing scheduled will run. Set it in ~/.constella/.env, then restart.");
|
|
44
45
|
const headers = (SECRET && (isLoopback || ALLOW_REMOTE)) ? { "x-worker-secret": SECRET } : {};
|
|
45
46
|
|
|
46
47
|
/* ---- 24/7 tick ---- */
|
package/docs/UPDATE.md
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|
|
|
7
|
-
**Current stable release: `v0.3.
|
|
8
|
-
|
|
7
|
+
**Current stable release: `v0.3.6`** — a whole-project code-review hardening pass (security, correctness +
|
|
8
|
+
robustness). See what changed in the [Changelog](../CHANGELOG.md) (the Update module also shows it inline as
|
|
9
9
|
“What's new”).
|
|
10
10
|
|
|
11
11
|
> This is the page the **Update** module's “docs” button opens. It tells you, in plain terms, how to move Constella
|
|
@@ -24,6 +24,15 @@ it didn't earn: the updater writes the real result and the screen reflects it tr
|
|
|
24
24
|
Latest first. The in-app **Update** module shows the changelog inline as “What's new”; this is the same history, kept
|
|
25
25
|
here so the “docs” button always shows what each release added. Full detail: [Changelog](../CHANGELOG.md).
|
|
26
26
|
|
|
27
|
+
### v0.3.6 — hardening pass
|
|
28
|
+
- A whole-project code review (**security · correctness · robustness**): closed an operator-account takeover
|
|
29
|
+
(restored-DB path), hardened secret scanning (fine-grained PATs, `.cjs/.cts`, redirect re-validation), fixed
|
|
30
|
+
a RAG reindex that wiped curated KB chunks, a runner queue deadlock + a stuck "working" agent, a dropped
|
|
31
|
+
Telegram message, dev-server process-group + double-spawn, the year-57000 dates — among many others.
|
|
32
|
+
- **VPS one-click update hardened** — absolute npm/systemctl paths, sudoers scoped to `constellai@latest`, a
|
|
33
|
+
self-healing drop-in.
|
|
34
|
+
- Docs: an honest **compatibility status** + a **roadmap** skeleton.
|
|
35
|
+
|
|
27
36
|
### v0.3.5 — VPS update polish
|
|
28
37
|
- Dropped the inaccurate **"(Docker)"** label — VPS mode is **native** (systemd + Tailscale, no Docker).
|
|
29
38
|
- Fixed the passwordless self-update drop-in being **skipped at setup** (`visudo` wasn't on the non-root PATH), so
|
package/docs/roadmap.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# 🗺️ Constella Roadmap
|
|
2
|
+
|
|
3
|
+
[✦ Constella](../README.md) · [Changelog](../CHANGELOG.md)
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
> Where Constella is headed. A living document — items move between sections as work starts and ships.
|
|
8
|
+
> For what's already released, see the [Changelog](../CHANGELOG.md).
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 🚀 Now — in progress
|
|
13
|
+
|
|
14
|
+
_— to be filled in —_
|
|
15
|
+
|
|
16
|
+
## 🔜 Next — planned
|
|
17
|
+
|
|
18
|
+
_— to be filled in —_
|
|
19
|
+
|
|
20
|
+
## 🌌 Later — exploring
|
|
21
|
+
|
|
22
|
+
_— to be filled in —_
|
|
23
|
+
|
|
24
|
+
## 🧪 Compatibility & platforms
|
|
25
|
+
|
|
26
|
+
_— to be filled in —_
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## ✅ Shipped
|
|
31
|
+
|
|
32
|
+
Already released — see the full [Changelog](../CHANGELOG.md).
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
[✦ Constella](../README.md) · [Changelog](../CHANGELOG.md) · [Updating](./UPDATE.md) · [Report an issue](../ISSUE.md)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "constellai",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"description": "Constella — run autonomous AI agent-companies locally: real claude/codex agents, Goals → Specs → Issues → Plans, local models, GitHub & Telegram, all from one cosmic control plane.",
|
|
5
5
|
"//name": "Published as `constellai` (the unscoped `constella` was taken). Ships BOTH a `constellai` and a `constella` bin (same launcher): `npx constellai` needs a bin matching the package name to run on Windows, and a global install also gives the short `constella` command.",
|
|
6
6
|
"license": "MIT",
|
package/scripts/i18n-parity.mjs
CHANGED
|
@@ -20,7 +20,7 @@ const src = readFileSync(join(root, "src/lib/i18n.ts"), "utf8");
|
|
|
20
20
|
function keysOf(name, endMarker) {
|
|
21
21
|
const start = src.indexOf(`const ${name}: Dict = {`);
|
|
22
22
|
if (start === -1) throw new Error(`Could not find \`const ${name}: Dict = {\` in i18n.ts`);
|
|
23
|
-
const end = src.indexOf(endMarker, start);
|
|
23
|
+
const end = src.indexOf("\n" + endMarker, start); // anchor to start-of-line so a translation VALUE containing the marker text can't truncate the key set
|
|
24
24
|
if (end === -1) throw new Error(`Could not find end marker \`${endMarker}\` after \`${name}\``);
|
|
25
25
|
const body = src.slice(start, end);
|
|
26
26
|
const keys = new Set();
|
package/scripts/install.sh
CHANGED
|
@@ -66,8 +66,10 @@ case "$MODE" in
|
|
|
66
66
|
|
|
67
67
|
--update)
|
|
68
68
|
if systemctl list-unit-files 2>/dev/null | grep -q '^constella\.service'; then
|
|
69
|
-
# VPS: update the global CLI + restart the systemd service.
|
|
70
|
-
|
|
69
|
+
# VPS: update the global CLI + restart the systemd service. Pass $RAW + the version as POSITIONAL args
|
|
70
|
+
# to the inner shell (not interpolated into the command string) so a version with shell-special chars
|
|
71
|
+
# can't word-split or inject.
|
|
72
|
+
exec bash -c 'curl -fsSL "$1/scripts/vps-update.sh" | bash -s -- "${2:-latest}"' _ "$RAW" "${2:-}"
|
|
71
73
|
else
|
|
72
74
|
ensure_node; $SUDO npm install -g "${PKG}@${2:-latest}"; say "✓ Updated. Relaunch: constella --start (or --vps / --portable)"
|
|
73
75
|
fi
|
|
@@ -41,7 +41,7 @@ const SECRETS = [
|
|
|
41
41
|
["DB URL with creds", /\b(?:postgres(?:ql)?|mysql|mongodb(?:\+srv)?|redis|amqp):\/\/([^\s:@/]+):([^\s:@/]+)@/, (m) => !PLACEHOLDER.test(m[1]) && !PLACEHOLDER.test(m[2])],
|
|
42
42
|
["Telegram bot token", /\b\d{6,}:[A-Za-z0-9_-]{35,}\b/],
|
|
43
43
|
];
|
|
44
|
-
const TEXT = /\.(m?[jt]sx?|json|md|css|ya?ml|toml|sh|env|txt|html?)$/i;
|
|
44
|
+
const TEXT = /\.(c?m?[jt]sx?|json|md|css|ya?ml|toml|sh|env|txt|html?)$/i; // c?m? also covers .cjs/.cts/.mjs/.mts (tracked skill helpers)
|
|
45
45
|
|
|
46
46
|
const isExcluded = (f) => EXCLUDE.some((p) => f === p || f.startsWith(p + "/"));
|
|
47
47
|
|
|
@@ -77,8 +77,17 @@ for (const f of publishFiles) {
|
|
|
77
77
|
let body;
|
|
78
78
|
try { if (statSync(f).size > 512 * 1024) continue; body = readFileSync(f, "utf8"); } catch { continue; }
|
|
79
79
|
for (const [name, re, valid] of SECRETS) {
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
if (valid) {
|
|
81
|
+
// Validated pattern (DB URL): scan ALL matches — a placeholder match first must not hide a REAL
|
|
82
|
+
// credential later in the file. `match()` returns only the first occurrence, so iterate.
|
|
83
|
+
const gre = new RegExp(re.source, re.flags.includes("g") ? re.flags : re.flags + "g");
|
|
84
|
+
let hit = false;
|
|
85
|
+
for (const m of body.matchAll(gre)) { if (valid(m)) { hit = true; break; } }
|
|
86
|
+
if (hit) { findings.push(`${f}: ${name}`); break; }
|
|
87
|
+
} else {
|
|
88
|
+
const m = body.match(re);
|
|
89
|
+
if (m) { findings.push(`${f}: ${name}`); break; }
|
|
90
|
+
}
|
|
82
91
|
}
|
|
83
92
|
}
|
|
84
93
|
// Belt-and-suspenders: make sure no src/ slipped into the publish set.
|
package/scripts/vps-clean.sh
CHANGED
|
@@ -40,7 +40,7 @@ fi
|
|
|
40
40
|
# 1) Stop + remove the systemd service.
|
|
41
41
|
if systemctl list-unit-files 2>/dev/null | grep -q '^constella\.service'; then
|
|
42
42
|
say "• Stopping + removing the constella systemd service…"
|
|
43
|
-
$SUDO systemctl disable --now constella
|
|
43
|
+
$SUDO systemctl disable --now constella || say " ⚠ disable failed — removing the unit anyway; the daemon-reload below clears any dangling .wants symlink."
|
|
44
44
|
$SUDO rm -f /etc/systemd/system/constella.service
|
|
45
45
|
$SUDO systemctl daemon-reload 2>/dev/null
|
|
46
46
|
else
|
package/scripts/vps-install.sh
CHANGED
|
@@ -40,13 +40,25 @@ fi
|
|
|
40
40
|
# 2) The Constella CLI.
|
|
41
41
|
say "• Installing the ${PKG} CLI…"
|
|
42
42
|
$SUDO npm install -g "$PKG"
|
|
43
|
-
|
|
43
|
+
# The service MUST run the binary that `sudo npm i -g` installs/updates — NOT whatever `command -v constella`
|
|
44
|
+
# resolves first on the operator's PATH. An earlier user-level `npm i -g` (into ~/.npm-global) shadows it, so
|
|
45
|
+
# ExecStart would pin THAT copy and every future `sudo npm i -g` (in-app update, vps-update.sh) would update a
|
|
46
|
+
# different prefix → "updated, but the app still shows the old version". Pin ExecStart to sudo's global prefix.
|
|
47
|
+
NPM_PREFIX="$($SUDO npm config get prefix 2>/dev/null)"; [ -n "$NPM_PREFIX" ] || NPM_PREFIX="/usr/local"
|
|
48
|
+
BIN="${NPM_PREFIX}/bin/constella"
|
|
49
|
+
[ -x "$BIN" ] || BIN="$(command -v constella || echo "$BIN")"
|
|
50
|
+
say " → service binary: ${BIN} (global prefix ${NPM_PREFIX})"
|
|
51
|
+
|
|
52
|
+
# Absolute npm/systemctl paths — passed to the in-app self-updater via the service env AND used in the sudoers
|
|
53
|
+
# rule below, so `sudo -n` matches the NOPASSWD entry regardless of how sudo's secure_path resolves a bare name.
|
|
54
|
+
NPM_PATH="$(command -v npm || echo "${NPM_PREFIX}/bin/npm")"
|
|
55
|
+
SYSTEMCTL_PATH="$(command -v systemctl || echo /usr/bin/systemctl)"
|
|
44
56
|
|
|
45
57
|
# Agent CLIs (claude / codex / …) install into per-USER bin dirs (~/.local/bin, ~/.npm-global/bin, the claude
|
|
46
58
|
# native install) that systemd's minimal PATH does NOT include — so the service couldn't run them: the onboarding
|
|
47
59
|
# "detected providers" missed Claude Code, and real agent runs would fail to spawn the CLI. Bake a PATH that
|
|
48
60
|
# covers the common locations + the installer's own PATH so the service sees exactly what your shell does.
|
|
49
|
-
NPM_BIN="$
|
|
61
|
+
NPM_BIN="${NPM_PREFIX}/bin"
|
|
50
62
|
SVC_PATH="${RUN_HOME}/.local/bin:${RUN_HOME}/.npm-global/bin:${NPM_BIN}:${RUN_HOME}/.claude/local:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PATH}"
|
|
51
63
|
|
|
52
64
|
# 3) Tailscale on the host (the host IS the tailnet node — no sidecar, no auth key prompt).
|
|
@@ -72,6 +84,8 @@ Environment=CONSTELLA_RUN_MODE=vps
|
|
|
72
84
|
Environment=CONSTELLA_HOME=${CHOME}
|
|
73
85
|
Environment=CONSTELLA_SKIP_TAILSCALE=1
|
|
74
86
|
Environment=PATH=${SVC_PATH}
|
|
87
|
+
Environment=CONSTELLA_NPM_PATH=${NPM_PATH}
|
|
88
|
+
Environment=CONSTELLA_SYSTEMCTL_PATH=${SYSTEMCTL_PATH}
|
|
75
89
|
ExecStart=${BIN} --vps --host 0.0.0.0 --port 3000
|
|
76
90
|
Restart=always
|
|
77
91
|
RestartSec=3
|
|
@@ -88,16 +102,16 @@ $SUDO systemctl enable --now constella
|
|
|
88
102
|
# package and restart the unit. Nothing else. Validated with `visudo -c` before it's installed (a malformed
|
|
89
103
|
# sudoers file would lock out sudo), and skipped gracefully if validation fails.
|
|
90
104
|
say "• Enabling passwordless self-update (sudoers.d/constella)…"
|
|
91
|
-
NPM_PATH="$(command -v npm || echo /usr/bin/npm)"
|
|
92
|
-
SYSTEMCTL_PATH="$(command -v systemctl || echo /usr/bin/systemctl)"
|
|
93
105
|
# visudo lives in /usr/sbin, which is NOT on a non-root user's PATH (this script may run as the operator via
|
|
94
106
|
# `curl | bash`). Resolve it explicitly and validate THROUGH sudo so it's both found and privileged.
|
|
95
107
|
VISUDO="$(command -v visudo || echo /usr/sbin/visudo)"
|
|
96
108
|
SUDOERS_TMP="$(mktemp)"
|
|
109
|
+
# EXACT commands only — `constellai@latest` (the in-app button always installs latest), not a trailing `@*`
|
|
110
|
+
# wildcard whose `*` can span whitespace and absorb extra npm flags under root.
|
|
97
111
|
cat > "$SUDOERS_TMP" <<EOF
|
|
98
112
|
# Constella self-update - managed by scripts/vps-install.sh. Lets ${RUN_USER} update Constella and restart
|
|
99
113
|
# its service without a password (the in-app Update button + scripts/vps-update.sh). Scoped to two commands.
|
|
100
|
-
${RUN_USER} ALL=(root) NOPASSWD: ${NPM_PATH} install -g constellai, ${NPM_PATH} install -g constellai
|
|
114
|
+
${RUN_USER} ALL=(root) NOPASSWD: ${NPM_PATH} install -g constellai, ${NPM_PATH} install -g constellai@latest, ${SYSTEMCTL_PATH} restart constella, ${SYSTEMCTL_PATH} restart constella.service
|
|
101
115
|
EOF
|
|
102
116
|
if $SUDO "$VISUDO" -cf "$SUDOERS_TMP" >/dev/null 2>&1; then
|
|
103
117
|
$SUDO install -m 0440 -o root -g root "$SUDOERS_TMP" /etc/sudoers.d/constella
|
package/scripts/vps-update.sh
CHANGED
|
@@ -16,28 +16,37 @@ VERSION="${1:-latest}"
|
|
|
16
16
|
RUN_USER="${SUDO_USER:-$(id -un)}"
|
|
17
17
|
|
|
18
18
|
say "• Installing ${PKG}@${VERSION}…"
|
|
19
|
-
|
|
19
|
+
# Install into the SAME prefix the systemd service actually runs from — not npm's default. If an earlier
|
|
20
|
+
# user-level `npm i -g` shadowed the binary, the service's ExecStart may point at a different prefix; a plain
|
|
21
|
+
# `npm i -g` would update the wrong copy and the app would keep showing the old version after a restart.
|
|
22
|
+
SVC_BIN="$(systemctl cat constella 2>/dev/null | sed -n 's/^ExecStart=//p' | head -1 | awk '{print $1}')"
|
|
23
|
+
if [ -n "${SVC_BIN:-}" ] && [ -x "$SVC_BIN" ]; then
|
|
24
|
+
SVC_PREFIX="$(dirname "$(dirname "$SVC_BIN")")"
|
|
25
|
+
say " → service runs ${SVC_BIN} — installing into prefix ${SVC_PREFIX}"
|
|
26
|
+
$SUDO npm install -g --prefix "$SVC_PREFIX" "${PKG}@${VERSION}"
|
|
27
|
+
else
|
|
28
|
+
$SUDO npm install -g "${PKG}@${VERSION}"
|
|
29
|
+
fi
|
|
20
30
|
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
# (Re)write the passwordless self-update drop-in EVERY run (not just when absent) — an older/malformed/wrong-path
|
|
32
|
+
# drop-in left by a previous installer must be REPAIRED, else the in-app "Update now" keeps failing `sudo -n`
|
|
33
|
+
# with no self-heal. Idempotent + validated with visudo before install so a bad file can never lock out sudo.
|
|
34
|
+
NPM_PATH="$(command -v npm || echo /usr/bin/npm)"
|
|
35
|
+
SYSTEMCTL_PATH="$(command -v systemctl || echo /usr/bin/systemctl)"
|
|
36
|
+
# visudo is in /usr/sbin (off a non-root PATH) — resolve it and validate through sudo so it's found + privileged.
|
|
37
|
+
VISUDO="$(command -v visudo || echo /usr/sbin/visudo)"
|
|
38
|
+
SUDOERS_TMP="$(mktemp)"
|
|
39
|
+
# EXACT `constellai@latest` (no trailing `@*` wildcard that could span whitespace into extra root npm flags).
|
|
40
|
+
cat > "$SUDOERS_TMP" <<EOF
|
|
31
41
|
# Constella self-update - managed by scripts/vps-update.sh. Lets ${RUN_USER} update Constella and restart its
|
|
32
42
|
# service without a password (the in-app Update button). Scoped to two commands.
|
|
33
|
-
${RUN_USER} ALL=(root) NOPASSWD: ${NPM_PATH} install -g constellai, ${NPM_PATH} install -g constellai
|
|
43
|
+
${RUN_USER} ALL=(root) NOPASSWD: ${NPM_PATH} install -g constellai, ${NPM_PATH} install -g constellai@latest, ${SYSTEMCTL_PATH} restart constella, ${SYSTEMCTL_PATH} restart constella.service
|
|
34
44
|
EOF
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
fi
|
|
39
|
-
rm -f "$SUDOERS_TMP"
|
|
45
|
+
if $SUDO "$VISUDO" -cf "$SUDOERS_TMP" >/dev/null 2>&1; then
|
|
46
|
+
$SUDO install -m 0440 -o root -g root "$SUDOERS_TMP" /etc/sudoers.d/constella
|
|
47
|
+
say "• Enabled passwordless one-click updates (sudoers.d/constella)."
|
|
40
48
|
fi
|
|
49
|
+
rm -f "$SUDOERS_TMP"
|
|
41
50
|
|
|
42
51
|
if systemctl list-unit-files 2>/dev/null | grep -q '^constella\.service'; then
|
|
43
52
|
say "• Restarting the constella service…"
|