constellai 0.3.4 → 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 +44 -44
- 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 +5 -5
- 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 +2 -2
- 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 +3 -3
- 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_client-reference-manifest.js +1 -1
- package/.next/server/app/(auth)/onboarding/page.js +2 -2
- package/.next/server/app/(auth)/onboarding/page_client-reference-manifest.js +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_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 +1 -1
- package/.next/server/app/api/telegram/poll/route.js +11 -11
- 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/2495.js +1 -0
- package/.next/server/chunks/2517.js +1 -1
- package/.next/server/chunks/259.js +9 -9
- 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/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-486bddbf87074d04.js +1 -0
- 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-8b3e7106703024ce.js +12 -0
- package/.next/static/chunks/9690-ea874aec65263b9d.js +1 -0
- package/.next/static/chunks/app/(app)/activity/{page-09bc1c776962737c.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-d457cdfa525acb85.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-3b78b76ecb21d616.js +1 -0
- package/.next/static/chunks/app/(app)/pm/page-78303379c1ea5dc5.js +1 -0
- 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-cf4e597389865ae8.js → page-cf6a3331775ca11b.js} +1 -1
- 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-809a73b94861f8b8.js +1 -0
- 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 +50 -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 +17 -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 +24 -7
- package/scripts/vps-update.sh +27 -16
- package/.next/server/chunks/319.js +0 -1
- package/.next/server/chunks/4828.js +0 -1
- package/.next/server/chunks/5697.js +0 -1
- package/.next/server/chunks/6151.js +0 -12
- package/.next/server/chunks/6798.js +0 -21
- package/.next/server/chunks/6903.js +0 -417
- package/.next/server/chunks/8486.js +0 -4
- package/.next/static/chunks/3219-9684aa1c634212de.js +0 -1
- package/.next/static/chunks/4353-12629098ed83e468.js +0 -1
- package/.next/static/chunks/4398-e798770ae782576f.js +0 -1
- package/.next/static/chunks/4428-09f7d473d9e33d59.js +0 -1
- package/.next/static/chunks/7457-c37382c6f4e115f8.js +0 -4
- package/.next/static/chunks/8370-6da6aa10d687b8ae.js +0 -12
- package/.next/static/chunks/9690-00ad96a74abac075.js +0 -1
- package/.next/static/chunks/app/(app)/agents/[handle]/page-b11e5f8f25fb2f88.js +0 -1
- package/.next/static/chunks/app/(app)/code/page-ff6925db6e10e3cc.js +0 -1
- package/.next/static/chunks/app/(app)/config/page-4df2facd9c81adb5.js +0 -1
- package/.next/static/chunks/app/(app)/costs/page-c0a07c0283731a8c.js +0 -1
- package/.next/static/chunks/app/(app)/cron/page-662e6e1a25b14025.js +0 -1
- package/.next/static/chunks/app/(app)/dashboard/page-e6f62eaecc0f9926.js +0 -1
- package/.next/static/chunks/app/(app)/docs/[id]/page-4a1be0c9bd6ca402.js +0 -1
- package/.next/static/chunks/app/(app)/docs/page-e6db758a14f57ec8.js +0 -1
- package/.next/static/chunks/app/(app)/github/page-57bb812627d083a1.js +0 -1
- package/.next/static/chunks/app/(app)/goals/page-81e1af515f78e13b.js +0 -1
- package/.next/static/chunks/app/(app)/inbox/page-0baef1b01009c832.js +0 -12
- package/.next/static/chunks/app/(app)/knowledge/page-eb1317bf385e31ed.js +0 -1
- package/.next/static/chunks/app/(app)/layout-dcd4f30b53cb140f.js +0 -1
- package/.next/static/chunks/app/(app)/models/page-d73965ae6ca317e8.js +0 -1
- package/.next/static/chunks/app/(app)/notifications/page-b3ff14483cb6694e.js +0 -12
- package/.next/static/chunks/app/(app)/org/page-3075b218dbc681ce.js +0 -12
- package/.next/static/chunks/app/(app)/organizations/page-a6d35dbb21a61b7c.js +0 -1
- package/.next/static/chunks/app/(app)/page-c9e4fc0616a0083e.js +0 -1
- package/.next/static/chunks/app/(app)/planner/page-809dd3edda4ada93.js +0 -1
- package/.next/static/chunks/app/(app)/plugins/page-7e2aad1b702b5c88.js +0 -1
- package/.next/static/chunks/app/(app)/pm/page-709f9ac68ac98693.js +0 -1
- package/.next/static/chunks/app/(app)/prepare-deploy/page-f9609626153c2483.js +0 -1
- package/.next/static/chunks/app/(app)/profile/page-6d22c7bd0adb7a52.js +0 -1
- package/.next/static/chunks/app/(app)/pulse/page-f529917828ff4884.js +0 -1
- package/.next/static/chunks/app/(app)/reports/[id]/page-662e6e1a25b14025.js +0 -1
- package/.next/static/chunks/app/(app)/reports/page-5248735b18767054.js +0 -1
- package/.next/static/chunks/app/(app)/search/page-4d1e07c4c43a7489.js +0 -1
- package/.next/static/chunks/app/(app)/security/page-db7b8840d9cc6b72.js +0 -1
- package/.next/static/chunks/app/(app)/skills/page-a98da9e415efc310.js +0 -1
- package/.next/static/chunks/app/(app)/tasks/page-ab33402626a50c88.js +0 -1
- package/.next/static/chunks/app/(app)/test-dev/page-34612a4b47ec9aa2.js +0 -1
- package/.next/static/chunks/app/(app)/update/page-99d63495bfdd56a9.js +0 -1
- package/.next/static/chunks/app/(auth)/login/page-c7b372a5053512f0.js +0 -1
- package/.next/static/chunks/app/(auth)/onboarding/page-450bfc87fb942f9b.js +0 -1
- /package/.next/static/{mOVW9EdxrQ1xPT7vDdRdK → fb-rRThu8P8AXEQQBbLgT}/_buildManifest.js +0 -0
- /package/.next/static/{mOVW9EdxrQ1xPT7vDdRdK → fb-rRThu8P8AXEQQBbLgT}/_ssgManifest.js +0 -0
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,9 @@
|
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|
|
|
7
|
-
**Current stable release: `v0.3.
|
|
8
|
-
[Changelog](../CHANGELOG.md) (the Update module also shows it inline as
|
|
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
|
+
“What's new”).
|
|
9
10
|
|
|
10
11
|
> This is the page the **Update** module's “docs” button opens. It tells you, in plain terms, how to move Constella
|
|
11
12
|
> to a newer version — from the app or the terminal — and how to roll back if you ever need to. Your data
|
|
@@ -23,6 +24,20 @@ it didn't earn: the updater writes the real result and the screen reflects it tr
|
|
|
23
24
|
Latest first. The in-app **Update** module shows the changelog inline as “What's new”; this is the same history, kept
|
|
24
25
|
here so the “docs” button always shows what each release added. Full detail: [Changelog](../CHANGELOG.md).
|
|
25
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
|
+
|
|
36
|
+
### v0.3.5 — VPS update polish
|
|
37
|
+
- Dropped the inaccurate **"(Docker)"** label — VPS mode is **native** (systemd + Tailscale, no Docker).
|
|
38
|
+
- Fixed the passwordless self-update drop-in being **skipped at setup** (`visudo` wasn't on the non-root PATH), so
|
|
39
|
+
one-click VPS updates actually get enabled now.
|
|
40
|
+
|
|
26
41
|
### v0.3.4 — a VPS updates itself
|
|
27
42
|
- **One-click updates on a VPS.** **Update now** installs the new release and restarts the service **by itself** —
|
|
28
43
|
it updates the global package, lets **systemd** cycle the unit onto the new code, and the page **reloads itself**
|
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,15 +102,18 @@ $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
|
-
|
|
92
|
-
|
|
105
|
+
# visudo lives in /usr/sbin, which is NOT on a non-root user's PATH (this script may run as the operator via
|
|
106
|
+
# `curl | bash`). Resolve it explicitly and validate THROUGH sudo so it's both found and privileged.
|
|
107
|
+
VISUDO="$(command -v visudo || echo /usr/sbin/visudo)"
|
|
93
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.
|
|
94
111
|
cat > "$SUDOERS_TMP" <<EOF
|
|
95
|
-
# Constella self-update
|
|
112
|
+
# Constella self-update - managed by scripts/vps-install.sh. Lets ${RUN_USER} update Constella and restart
|
|
96
113
|
# its service without a password (the in-app Update button + scripts/vps-update.sh). Scoped to two commands.
|
|
97
|
-
${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
|
|
98
115
|
EOF
|
|
99
|
-
if
|
|
116
|
+
if $SUDO "$VISUDO" -cf "$SUDOERS_TMP" >/dev/null 2>&1; then
|
|
100
117
|
$SUDO install -m 0440 -o root -g root "$SUDOERS_TMP" /etc/sudoers.d/constella
|
|
101
118
|
say " ✓ One-click updates enabled — the Update module can install + restart on its own."
|
|
102
119
|
else
|
package/scripts/vps-update.sh
CHANGED
|
@@ -16,26 +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
|
-
#
|
|
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
|
|
41
|
+
# Constella self-update - managed by scripts/vps-update.sh. Lets ${RUN_USER} update Constella and restart its
|
|
30
42
|
# service without a password (the in-app Update button). Scoped to two commands.
|
|
31
|
-
${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
|
|
32
44
|
EOF
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
fi
|
|
37
|
-
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)."
|
|
38
48
|
fi
|
|
49
|
+
rm -f "$SUDOERS_TMP"
|
|
39
50
|
|
|
40
51
|
if systemctl list-unit-files 2>/dev/null | grep -q '^constella\.service'; then
|
|
41
52
|
say "• Restarting the constella service…"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";exports.id=319,exports.ids=[319,7336],exports.modules={3014:(a,b,c)=>{c.r(b),c.d(b,{"0020ee1e4504363fce8f1b7fda9b92e0b5f0073be2":()=>d.cT,"00aa0d28cabf2459beec6d25ce8d4cc2266ca99154":()=>d.Kd,"40139e6107d1834286c2b80d82e1525a7c0753066e":()=>d.OD,"40664d1b326c4e702d0a3077bb46439f2b2600cd50":()=>d.j0});var d=c(14565)},4719:(a,b,c)=>{c.d(b,{ViewChrome:()=>d});let d=(0,c(62060).registerClientReference)(function(){throw Error("Attempted to call ViewChrome() from the server but ViewChrome is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"C:\\Users\\Usuario\\Documents\\constella\\src\\components\\shell\\view-chrome.tsx","ViewChrome")},5323:(a,b,c)=>{c.d(b,{_:()=>g});var d=c(61576),e=c(1308),f=c(4719);function g({title:a,sub:b,right:c,icon:h,flush:i,children:j}){return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(e.b,{title:a}),(0,d.jsx)(f.ViewChrome,{title:a,sub:b,right:c,icon:h,flush:i,children:j})]})}},18612:(a,b,c)=>{c.d(b,{r$:()=>h,EX:()=>p,CS:()=>function a(b,c=""){let d=[];for(let e of l(b,c))if(e.isDir){if(m.has(e.name))continue;d.push(...a(b,e.path))}else d.push(e.path);return d},HZ:()=>j,Ci:()=>l,sL:()=>n,dx:()=>o});var d=c(73024),e=c(76760),f=c(48161),g=c(28430);function h(){return process.env.CONSTELLA_HOME?(0,g.Y)(process.env.CONSTELLA_HOME):(0,e.join)((0,f.homedir)(),".constella")}let i=new Set;function j(a){if(!/^[A-Za-z0-9_-]{6,64}$/.test(a))throw Error("Invalid orgId");let b=(0,e.join)(h(),"organizations",a,"workspace");if(!i.has(a)){i.add(a);try{let c=(0,e.join)(h(),"organizations",a,"constella"),f=!(0,d.existsSync)(b)||0===(0,d.readdirSync)(b).length;if((0,d.existsSync)(c)&&f)try{(0,d.renameSync)(c,b)}catch{(0,d.mkdirSync)(b,{recursive:!0}),0===(0,d.readdirSync)(b).length&&(0,d.cpSync)(c,b,{recursive:!0})}}catch{}}return b}function k(a,b){let c=(0,e.normalize)((0,e.join)(a,b));if(c!==a&&!c.startsWith(a+e.sep))throw Error("Path escapes workspace: "+b);if((0,d.existsSync)(a)){let f;try{f=d.realpathSync.native(a)}catch{f=a}let g=function(a){let b=a;for(;;){if((0,d.existsSync)(b))try{return d.realpathSync.native(b)}catch{return b}let a=(0,e.dirname)(b);if(a===b)return b;b=a}}(c);if(g!==f&&!g.startsWith(f+e.sep))throw Error("Path escapes workspace (symlink): "+b)}return c}function l(a,b=""){let c=k(j(a),b);return(0,d.existsSync)(c)?(0,d.readdirSync)(c).map(a=>{let f=(0,e.join)(c,a),g=(b?b+"/":"")+a;return{name:a,path:g,isDir:(0,d.statSync)(f).isDirectory()}}).sort((a,b)=>a.isDir===b.isDir?a.name.localeCompare(b.name):a.isDir?-1:1):[]}let m=new Set(["node_modules",".git",".next",".turbo","dist","build","out","coverage",".cache","archives",".testdev",".pnpm-store",".vercel","vendor"]);function n(a,b){let c=k(j(a),b);return(0,d.existsSync)(c)?(0,d.readFileSync)(c,"utf8"):null}function o(a,b,c){let f=k(j(a),b);(0,d.mkdirSync)((0,e.dirname)(f),{recursive:!0}),(0,d.writeFileSync)(f,c,"utf8")}function p(a,b){let c=k(j(a),b);(0,d.existsSync)(c)&&(0,d.rmSync)(c,{recursive:!0,force:!0})}},32367:(a,b,c)=>{c.d(b,{K:()=>e});var d=c(2910);let e=(0,d.createServerReference)("40a38caeec3ba27df94e136db8976ff46f62348474",d.callServer,void 0,d.findSourceMapURL,"previewFrameableAction")},47336:(a,b,c)=>{c.d(b,{checkForUpdate:()=>l});var d=c(73024),e=c(76760),f=c(30043);let g="constellai",h=null,i=a=>a.replace(/^v/,"").split("-")[0].split(".").map(a=>parseInt(a,10)||0);async function j(a){try{let b=new AbortController,c=setTimeout(()=>b.abort(),3e3),d=await fetch(a,{signal:b.signal,headers:{"user-agent":"constella"}});return clearTimeout(c),d.ok?await d.json():null}catch{return null}}async function k(a){try{let b=new AbortController,c=setTimeout(()=>b.abort(),3e3),d=await fetch(a,{signal:b.signal,headers:{"user-agent":"constella"}});return clearTimeout(c),d.ok?await d.text():null}catch{return null}}async function l(a=!1){let b,c,m=function(){if(process.env.CONSTELLA_VERSION)return process.env.CONSTELLA_VERSION;try{let a=JSON.parse((0,d.readFileSync)((0,e.join)((0,f.v)(),"package.json"),"utf8"));if(a?.version)return a.version}catch{}return"0.0.0"}(),n=`npm install -g ${g}@latest`;if(!a&&h&&Date.now()-h.at<216e5)return h.info;let o=await j(`https://registry.npmjs.org/${g}/latest`),p=o?.version??null,q=!!p&&function(a,b){let c=i(a),d=i(b);for(let a=0;a<3;a++){if((c[a]||0)>(d[a]||0))return!0;if((c[a]||0)<(d[a]||0))break}return!1}(p,m),r=null;if(q&&p){let a=await k("https://raw.githubusercontent.com/gabriel7silva/constella/main/CHANGELOG.md");r=a?function(a,b){let c=b.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),d=a.match(RegExp(`(^|\\n)##\\s*\\[?${c}\\]?[\\s\\S]*?(?=\\n##\\s|$)`));if(d)return d[0].trim();let e=a.split(/\n##\s/)[1];return e?"## "+e.trim():null}(a,p):null}let s={current:m,latest:p,updateAvailable:q,type:p?(b=i(p),c=i(m),b[0]>c[0]?"major":b[1]>c[1]?"minor":b[2]>c[2]?"patch":null):null,command:n,changelog:r};return h={at:Date.now(),info:s},s}},51221:(a,b,c)=>{c.d(b,{ViewChrome:()=>h});var d=c(4374),e=c(43526),f=c(48442),g=c(31819);function h({title:a,sub:b,right:c,icon:i,flush:j,children:k}){let l=(0,g.k)(),m=f.e.find(b=>b.title===a),n=i??m?.icon,o=m?l(`mod.${m.id}`):a;return(0,d.jsxs)("div",{className:"app-view",children:[(0,d.jsxs)("div",{className:"view-head",children:[n&&(0,d.jsx)("div",{className:"vh-icon",children:(0,d.jsx)(e.I,{name:n,size:18})}),(0,d.jsxs)("div",{style:{flex:1,minWidth:0},children:[(0,d.jsx)("div",{className:"view-title",children:o}),b&&(0,d.jsx)("div",{className:"view-sub",children:b})]}),c]}),(0,d.jsx)("div",{className:"view-body",style:j?{padding:0,overflow:"hidden"}:void 0,children:k})]})}},52932:(a,b,c)=>{c.d(b,{pM:()=>z,lP:()=>y,Kg:()=>x,eU:()=>B,PG:()=>A});var d=c(6866),e=c(53993),f=c(30043),g=c(64567),h=c(30170);function i(){return(0,h.n)()?"dev":"vps"===(0,g.T)()?"vps":"portable"===(0,g.T)()?"portable":/[\\/]_npx[\\/]/.test((0,f.v)())?"npx":"global"}var j=c(47336),k=c(73024),l=c(76760),m=c(48161),n=c(31421),o=c(57086);let p=()=>new Date().toISOString().replace(/[:.]/g,"-"),q=()=>(0,l.join)((0,o.r$)(),"backups","last-update.json");async function r(){let a=await (0,j.checkForUpdate)(!0),b=i(),c=a.command;if(!a.updateAvailable)return{ok:!0,context:b,command:c,message:"Already up to date."};let d=function(){try{let a=(0,o.r$)(),b=(0,l.join)(a,"backups",p());for(let c of((0,k.mkdirSync)(b,{recursive:!0}),[".env","constella.db","constella.db-wal","constella.db-shm"])){let d=(0,l.join)(a,c);if((0,k.existsSync)(d))try{(0,k.copyFileSync)(d,(0,l.join)(b,c))}catch{}}return b}catch{return null}}()??void 0;if("dev"===b)return{ok:!1,context:b,command:c,backupDir:d,message:"Running from source — update with: git pull && pnpm install && pnpm build"};if("npx"===b)return{ok:!1,context:b,command:c,backupDir:d,message:"npx runs an ephemeral copy — re-run: npx constellai@latest"};if("vps"===b){var e="bash scripts/vps-update.sh";try{(0,k.writeFileSync)(q(),JSON.stringify({status:"running",to:a.latest,at:p()}));let b=(0,o.r$)(),c=process.env.CONSTELLA_PKG_ROOT||process.cwd(),f=(0,l.join)(c,"bin","constella-update.mjs"),g=a.latest?["--version",a.latest]:[];return(0,n.spawn)(process.execPath,[f,"--quiet","--mode","vps","--home",b,...g],{detached:!0,stdio:"ignore",cwd:(0,m.tmpdir)()}).unref(),{ok:!0,started:!0,needsRestart:!0,context:"vps",command:e,backupDir:d,message:`Updating to ${a.latest} and restarting the service — this page reconnects in a few seconds.`}}catch(a){return{ok:!1,context:"vps",command:e,backupDir:d,message:"Couldn't launch the updater: "+String(a instanceof Error?a.message:a)}}}return function(a,b,c,d){try{(0,k.writeFileSync)(q(),JSON.stringify({status:"running",to:a.latest,at:p()}));let e=process.env.CONSTELLA_RUN_MODE||"start",f=process.env.CONSTELLA_LAUNCHER_PID||(process.ppid?String(process.ppid):"0"),g=(0,o.r$)(),h=process.env.PORT||"3000",i=process.env.CONSTELLA_PKG_ROOT||process.cwd(),j=(0,l.join)(i,"bin","constella-update.mjs"),r=a.latest?["--version",a.latest]:[];return(0,n.spawn)(process.execPath,[j,"--quiet","--pid",f,"--mode",e,"--home",g,"--port",h,...r],{detached:!0,stdio:"ignore",windowsHide:!0,cwd:(0,m.tmpdir)()}).unref(),{ok:!0,started:!0,needsRestart:!0,context:b,command:c,backupDir:d,message:`Updating to ${a.latest} and restarting — this page reconnects in a few seconds.`}}catch(a){return{ok:!1,context:b,command:c,backupDir:d,message:"Couldn't launch the updater: "+String(a instanceof Error?a.message:a)}}}(a,b,c,d)}var s=c(97603),t=c(65705),u=c(1890),v=c(10245);async function w(){let a=await t.db.select({lastPulse:u.agent.lastPulse}).from(u.agent).where((0,s.eq)(u.agent.status,"working")),b=Date.now()-v.fQ;return a.some(a=>null!=a.lastPulse&&new Date(a.lastPulse).getTime()>=b)}async function x(a=!1){return(0,j.checkForUpdate)(a)}async function y(a=!1){let[b,c]=await Promise.all([(0,j.checkForUpdate)(a),w()]);return{info:b,busy:c}}async function z(){return i()}async function A(){return(await (0,e.nP)(),await w())?{ok:!1,started:!1,blocked:!0,context:"",command:"",message:"An agent is working — pause it before updating."}:r()}async function B(){try{return JSON.parse((0,k.readFileSync)(q(),"utf8"))}catch{return{status:"idle"}}}(0,c(74252).D)([x,y,z,A,B]),(0,d.A)(x,"4004a6c259bf62ad9da23ecac5c399dfdb19ad08e6",null),(0,d.A)(y,"405ee9cc58fe89e8c6f9f1f265a850575a129a7936",null),(0,d.A)(z,"006dde1a30becdb64e00136e2a0395ca3d1232afdf",null),(0,d.A)(A,"00448c48579abd11cee040b8b9ddca4e41be6f184e",null),(0,d.A)(B,"0083096d6b88e89fee2e833270be160a64f9948543",null)},60686:(a,b,c)=>{c.d(b,{Fy:()=>m,KD:()=>q,Rr:()=>l,TH:()=>s,Xu:()=>r,j0:()=>n,nx:()=>o,zC:()=>p});var d=c(6866),e=c(31371),f=c(53993),g=c(63562),h=c(81204),i=c(70221),j=c(77558),k=c(24701);async function l(){let{org:a,workspace:b}=await (0,f.nP)(),c=await (0,g.ZF)(b.id,a.id);return(0,e.revalidatePath)("/test-dev"),c}async function m(){let{workspace:a}=await (0,f.nP)(),b=await (0,g.n9)(a.id);return(0,e.revalidatePath)("/test-dev"),b}async function n(){let{workspace:a}=await (0,f.nP)();return(0,g.CS)(a.id)}async function o(){let{org:a,workspace:b}=await (0,f.nP)(),c=(0,g.CS)(b.id);if("running"!==c.status&&"starting"!==c.status&&(c=await (0,g.ZF)(b.id,a.id)),!c.url||"running"!==c.status&&"starting"!==c.status)return{ok:!1,error:"The dev server isn't running — start the app first."};let d=await (0,h.nK)(b.id,c.url);return d?{ok:!0,url:d.url}:{ok:!1,error:"Could not start the inspect proxy."}}async function p(){let{workspace:a}=await (0,f.nP)();return(0,h.hA)(a.id),{ok:!0}}async function q(a){if(await (0,f.nP)(),!/^https?:\/\/(127\.0\.0\.1|localhost)(:\d+)?/i.test(a))return{frameable:!0};try{let b=await fetch(a,{redirect:"manual",signal:AbortSignal.timeout(3e3)}),c=(b.headers.get("x-frame-options")||"").toLowerCase(),d=(b.headers.get("content-security-policy")||"").toLowerCase(),e=/frame-ancestors\s+([^;]+)/.exec(d)?.[1]??"",f=c.includes("deny")||c.includes("sameorigin"),g=!!e&&!/(\*|localhost|127\.0\.0\.1)/.test(e);return{frameable:!(f||g)}}catch{return{frameable:!0}}}async function r(a){let{org:b,workspace:c}=await (0,f.nP)(),d=a?.issueId?await (0,i.B)(c.id,a.issueId):void 0,g=await (0,i.z)(c.id,b.id,{goalId:a?.goalId,issueId:a?.issueId,routes:d,by:"operator"});return(0,e.revalidatePath)("/test-dev"),g}async function s(a,b){let{workspace:c}=await (0,f.nP)();return await (0,j.vE)(c.id,{kind:"validation",refType:"validation",refId:a,title:`Validate ${a}`,detail:b.slice(0,500)}),await (0,k.I)(c.id,{kind:"review",text:`Validation requested — ${a}`,detail:b.slice(0,300)}),(0,e.revalidatePath)("/inbox"),{ok:!0}}(0,c(74252).D)([l,m,n,o,p,q,r,s]),(0,d.A)(l,"0052f8e2104f8633ca5df1d85c292d80b538d270cc",null),(0,d.A)(m,"00f45798ef0b92ff36e203fd85a965da22d38dad47",null),(0,d.A)(n,"001f7b38a3f729f9228f00bee7e2a5304a041ae35b",null),(0,d.A)(o,"000b3acc60b4d2b8a70e8d2d829b9aacc71ab61f76",null),(0,d.A)(p,"006d073b0c6542ef6eb5bdce823ce839aa00eb00ce",null),(0,d.A)(q,"40a38caeec3ba27df94e136db8976ff46f62348474",null),(0,d.A)(r,"4097bf88873bcc36e56b144ef77ec8cea15fa3de24",null),(0,d.A)(s,"60e8f7ea058e6f0799881f6c5d494eca17a7a94e72",null)},64567:(a,b,c)=>{c.d(b,{T:()=>e});let d=["start","auth","vps","portable"];function e(){let a=process.env.CONSTELLA_RUN_MODE;return a&&d.includes(a)?a:"start"}},67463:(a,b,c)=>{c.d(b,{j:()=>e});var d=c(2910);let e=(0,d.createServerReference)("001f7b38a3f729f9228f00bee7e2a5304a041ae35b",d.callServer,void 0,d.findSourceMapURL,"devServerStatusAction")},67919:(a,b,c)=>{c.d(b,{R:()=>e});var d=c(2910);let e=(0,d.createServerReference)("0052f8e2104f8633ca5df1d85c292d80b538d270cc",d.callServer,void 0,d.findSourceMapURL,"startDevServerAction")},67949:(a,b,c)=>{c.d(b,{l:()=>g});var d=c(79676),e=c(75785);async function f(){return(0,e.e)((await (0,d.cookies)()).get("cn-lang")?.value)}async function g(){let a=await f();return(b,c)=>(0,e.t)(a,b,c)}}};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";exports.id=4828,exports.ids=[4828],exports.modules={3014:(a,b,c)=>{c.r(b),c.d(b,{"0020ee1e4504363fce8f1b7fda9b92e0b5f0073be2":()=>d.cT,"00aa0d28cabf2459beec6d25ce8d4cc2266ca99154":()=>d.Kd,"40139e6107d1834286c2b80d82e1525a7c0753066e":()=>d.OD,"40664d1b326c4e702d0a3077bb46439f2b2600cd50":()=>d.j0});var d=c(14565)},8304:(a,b,c)=>{c.d(b,{t:()=>e});var d=c(2910);let e=(0,d.createServerReference)("40aed83757bf4e7d35906a784d6f38596d11a37abf",d.callServer,void 0,d.findSourceMapURL,"approveIssue")},10351:(a,b,c)=>{c.d(b,{IssueApprove:()=>x,PlanGate:()=>v,PlanGateLive:()=>u,Run247Button:()=>y,p:()=>w});var d=c(4374),e=c(74679),f=c(47104),g=c(43526),h=c(31819),i=c(73134),j=c(2910);let k=(0,j.createServerReference)("40e3b911773e190273915e8ecd96b865a3e34df027",j.callServer,void 0,j.findSourceMapURL,"generatePlan"),l=(0,j.createServerReference)("009534a6350f6d7ee36028fb9ab4659b11f05bd937",j.callServer,void 0,j.findSourceMapURL,"requestPlanChanges");var m=c(17642),n=c(86955),o=c(72019),p=c(8304),q=c(33387);let r=(0,j.createServerReference)("40ea0236fb2729d70fa5f0bf6383e5f20dfa0c930e",j.callServer,void 0,j.findSourceMapURL,"setAuto247"),s=(0,j.createServerReference)("00194592ad47500e882eca534f2a4293d58ced6167",j.callServer,void 0,j.findSourceMapURL,"skipDesignGate");function t(a,b){window.dispatchEvent(new CustomEvent("constella:open-dm",{detail:{handle:a,text:b}}))}function u({planning:a,planSince:b,designRecommended:c=!1,designPending:j=!1}){let l=(0,h.k)(),[m,n]=(0,e.useTransition)(),o=(0,f.useRouter)(),[p,q]=(0,e.useState)(!1),[r,t]=(0,e.useState)(""),v=a||p;function w(){t(""),q(!0),window.dispatchEvent(new CustomEvent("constella:agent-run",{detail:{channel:"planner"}})),n(async()=>{try{let a=await k();(!a?.ok||!1===a.started)&&(q(!1),a?.error&&t(a.error)),o.refresh()}catch{q(!1),t(l("planner.gate.staleTab"))}})}return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(i.AgentRunLive,{channel:"planner",resume:a,sinceSeq:a?b-1:0,onFinish:()=>q(!1)}),v?(0,d.jsxs)("div",{className:"plan-gate",children:[(0,d.jsx)("div",{className:"plan-gate-bar","aria-hidden":!0}),(0,d.jsx)("div",{className:"pg-ic",children:(0,d.jsx)(g.I,{name:"bot",size:20})}),(0,d.jsxs)("div",{className:"pg-main",children:[(0,d.jsx)("div",{className:"pg-t",children:l("planner.gate.drafting.t")}),(0,d.jsx)("div",{className:"pg-d",children:l("planner.gate.drafting.d")})]})]}):c||j?(0,d.jsxs)("div",{className:"plan-gate",style:{borderColor:"rgba(99,102,241,.45)"},children:[(0,d.jsx)("div",{className:"plan-gate-bar","aria-hidden":!0,style:{background:"#6366f1"}}),(0,d.jsx)("div",{className:"pg-ic",style:{background:"rgba(99,102,241,.16)",color:"#6366f1"},children:(0,d.jsx)(g.I,{name:"skill",size:20})}),(0,d.jsxs)("div",{className:"pg-main",children:[(0,d.jsx)("div",{className:"pg-t",children:j?"Design step pending":"Recommended: prototype the design first"}),(0,d.jsx)("div",{className:"pg-d",children:j?"Ada is holding the plan on the design step. Open the Design module, build & approve the prototype with Grace, then Send to execution — Ada turns the approved design into specs & issues (zero drift).":"This is a frontend product. Prototype & approve the UI in the Design module before generating the plan — Grace turns the brief into a real visual reference, so the specs are precise and you avoid rework."}),r&&(0,d.jsx)("div",{className:"pg-d",style:{color:"var(--sx-keyword)",marginTop:6},children:r})]}),(0,d.jsxs)("div",{className:"pg-actions",children:[(0,d.jsxs)("button",{className:"btn-accent",onClick:()=>o.push("/design"),children:[(0,d.jsx)(g.I,{name:"skill",size:14})," Open Design"]}),(0,d.jsxs)("button",{className:"btn-ghost",disabled:m,onClick:function(){n(async()=>{try{await s()}catch{}}),w()},style:{fontSize:12},children:[(0,d.jsx)(g.I,{name:m?"refresh":"bot",size:13,className:m?"sync-spin":""})," ",m?l("planner.gate.analyzing"):"Skip design & plan anyway"]})]})]}):(0,d.jsxs)("div",{className:"plan-gate",children:[(0,d.jsx)("div",{className:"plan-gate-bar","aria-hidden":!0}),(0,d.jsx)("div",{className:"pg-ic",children:(0,d.jsx)(g.I,{name:"bot",size:20})}),(0,d.jsxs)("div",{className:"pg-main",children:[(0,d.jsx)("div",{className:"pg-t",children:l("planner.gate.noPlan.t")}),(0,d.jsx)("div",{className:"pg-d",children:l("planner.gate.noPlan.d")}),r&&(0,d.jsx)("div",{className:"pg-d",style:{color:"var(--sx-keyword)",marginTop:6},children:r})]}),(0,d.jsxs)("div",{className:"pg-actions",children:[(0,d.jsxs)("div",{className:"plan-hint",children:[(0,d.jsx)("div",{className:"plan-hint-t",children:l("planner.gate.hint.t")}),(0,d.jsx)("div",{className:"plan-hint-d",children:l("planner.gate.hint.d")})]}),(0,d.jsxs)("button",{className:"btn-accent",disabled:m,onClick:w,children:[(0,d.jsx)(g.I,{name:m?"refresh":"bot",size:14,className:m?"sync-spin":""})," ",m?l("planner.gate.analyzing"):l("planner.gate.generate")]})]})]})]})}function v({specs:a,total:b}){let c=(0,h.k)(),[f,i]=(0,e.useTransition)();return(0,d.jsxs)("div",{className:"plan-gate",children:[(0,d.jsx)("div",{className:"pg-ic",children:(0,d.jsx)(g.I,{name:"bot",size:20})}),(0,d.jsxs)("div",{className:"pg-main",children:[(0,d.jsx)("div",{className:"pg-t",children:c("planner.gate.ready.t")}),(0,d.jsx)("div",{className:"pg-d",children:c("planner.gate.ready.d",{specs:a,total:b})})]}),(0,d.jsxs)("div",{className:"pg-actions",children:[(0,d.jsxs)("button",{className:"btn-ghost",disabled:f,onClick:()=>i(async()=>{await l(),t("ada",c("planner.gate.rejectPlanDm"))}),children:[(0,d.jsx)(g.I,{name:"refresh",size:13})," ",c("planner.gate.requestChanges")]}),(0,d.jsxs)("button",{className:"btn-accent",disabled:f,onClick:()=>i(()=>(0,m.P)()),children:[(0,d.jsx)(g.I,{name:"check",size:14})," ",c("planner.gate.approvePlan")]})]})]})}function w({specId:a,specKey:b,approved:c}){let f=(0,h.k)(),[i,j]=(0,e.useTransition)();return c?(0,d.jsxs)("span",{className:"pill",style:{background:"var(--sx-string)22",color:"var(--sx-string)"},children:[(0,d.jsx)(g.I,{name:"check",size:11})," ",f("planner.approved")]}):(0,d.jsxs)("span",{style:{display:"inline-flex",gap:6},children:[(0,d.jsxs)("button",{className:"sc2-btn",disabled:i,onClick:()=>j(()=>(0,n.B)(a)),children:[(0,d.jsx)(g.I,{name:"check",size:11})," ",f("planner.approve")]}),(0,d.jsxs)("button",{className:"sc2-btn danger",disabled:i,onClick:()=>j(async()=>{t((await (0,o.J)(a)).handle,f("planner.rejectItemDm",{key:b}))}),children:[(0,d.jsx)(g.I,{name:"refresh",size:11})," ",f("planner.reject")]})]})}function x({issueId:a,issueKey:b,approved:c}){let f=(0,h.k)(),[i,j]=(0,e.useTransition)();return c?(0,d.jsxs)("span",{className:"pill",style:{background:"var(--sx-string)22",color:"var(--sx-string)"},children:[(0,d.jsx)(g.I,{name:"check",size:11})," ",f("planner.approved")]}):(0,d.jsxs)("span",{style:{display:"inline-flex",gap:6},children:[(0,d.jsxs)("button",{className:"sc2-btn",disabled:i,onClick:()=>j(()=>(0,p.t)(a)),children:[(0,d.jsx)(g.I,{name:"check",size:11})," ",f("planner.approve")]}),(0,d.jsxs)("button",{className:"sc2-btn danger",disabled:i,onClick:()=>j(async()=>{t((await (0,q.d)(a)).handle,f("planner.rejectItemDm",{key:b}))}),children:[(0,d.jsx)(g.I,{name:"refresh",size:11})," ",f("planner.reject")]})]})}function y({auto:a,approved:b,state:c}){let f=(0,h.k)(),[i,j]=(0,e.useTransition)(),k=f(i?a?"planner.run247.pausing":"planner.run247.starting":"waiting-approval"===c?"planner.run247.approveToRun":"all-done"===c?"planner.run247.allDone":a?"planner.run247.pause":"planner.run247.run"),l="blocked"===c?f("planner.run247.blockedTip"):void 0,m="off"===c&&!i;return(0,d.jsxs)("button",{className:"btn-"+(a?"ghost":"accent")+(m?" run-attn":""),disabled:!b||"all-done"===c||i,title:l,onClick:()=>j(()=>r(!a)),children:[(0,d.jsx)(g.I,{name:i?"refresh":"waiting-approval"===c?"bot":"all-done"===c?"check":a?"close":"play",size:14,className:i?"sync-spin":""})," ",k,("running"===c||m)&&(0,d.jsx)("span",{className:"dotpulse",style:{marginLeft:6}})]})}},17642:(a,b,c)=>{c.d(b,{P:()=>e});var d=c(2910);let e=(0,d.createServerReference)("00417fb0c5992b5d8c9bf7bfdb20091c0b75f967d3",d.callServer,void 0,d.findSourceMapURL,"approvePlan")},25543:(a,b,c)=>{c.d(b,{IssueApprove:()=>g,PlanGate:()=>f,PlanGateLive:()=>e,Run247Button:()=>h});var d=c(62060);let e=(0,d.registerClientReference)(function(){throw Error("Attempted to call PlanGateLive() from the server but PlanGateLive is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"C:\\Users\\Usuario\\Documents\\constella\\src\\components\\modules\\plan-gate.tsx","PlanGateLive");(0,d.registerClientReference)(function(){throw Error("Attempted to call GeneratePlanButton() from the server but GeneratePlanButton is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"C:\\Users\\Usuario\\Documents\\constella\\src\\components\\modules\\plan-gate.tsx","GeneratePlanButton");let f=(0,d.registerClientReference)(function(){throw Error("Attempted to call PlanGate() from the server but PlanGate is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"C:\\Users\\Usuario\\Documents\\constella\\src\\components\\modules\\plan-gate.tsx","PlanGate");(0,d.registerClientReference)(function(){throw Error("Attempted to call SpecApprove() from the server but SpecApprove is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"C:\\Users\\Usuario\\Documents\\constella\\src\\components\\modules\\plan-gate.tsx","SpecApprove");let g=(0,d.registerClientReference)(function(){throw Error("Attempted to call IssueApprove() from the server but IssueApprove is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"C:\\Users\\Usuario\\Documents\\constella\\src\\components\\modules\\plan-gate.tsx","IssueApprove"),h=(0,d.registerClientReference)(function(){throw Error("Attempted to call Run247Button() from the server but Run247Button is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"C:\\Users\\Usuario\\Documents\\constella\\src\\components\\modules\\plan-gate.tsx","Run247Button")},33387:(a,b,c)=>{c.d(b,{d:()=>e});var d=c(2910);let e=(0,d.createServerReference)("4088847163a13dc2e80c3095763da6ac497a5b9e37",d.callServer,void 0,d.findSourceMapURL,"rejectIssue")},72019:(a,b,c)=>{c.d(b,{J:()=>e});var d=c(2910);let e=(0,d.createServerReference)("4096c37c3555263308f9a36206eaf746d0defe25ad",d.callServer,void 0,d.findSourceMapURL,"rejectSpec")},73134:(a,b,c)=>{c.d(b,{AgentRunLive:()=>j});var d=c(4374),e=c(74679),f=c(47104),g=c(43526);c(27326);var h=c(31819);let i=["read","create","edit","run","search","thinking","done","error"];function j({channel:a,resume:b=!1,sinceSeq:c=0,onFinish:k}){let l=(0,h.k)();(0,f.useRouter)();let[m,n]=(0,e.useState)(b),[o,p]=(0,e.useState)([]),[q,r]=(0,e.useState)(0);if((0,e.useRef)(b?c:0),(0,e.useRef)(!1),(0,e.useRef)(0),!m&&0===o.length)return null;let s=function(a){let b=[];for(let c of a)if("text"===c.kind){let a=(c.detail||"").replace(/\s+/g," ").trim();if(!a)continue;let d=b[b.length-1];d&&"text"===d.kind?d.content=(d.content+" "+a).slice(-600):b.push({id:c.id,kind:"text",content:a})}else if("thinking"===c.kind){let a=(c.detail||c.target||"").replace(/\s+/g," ").trim();a&&b.push({id:c.id,kind:"thinking",content:a})}else b.push({id:c.id,kind:c.kind,content:function(a){if(!a)return"";let b=a.split(/[\\/]/);return b.length>1?b.slice(-2).join("/"):a}(c.target)||c.detail||""});return b}(o),t=s.slice(-5),u=s.length-t.length,v=o.some(a=>"done"===a.kind||"error"===a.kind),w=o.some(a=>"error"===a.kind),x=String(Math.floor(q/60)).padStart(2,"0"),y=String(q%60).padStart(2,"0");return(0,d.jsxs)("div",{className:"card live-stream",style:{marginBottom:16,borderColor:w?"var(--sx-keyword)":"var(--accent)"},children:[(0,d.jsxs)("div",{className:"set-desc",style:{marginBottom:8,display:"flex",alignItems:"center",gap:7},children:[m&&!v?(0,d.jsx)("span",{className:"dotpulse"}):(0,d.jsx)(g.I,{name:w?"close":"check",size:13,style:{color:w?"var(--sx-keyword)":"var(--sx-string)"}}),m&&!v?l("agent.run.working"):w?l("agent.run.failed"):l("agent.run.finished"),s.length>0&&(0,d.jsxs)("span",{style:{color:"var(--text-faint)"},children:["\xb7 ",l(1===s.length?"agent.run.steps.one":"agent.run.steps.other",{n:s.length})]}),(0,d.jsxs)("span",{className:"live-elapsed",style:{marginLeft:"auto"},children:[x,":",y]})]}),0===t.length?(0,d.jsxs)("div",{className:"muted",style:{fontSize:12,display:"flex",alignItems:"center",gap:7},children:[(0,d.jsx)("span",{className:"sync-spin",children:(0,d.jsx)(g.I,{name:"refresh",size:12})})," ",l("agent.run.reading")]}):(0,d.jsxs)(d.Fragment,{children:[u>0&&(0,d.jsx)("div",{className:"live-more",children:l(1===u?"agent.run.earlier.one":"agent.run.earlier.other",{n:u})}),(0,d.jsx)("div",{className:"live-stream-lines",children:t.map(a=>(0,d.jsxs)("div",{className:"live-line "+a.kind,children:["text"!==a.kind&&(0,d.jsx)("span",{className:"ll-k",children:i.includes(a.kind)?l(`agent.verb.${a.kind}`):a.kind}),(0,d.jsxs)("span",{className:"ll-c",children:[a.content,!v&&a===t[t.length-1]&&"text"===a.kind&&(0,d.jsx)("span",{className:"ll-caret"})]})]},a.id))})]})]})}},86955:(a,b,c)=>{c.d(b,{B:()=>e});var d=c(2910);let e=(0,d.createServerReference)("4019def9d61c1f2ae2b3ef51af11efa0f5c439d65d",d.callServer,void 0,d.findSourceMapURL,"approveSpec")}};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";exports.id=5697,exports.ids=[5697,7336],exports.modules={4719:(a,b,c)=>{c.d(b,{ViewChrome:()=>d});let d=(0,c(62060).registerClientReference)(function(){throw Error("Attempted to call ViewChrome() from the server but ViewChrome is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"C:\\Users\\Usuario\\Documents\\constella\\src\\components\\shell\\view-chrome.tsx","ViewChrome")},5323:(a,b,c)=>{c.d(b,{_:()=>g});var d=c(61576),e=c(1308),f=c(4719);function g({title:a,sub:b,right:c,icon:h,flush:i,children:j}){return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(e.b,{title:a}),(0,d.jsx)(f.ViewChrome,{title:a,sub:b,right:c,icon:h,flush:i,children:j})]})}},7403:(a,b,c)=>{c.d(b,{O:()=>e});var d=c(2910);let e=(0,d.createServerReference)("00cc51162e050f1938c1f15d597fdd4ebe929aa049",d.callServer,void 0,d.findSourceMapURL,"curateKbAction")},9842:(a,b,c)=>{c.d(b,{IZ:()=>k,Ix:()=>j,ZF:()=>m,h6:()=>n,w1:()=>l});var d=c(1782),e=c(76760),f=c(80280),g=c(25533),h=c(18612),i=c(54033);function j(a,b){if(!b)return null;let c=(0,h.HZ)(a),d=((0,e.isAbsolute)(b)?(0,e.relative)(c,b):b).replace(/\\/g,"/");return!d||d.startsWith("..")||d.startsWith(".git/")||d.startsWith(".claude/")||d.startsWith("archives/")?null:d}async function k(a,b,c){let e=(0,d.Uo)((0,d.eq)(g.fileLock.workspaceId,a),(0,d.eq)(g.fileLock.path,b)),[h]=await f.db.select().from(g.fileLock).where(e);if(h){let a=!!c.taskId&&h.taskId===c.taskId,b=!h.taskId&&!!c.agentId&&h.agentId===c.agentId;return a||b?(await f.db.update(g.fileLock).set({heartbeatAt:new Date}).where(e),{ok:!0}):{ok:!1,heldBy:{handle:h.agentHandle,taskId:h.taskId}}}try{return await f.db.insert(g.fileLock).values({workspaceId:a,path:b,taskId:c.taskId||"",agentId:c.agentId||"",agentHandle:c.handle||"",acquiredAt:new Date,heartbeatAt:new Date}),{ok:!0}}catch{let[a]=await f.db.select().from(g.fileLock).where(e);if(a&&(a.taskId===c.taskId||a.agentId===c.agentId))return{ok:!0};return{ok:!1,heldBy:a?{handle:a.agentHandle,taskId:a.taskId}:void 0}}}async function l(a,b){if(b)try{let c=await f.db.select({path:g.fileLock.path}).from(g.fileLock).where((0,d.Uo)((0,d.eq)(g.fileLock.workspaceId,a),(0,d.eq)(g.fileLock.taskId,b)));for(let e of(await f.db.delete(g.fileLock).where((0,d.Uo)((0,d.eq)(g.fileLock.workspaceId,a),(0,d.eq)(g.fileLock.taskId,b))),c))await (0,i.W_)(a,"task",`lock:${e.path}`)}catch{}}async function m(a=3e5){try{await f.db.delete(g.fileLock).where((0,d.lt)(g.fileLock.heartbeatAt,new Date(Date.now()-a)))}catch{}}async function n(a){try{return await f.db.select({path:g.fileLock.path,agentHandle:g.fileLock.agentHandle,taskId:g.fileLock.taskId}).from(g.fileLock).where((0,d.eq)(g.fileLock.workspaceId,a))}catch{return[]}}},47336:(a,b,c)=>{c.d(b,{checkForUpdate:()=>l});var d=c(73024),e=c(76760),f=c(30043);let g="constellai",h=null,i=a=>a.replace(/^v/,"").split("-")[0].split(".").map(a=>parseInt(a,10)||0);async function j(a){try{let b=new AbortController,c=setTimeout(()=>b.abort(),3e3),d=await fetch(a,{signal:b.signal,headers:{"user-agent":"constella"}});return clearTimeout(c),d.ok?await d.json():null}catch{return null}}async function k(a){try{let b=new AbortController,c=setTimeout(()=>b.abort(),3e3),d=await fetch(a,{signal:b.signal,headers:{"user-agent":"constella"}});return clearTimeout(c),d.ok?await d.text():null}catch{return null}}async function l(a=!1){let b,c,m=function(){if(process.env.CONSTELLA_VERSION)return process.env.CONSTELLA_VERSION;try{let a=JSON.parse((0,d.readFileSync)((0,e.join)((0,f.v)(),"package.json"),"utf8"));if(a?.version)return a.version}catch{}return"0.0.0"}(),n=`npm install -g ${g}@latest`;if(!a&&h&&Date.now()-h.at<216e5)return h.info;let o=await j(`https://registry.npmjs.org/${g}/latest`),p=o?.version??null,q=!!p&&function(a,b){let c=i(a),d=i(b);for(let a=0;a<3;a++){if((c[a]||0)>(d[a]||0))return!0;if((c[a]||0)<(d[a]||0))break}return!1}(p,m),r=null;if(q&&p){let a=await k("https://raw.githubusercontent.com/gabriel7silva/constella/main/CHANGELOG.md");r=a?function(a,b){let c=b.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),d=a.match(RegExp(`(^|\\n)##\\s*\\[?${c}\\]?[\\s\\S]*?(?=\\n##\\s|$)`));if(d)return d[0].trim();let e=a.split(/\n##\s/)[1];return e?"## "+e.trim():null}(a,p):null}let s={current:m,latest:p,updateAvailable:q,type:p?(b=i(p),c=i(m),b[0]>c[0]?"major":b[1]>c[1]?"minor":b[2]>c[2]?"patch":null):null,command:n,changelog:r};return h={at:Date.now(),info:s},s}},51221:(a,b,c)=>{c.d(b,{ViewChrome:()=>h});var d=c(4374),e=c(43526),f=c(48442),g=c(31819);function h({title:a,sub:b,right:c,icon:i,flush:j,children:k}){let l=(0,g.k)(),m=f.e.find(b=>b.title===a),n=i??m?.icon,o=m?l(`mod.${m.id}`):a;return(0,d.jsxs)("div",{className:"app-view",children:[(0,d.jsxs)("div",{className:"view-head",children:[n&&(0,d.jsx)("div",{className:"vh-icon",children:(0,d.jsx)(e.I,{name:n,size:18})}),(0,d.jsxs)("div",{style:{flex:1,minWidth:0},children:[(0,d.jsx)("div",{className:"view-title",children:o}),b&&(0,d.jsx)("div",{className:"view-sub",children:b})]}),c]}),(0,d.jsx)("div",{className:"view-body",style:j?{padding:0,overflow:"hidden"}:void 0,children:k})]})}},52932:(a,b,c)=>{c.d(b,{pM:()=>z,lP:()=>y,Kg:()=>x,eU:()=>B,PG:()=>A});var d=c(6866),e=c(53993),f=c(30043),g=c(64567),h=c(30170);function i(){return(0,h.n)()?"dev":"vps"===(0,g.T)()?"vps":"portable"===(0,g.T)()?"portable":/[\\/]_npx[\\/]/.test((0,f.v)())?"npx":"global"}var j=c(47336),k=c(73024),l=c(76760),m=c(48161),n=c(31421),o=c(57086);let p=()=>new Date().toISOString().replace(/[:.]/g,"-"),q=()=>(0,l.join)((0,o.r$)(),"backups","last-update.json");async function r(){let a=await (0,j.checkForUpdate)(!0),b=i(),c=a.command;if(!a.updateAvailable)return{ok:!0,context:b,command:c,message:"Already up to date."};let d=function(){try{let a=(0,o.r$)(),b=(0,l.join)(a,"backups",p());for(let c of((0,k.mkdirSync)(b,{recursive:!0}),[".env","constella.db","constella.db-wal","constella.db-shm"])){let d=(0,l.join)(a,c);if((0,k.existsSync)(d))try{(0,k.copyFileSync)(d,(0,l.join)(b,c))}catch{}}return b}catch{return null}}()??void 0;if("dev"===b)return{ok:!1,context:b,command:c,backupDir:d,message:"Running from source — update with: git pull && pnpm install && pnpm build"};if("npx"===b)return{ok:!1,context:b,command:c,backupDir:d,message:"npx runs an ephemeral copy — re-run: npx constellai@latest"};if("vps"===b){var e="bash scripts/vps-update.sh";try{(0,k.writeFileSync)(q(),JSON.stringify({status:"running",to:a.latest,at:p()}));let b=(0,o.r$)(),c=process.env.CONSTELLA_PKG_ROOT||process.cwd(),f=(0,l.join)(c,"bin","constella-update.mjs"),g=a.latest?["--version",a.latest]:[];return(0,n.spawn)(process.execPath,[f,"--quiet","--mode","vps","--home",b,...g],{detached:!0,stdio:"ignore",cwd:(0,m.tmpdir)()}).unref(),{ok:!0,started:!0,needsRestart:!0,context:"vps",command:e,backupDir:d,message:`Updating to ${a.latest} and restarting the service — this page reconnects in a few seconds.`}}catch(a){return{ok:!1,context:"vps",command:e,backupDir:d,message:"Couldn't launch the updater: "+String(a instanceof Error?a.message:a)}}}return function(a,b,c,d){try{(0,k.writeFileSync)(q(),JSON.stringify({status:"running",to:a.latest,at:p()}));let e=process.env.CONSTELLA_RUN_MODE||"start",f=process.env.CONSTELLA_LAUNCHER_PID||(process.ppid?String(process.ppid):"0"),g=(0,o.r$)(),h=process.env.PORT||"3000",i=process.env.CONSTELLA_PKG_ROOT||process.cwd(),j=(0,l.join)(i,"bin","constella-update.mjs"),r=a.latest?["--version",a.latest]:[];return(0,n.spawn)(process.execPath,[j,"--quiet","--pid",f,"--mode",e,"--home",g,"--port",h,...r],{detached:!0,stdio:"ignore",windowsHide:!0,cwd:(0,m.tmpdir)()}).unref(),{ok:!0,started:!0,needsRestart:!0,context:b,command:c,backupDir:d,message:`Updating to ${a.latest} and restarting — this page reconnects in a few seconds.`}}catch(a){return{ok:!1,context:b,command:c,backupDir:d,message:"Couldn't launch the updater: "+String(a instanceof Error?a.message:a)}}}(a,b,c,d)}var s=c(97603),t=c(65705),u=c(1890),v=c(10245);async function w(){let a=await t.db.select({lastPulse:u.agent.lastPulse}).from(u.agent).where((0,s.eq)(u.agent.status,"working")),b=Date.now()-v.fQ;return a.some(a=>null!=a.lastPulse&&new Date(a.lastPulse).getTime()>=b)}async function x(a=!1){return(0,j.checkForUpdate)(a)}async function y(a=!1){let[b,c]=await Promise.all([(0,j.checkForUpdate)(a),w()]);return{info:b,busy:c}}async function z(){return i()}async function A(){return(await (0,e.nP)(),await w())?{ok:!1,started:!1,blocked:!0,context:"",command:"",message:"An agent is working — pause it before updating."}:r()}async function B(){try{return JSON.parse((0,k.readFileSync)(q(),"utf8"))}catch{return{status:"idle"}}}(0,c(74252).D)([x,y,z,A,B]),(0,d.A)(x,"4004a6c259bf62ad9da23ecac5c399dfdb19ad08e6",null),(0,d.A)(y,"405ee9cc58fe89e8c6f9f1f265a850575a129a7936",null),(0,d.A)(z,"006dde1a30becdb64e00136e2a0395ca3d1232afdf",null),(0,d.A)(A,"00448c48579abd11cee040b8b9ddca4e41be6f184e",null),(0,d.A)(B,"0083096d6b88e89fee2e833270be160a64f9948543",null)},64567:(a,b,c)=>{c.d(b,{T:()=>e});let d=["start","auth","vps","portable"];function e(){let a=process.env.CONSTELLA_RUN_MODE;return a&&d.includes(a)?a:"start"}},67949:(a,b,c)=>{c.d(b,{l:()=>g});var d=c(79676),e=c(75785);async function f(){return(0,e.e)((await (0,d.cookies)()).get("cn-lang")?.value)}async function g(){let a=await f();return(b,c)=>(0,e.t)(a,b,c)}},90388:(a,b,c)=>{c.r(b),c.d(b,{"001b3f03a4be8dae997cef3766f261a8abe4f1f85a":()=>i.V,"0020ba3cad47f2e7c8173f78aff33a686a334486c7":()=>e.GK,"0025f5c700bf585074afe9a3d74daf5d034b95a18d":()=>d.xU,"002dfa6e2da323d4372c36e94679624da8728b1435":()=>e.PE,"00448c48579abd11cee040b8b9ddca4e41be6f184e":()=>n.PG,"004d9216cd0b492704be3f3914da6586dd305de8d5":()=>d.bt,"0065234ec6235cc124d8268103b09cd0ad037b016f":()=>k.io,"006bc3f553199954dcf2c1a667ea89a5b6afe55440":()=>e.y_,"006dde1a30becdb64e00136e2a0395ca3d1232afdf":()=>n.pM,"0083096d6b88e89fee2e833270be160a64f9948543":()=>n.eU,"008385a17df8e9a6678d83c4e627af6724a6f6bd63":()=>h.Mp,"00a15e709e3207ab4c46e487231119285bf1ecb00d":()=>j.f,"00cc51162e050f1938c1f15d597fdd4ebe929aa049":()=>j.O,"00d896599aa05f6b9b14826b3e2ffa5b7a98370f22":()=>e.KO,"00ee9b9abaabf91913653db0b6b047580fe9e40d61":()=>k.eg,"00f01dbe7e3288c64986b5cec39c20d584b4648648":()=>k.dj,"00ffdd5039d3f6a2972d259f688e974bc22fce2faa":()=>h.x7,"4004a6c259bf62ad9da23ecac5c399dfdb19ad08e6":()=>n.Kg,"401b43fc7b171ab4f339d8b50f0126ae09197482ce":()=>k.De,"402a68b40ff3fcd1dda4de0258b9204475d0ee7d46":()=>e.RG,"403917580efb407e1766db48881562b96dbf6c5fcb":()=>h.sE,"403972c138470189ab9c965aa2785e0f74d37a5ec3":()=>l.TX,"40474231a88f9e8bd4f8bcb6d7e140a521cd469e9c":()=>i.VJ,"405e24180c17959a1265888000a45d837e7964045b":()=>h.lR,"405ee9cc58fe89e8c6f9f1f265a850575a129a7936":()=>n.lP,"40632f18c6e8cc524a1b65fbb8e73c1786b9759f01":()=>g.p,"40673eeabfff5b8aa941d94d53ce3478e168718e95":()=>d.rd,"40703e1390372ba8fd666366ceb11519e934daad10":()=>e.S,"407c0cb497cd58cede6444312d86a0897e484fcbf4":()=>e.ey,"408bdae443a0482c1bfbd42dc2b720e682b1423fab":()=>d.VL,"408cb12118c88d982632feabb744bd15c77b28ff96":()=>i.zS,"408ebe3c75c8f47e1a33ca1ac0e850c6a92692ec67":()=>l.IL,"409593733c2627144a84b980b2909a9bf701a39f13":()=>i.E_,"40972e72e17f52772e05b1c26618888916aa0a95cc":()=>d.GW,"40b05dffaf8ef88241a211ca40c5da2d954b5a412e":()=>m.y,"40bc3f927e0fe8d759dd0dea9050858496659453f6":()=>e.jc,"40bdecbf659bb86c86705318c2779dca409a75fc6a":()=>d.gg,"40cee959506187490f4f61c2b214db367eb7ce8ff4":()=>i.F,"40d9ef0b5544036e6021cca383858b56347d4c5411":()=>e.lJ,"40daf6dca3077229fd6d6cbccfd335893f03280125":()=>d.H7,"40e5564668bafedda17fe12ac371e358864fd39c63":()=>g.L,"40e6f8258f8df805f6fcd2e91a396cd355b0751db3":()=>l.q4,"40fb601e332b01b2db0128c9248448e91ee1e8823a":()=>d.Wu,"40fe7401f127a1c1cc7a0858efa9433492cd7b6733":()=>e.r7,"601269a69c549fe5fca4611d91fa20388e33f4e50b":()=>d.rm,"60274f514b61483b6e070a65f4817ee1ad9fe43504":()=>f.k,"6029b8dd07385c22b79cec8930cd425924cfa64f1c":()=>d.n4,"602b26646ec90ca51fda510271d274904b830577d5":()=>l.bV,"603d5aa97fbe0bbf3427d3ee472365f0b23650bcda":()=>e.q$,"6061163d33474b69b44ca71969e7e32eea6632c216":()=>d.Fu,"606c496fc7ae51c9732c206c25c0180519765eb1c5":()=>d.ME,"609bdc02d3153f832541f2c952a5e7cb917a504f2c":()=>l.bk,"60dbdf46cddec83114ce6551fd870fa84f68016765":()=>f.I,"60e3c5311af1bc54bbb9acfb1fdfd248223c4e1b8d":()=>e.LZ,"60e445cd55fb14a068d8f02683ec15e66fd3ae9758":()=>e.AA,"60ebcc6da0ab0e901014ce384cb554138b17e7a52a":()=>l.Jp,"60face35dada2c40df11c8516d8fa9bd434df12801":()=>d.jw,"70134ed93c744753cbd112c32720864d9c20816aac":()=>e.M8,"702777ba042d40b1d5705ed063aec09cc357fcdd61":()=>d._z});var d=c(97140),e=c(15487),f=c(79505),g=c(51605),h=c(46363),i=c(46282),j=c(387),k=c(13604),l=c(7482),m=c(58169),n=c(52932)}};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";exports.id=6151,exports.ids=[6151],exports.modules={3014:(a,b,c)=>{c.r(b),c.d(b,{"0020ee1e4504363fce8f1b7fda9b92e0b5f0073be2":()=>d.cT,"00aa0d28cabf2459beec6d25ce8d4cc2266ca99154":()=>d.Kd,"40139e6107d1834286c2b80d82e1525a7c0753066e":()=>d.OD,"40664d1b326c4e702d0a3077bb46439f2b2600cd50":()=>d.j0});var d=c(14565)},8184:(a,b,c)=>{c.r(b),c.d(b,{"00129bdf84309d37c69af57dcdc7e6d074fd3bbea5":()=>E,"001b3f03a4be8dae997cef3766f261a8abe4f1f85a":()=>i.V,"0020ba3cad47f2e7c8173f78aff33a686a334486c7":()=>e.GK,"0025f5c700bf585074afe9a3d74daf5d034b95a18d":()=>d.xU,"002dfa6e2da323d4372c36e94679624da8728b1435":()=>e.PE,"00448c48579abd11cee040b8b9ddca4e41be6f184e":()=>F.PG,"004d9216cd0b492704be3f3914da6586dd305de8d5":()=>d.bt,"0065234ec6235cc124d8268103b09cd0ad037b016f":()=>k.io,"006bc3f553199954dcf2c1a667ea89a5b6afe55440":()=>e.y_,"006dde1a30becdb64e00136e2a0395ca3d1232afdf":()=>F.pM,"0083096d6b88e89fee2e833270be160a64f9948543":()=>F.eU,"008385a17df8e9a6678d83c4e627af6724a6f6bd63":()=>h.Mp,"00a15e709e3207ab4c46e487231119285bf1ecb00d":()=>j.f,"00cc51162e050f1938c1f15d597fdd4ebe929aa049":()=>j.O,"00d896599aa05f6b9b14826b3e2ffa5b7a98370f22":()=>e.KO,"00ee9b9abaabf91913653db0b6b047580fe9e40d61":()=>k.eg,"00f01dbe7e3288c64986b5cec39c20d584b4648648":()=>k.dj,"00ffdd5039d3f6a2972d259f688e974bc22fce2faa":()=>h.x7,"4004a6c259bf62ad9da23ecac5c399dfdb19ad08e6":()=>F.Kg,"401b43fc7b171ab4f339d8b50f0126ae09197482ce":()=>k.De,"402a68b40ff3fcd1dda4de0258b9204475d0ee7d46":()=>e.RG,"403917580efb407e1766db48881562b96dbf6c5fcb":()=>h.sE,"403972c138470189ab9c965aa2785e0f74d37a5ec3":()=>l.TX,"40414362a918ed9883f7f96063ae909d7764323ac5":()=>A,"40474231a88f9e8bd4f8bcb6d7e140a521cd469e9c":()=>i.VJ,"4049dec62ca0c07db783e6f11261bc1d5b678ebdd6":()=>C,"405e24180c17959a1265888000a45d837e7964045b":()=>h.lR,"405ee9cc58fe89e8c6f9f1f265a850575a129a7936":()=>F.lP,"40632f18c6e8cc524a1b65fbb8e73c1786b9759f01":()=>g.p,"40673eeabfff5b8aa941d94d53ce3478e168718e95":()=>d.rd,"40703e1390372ba8fd666366ceb11519e934daad10":()=>e.S,"407c0cb497cd58cede6444312d86a0897e484fcbf4":()=>e.ey,"408bdae443a0482c1bfbd42dc2b720e682b1423fab":()=>d.VL,"408cb12118c88d982632feabb744bd15c77b28ff96":()=>i.zS,"408ebe3c75c8f47e1a33ca1ac0e850c6a92692ec67":()=>l.IL,"409593733c2627144a84b980b2909a9bf701a39f13":()=>i.E_,"40972e72e17f52772e05b1c26618888916aa0a95cc":()=>d.GW,"40b05dffaf8ef88241a211ca40c5da2d954b5a412e":()=>m.y,"40bc3f927e0fe8d759dd0dea9050858496659453f6":()=>e.jc,"40bd66ddb36ada6eb231c0632d98bf438f9246a503":()=>z,"40bdecbf659bb86c86705318c2779dca409a75fc6a":()=>d.gg,"40c33c80e6fb2e7ccf46054b250a693ed4f1d17cb9":()=>D,"40cee959506187490f4f61c2b214db367eb7ce8ff4":()=>i.F,"40d9ef0b5544036e6021cca383858b56347d4c5411":()=>e.lJ,"40daf6dca3077229fd6d6cbccfd335893f03280125":()=>d.H7,"40e5564668bafedda17fe12ac371e358864fd39c63":()=>g.L,"40e6f8258f8df805f6fcd2e91a396cd355b0751db3":()=>l.q4,"40fb601e332b01b2db0128c9248448e91ee1e8823a":()=>d.Wu,"40fe7401f127a1c1cc7a0858efa9433492cd7b6733":()=>e.r7,"601269a69c549fe5fca4611d91fa20388e33f4e50b":()=>d.rm,"60161a7ce4205a4dfc2110860057bd8a6b5bfa79a6":()=>y,"60274f514b61483b6e070a65f4817ee1ad9fe43504":()=>f.k,"6029b8dd07385c22b79cec8930cd425924cfa64f1c":()=>d.n4,"602b26646ec90ca51fda510271d274904b830577d5":()=>l.bV,"603d5aa97fbe0bbf3427d3ee472365f0b23650bcda":()=>e.q$,"6061163d33474b69b44ca71969e7e32eea6632c216":()=>d.Fu,"606c496fc7ae51c9732c206c25c0180519765eb1c5":()=>d.ME,"6095919e7645e5157a5018dc8231ed407b42b8fd14":()=>B,"609bdc02d3153f832541f2c952a5e7cb917a504f2c":()=>l.bk,"60dbdf46cddec83114ce6551fd870fa84f68016765":()=>f.I,"60e3c5311af1bc54bbb9acfb1fdfd248223c4e1b8d":()=>e.LZ,"60e445cd55fb14a068d8f02683ec15e66fd3ae9758":()=>e.AA,"60ebcc6da0ab0e901014ce384cb554138b17e7a52a":()=>l.Jp,"60face35dada2c40df11c8516d8fa9bd434df12801":()=>d.jw,"70134ed93c744753cbd112c32720864d9c20816aac":()=>e.M8,"702777ba042d40b1d5705ed063aec09cc357fcdd61":()=>d._z});var d=c(97140),e=c(15487),f=c(79505),g=c(51605),h=c(46363),i=c(46282),j=c(387),k=c(13604),l=c(7482),m=c(58169),n=c(6866),o=c(77598),p=c(97603),q=c(31371),r=c(65705),s=c(1890),t=c(53993),u=c(70149),v=c(56338),w=c(24701),x=c(83963);async function y(a,b){let{workspace:c}=await (0,t.nP)();await r.db.update(s.routine).set({enabled:b}).where((0,p.Uo)((0,p.eq)(s.routine.id,a),(0,p.eq)(s.routine.workspaceId,c.id))),(0,q.revalidatePath)("/routines")}async function z(a){let{workspace:b}=await (0,t.nP)(),c=a.name.trim();return c?(await r.db.insert(s.routine).values({id:(0,o.randomUUID)(),workspaceId:b.id,name:c.slice(0,120),cmd:(a.cmd??"").trim().slice(0,500),freq:(a.freq??"Daily").trim()||"Daily",agentId:a.agentId||null,enabled:!0}),(0,q.revalidatePath)("/routines"),{ok:!0}):{ok:!1,error:"Name the routine."}}async function A(a){let{workspace:b}=await (0,t.nP)();await r.db.delete(s.routine).where((0,p.Uo)((0,p.eq)(s.routine.id,a),(0,p.eq)(s.routine.workspaceId,b.id))),(0,q.revalidatePath)("/routines")}async function B(a,b){let{workspace:c}=await (0,t.nP)();await r.db.update(s.plugin).set({enabled:b}).where((0,p.Uo)((0,p.eq)(s.plugin.id,a),(0,p.eq)(s.plugin.workspaceId,c.id))),(0,q.revalidatePath)("/plugins")}async function C(a){let{workspace:b}=await (0,t.nP)();await r.db.delete(s.inboxItem).where((0,p.Uo)((0,p.eq)(s.inboxItem.id,a),(0,p.eq)(s.inboxItem.workspaceId,b.id))),(0,q.revalidatePath)("/inbox")}async function D(a){let{workspace:b}=await (0,t.nP)();await r.db.update(s.finding).set({status:"fixed"}).where((0,p.Uo)((0,p.eq)(s.finding.id,a),(0,p.eq)(s.finding.workspaceId,b.id))),await r.db.insert(s.notification).values({id:(0,o.randomUUID)(),workspaceId:b.id,kind:"security",text:"Finding patched by the Code Review Agent",detail:"A security finding was fixed and a report was filed."}),(0,q.revalidatePath)("/security")}async function E(){let{org:a,workspace:b}=await (0,t.nP)(),c=await r.db.select().from(s.agent).where((0,p.eq)(s.agent.workspaceId,b.id)),d=c.find(a=>"whitfield"===a.handle)??c.find(a=>/cyber|sec/i.test(a.role))??c[0],e=(0,o.randomUUID)();if(!d)return{ok:!1,count:0,runId:e,error:"no agent"};await r.db.update(s.agent).set({status:"working"}).where((0,p.eq)(s.agent.id,d.id)),await (0,f.I)(b.id,{runId:e,channel:"security",agentId:d.id,kind:"thinking",target:`${d.name} is reviewing the workspace…`});let g=await r.db.select({name:s.skill.name,instructions:s.skill.instructions,summary:s.skill.summary}).from(s.agentSkill).innerJoin(s.skill,(0,p.eq)(s.agentSkill.skillId,s.skill.id)).where((0,p.Uo)((0,p.eq)(s.agentSkill.agentId,d.id),(0,p.RV)(s.skill.name,["owasp-top-10","owasp-asvs","appsec-fundamentals","secrets-management","secure-auth-sessions","dependency-supply-chain","review-code-perf-security","code-review-practices"]))),h=g.length?`
|
|
2
|
-
Apply these review skills (consult before judging):
|
|
3
|
-
${g.map(a=>`- ${a.name}: ${(a.instructions||a.summary).replace(/\s+/g," ").slice(0,300)}`).join("\n")}`:"",i=await (0,v.yY)(a.id,"security review: vulnerabilities, auth, secrets, prior findings and decisions",{agentHandle:d.handle,k:6}),j=i.context?`
|
|
4
|
-
Project knowledge (prior findings, decisions, patterns — do not contradict):
|
|
5
|
-
${i.context}`:"",k=[`You are ${d.name}, the security reviewer. Review the code in the current workspace directory for vulnerabilities, secret/token exposure, permission & workspace-isolation issues, and risky patterns.`,h,j,"Output ONLY a JSON array (no prose, no markdown fences) of findings:",'[{"sev":"high"|"med"|"low","title":"short title","file":"relative/path","suggestion":"how to fix"}]',"If the workspace is clean or empty, output []. Do not modify any files."].filter(Boolean).join("\n"),l=(0,u.hW)(d.adapter,d.model),m=(0,u.qX)(d.adapter),n=await (0,u.p1)(k,{orgId:a.id,binary:l,model:m,timeoutMs:24e4},a=>{(0,f.I)(b.id,{runId:e,channel:"security",agentId:d.id,kind:a.kind,target:a.target,detail:a.detail})}),y=[],z=n.text.match(/\[[\s\S]*\]/);if(z)try{y=JSON.parse(z[0])}catch{y=[]}for(let a of y.slice(0,40)){let c="high"===a.sev||"low"===a.sev?a.sev:"med";await r.db.insert(s.finding).values({id:(0,o.randomUUID)(),workspaceId:b.id,sev:c,title:String(a.title??"Finding").slice(0,200),file:String(a.file??""),suggestion:String(a.suggestion??""),status:"open"})}y.length&&(0,v.ru)(a.id,y.slice(0,40).map(a=>({type:"vuln",title:String(a.title??"Finding").slice(0,120),summary:`${a.sev??"med"}: ${String(a.suggestion??"")}`.slice(0,1e3),paths:a.file?[String(a.file)]:void 0,agentHandle:d.handle,sourceKind:"review",sourceRef:`${String(a.file??"")}::${String(a.title??"")}`.slice(0,200)}))).catch(()=>{}),(n.usd>0||n.inputTokens+n.outputTokens>0)&&await r.db.insert(s.costEntry).values({id:(0,o.randomUUID)(),workspaceId:b.id,agentId:d.id,provider:n.binary,model:n.model??d.model,usd:n.usd,tokens:n.inputTokens+n.outputTokens,at:new Date}),await r.db.update(s.workspace).set({settings:{...b.settings??{},lastSecurityRun:Date.now()}}).where((0,p.eq)(s.workspace.id,b.id)),await r.db.update(s.agent).set({status:"idle"}).where((0,p.eq)(s.agent.id,d.id));let A=new Date().toISOString().replace("T"," ").slice(0,19),B=`# Security review
|
|
6
|
-
|
|
7
|
-
_By @${d.handle} (${d.role}) \xb7 ${A}_
|
|
8
|
-
|
|
9
|
-
`+(y.length?`Filed ${y.length} finding(s):
|
|
10
|
-
|
|
11
|
-
`+y.slice(0,40).map(a=>`- **${a.sev??"med"}** ${a.title??"Finding"} — \`${a.file??"?"}\`
|
|
12
|
-
- ${a.suggestion??""}`).join("\n")+"\n":"No findings — the workspace looks clean.\n");try{await (0,x.g)(a.id,"Reports/security-review.md",B)}catch(a){console.error("[review] security report write failed:",a)}return await (0,f.I)(b.id,{runId:e,channel:"security",agentId:d.id,kind:n.ok?"done":"error",target:n.ok?`${y.length} finding(s) filed`:(n.error??"review failed").slice(0,200)}),await (0,w.I)(b.id,{kind:"security",text:"Security sweep finished",detail:`${d.name} filed ${y.length} finding(s).`,agentId:d.id}),(0,q.revalidatePath)("/security"),(0,q.revalidatePath)("/","layout"),{ok:n.ok,count:y.length,runId:e,error:n.error}}(0,c(74252).D)([y,z,A,B,C,D,E]),(0,n.A)(y,"60161a7ce4205a4dfc2110860057bd8a6b5bfa79a6",null),(0,n.A)(z,"40bd66ddb36ada6eb231c0632d98bf438f9246a503",null),(0,n.A)(A,"40414362a918ed9883f7f96063ae909d7764323ac5",null),(0,n.A)(B,"6095919e7645e5157a5018dc8231ed407b42b8fd14",null),(0,n.A)(C,"4049dec62ca0c07db783e6f11261bc1d5b678ebdd6",null),(0,n.A)(D,"40c33c80e6fb2e7ccf46054b250a693ed4f1d17cb9",null),(0,n.A)(E,"00129bdf84309d37c69af57dcdc7e6d074fd3bbea5",null);var F=c(52932)},86450:(a,b,c)=>{c.d(b,{FixButton:()=>f,RunReviewButton:()=>g,Toggle:()=>e});var d=c(62060);let e=(0,d.registerClientReference)(function(){throw Error("Attempted to call Toggle() from the server but Toggle is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"C:\\Users\\Usuario\\Documents\\constella\\src\\components\\modules\\module-toggles.tsx","Toggle");(0,d.registerClientReference)(function(){throw Error("Attempted to call ResolveButton() from the server but ResolveButton is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"C:\\Users\\Usuario\\Documents\\constella\\src\\components\\modules\\module-toggles.tsx","ResolveButton");let f=(0,d.registerClientReference)(function(){throw Error("Attempted to call FixButton() from the server but FixButton is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"C:\\Users\\Usuario\\Documents\\constella\\src\\components\\modules\\module-toggles.tsx","FixButton"),g=(0,d.registerClientReference)(function(){throw Error("Attempted to call RunReviewButton() from the server but RunReviewButton is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"C:\\Users\\Usuario\\Documents\\constella\\src\\components\\modules\\module-toggles.tsx","RunReviewButton")},94724:(a,b,c)=>{c.d(b,{FixButton:()=>n,RunReviewButton:()=>o,Toggle:()=>m});var d=c(4374),e=c(74679),f=c(2910);let g=(0,f.createServerReference)("60161a7ce4205a4dfc2110860057bd8a6b5bfa79a6",f.callServer,void 0,f.findSourceMapURL,"toggleRoutine"),h=(0,f.createServerReference)("6095919e7645e5157a5018dc8231ed407b42b8fd14",f.callServer,void 0,f.findSourceMapURL,"togglePlugin"),i=(0,f.createServerReference)("40c33c80e6fb2e7ccf46054b250a693ed4f1d17cb9",f.callServer,void 0,f.findSourceMapURL,"fixFinding"),j=(0,f.createServerReference)("00129bdf84309d37c69af57dcdc7e6d074fd3bbea5",f.callServer,void 0,f.findSourceMapURL,"runReview");var k=c(43526),l=c(31819);function m({kind:a,id:b,on:c}){let[f,i]=(0,e.useTransition)(),j="routine"===a?g:h;return(0,d.jsx)("div",{className:"toggle"+(c?" on":""),"aria-disabled":f,role:"switch","aria-checked":c,onClick:()=>!f&&i(()=>j(b,!c))})}function n({id:a}){let b=(0,l.k)(),[c,f]=(0,e.useTransition)();return(0,d.jsxs)("button",{className:"sc2-btn",disabled:c,onClick:()=>f(()=>i(a)),children:[(0,d.jsx)(k.I,{name:"bot",size:12})," ",b("security.letAgentFix")]})}function o(){let a=(0,l.k)(),[b,c]=(0,e.useTransition)();return(0,d.jsxs)("button",{className:"btn-accent",disabled:b,onClick:()=>{window.dispatchEvent(new CustomEvent("constella:agent-run",{detail:{channel:"security"}})),c(async()=>{await j()})},children:[(0,d.jsx)(k.I,{name:"refresh",size:14,className:b?"sync-spin":""})," ",a(b?"security.reviewing":"security.runReview")]})}}};
|