trybeacon 0.1.16 → 0.1.18
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 +9 -9
- package/.next/build-manifest.json +3 -3
- package/.next/next-server.js.nft.json +1 -1
- package/.next/prerender-manifest.json +3 -3
- package/.next/required-server-files.js +4 -4
- package/.next/required-server-files.json +4 -4
- package/.next/server/app/_global-error/page.js +3 -3
- 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 +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page.js +2 -2
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +9 -9
- package/.next/server/app/_not-found.segments/_full.segment.rsc +9 -9
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +9 -9
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/api/board-annotations/[id]/route.js +1 -1
- package/.next/server/app/api/board-annotations/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/board-annotations/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/board-annotations/route.js +1 -1
- package/.next/server/app/api/board-annotations/route.js.nft.json +1 -1
- package/.next/server/app/api/board-annotations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/bug-flags/[id]/route.js +1 -1
- package/.next/server/app/api/bug-flags/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/bug-flags/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/bug-flags/route.js +1 -1
- package/.next/server/app/api/bug-flags/route.js.nft.json +1 -1
- package/.next/server/app/api/bug-flags/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/code-graph/position/route.js +1 -1
- package/.next/server/app/api/code-graph/position/route.js.nft.json +1 -1
- package/.next/server/app/api/code-graph/position/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/code-graph/route.js +1 -1
- package/.next/server/app/api/code-graph/route.js.nft.json +1 -1
- package/.next/server/app/api/code-graph/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/context/feature/route.js +1 -1
- package/.next/server/app/api/context/feature/route.js.nft.json +1 -1
- package/.next/server/app/api/context/feature/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/context/file/route.js +1 -1
- package/.next/server/app/api/context/file/route.js.nft.json +1 -1
- package/.next/server/app/api/context/file/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/context/route.js +1 -1
- package/.next/server/app/api/context/route.js.nft.json +1 -1
- package/.next/server/app/api/context/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/db/arrange/route.js +1 -1
- package/.next/server/app/api/db/arrange/route.js.nft.json +1 -1
- package/.next/server/app/api/db/arrange/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/db/backfill-access/route.js +1 -1
- package/.next/server/app/api/db/backfill-access/route.js.nft.json +1 -1
- package/.next/server/app/api/db/backfill-access/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/db/position/route.js +1 -1
- package/.next/server/app/api/db/position/route.js.nft.json +1 -1
- package/.next/server/app/api/db/position/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/db/reconcile-endpoints/route.js +1 -1
- package/.next/server/app/api/db/reconcile-endpoints/route.js.nft.json +1 -1
- package/.next/server/app/api/db/reconcile-endpoints/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/db/relations/[id]/route.js +1 -1
- package/.next/server/app/api/db/relations/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/db/relations/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/db/tables/[id]/route.js +1 -1
- package/.next/server/app/api/db/tables/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/db/tables/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/draft/approve/route.js +2 -2
- package/.next/server/app/api/draft/approve/route.js.nft.json +1 -1
- package/.next/server/app/api/draft/approve/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/draft/route.js +2 -2
- package/.next/server/app/api/draft/route.js.nft.json +1 -1
- package/.next/server/app/api/draft/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/draft/status/route.js +1 -1
- package/.next/server/app/api/draft/status/route.js.nft.json +1 -1
- package/.next/server/app/api/draft/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/edges/[id]/route.js +1 -1
- package/.next/server/app/api/edges/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/edges/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/edges/route.js +1 -1
- package/.next/server/app/api/edges/route.js.nft.json +1 -1
- package/.next/server/app/api/edges/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/endpoints/[id]/route.js +1 -1
- package/.next/server/app/api/endpoints/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/endpoints/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/entities/route.js +1 -1
- package/.next/server/app/api/entities/route.js.nft.json +1 -1
- package/.next/server/app/api/entities/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/feedback/[id]/route.js +1 -1
- package/.next/server/app/api/feedback/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/feedback/[id]/vote/route.js +1 -1
- package/.next/server/app/api/feedback/[id]/vote/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/feedback/route.js +1 -1
- package/.next/server/app/api/feedback/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/ingest/route.js +2 -2
- package/.next/server/app/api/ingest/route.js.nft.json +1 -1
- package/.next/server/app/api/ingest/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/init/route.js +2 -2
- package/.next/server/app/api/init/route.js.nft.json +1 -1
- package/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/map/describe/route.js +2 -2
- package/.next/server/app/api/map/describe/route.js.nft.json +1 -1
- package/.next/server/app/api/map/describe/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/map/files/route.js +1 -1
- package/.next/server/app/api/map/files/route.js.nft.json +1 -1
- package/.next/server/app/api/map/files/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/map/finish/route.js +1 -1
- package/.next/server/app/api/map/finish/route.js.nft.json +1 -1
- package/.next/server/app/api/map/finish/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/map/route.js +1 -1
- package/.next/server/app/api/map/route.js.nft.json +1 -1
- package/.next/server/app/api/map/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/map/start/route.js +1 -1
- package/.next/server/app/api/map/start/route.js.nft.json +1 -1
- package/.next/server/app/api/map/start/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/map/touch-active/route.js +1 -1
- package/.next/server/app/api/map/touch-active/route.js.nft.json +1 -1
- package/.next/server/app/api/map/touch-active/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/nodes/[id]/position/route.js +1 -1
- package/.next/server/app/api/nodes/[id]/position/route.js.nft.json +1 -1
- package/.next/server/app/api/nodes/[id]/position/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/nodes/[id]/route.js +1 -1
- package/.next/server/app/api/nodes/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/nodes/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/nodes/positions/route.js +1 -1
- package/.next/server/app/api/nodes/positions/route.js.nft.json +1 -1
- package/.next/server/app/api/nodes/positions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/nodes/route.js +1 -1
- package/.next/server/app/api/nodes/route.js.nft.json +1 -1
- package/.next/server/app/api/nodes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/nodes/subtasks/route.js +1 -1
- package/.next/server/app/api/nodes/subtasks/route.js.nft.json +1 -1
- package/.next/server/app/api/nodes/subtasks/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/notes/[id]/route.js +1 -1
- package/.next/server/app/api/notes/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/notes/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/notes/route.js +1 -1
- package/.next/server/app/api/notes/route.js.nft.json +1 -1
- package/.next/server/app/api/notes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/open/route.js +1 -1
- package/.next/server/app/api/open/route.js.nft.json +1 -1
- package/.next/server/app/api/open/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/plan/annotations/route.js +2 -2
- package/.next/server/app/api/plan/annotations/route.js.nft.json +1 -1
- package/.next/server/app/api/plan/annotations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/plan/approve/route.js +1 -1
- package/.next/server/app/api/plan/approve/route.js.nft.json +1 -1
- package/.next/server/app/api/plan/approve/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/plan/history/route.js +1 -1
- package/.next/server/app/api/plan/history/route.js.nft.json +1 -1
- package/.next/server/app/api/plan/history/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/plan/markdown/route.js +1 -1
- package/.next/server/app/api/plan/markdown/route.js.nft.json +1 -1
- package/.next/server/app/api/plan/markdown/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/plan/presence/route.js +1 -1
- package/.next/server/app/api/plan/presence/route.js.nft.json +1 -1
- package/.next/server/app/api/plan/presence/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/plan/route.js +1 -1
- package/.next/server/app/api/plan/route.js.nft.json +1 -1
- package/.next/server/app/api/plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/plan/verdict/route.js +2 -2
- package/.next/server/app/api/plan/verdict/route.js.nft.json +1 -1
- package/.next/server/app/api/plan/verdict/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/preferences/route.js +1 -1
- package/.next/server/app/api/preferences/route.js.nft.json +1 -1
- package/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/reset/route.js +1 -1
- package/.next/server/app/api/reset/route.js.nft.json +1 -1
- package/.next/server/app/api/reset/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/stream/route.js +2 -2
- package/.next/server/app/api/stream/route.js.nft.json +1 -1
- package/.next/server/app/api/stream/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/version/route.js +1 -1
- package/.next/server/app/api/version/route.js.nft.json +1 -1
- package/.next/server/app/api/version/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/workspace/activate/route.js +1 -1
- package/.next/server/app/api/workspace/activate/route.js.nft.json +1 -1
- package/.next/server/app/api/workspace/activate/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/workspace/route.js +1 -1
- package/.next/server/app/api/workspace/route.js.nft.json +1 -1
- package/.next/server/app/api/workspace/route_client-reference-manifest.js +1 -1
- package/.next/server/app/apple-icon.png/route.js +1 -1
- package/.next/server/app/docs/page.js +2 -2
- package/.next/server/app/docs/page.js.nft.json +1 -1
- package/.next/server/app/docs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/docs.html +1 -1
- package/.next/server/app/docs.rsc +10 -10
- package/.next/server/app/docs.segments/_full.segment.rsc +10 -10
- package/.next/server/app/docs.segments/_head.segment.rsc +1 -1
- package/.next/server/app/docs.segments/_index.segment.rsc +9 -9
- package/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/docs.segments/docs.segment.rsc +1 -1
- package/.next/server/app/feedback/page.js +2 -2
- package/.next/server/app/feedback/page.js.nft.json +1 -1
- package/.next/server/app/feedback/page_client-reference-manifest.js +1 -1
- package/.next/server/app/feedback.html +1 -1
- package/.next/server/app/feedback.rsc +10 -10
- package/.next/server/app/feedback.segments/_full.segment.rsc +10 -10
- package/.next/server/app/feedback.segments/_head.segment.rsc +1 -1
- package/.next/server/app/feedback.segments/_index.segment.rsc +9 -9
- package/.next/server/app/feedback.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/feedback.segments/feedback/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/feedback.segments/feedback.segment.rsc +1 -1
- package/.next/server/app/help/page.js +2 -2
- package/.next/server/app/help/page.js.nft.json +1 -1
- package/.next/server/app/help/page_client-reference-manifest.js +1 -1
- package/.next/server/app/help.html +1 -1
- package/.next/server/app/help.rsc +28 -29
- package/.next/server/app/help.segments/_full.segment.rsc +28 -29
- package/.next/server/app/help.segments/_head.segment.rsc +1 -1
- package/.next/server/app/help.segments/_index.segment.rsc +9 -9
- package/.next/server/app/help.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/help.segments/help/__PAGE__.segment.rsc +3 -3
- package/.next/server/app/help.segments/help.segment.rsc +1 -1
- package/.next/server/app/icon.svg/route.js +1 -1
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.rsc +10 -10
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/index.segments/_full.segment.rsc +10 -10
- package/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/server/app/index.segments/_index.segment.rsc +9 -9
- package/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/map/page.js +2 -2
- package/.next/server/app/map/page.js.nft.json +1 -1
- package/.next/server/app/map/page_client-reference-manifest.js +1 -1
- package/.next/server/app/page.js +2 -2
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/plan/page.js +2 -2
- package/.next/server/app/plan/page.js.nft.json +1 -1
- package/.next/server/app/plan/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/page.js +2 -2
- package/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +9 -9
- package/.next/server/chunks/2981.js +1 -1
- package/.next/server/chunks/3015.js +1 -0
- package/.next/server/chunks/319.js +3 -3
- package/.next/server/chunks/5258.js +1 -1
- package/.next/server/chunks/7604.js +1 -0
- package/.next/server/chunks/9127.js +1 -1
- package/.next/server/instrumentation.js +1 -1
- package/.next/server/instrumentation.js.nft.json +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware.js +2 -2
- package/.next/server/next-font-manifest.js +1 -1
- package/.next/server/next-font-manifest.json +1 -1
- package/.next/server/pages/404.html +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/9185-2dc95ca34d3ed35e.js +1 -0
- package/.next/static/chunks/app/_not-found/page-57c7dfeb659fcab6.js +1 -0
- package/.next/static/chunks/app/docs/page-5b14c5cfd82e6427.js +1 -0
- package/.next/static/chunks/app/feedback/{page-24a5b2f8d24d9024.js → page-9c313281ba613e34.js} +1 -1
- package/.next/static/chunks/app/help/page-d720609312abff8b.js +1 -0
- package/.next/static/chunks/app/layout-78fefdd943b8c8f9.js +1 -0
- package/.next/static/chunks/app/map/{page-5020db02dba43678.js → page-8a50ebc7430720f9.js} +1 -1
- package/.next/static/chunks/app/{page-2c4582b256e877c0.js → page-bb6bef10a857544d.js} +1 -1
- package/.next/static/chunks/app/plan/{page-cd3785902dd95dce.js → page-8c84c74359ee2ea0.js} +1 -1
- package/.next/static/chunks/app/settings/page-d1b0fe0c79c8a745.js +1 -0
- package/.next/static/chunks/main-app-1a32dc335629e4e4.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/global-error-df87398e192c5e45.js +1 -0
- package/.next/trace +37 -37
- package/.next/trace-build +1 -1
- package/.next/types/app/api/board-annotations/[id]/route.ts +1 -1
- package/.next/types/app/api/board-annotations/route.ts +1 -1
- package/.next/types/app/api/bug-flags/[id]/route.ts +1 -1
- package/.next/types/app/api/bug-flags/route.ts +1 -1
- package/.next/types/app/api/code-graph/position/route.ts +1 -1
- package/.next/types/app/api/code-graph/route.ts +1 -1
- package/.next/types/app/api/context/feature/route.ts +1 -1
- package/.next/types/app/api/context/file/route.ts +1 -1
- package/.next/types/app/api/context/route.ts +1 -1
- package/.next/types/app/api/db/arrange/route.ts +1 -1
- package/.next/types/app/api/db/backfill-access/route.ts +1 -1
- package/.next/types/app/api/db/position/route.ts +1 -1
- package/.next/types/app/api/db/reconcile-endpoints/route.ts +1 -1
- package/.next/types/app/api/db/relations/[id]/route.ts +1 -1
- package/.next/types/app/api/db/tables/[id]/route.ts +1 -1
- package/.next/types/app/api/draft/approve/route.ts +1 -1
- package/.next/types/app/api/draft/route.ts +1 -1
- package/.next/types/app/api/draft/status/route.ts +1 -1
- package/.next/types/app/api/edges/[id]/route.ts +1 -1
- package/.next/types/app/api/edges/route.ts +1 -1
- package/.next/types/app/api/endpoints/[id]/route.ts +1 -1
- package/.next/types/app/api/entities/route.ts +1 -1
- package/.next/types/app/api/feedback/[id]/route.ts +1 -1
- package/.next/types/app/api/feedback/[id]/vote/route.ts +1 -1
- package/.next/types/app/api/feedback/route.ts +1 -1
- package/.next/types/app/api/ingest/route.ts +1 -1
- package/.next/types/app/api/init/route.ts +1 -1
- package/.next/types/app/api/map/describe/route.ts +1 -1
- package/.next/types/app/api/map/files/route.ts +1 -1
- package/.next/types/app/api/map/finish/route.ts +1 -1
- package/.next/types/app/api/map/route.ts +1 -1
- package/.next/types/app/api/map/start/route.ts +1 -1
- package/.next/types/app/api/map/touch-active/route.ts +1 -1
- package/.next/types/app/api/nodes/[id]/position/route.ts +1 -1
- package/.next/types/app/api/nodes/[id]/route.ts +1 -1
- package/.next/types/app/api/nodes/positions/route.ts +1 -1
- package/.next/types/app/api/nodes/route.ts +1 -1
- package/.next/types/app/api/nodes/subtasks/route.ts +1 -1
- package/.next/types/app/api/notes/[id]/route.ts +1 -1
- package/.next/types/app/api/notes/route.ts +1 -1
- package/.next/types/app/api/open/route.ts +1 -1
- package/.next/types/app/api/plan/annotations/route.ts +1 -1
- package/.next/types/app/api/plan/approve/route.ts +1 -1
- package/.next/types/app/api/plan/history/route.ts +1 -1
- package/.next/types/app/api/plan/markdown/route.ts +1 -1
- package/.next/types/app/api/plan/presence/route.ts +1 -1
- package/.next/types/app/api/plan/verdict/route.ts +1 -1
- package/.next/types/app/api/preferences/route.ts +1 -1
- package/.next/types/app/api/reset/route.ts +1 -1
- package/.next/types/app/api/stream/route.ts +1 -1
- package/.next/types/app/api/version/route.ts +1 -1
- package/.next/types/app/api/workspace/activate/route.ts +1 -1
- package/.next/types/app/api/workspace/route.ts +1 -1
- package/.next/types/app/docs/page.ts +1 -1
- package/.next/types/app/feedback/page.ts +1 -1
- package/.next/types/app/help/page.ts +1 -1
- package/.next/types/app/map/page.ts +1 -1
- package/.next/types/app/page.ts +1 -1
- package/.next/types/app/plan/page.ts +1 -1
- package/.next/types/app/settings/page.ts +1 -1
- package/dist/bin/doctor.js +16 -16
- package/dist/bin/hook.js +16 -16
- package/dist/bin/mcp.js +16 -16
- package/dist/bin/plan.js +16 -16
- package/dist/bin/uninstall.js +17 -17
- package/dist/lib/{global-install.js → codex-install.js} +15 -15
- package/package.json +1 -1
- package/.next/server/chunks/1263.js +0 -1
- package/.next/server/chunks/333.js +0 -1
- package/.next/static/chunks/6666-31528aed4743588c.js +0 -1
- package/.next/static/chunks/app/_not-found/page-b2c1eefe2cdbb8c3.js +0 -1
- package/.next/static/chunks/app/docs/page-c28a9d071c9f4e9a.js +0 -1
- package/.next/static/chunks/app/help/page-7ece210a72cf4a67.js +0 -1
- package/.next/static/chunks/app/layout-d4b764b7fd4ec5c6.js +0 -1
- package/.next/static/chunks/app/settings/page-36505744af5d38d8.js +0 -1
- package/.next/static/chunks/main-app-cb1a040ffaced80b.js +0 -1
- package/.next/static/chunks/next/dist/client/components/builtin/global-error-c82bd7a72a198de4.js +0 -1
- /package/.next/static/{fnj-duECSYw_AlTFP7r7a → zLC93esTvoKLzicL2UsF6}/_buildManifest.js +0 -0
- /package/.next/static/{fnj-duECSYw_AlTFP7r7a → zLC93esTvoKLzicL2UsF6}/_ssgManifest.js +0 -0
package/dist/bin/doctor.js
CHANGED
|
@@ -206,20 +206,7 @@ ${Y}
|
|
|
206
206
|
`)?V:`${V}
|
|
207
207
|
`)}function R(Q,Z){try{return S(Q,"utf8").includes(Z)}catch{return!1}}function t(Q,Z,$){let J="";try{J=S(Q,"utf8")}catch{return!1}let Y=new RegExp(`${Z}[\\s\\S]*?${$}\\n?`);if(!Y.test(J))return!1;let V=J.replace(Y,"").replace(/\n{3,}/g,`
|
|
208
208
|
|
|
209
|
-
`).trimStart();return m(Q,V),!0}function s(Q,Z,$){let J=h(Q,Z);HQ(J,{recursive:!0});let Y=h(J,"SKILL.md");return m(Y,$),Y}function E(Q,Z){return kQ(h(Q,Z,"SKILL.md"))}function a(Q,Z){let $=h(Q,Z);if(!kQ($))return!1;return TZ($,{recursive:!0,force:!0}),!0}var BQ=()=>{};import{mkdirSync as uZ,renameSync as FZ,rmSync as gZ,writeFileSync as RZ}from"fs";import{dirname as EZ}from"path";function vQ(Q,Z){uZ(EZ(Q),{recursive:!0});let $=`${Q}.tmp`;try{RZ($,Z),FZ($,Q)}catch(J){throw gZ($,{force:!0}),J}}var SQ=()=>{};
|
|
210
|
-
`)?`
|
|
211
|
-
`:`
|
|
212
|
-
|
|
213
|
-
`,J=Q+$+DZ;if(D(J)?.mcp_servers?.beacon?.command!=="beacon")return{added:!1,error:`could not safely append [mcp_servers.beacon] \u2014 ${I}`};return vQ(T(),J),{added:!0}}function tQ(){let Q="";try{Q=o(T(),"utf8")}catch{return{removed:!1}}let Z=Q.split(`
|
|
214
|
-
`),$=Z.indexOf(cQ);if($===-1)return{removed:!1,skipped:KQ()};let J=Z.indexOf(lQ,$);if(J===-1)return{removed:!1,skipped:!0};Z.splice($,J-$+1);let Y=Z.join(`
|
|
215
|
-
`).replace(/\n{3,}/g,`
|
|
216
|
-
|
|
217
|
-
`).replace(/^\n+/,"");if(D(Y)===null)return{removed:!1,skipped:!0};return vQ(T(),Y),{removed:!0}}async function OZ(){let{INIT_SKILL:Q,REFRESH_SKILL:Z,PLAN_SKILL:$}=await Promise.resolve().then(() => (L(),PQ)),J={"beacon-init":Q,"beacon-refresh":Z,"beacon-plan":$},Y=[];for(let z of B){if(!E(r(),z))Y.push(z);s(r(),z,J[z])}let V=0;for(let z of K)if(p(xQ(),{event:z.event,matcher:z.matcher,command:z.command}))V++;let X=R(d(),i);n(d(),i,pQ,wQ);let U=nQ();return{skillsAdded:Y,hooksAdded:V,agentsMdBlockTouched:!X,mcp:U}}function MQ(){let Q={};for(let $ of B)Q[$]=E(r(),$);let Z={};for(let $ of K)Z[$.event]=c(xQ(),{event:$.event,command:$.command});return{detected:e(),skills:Q,hooks:Z,agentsMdBlock:R(d(),i),mcp:KQ()}}function AZ(){let Q=[];for(let Y of B)if(a(r(),Y))Q.push(Y);let Z=0;for(let Y of K)if(l(xQ(),{event:Y.event,command:Y.command}))Z++;let $=t(d(),i,pQ),J=tQ();return{skillsRemoved:Q,hooksRemoved:Z,agentsMdBlockRemoved:$,mcpRemoved:J.removed,mcpSkipped:J.skipped}}var GQ=()=>O(mQ(),".codex"),xQ=()=>O(GQ(),"hooks.json"),T=()=>O(GQ(),"config.toml"),d=()=>O(GQ(),"AGENTS.md"),r=()=>O(mQ(),".agents","skills"),i="<!-- beacon:global:start -->",pQ="<!-- beacon:global:end -->",K,NQ,cQ="# beacon:start (managed by Beacon \u2014 `beacon uninstall` removes this block)",lQ="# beacon:end",DZ,I="add it manually: codex mcp add beacon -- beacon mcp";var fQ=f(()=>{BQ();SQ();TQ();K=[{event:"PostToolUse",matcher:"apply_patch",command:"beacon hook",description:"Report file edits to Beacon's active feature so the map stays fresh."},{event:"UserPromptSubmit",matcher:"*",command:"beacon prompt",description:"On feature-y prompts in a Beacon-wired repo, remind the agent to run the context\u2192propose\u2192describe loop (no-op otherwise)."},{event:"Stop",matcher:"*",command:"beacon stop-hook",description:"When the agent ends a turn asking for plan approval in prose, nudge it to present the plan on Beacon's /plan canvas."}];DZ=`${cQ}
|
|
218
|
-
[mcp_servers.beacon]
|
|
219
|
-
command = "beacon"
|
|
220
|
-
args = ["mcp"]
|
|
221
|
-
${lQ}
|
|
222
|
-
`});import{existsSync as yZ}from"fs";import{homedir as bZ}from"os";import{join as QQ}from"path";function _Z(){return process.env.HOME||process.env.USERPROFILE||bZ()}function kZ(Q,Z){return s(uQ(),Q,Z)}function dQ(Q){return E(uQ(),Q)}function LZ(Q){return a(uQ(),Q)}function hZ(Q){return p(FQ(),Q)}function SZ(Q){return c(FQ(),Q)}function mZ(Q){return l(FQ(),Q)}function pZ(Q){n(gQ(),RQ,aQ,Q)}function rQ(){return R(gQ(),RQ)}function cZ(){return t(gQ(),RQ,aQ)}function iQ(){let Q={};for(let $ of B)Q[$]=dQ($);let Z={};for(let $ of u)Z[$.event]=SZ({event:$.event,command:$.command});return{homeExists:yZ(ZQ()),skills:Q,hooks:Z,claudeMdBlock:rQ()}}async function lZ(){let{INIT_SKILL:Q,REFRESH_SKILL:Z,PLAN_SKILL:$}=await Promise.resolve().then(() => (L(),PQ)),J={"beacon-init":Q,"beacon-refresh":Z,"beacon-plan":$},Y=[];for(let U of B){if(!dQ(U))Y.push(U);kZ(U,J[U])}let V=0;for(let U of u)if(hZ({event:U.event,matcher:U.matcher,command:U.command}))V++;let X=rQ();return pZ(wQ),{skillsAdded:Y,hooksAdded:V,claudeMdBlockTouched:!X}}async function p0(){let Q;try{Q={ok:!0,...await lZ()}}catch(Z){Q={ok:!1,error:Z instanceof Error?Z.message:String(Z),skillsAdded:[],hooksAdded:0,claudeMdBlockTouched:!1}}try{let Z=await Promise.resolve().then(() => (fQ(),sQ));if(Z.codexDetected())Q.codex={ok:!0,...await Z.setupCodexAssets()}}catch(Z){Q.codex={ok:!1,error:Z instanceof Error?Z.message:String(Z),skillsAdded:[],hooksAdded:0,agentsMdBlockTouched:!1,mcp:{added:!1}}}return Q}function c0(){let Q=[];for(let J of B)if(LZ(J))Q.push(J);let Z=0;for(let J of u)if(mZ(J))Z++;let $=cZ();return{skillsRemoved:Q,hooksRemoved:Z,claudeMdBlockRemoved:$}}var ZQ=()=>QQ(_Z(),".claude"),uQ=()=>QQ(ZQ(),"skills"),FQ=()=>QQ(ZQ(),"settings.json"),gQ=()=>QQ(ZQ(),"CLAUDE.md"),RQ="<!-- beacon:global:start -->",aQ="<!-- beacon:global:end -->",B,u,wQ=`## Beacon (visual planning panel)
|
|
209
|
+
`).trimStart();return m(Q,V),!0}function s(Q,Z,$){let J=h(Q,Z);HQ(J,{recursive:!0});let Y=h(J,"SKILL.md");return m(Y,$),Y}function E(Q,Z){return kQ(h(Q,Z,"SKILL.md"))}function a(Q,Z){let $=h(Q,Z);if(!kQ($))return!1;return TZ($,{recursive:!0,force:!0}),!0}var BQ=()=>{};import{mkdirSync as uZ,renameSync as FZ,rmSync as gZ,writeFileSync as RZ}from"fs";import{dirname as EZ}from"path";function vQ(Q,Z){uZ(EZ(Q),{recursive:!0});let $=`${Q}.tmp`;try{RZ($,Z),FZ($,Q)}catch(J){throw gZ($,{force:!0}),J}}var SQ=()=>{};import{existsSync as IZ}from"fs";import{homedir as DZ}from"os";import{join as d}from"path";function OZ(){return process.env.HOME||process.env.USERPROFILE||DZ()}function AZ(Q,Z){return s(GQ(),Q,Z)}function cQ(Q){return E(GQ(),Q)}function yZ(Q){return a(GQ(),Q)}function bZ(Q){return p(xQ(),Q)}function _Z(Q){return c(xQ(),Q)}function kZ(Q){return l(xQ(),Q)}function LZ(Q){n(KQ(),CQ,pQ,Q)}function lQ(){return R(KQ(),CQ)}function hZ(){return t(KQ(),CQ,pQ)}function nQ(){let Q={};for(let $ of B)Q[$]=cQ($);let Z={};for(let $ of T)Z[$.event]=_Z({event:$.event,command:$.command});return{homeExists:IZ(r()),skills:Q,hooks:Z,claudeMdBlock:lQ()}}async function SZ(){let{INIT_SKILL:Q,REFRESH_SKILL:Z,PLAN_SKILL:$}=await Promise.resolve().then(() => (L(),PQ)),J={"beacon-init":Q,"beacon-refresh":Z,"beacon-plan":$},Y=[];for(let U of B){if(!cQ(U))Y.push(U);AZ(U,J[U])}let V=0;for(let U of T)if(bZ({event:U.event,matcher:U.matcher,command:U.command}))V++;let X=lQ();return LZ(MQ),{skillsAdded:Y,hooksAdded:V,claudeMdBlockTouched:!X}}async function _0(){let Q;try{Q={ok:!0,...await SZ()}}catch(Z){Q={ok:!1,error:Z instanceof Error?Z.message:String(Z),skillsAdded:[],hooksAdded:0,claudeMdBlockTouched:!1}}try{let Z=await Promise.resolve().then(() => (NQ(),mQ));if(Z.codexDetected())Q.codex={ok:!0,...await Z.setupCodexAssets()}}catch(Z){Q.codex={ok:!1,error:Z instanceof Error?Z.message:String(Z),skillsAdded:[],hooksAdded:0,agentsMdBlockTouched:!1,mcp:{added:!1}}}return Q}function k0(){let Q=[];for(let J of B)if(yZ(J))Q.push(J);let Z=0;for(let J of T)if(kZ(J))Z++;let $=hZ();return{skillsRemoved:Q,hooksRemoved:Z,claudeMdBlockRemoved:$}}var r=()=>d(OZ(),".claude"),GQ=()=>d(r(),"skills"),xQ=()=>d(r(),"settings.json"),KQ=()=>d(r(),"CLAUDE.md"),CQ="<!-- beacon:global:start -->",pQ="<!-- beacon:global:end -->",B,T,MQ=`## Beacon (visual planning panel)
|
|
223
210
|
|
|
224
211
|
This machine has Beacon installed \u2014 a local visual planning surface for the terminal-side
|
|
225
212
|
agent. Beacon proposes feature plans (roadmap features + DB schema + endpoints) via MCP,
|
|
@@ -240,6 +227,19 @@ the user reviews on a canvas at /plan, and feedback flows back as the next round
|
|
|
240
227
|
Feedback bundles inline annotations on the markdown PLUS any edits the user made directly
|
|
241
228
|
on the /map and /db boards (added features, attached subtasks, edited columns, new
|
|
242
229
|
endpoints). Treat board edits as the user's revision intent \u2014 re-propose matching them
|
|
243
|
-
verbatim. Do NOT implement until the tool returns approval.`;var
|
|
244
|
-
|
|
230
|
+
verbatim. Do NOT implement until the tool returns approval.`;var fQ=f(()=>{BQ();B=["beacon-init","beacon-refresh","beacon-plan"],T=[{event:"PostToolUse",matcher:"Edit|Write|MultiEdit",command:"beacon hook",description:"Report file edits to Beacon's active feature so the map stays fresh."},{event:"PermissionRequest",matcher:"ExitPlanMode",command:"beacon plan",description:"Pipe the agent's plan markdown into Beacon's /plan canvas for review."},{event:"UserPromptSubmit",matcher:"*",command:"beacon prompt",description:"On feature-y prompts in a Beacon-wired repo, remind the agent to run the context\u2192propose\u2192describe loop (no-op otherwise)."},{event:"Stop",matcher:"*",command:"beacon stop-hook",description:"When the agent ends a turn asking for plan approval in prose (instead of presenting it), nudge it to present the plan on Beacon's /plan canvas. Bounded by stop_hook_active \u2014 at most one nudge."}]});var mQ={};zQ(mQ,{setupCodexAssets:()=>cZ,removeCodexMcp:()=>iQ,removeCodexArtifacts:()=>lZ,hasCodexMcp:()=>FQ,ensureCodexMcp:()=>rQ,codexMcpProblem:()=>gQ,codexDetected:()=>ZQ,auditCodex:()=>RQ,CODEX_HOOKS:()=>K});import{readFileSync as QQ}from"fs";import{homedir as mZ}from"os";import{join as O}from"path";function tQ(){return process.env.HOME||process.env.USERPROFILE||mZ()}function ZQ(){if(process.env.BEACON_CODEX==="1")return!0;if(process.env.BEACON_CODEX==="0")return!1;if(wQ===void 0)wQ=Bun.which("codex")!==null;return wQ}function D(Q){try{return Bun.TOML.parse(Q)}catch{return null}}function FQ(){try{return Boolean(D(QQ(u(),"utf8"))?.mcp_servers?.beacon)}catch{return!1}}function gQ(){let Q="";try{Q=QQ(u(),"utf8")}catch{return null}let Z=D(Q);if(!Z)return`~/.codex/config.toml does not parse \u2014 ${I}`;if(Z.mcp_servers?.beacon)return null;if(/^\s*mcp_servers\s*=/m.test(Q))return`mcp_servers is an inline table \u2014 ${I}`;return null}function rQ(){let Q="",Z=!1;try{Q=QQ(u(),"utf8"),Z=!0}catch{}if(Z){let V=D(Q);if(!V)return{added:!1,error:`~/.codex/config.toml does not parse \u2014 ${I}`};if(V.mcp_servers?.beacon)return{added:!1};if(/^\s*mcp_servers\s*=/m.test(Q))return{added:!1,error:`mcp_servers is an inline table \u2014 ${I}`}}let $=!Q?"":Q.endsWith(`
|
|
231
|
+
`)?`
|
|
232
|
+
`:`
|
|
233
|
+
|
|
234
|
+
`,J=Q+$+pZ;if(D(J)?.mcp_servers?.beacon?.command!=="beacon")return{added:!1,error:`could not safely append [mcp_servers.beacon] \u2014 ${I}`};return vQ(u(),J),{added:!0}}function iQ(){let Q="";try{Q=QQ(u(),"utf8")}catch{return{removed:!1}}let Z=Q.split(`
|
|
235
|
+
`),$=Z.indexOf(aQ);if($===-1)return{removed:!1,skipped:FQ()};let J=Z.indexOf(dQ,$);if(J===-1)return{removed:!1,skipped:!0};Z.splice($,J-$+1);let Y=Z.join(`
|
|
236
|
+
`).replace(/\n{3,}/g,`
|
|
237
|
+
|
|
238
|
+
`).replace(/^\n+/,"");if(D(Y)===null)return{removed:!1,skipped:!0};return vQ(u(),Y),{removed:!0}}async function cZ(){let{INIT_SKILL:Q,REFRESH_SKILL:Z,PLAN_SKILL:$}=await Promise.resolve().then(() => (L(),PQ)),J={"beacon-init":Q,"beacon-refresh":Z,"beacon-plan":$},Y=[];for(let z of B){if(!E(o(),z))Y.push(z);s(o(),z,J[z])}let V=0;for(let z of K)if(p(uQ(),{event:z.event,matcher:z.matcher,command:z.command}))V++;let X=R(i(),e);n(i(),e,sQ,MQ);let U=rQ();return{skillsAdded:Y,hooksAdded:V,agentsMdBlockTouched:!X,mcp:U}}function RQ(){let Q={};for(let $ of B)Q[$]=E(o(),$);let Z={};for(let $ of K)Z[$.event]=c(uQ(),{event:$.event,command:$.command});return{detected:ZQ(),skills:Q,hooks:Z,agentsMdBlock:R(i(),e),mcp:FQ()}}function lZ(){let Q=[];for(let Y of B)if(a(o(),Y))Q.push(Y);let Z=0;for(let Y of K)if(l(uQ(),{event:Y.event,command:Y.command}))Z++;let $=t(i(),e,sQ),J=iQ();return{skillsRemoved:Q,hooksRemoved:Z,agentsMdBlockRemoved:$,mcpRemoved:J.removed,mcpSkipped:J.skipped}}var TQ=()=>O(tQ(),".codex"),uQ=()=>O(TQ(),"hooks.json"),u=()=>O(TQ(),"config.toml"),i=()=>O(TQ(),"AGENTS.md"),o=()=>O(tQ(),".agents","skills"),e="<!-- beacon:global:start -->",sQ="<!-- beacon:global:end -->",K,wQ,aQ="# beacon:start (managed by Beacon \u2014 `beacon uninstall` removes this block)",dQ="# beacon:end",pZ,I="add it manually: codex mcp add beacon -- beacon mcp";var NQ=f(()=>{BQ();SQ();fQ();K=[{event:"PostToolUse",matcher:"apply_patch",command:"beacon hook",description:"Report file edits to Beacon's active feature so the map stays fresh."},{event:"UserPromptSubmit",matcher:"*",command:"beacon prompt",description:"On feature-y prompts in a Beacon-wired repo, remind the agent to run the context\u2192propose\u2192describe loop (no-op otherwise)."},{event:"Stop",matcher:"*",command:"beacon stop-hook",description:"When the agent ends a turn asking for plan approval in prose, nudge it to present the plan on Beacon's /plan canvas."}];pZ=`${aQ}
|
|
239
|
+
[mcp_servers.beacon]
|
|
240
|
+
command = "beacon"
|
|
241
|
+
args = ["mcp"]
|
|
242
|
+
${dQ}
|
|
243
|
+
`});var eQ={};zQ(eQ,{provisionDb:()=>$0});import{createClient as nZ}from"@libsql/client";import{drizzle as tZ}from"drizzle-orm/libsql";import{migrate as sZ}from"drizzle-orm/libsql/migrator";import{readMigrationFiles as aZ}from"drizzle-orm/migrator";import{dirname as EQ,join as dZ}from"path";import{fileURLToPath as rZ}from"url";async function $Q(Q,Z){return(await Q.execute({sql:"SELECT 1 FROM sqlite_master WHERE type='table' AND name = ?",args:[Z]})).rows.length>0}async function Q0(Q,Z){let $=await Q.execute(`PRAGMA table_info("${Z}")`);return new Set($.rows.map((J)=>String(J.name)))}async function oQ(Q){if(!await $Q(Q,"__drizzle_migrations"))return 0;let Z=await Q.execute('SELECT count(*) AS n FROM "__drizzle_migrations"');return Number(Z.rows[0]?.n??0)}async function Z0(Q){for(let[Z,$]of Object.entries(eZ)){if(!await $Q(Q,Z))continue;let J=await Q0(Q,Z);for(let Y of $){if(!J.has(Y))continue;await Q.execute(`UPDATE "${Z}" SET "${Y}" = CAST((julianday("${Y}") - 2440587.5) * 86400000 AS INTEGER) WHERE typeof("${Y}") = 'text'`)}}}async function $0(Q,Z=oZ){let $=nZ({url:Q});try{await $.execute("PRAGMA journal_mode = WAL;"),await $.execute("PRAGMA foreign_keys = ON;");let J=await $Q($,"__drizzle_migrations"),Y=await $Q($,"Node"),V=!1;if(Y&&!J){let U=aZ({migrationsFolder:Z})[0];if(U)await $.execute('CREATE TABLE IF NOT EXISTS "__drizzle_migrations" (id SERIAL PRIMARY KEY, hash text NOT NULL, created_at numeric)'),await $.execute({sql:'INSERT INTO "__drizzle_migrations" ("hash", "created_at") VALUES (?, ?)',args:[U.hash,U.folderMillis]}),V=!0}let X=await oQ($);if(await sZ(tZ($),{migrationsFolder:Z}),await oQ($)>X)V=!0;return await Z0($),{migrated:V}}finally{$.close()}}var iZ,oZ,eZ;var QZ=f(async()=>{iZ=EQ(EQ(EQ(rZ(import.meta.url)))),oZ=process.env.BEACON_MIGRATIONS_DIR||dZ(iZ,"drizzle"),eZ={Node:["createdAt","updatedAt"],Note:["createdAt","updatedAt"],DbTable:["createdAt","updatedAt"],Endpoint:["createdAt","updatedAt"],DraftTable:["createdAt"],SyncState:["codeGraphSyncedAt","updatedAt"],AppSetting:["updatedAt"],ProjectMeta:["updatedAt"],CodeFile:["updatedAt"]}});import{AsyncLocalStorage as J0}from"async_hooks";import{spawnSync as Y0}from"child_process";import{createHash as V0}from"crypto";import{existsSync as $Z,mkdirSync as JQ,readFileSync as JZ,writeFileSync as YZ}from"fs";import{homedir as z0}from"os";import{basename as q0,join as F}from"path";function x(){return process.env.BEACON_HOME||F(z0(),".beacon")}function IQ(){return F(x(),"workspaces.json")}function VZ(Q){return V0("sha256").update(Q).digest("hex").slice(0,12)}function J1(Q=process.cwd()){let Z=Y0("git",["rev-parse","--show-toplevel"],{cwd:Q,stdio:["ignore","pipe","ignore"]});if(Z.status===0){let $=Z.stdout?.toString().trim();if($)return $}return Q}function DQ(Q){return F(x(),Q)}function X0(Q){return`file:${F(DQ(Q),"db.sqlite")}`}function A(){try{let Q=JSON.parse(JZ(IQ(),"utf8"));return Array.isArray(Q)?Q:[]}catch{return[]}}function OQ(Q){JQ(x(),{recursive:!0}),YZ(IQ(),JSON.stringify(Q,null,2))}function AQ(){return A().sort((Q,Z)=>Z.lastOpenedAt.localeCompare(Q.lastOpenedAt))}function C(Q){return A().find((Z)=>Z.id===Q)??null}function U0(Q,Z,$=new Date().toISOString()){let J=VZ(Q),Y=A(),V=Y.find((z)=>z.id===J),X={id:J,path:Q,name:Z||V?.name||q0(Q),lastOpenedAt:$},U=[X,...Y.filter((z)=>z.id!==J)];return JQ(DQ(J),{recursive:!0}),OQ(U),X}function Y1(Q,Z=new Date().toISOString()){let $=A(),J=$.find((Y)=>Y.id===Q);if(!J)return;J.lastOpenedAt=Z,OQ($)}function V1(Q){if(OQ(A().filter((Z)=>Z.id!==Q)),yQ()===Q)W0(AQ()[0]?.id??null)}function zZ(){return F(x(),"active")}function yQ(){try{return JZ(zZ(),"utf8").trim()||null}catch{return null}}function W0(Q){JQ(x(),{recursive:!0}),YZ(zZ(),Q??"")}function z1(){let Q=yQ();return Q?C(Q):null}function q1(){let Q=H0()??yQ();return Q?C(Q):null}function X1(Q){return C(Q)?.path??null}function U1(){return $Z(IQ())}var qZ="beacon_ws";function XZ(Q,Z){let $=Q.headers.get("cookie");if(!$)return null;for(let J of $.split(";")){let Y=J.indexOf("=");if(Y===-1)continue;if(J.slice(0,Y).trim()===Z)return decodeURIComponent(J.slice(Y+1).trim())}return null}function W1(Q){let Z=Q.headers.get("x-beacon-workspace");if(Z&&C(Z))return Z;let $=XZ(Q,qZ);if($&&C($))return $;return null}var P0="x-beacon-workspace-path";async function P1(Q){let Z=Q.headers.get("x-beacon-workspace");if(Z&&C(Z))return Z;let $=Q.headers.get(P0);if($&&(!Z||VZ($)===Z)){let Y=U0($);return await j0(Y.id),Y.id}let J=XZ(Q,qZ);if(J&&C(J))return J;return null}var UZ=new J0;function H1(Q,Z){return Q?UZ.run(Q,Z):Z()}function H0(){return UZ.getStore()??null}var ZZ=new Set;async function j0(Q){let Z=DQ(Q),$=F(Z,"db.sqlite"),J=$Z($);if(J&&ZZ.has($))return{ok:!0,created:!1,migrated:!1};try{JQ(Z,{recursive:!0});let{provisionDb:Y}=await QZ().then(() => eQ),V=await Y(X0(Q));return ZZ.add($),{ok:!0,created:!J,migrated:J&&V.migrated}}catch(Y){return{ok:!1,created:!1,migrated:!1,error:Y instanceof Error?Y.message:String(Y)}}}L();NQ();fQ();import{execSync as B0,spawnSync as WZ}from"child_process";import{existsSync as v0,readFileSync as N0}from"fs";import{join as PZ}from"path";var W=(Q)=>`\x1B[32m\u2713\x1B[0m ${Q}`,P=(Q)=>`\x1B[31m\u2717\x1B[0m ${Q}`,M=(Q)=>`\x1B[2m${Q}\x1B[0m`,y=(Q)=>`
|
|
244
|
+
\x1B[1m${Q}\x1B[0m`;function G0(){try{return B0("git rev-parse --show-toplevel",{cwd:process.cwd(),stdio:["ignore","pipe","ignore"]}).toString().trim()}catch{return""}}function x0(){let Q=PZ(x(),"server.json");try{let Z=JSON.parse(N0(Q,"utf8"));if(!Z.pid)return P("daemon: no server.json yet");try{return process.kill(Z.pid,0),W(`daemon running (pid ${Z.pid}, port ${Z.port??"?"})`)}catch{return P(`daemon NOT running (server.json stale: pid ${Z.pid})`)}}catch{return P("daemon: no server.json (never started)")}}function K0(){let Q=WZ("bun",["--version"],{stdio:["ignore","pipe","ignore"]});if(Q.status===0)return W(`bun ${Q.stdout.toString().trim()}`);return P("bun NOT found on PATH (required to run Beacon)")}function C0(){return G0()||process.cwd()}var YQ=C0(),g=nQ(),HZ=AQ(),M0=HZ.some((Q)=>Q.path===YQ),H=M0||v0(PZ(YQ,".mcp.json"))?WQ(YQ):null;console.log(y("Beacon \xB7 doctor"));console.log(y("Runtime"));console.log(` ${K0()}`);console.log(` ${x0()}`);console.log(` ${W(`home: ${x()}`)}`);console.log(` ${W(`workspaces registered: ${HZ.length}`)}`);console.log(y("Global (~/.claude/)"));for(let Q of B)console.log(` ${g.skills[Q]?W(`skill ${Q}`):P(`skill ${Q} \u2014 missing`)}`);for(let Q of T)console.log(` ${g.hooks[Q.event]?W(`hook ${Q.event} \u2192 ${Q.command}`):P(`hook ${Q.event} \u2192 ${Q.command} \u2014 missing`)} ${M(Q.description)}`);console.log(` ${g.claudeMdBlock?W("global CLAUDE.md block"):P("global CLAUDE.md block \u2014 missing (every Claude session won't auto-discover Beacon)")}`);console.log(y("Codex (~/.codex/ + ~/.agents/)"));var v=ZQ()?RQ():null;if(!v)console.log(` ${M("codex not on PATH \u2014 Codex integration inactive (wires automatically once codex is installed)")}`);else{let Q=WZ("codex",["--version"],{stdio:["ignore","pipe","ignore"]});console.log(` ${Q.status===0?W(`codex ${Q.stdout.toString().trim()}`):M("codex version unavailable (BEACON_CODEX override?)")}`);for(let $ of B)console.log(` ${v.skills[$]?W(`skill ${$} (~/.agents/skills)`):P(`skill ${$} (~/.agents/skills) \u2014 missing`)}`);for(let $ of K)console.log(` ${v.hooks[$.event]?W(`hook ${$.event} \u2192 ${$.command}`):P(`hook ${$.event} \u2192 ${$.command} \u2014 missing`)} ${M($.description)}`);console.log(` ${v.agentsMdBlock?W("global ~/.codex/AGENTS.md block"):P("global ~/.codex/AGENTS.md block \u2014 missing")}`);let Z=gQ();console.log(` ${v.mcp?W("config.toml has [mcp_servers.beacon]"):P(`config.toml missing [mcp_servers.beacon]${Z?` \u2014 ${Z}`:""}`)}`)}console.log(y(`Current repo (${YQ})`));if(!H)console.log(` ${M("not registered with Beacon and no .mcp.json \u2014 run `beacon` here to wire it.")}`);else if(console.log(` ${H.mcpRegistered?W(".mcp.json has beacon entry"):P(".mcp.json missing beacon entry")}`),console.log(` ${H.agentsMdBlock?W("AGENTS.md has Beacon workflow block"):P("AGENTS.md missing Beacon workflow block")}`),console.log(` ${H.claudeMdImport?W("CLAUDE.md @-imports AGENTS.md"):P("CLAUDE.md does NOT @-import AGENTS.md")}`),console.log(` ${H.skills["beacon-init"]?W("skill beacon-init (repo)"):P("skill beacon-init (repo) \u2014 missing")}`),console.log(` ${H.skills["beacon-refresh"]?W("skill beacon-refresh (repo)"):P("skill beacon-refresh (repo) \u2014 missing")}`),v)console.log(` ${H.codexSkills["beacon-init"]?W("skill beacon-init (.agents/skills)"):P("skill beacon-init (.agents/skills) \u2014 missing")}`),console.log(` ${H.codexSkills["beacon-refresh"]?W("skill beacon-refresh (.agents/skills)"):P("skill beacon-refresh (.agents/skills) \u2014 missing")}`);var f0=B.some((Q)=>!g.skills[Q])||T.some((Q)=>!g.hooks[Q.event])||!g.claudeMdBlock||(v?B.some((Q)=>!v.skills[Q])||K.some((Q)=>!v.hooks[Q.event])||!v.agentsMdBlock||!v.mcp:!1)||(H?!H.mcpRegistered||!H.agentsMdBlock||!H.claudeMdImport||!H.skills["beacon-init"]||!H.skills["beacon-refresh"]||(v?!H.codexSkills["beacon-init"]||!H.codexSkills["beacon-refresh"]:!1):!1);if(f0)console.log(`
|
|
245
245
|
${M("Fix everything marked \u2717 by running")} \x1B[1mbeacon\x1B[0m ${M("in this repo.")}`);console.log();
|
package/dist/bin/hook.js
CHANGED
|
@@ -206,20 +206,7 @@ ${Y}
|
|
|
206
206
|
`)?V:`${V}
|
|
207
207
|
`)}function u(Q,Z){try{return O(Q,"utf8").includes(Z)}catch{return!1}}function k(Q,Z,$){let J="";try{J=O(Q,"utf8")}catch{return!1}let Y=new RegExp(`${Z}[\\s\\S]*?${$}\\n?`);if(!Y.test(J))return!1;let V=J.replace(Y,"").replace(/\n{3,}/g,`
|
|
208
208
|
|
|
209
|
-
`).trimStart();return I(Q,V),!0}function L(Q,Z,$){let J=b(Q,Z);$Q(J,{recursive:!0});let Y=b(J,"SKILL.md");return I(Y,$),Y}function v(Q,Z){return gQ(b(Q,Z,"SKILL.md"))}function _(Q,Z){let $=b(Q,Z);if(!gQ($))return!1;return BZ($,{recursive:!0,force:!0}),!0}var YQ=()=>{};import{mkdirSync as HZ,renameSync as jZ,rmSync as GZ,writeFileSync as NZ}from"fs";import{dirname as KZ}from"path";function VQ(Q,Z){HZ(KZ(Q),{recursive:!0});let $=`${Q}.tmp`;try{NZ($,Z),jZ($,Q)}catch(J){throw GZ($,{force:!0}),J}}var fQ=()=>{};
|
|
210
|
-
`)?`
|
|
211
|
-
`:`
|
|
212
|
-
|
|
213
|
-
`,J=Q+$+vZ;if(M(J)?.mcp_servers?.beacon?.command!=="beacon")return{added:!1,error:`could not safely append [mcp_servers.beacon] \u2014 ${C}`};return VQ(N(),J),{added:!0}}function EQ(){let Q="";try{Q=p(N(),"utf8")}catch{return{removed:!1}}let Z=Q.split(`
|
|
214
|
-
`),$=Z.indexOf(IQ);if($===-1)return{removed:!1,skipped:UQ()};let J=Z.indexOf(AQ,$);if(J===-1)return{removed:!1,skipped:!0};Z.splice($,J-$+1);let Y=Z.join(`
|
|
215
|
-
`).replace(/\n{3,}/g,`
|
|
216
|
-
|
|
217
|
-
`).replace(/^\n+/,"");if(M(Y)===null)return{removed:!1,skipped:!0};return VQ(N(),Y),{removed:!0}}async function MZ(){let{INIT_SKILL:Q,REFRESH_SKILL:Z,PLAN_SKILL:$}=await Promise.resolve().then(() => (ZQ(),QQ)),J={"beacon-init":Q,"beacon-refresh":Z,"beacon-plan":$},Y=[];for(let z of B){if(!v(S(),z))Y.push(z);L(S(),z,J[z])}let V=0;for(let z of c)if(A(XQ(),{event:z.event,matcher:z.matcher,command:z.command}))V++;let q=u(h(),m);y(h(),m,bQ,WQ);let U=DQ();return{skillsAdded:Y,hooksAdded:V,agentsMdBlockTouched:!q,mcp:U}}function wZ(){let Q={};for(let $ of B)Q[$]=v(S(),$);let Z={};for(let $ of c)Z[$.event]=D(XQ(),{event:$.event,command:$.command});return{detected:OQ(),skills:Q,hooks:Z,agentsMdBlock:u(h(),m),mcp:UQ()}}function gZ(){let Q=[];for(let Y of B)if(_(S(),Y))Q.push(Y);let Z=0;for(let Y of c)if(E(XQ(),{event:Y.event,command:Y.command}))Z++;let $=k(h(),m,bQ),J=EQ();return{skillsRemoved:Q,hooksRemoved:Z,agentsMdBlockRemoved:$,mcpRemoved:J.removed,mcpSkipped:J.skipped}}var qQ=()=>w(RQ(),".codex"),XQ=()=>w(qQ(),"hooks.json"),N=()=>w(qQ(),"config.toml"),h=()=>w(qQ(),"AGENTS.md"),S=()=>w(RQ(),".agents","skills"),m="<!-- beacon:global:start -->",bQ="<!-- beacon:global:end -->",c,zQ,IQ="# beacon:start (managed by Beacon \u2014 `beacon uninstall` removes this block)",AQ="# beacon:end",vZ,C="add it manually: codex mcp add beacon -- beacon mcp";var kQ=j(()=>{YQ();fQ();PQ();c=[{event:"PostToolUse",matcher:"apply_patch",command:"beacon hook",description:"Report file edits to Beacon's active feature so the map stays fresh."},{event:"UserPromptSubmit",matcher:"*",command:"beacon prompt",description:"On feature-y prompts in a Beacon-wired repo, remind the agent to run the context\u2192propose\u2192describe loop (no-op otherwise)."},{event:"Stop",matcher:"*",command:"beacon stop-hook",description:"When the agent ends a turn asking for plan approval in prose, nudge it to present the plan on Beacon's /plan canvas."}];vZ=`${IQ}
|
|
218
|
-
[mcp_servers.beacon]
|
|
219
|
-
command = "beacon"
|
|
220
|
-
args = ["mcp"]
|
|
221
|
-
${AQ}
|
|
222
|
-
`});import{existsSync as TZ}from"fs";import{homedir as FZ}from"os";import{join as d}from"path";function fZ(){return process.env.HOME||process.env.USERPROFILE||FZ()}function RZ(Q,Z){return L(xQ(),Q,Z)}function _Q(Q){return v(xQ(),Q)}function bZ(Q){return _(xQ(),Q)}function OZ(Q){return A(BQ(),Q)}function IZ(Q){return D(BQ(),Q)}function AZ(Q){return E(BQ(),Q)}function DZ(Q){y(HQ(),jQ,LQ,Q)}function hQ(){return u(HQ(),jQ)}function EZ(){return k(HQ(),jQ,LQ)}function O0(){let Q={};for(let $ of B)Q[$]=_Q($);let Z={};for(let $ of GQ)Z[$.event]=IZ({event:$.event,command:$.command});return{homeExists:TZ(n()),skills:Q,hooks:Z,claudeMdBlock:hQ()}}async function yZ(){let{INIT_SKILL:Q,REFRESH_SKILL:Z,PLAN_SKILL:$}=await Promise.resolve().then(() => (ZQ(),QQ)),J={"beacon-init":Q,"beacon-refresh":Z,"beacon-plan":$},Y=[];for(let U of B){if(!_Q(U))Y.push(U);RZ(U,J[U])}let V=0;for(let U of GQ)if(OZ({event:U.event,matcher:U.matcher,command:U.command}))V++;let q=hQ();return DZ(WQ),{skillsAdded:Y,hooksAdded:V,claudeMdBlockTouched:!q}}async function SQ(){let Q;try{Q={ok:!0,...await yZ()}}catch(Z){Q={ok:!1,error:Z instanceof Error?Z.message:String(Z),skillsAdded:[],hooksAdded:0,claudeMdBlockTouched:!1}}try{let Z=await Promise.resolve().then(() => (kQ(),yQ));if(Z.codexDetected())Q.codex={ok:!0,...await Z.setupCodexAssets()}}catch(Z){Q.codex={ok:!1,error:Z instanceof Error?Z.message:String(Z),skillsAdded:[],hooksAdded:0,agentsMdBlockTouched:!1,mcp:{added:!1}}}return Q}function I0(){let Q=[];for(let J of B)if(bZ(J))Q.push(J);let Z=0;for(let J of GQ)if(AZ(J))Z++;let $=EZ();return{skillsRemoved:Q,hooksRemoved:Z,claudeMdBlockRemoved:$}}var n=()=>d(fZ(),".claude"),xQ=()=>d(n(),"skills"),BQ=()=>d(n(),"settings.json"),HQ=()=>d(n(),"CLAUDE.md"),jQ="<!-- beacon:global:start -->",LQ="<!-- beacon:global:end -->",B,GQ,WQ=`## Beacon (visual planning panel)
|
|
209
|
+
`).trimStart();return I(Q,V),!0}function L(Q,Z,$){let J=b(Q,Z);$Q(J,{recursive:!0});let Y=b(J,"SKILL.md");return I(Y,$),Y}function v(Q,Z){return gQ(b(Q,Z,"SKILL.md"))}function _(Q,Z){let $=b(Q,Z);if(!gQ($))return!1;return BZ($,{recursive:!0,force:!0}),!0}var YQ=()=>{};import{mkdirSync as HZ,renameSync as jZ,rmSync as GZ,writeFileSync as NZ}from"fs";import{dirname as KZ}from"path";function VQ(Q,Z){HZ(KZ(Q),{recursive:!0});let $=`${Q}.tmp`;try{NZ($,Z),jZ($,Q)}catch(J){throw GZ($,{force:!0}),J}}var fQ=()=>{};import{existsSync as uZ}from"fs";import{homedir as vZ}from"os";import{join as h}from"path";function CZ(){return process.env.HOME||process.env.USERPROFILE||vZ()}function MZ(Q,Z){return L(zQ(),Q,Z)}function IQ(Q){return v(zQ(),Q)}function wZ(Q){return _(zQ(),Q)}function gZ(Q){return A(qQ(),Q)}function TZ(Q){return D(qQ(),Q)}function FZ(Q){return E(qQ(),Q)}function fZ(Q){y(XQ(),UQ,OQ,Q)}function AQ(){return u(XQ(),UQ)}function RZ(){return k(XQ(),UQ,OQ)}function g0(){let Q={};for(let $ of B)Q[$]=IQ($);let Z={};for(let $ of WQ)Z[$.event]=TZ({event:$.event,command:$.command});return{homeExists:uZ(S()),skills:Q,hooks:Z,claudeMdBlock:AQ()}}async function bZ(){let{INIT_SKILL:Q,REFRESH_SKILL:Z,PLAN_SKILL:$}=await Promise.resolve().then(() => (ZQ(),QQ)),J={"beacon-init":Q,"beacon-refresh":Z,"beacon-plan":$},Y=[];for(let U of B){if(!IQ(U))Y.push(U);MZ(U,J[U])}let V=0;for(let U of WQ)if(gZ({event:U.event,matcher:U.matcher,command:U.command}))V++;let q=AQ();return fZ(PQ),{skillsAdded:Y,hooksAdded:V,claudeMdBlockTouched:!q}}async function DQ(){let Q;try{Q={ok:!0,...await bZ()}}catch(Z){Q={ok:!1,error:Z instanceof Error?Z.message:String(Z),skillsAdded:[],hooksAdded:0,claudeMdBlockTouched:!1}}try{let Z=await Promise.resolve().then(() => (bQ(),RQ));if(Z.codexDetected())Q.codex={ok:!0,...await Z.setupCodexAssets()}}catch(Z){Q.codex={ok:!1,error:Z instanceof Error?Z.message:String(Z),skillsAdded:[],hooksAdded:0,agentsMdBlockTouched:!1,mcp:{added:!1}}}return Q}function T0(){let Q=[];for(let J of B)if(wZ(J))Q.push(J);let Z=0;for(let J of WQ)if(FZ(J))Z++;let $=RZ();return{skillsRemoved:Q,hooksRemoved:Z,claudeMdBlockRemoved:$}}var S=()=>h(CZ(),".claude"),zQ=()=>h(S(),"skills"),qQ=()=>h(S(),"settings.json"),XQ=()=>h(S(),"CLAUDE.md"),UQ="<!-- beacon:global:start -->",OQ="<!-- beacon:global:end -->",B,WQ,PQ=`## Beacon (visual planning panel)
|
|
223
210
|
|
|
224
211
|
This machine has Beacon installed \u2014 a local visual planning surface for the terminal-side
|
|
225
212
|
agent. Beacon proposes feature plans (roadmap features + DB schema + endpoints) via MCP,
|
|
@@ -240,5 +227,18 @@ the user reviews on a canvas at /plan, and feedback flows back as the next round
|
|
|
240
227
|
Feedback bundles inline annotations on the markdown PLUS any edits the user made directly
|
|
241
228
|
on the /map and /db boards (added features, attached subtasks, edited columns, new
|
|
242
229
|
endpoints). Treat board edits as the user's revision intent \u2014 re-propose matching them
|
|
243
|
-
verbatim. Do NOT implement until the tool returns approval.`;var
|
|
244
|
-
`)
|
|
230
|
+
verbatim. Do NOT implement until the tool returns approval.`;var xQ=j(()=>{YQ();B=["beacon-init","beacon-refresh","beacon-plan"],WQ=[{event:"PostToolUse",matcher:"Edit|Write|MultiEdit",command:"beacon hook",description:"Report file edits to Beacon's active feature so the map stays fresh."},{event:"PermissionRequest",matcher:"ExitPlanMode",command:"beacon plan",description:"Pipe the agent's plan markdown into Beacon's /plan canvas for review."},{event:"UserPromptSubmit",matcher:"*",command:"beacon prompt",description:"On feature-y prompts in a Beacon-wired repo, remind the agent to run the context\u2192propose\u2192describe loop (no-op otherwise)."},{event:"Stop",matcher:"*",command:"beacon stop-hook",description:"When the agent ends a turn asking for plan approval in prose (instead of presenting it), nudge it to present the plan on Beacon's /plan canvas. Bounded by stop_hook_active \u2014 at most one nudge."}]});var RQ={};r(RQ,{setupCodexAssets:()=>DZ,removeCodexMcp:()=>SQ,removeCodexArtifacts:()=>yZ,hasCodexMcp:()=>GQ,ensureCodexMcp:()=>hQ,codexMcpProblem:()=>AZ,codexDetected:()=>kQ,auditCodex:()=>EZ,CODEX_HOOKS:()=>n});import{readFileSync as d}from"fs";import{homedir as OZ}from"os";import{join as w}from"path";function EQ(){return process.env.HOME||process.env.USERPROFILE||OZ()}function kQ(){if(process.env.BEACON_CODEX==="1")return!0;if(process.env.BEACON_CODEX==="0")return!1;if(BQ===void 0)BQ=Bun.which("codex")!==null;return BQ}function M(Q){try{return Bun.TOML.parse(Q)}catch{return null}}function GQ(){try{return Boolean(M(d(N(),"utf8"))?.mcp_servers?.beacon)}catch{return!1}}function AZ(){let Q="";try{Q=d(N(),"utf8")}catch{return null}let Z=M(Q);if(!Z)return`~/.codex/config.toml does not parse \u2014 ${C}`;if(Z.mcp_servers?.beacon)return null;if(/^\s*mcp_servers\s*=/m.test(Q))return`mcp_servers is an inline table \u2014 ${C}`;return null}function hQ(){let Q="",Z=!1;try{Q=d(N(),"utf8"),Z=!0}catch{}if(Z){let V=M(Q);if(!V)return{added:!1,error:`~/.codex/config.toml does not parse \u2014 ${C}`};if(V.mcp_servers?.beacon)return{added:!1};if(/^\s*mcp_servers\s*=/m.test(Q))return{added:!1,error:`mcp_servers is an inline table \u2014 ${C}`}}let $=!Q?"":Q.endsWith(`
|
|
231
|
+
`)?`
|
|
232
|
+
`:`
|
|
233
|
+
|
|
234
|
+
`,J=Q+$+IZ;if(M(J)?.mcp_servers?.beacon?.command!=="beacon")return{added:!1,error:`could not safely append [mcp_servers.beacon] \u2014 ${C}`};return VQ(N(),J),{added:!0}}function SQ(){let Q="";try{Q=d(N(),"utf8")}catch{return{removed:!1}}let Z=Q.split(`
|
|
235
|
+
`),$=Z.indexOf(LQ);if($===-1)return{removed:!1,skipped:GQ()};let J=Z.indexOf(_Q,$);if(J===-1)return{removed:!1,skipped:!0};Z.splice($,J-$+1);let Y=Z.join(`
|
|
236
|
+
`).replace(/\n{3,}/g,`
|
|
237
|
+
|
|
238
|
+
`).replace(/^\n+/,"");if(M(Y)===null)return{removed:!1,skipped:!0};return VQ(N(),Y),{removed:!0}}async function DZ(){let{INIT_SKILL:Q,REFRESH_SKILL:Z,PLAN_SKILL:$}=await Promise.resolve().then(() => (ZQ(),QQ)),J={"beacon-init":Q,"beacon-refresh":Z,"beacon-plan":$},Y=[];for(let z of B){if(!v(p(),z))Y.push(z);L(p(),z,J[z])}let V=0;for(let z of n)if(A(jQ(),{event:z.event,matcher:z.matcher,command:z.command}))V++;let q=u(m(),c);y(m(),c,yQ,PQ);let U=hQ();return{skillsAdded:Y,hooksAdded:V,agentsMdBlockTouched:!q,mcp:U}}function EZ(){let Q={};for(let $ of B)Q[$]=v(p(),$);let Z={};for(let $ of n)Z[$.event]=D(jQ(),{event:$.event,command:$.command});return{detected:kQ(),skills:Q,hooks:Z,agentsMdBlock:u(m(),c),mcp:GQ()}}function yZ(){let Q=[];for(let Y of B)if(_(p(),Y))Q.push(Y);let Z=0;for(let Y of n)if(E(jQ(),{event:Y.event,command:Y.command}))Z++;let $=k(m(),c,yQ),J=SQ();return{skillsRemoved:Q,hooksRemoved:Z,agentsMdBlockRemoved:$,mcpRemoved:J.removed,mcpSkipped:J.skipped}}var HQ=()=>w(EQ(),".codex"),jQ=()=>w(HQ(),"hooks.json"),N=()=>w(HQ(),"config.toml"),m=()=>w(HQ(),"AGENTS.md"),p=()=>w(EQ(),".agents","skills"),c="<!-- beacon:global:start -->",yQ="<!-- beacon:global:end -->",n,BQ,LQ="# beacon:start (managed by Beacon \u2014 `beacon uninstall` removes this block)",_Q="# beacon:end",IZ,C="add it manually: codex mcp add beacon -- beacon mcp";var bQ=j(()=>{YQ();fQ();xQ();n=[{event:"PostToolUse",matcher:"apply_patch",command:"beacon hook",description:"Report file edits to Beacon's active feature so the map stays fresh."},{event:"UserPromptSubmit",matcher:"*",command:"beacon prompt",description:"On feature-y prompts in a Beacon-wired repo, remind the agent to run the context\u2192propose\u2192describe loop (no-op otherwise)."},{event:"Stop",matcher:"*",command:"beacon stop-hook",description:"When the agent ends a turn asking for plan approval in prose, nudge it to present the plan on Beacon's /plan canvas."}];IZ=`${LQ}
|
|
239
|
+
[mcp_servers.beacon]
|
|
240
|
+
command = "beacon"
|
|
241
|
+
args = ["mcp"]
|
|
242
|
+
${_Q}
|
|
243
|
+
`});var pQ={};r(pQ,{provisionDb:()=>sZ});import{createClient as kZ}from"@libsql/client";import{drizzle as LZ}from"drizzle-orm/libsql";import{migrate as _Z}from"drizzle-orm/libsql/migrator";import{readMigrationFiles as hZ}from"drizzle-orm/migrator";import{dirname as NQ,join as SZ}from"path";import{fileURLToPath as mZ}from"url";async function a(Q,Z){return(await Q.execute({sql:"SELECT 1 FROM sqlite_master WHERE type='table' AND name = ?",args:[Z]})).rows.length>0}async function nZ(Q,Z){let $=await Q.execute(`PRAGMA table_info("${Z}")`);return new Set($.rows.map((J)=>String(J.name)))}async function mQ(Q){if(!await a(Q,"__drizzle_migrations"))return 0;let Z=await Q.execute('SELECT count(*) AS n FROM "__drizzle_migrations"');return Number(Z.rows[0]?.n??0)}async function aZ(Q){for(let[Z,$]of Object.entries(dZ)){if(!await a(Q,Z))continue;let J=await nZ(Q,Z);for(let Y of $){if(!J.has(Y))continue;await Q.execute(`UPDATE "${Z}" SET "${Y}" = CAST((julianday("${Y}") - 2440587.5) * 86400000 AS INTEGER) WHERE typeof("${Y}") = 'text'`)}}}async function sZ(Q,Z=cZ){let $=kZ({url:Q});try{await $.execute("PRAGMA journal_mode = WAL;"),await $.execute("PRAGMA foreign_keys = ON;");let J=await a($,"__drizzle_migrations"),Y=await a($,"Node"),V=!1;if(Y&&!J){let U=hZ({migrationsFolder:Z})[0];if(U)await $.execute('CREATE TABLE IF NOT EXISTS "__drizzle_migrations" (id SERIAL PRIMARY KEY, hash text NOT NULL, created_at numeric)'),await $.execute({sql:'INSERT INTO "__drizzle_migrations" ("hash", "created_at") VALUES (?, ?)',args:[U.hash,U.folderMillis]}),V=!0}let q=await mQ($);if(await _Z(LZ($),{migrationsFolder:Z}),await mQ($)>q)V=!0;return await aZ($),{migrated:V}}finally{$.close()}}var pZ,cZ,dZ;var cQ=j(async()=>{pZ=NQ(NQ(NQ(mZ(import.meta.url)))),cZ=process.env.BEACON_MIGRATIONS_DIR||SZ(pZ,"drizzle"),dZ={Node:["createdAt","updatedAt"],Note:["createdAt","updatedAt"],DbTable:["createdAt","updatedAt"],Endpoint:["createdAt","updatedAt"],DraftTable:["createdAt"],SyncState:["codeGraphSyncedAt","updatedAt"],AppSetting:["updatedAt"],ProjectMeta:["updatedAt"],CodeFile:["updatedAt"]}});import{AsyncLocalStorage as tZ}from"async_hooks";import{spawnSync as lZ}from"child_process";import{createHash as rZ}from"crypto";import{existsSync as nQ,mkdirSync as s,readFileSync as aQ,writeFileSync as sQ}from"fs";import{homedir as oZ}from"os";import{basename as iZ,join as K}from"path";function g(){return process.env.BEACON_HOME||K(oZ(),".beacon")}function KQ(){return K(g(),"workspaces.json")}function t(Q){return rZ("sha256").update(Q).digest("hex").slice(0,12)}function tQ(Q=process.cwd()){let Z=lZ("git",["rev-parse","--show-toplevel"],{cwd:Q,stdio:["ignore","pipe","ignore"]});if(Z.status===0){let $=Z.stdout?.toString().trim();if($)return $}return Q}function uQ(Q){return K(g(),Q)}function eZ(Q){return`file:${K(uQ(Q),"db.sqlite")}`}function T(){try{let Q=JSON.parse(aQ(KQ(),"utf8"));return Array.isArray(Q)?Q:[]}catch{return[]}}function vQ(Q){s(g(),{recursive:!0}),sQ(KQ(),JSON.stringify(Q,null,2))}function Q0(){return T().sort((Q,Z)=>Z.lastOpenedAt.localeCompare(Q.lastOpenedAt))}function H(Q){return T().find((Z)=>Z.id===Q)??null}function Z0(Q,Z,$=new Date().toISOString()){let J=t(Q),Y=T(),V=Y.find((z)=>z.id===J),q={id:J,path:Q,name:Z||V?.name||iZ(Q),lastOpenedAt:$},U=[q,...Y.filter((z)=>z.id!==J)];return s(uQ(J),{recursive:!0}),vQ(U),q}function n0(Q,Z=new Date().toISOString()){let $=T(),J=$.find((Y)=>Y.id===Q);if(!J)return;J.lastOpenedAt=Z,vQ($)}function a0(Q){if(vQ(T().filter((Z)=>Z.id!==Q)),CQ()===Q)$0(Q0()[0]?.id??null)}function lQ(){return K(g(),"active")}function CQ(){try{return aQ(lQ(),"utf8").trim()||null}catch{return null}}function $0(Q){s(g(),{recursive:!0}),sQ(lQ(),Q??"")}function s0(){let Q=CQ();return Q?H(Q):null}function t0(){let Q=Y0()??CQ();return Q?H(Q):null}function l0(Q){return H(Q)?.path??null}function r0(){return nQ(KQ())}var rQ="beacon_ws";function oQ(Q,Z){let $=Q.headers.get("cookie");if(!$)return null;for(let J of $.split(";")){let Y=J.indexOf("=");if(Y===-1)continue;if(J.slice(0,Y).trim()===Z)return decodeURIComponent(J.slice(Y+1).trim())}return null}function o0(Q){let Z=Q.headers.get("x-beacon-workspace");if(Z&&H(Z))return Z;let $=oQ(Q,rQ);if($&&H($))return $;return null}var J0="x-beacon-workspace-path";async function i0(Q){let Z=Q.headers.get("x-beacon-workspace");if(Z&&H(Z))return Z;let $=Q.headers.get(J0);if($&&(!Z||t($)===Z)){let Y=Z0($);return await V0(Y.id),Y.id}let J=oQ(Q,rQ);if(J&&H(J))return J;return null}var iQ=new tZ;function e0(Q,Z){return Q?iQ.run(Q,Z):Z()}function Y0(){return iQ.getStore()??null}var dQ=new Set;async function V0(Q){let Z=uQ(Q),$=K(Z,"db.sqlite"),J=nQ($);if(J&&dQ.has($))return{ok:!0,created:!1,migrated:!1};try{s(Z,{recursive:!0});let{provisionDb:Y}=await cQ().then(() => pQ),V=await Y(eZ(Q));return dQ.add($),{ok:!0,created:!J,migrated:J&&V.migrated}}catch(Y){return{ok:!1,created:!1,migrated:!1,error:Y instanceof Error?Y.message:String(Y)}}}xQ();import{resolve as z0}from"path";var q0="*** Begin Patch",X0=/^\*\*\* (Update File|Add File|Move to): (.+)$/;function U0(Q){let Z=[];for(let $ of Q.split(`
|
|
244
|
+
`)){let J=X0.exec($.trim());if(!J)continue;let Y=J[2].trim();if(J[1]==="Move to")Z.pop();Z.push(Y)}return Z}function eQ(Q){let Z=Q.tool_input;if(Z===null||typeof Z!=="object")return[];let $=Z,J=[];if(typeof $.file_path==="string")J.push($.file_path);if(typeof $.path==="string")J.push($.path);if(Array.isArray($.files))for(let V of $.files){let q=V?.file_path;if(typeof q==="string")J.push(q)}if(J.length)return J;let Y=typeof Q.cwd==="string"?Q.cwd:process.cwd();for(let V of Object.values($)){if(typeof V!=="string"||!V.includes(q0))continue;return U0(V).map((q)=>z0(Y,q))}return[]}var W0=process.env.BEACON_URL||`http://localhost:${process.env.PORT||4319}`;await DQ();var QZ="";for await(let Q of process.stdin)QZ+=Q;try{let Q=JSON.parse(QZ||"{}"),Z=eQ(Q);if(Z.length){let $=t(tQ(typeof Q.cwd==="string"?Q.cwd:void 0));await fetch(`${W0}/api/map/touch-active`,{method:"POST",headers:{"content-type":"application/json","x-beacon-workspace":$},body:JSON.stringify({files:Z})}).catch(()=>{})}}catch{}process.exit(0);
|
package/dist/bin/mcp.js
CHANGED
|
@@ -206,20 +206,7 @@ ${X}
|
|
|
206
206
|
`)?H:`${H}
|
|
207
207
|
`)}function n($,Q){try{return G0($,"utf8").includes(Q)}catch{return!1}}function q0($,Q,Z){let Y="";try{Y=G0($,"utf8")}catch{return!1}let X=new RegExp(`${Q}[\\s\\S]*?${Z}\\n?`);if(!X.test(Y))return!1;let H=Y.replace(X,"").replace(/\n{3,}/g,`
|
|
208
208
|
|
|
209
|
-
`).trimStart();return P0($,H),!0}function w0($,Q,Z){let Y=j0($,Q);u0(Y,{recursive:!0});let X=j0(Y,"SKILL.md");return P0(X,Z),X}function a($,Q){return v5(j0($,Q,"SKILL.md"))}function C0($,Q){let Z=j0($,Q);if(!v5(Z))return!1;return T9(Z,{recursive:!0,force:!0}),!0}var b0=()=>{};import{mkdirSync as _9,renameSync as k9,rmSync as g9,writeFileSync as y9}from"fs";import{dirname as x9}from"path";function m0($,Q){_9(x9($),{recursive:!0});let Z=`${$}.tmp`;try{y9(Z,Q),k9(Z,$)}catch(Y){throw g9(Z,{force:!0}),Y}}var R5=()=>{};
|
|
210
|
-
`)?`
|
|
211
|
-
`:`
|
|
212
|
-
|
|
213
|
-
`,Y=$+Z+z9;if(i(Y)?.mcp_servers?.beacon?.command!=="beacon")return{added:!1,error:`could not safely append [mcp_servers.beacon] \u2014 ${r}`};return m0(m(),Y),{added:!0}}function _5(){let $="";try{$=R0(m(),"utf8")}catch{return{removed:!1}}let Q=$.split(`
|
|
214
|
-
`),Z=Q.indexOf(I5);if(Z===-1)return{removed:!1,skipped:d0()};let Y=Q.indexOf(L5,Z);if(Y===-1)return{removed:!1,skipped:!0};Q.splice(Z,Y-Z+1);let X=Q.join(`
|
|
215
|
-
`).replace(/\n{3,}/g,`
|
|
216
|
-
|
|
217
|
-
`).replace(/^\n+/,"");if(i(X)===null)return{removed:!1,skipped:!0};return m0(m(),X),{removed:!0}}async function u9(){let{INIT_SKILL:$,REFRESH_SKILL:Q,PLAN_SKILL:Z}=await Promise.resolve().then(() => (S0(),z0)),Y={"beacon-init":$,"beacon-refresh":Q,"beacon-plan":Z},X=[];for(let U of g){if(!a(O0(),U))X.push(U);w0(O0(),U,Y[U])}let H=0;for(let U of D0)if(B0(l0(),{event:U.event,matcher:U.matcher,command:U.command}))H++;let W=n(v0(),F0);M0(v0(),F0,A5,s0);let G=T5();return{skillsAdded:X,hooksAdded:H,agentsMdBlockTouched:!W,mcp:G}}function f9(){let $={};for(let Z of g)$[Z]=a(O0(),Z);let Q={};for(let Z of D0)Q[Z.event]=K0(l0(),{event:Z.event,command:Z.command});return{detected:E5(),skills:$,hooks:Q,agentsMdBlock:n(v0(),F0),mcp:d0()}}function b9(){let $=[];for(let X of g)if(C0(O0(),X))$.push(X);let Q=0;for(let X of D0)if(N0(l0(),{event:X.event,command:X.command}))Q++;let Z=q0(v0(),F0,A5),Y=_5();return{skillsRemoved:$,hooksRemoved:Q,agentsMdBlockRemoved:Z,mcpRemoved:Y.removed,mcpSkipped:Y.skipped}}var c0=()=>t(D5(),".codex"),l0=()=>t(c0(),"hooks.json"),m=()=>t(c0(),"config.toml"),v0=()=>t(c0(),"AGENTS.md"),O0=()=>t(D5(),".agents","skills"),F0="<!-- beacon:global:start -->",A5="<!-- beacon:global:end -->",D0,p0,I5="# beacon:start (managed by Beacon \u2014 `beacon uninstall` removes this block)",L5="# beacon:end",z9,r="add it manually: codex mcp add beacon -- beacon mcp";var g5=f(()=>{b0();R5();o0();D0=[{event:"PostToolUse",matcher:"apply_patch",command:"beacon hook",description:"Report file edits to Beacon's active feature so the map stays fresh."},{event:"UserPromptSubmit",matcher:"*",command:"beacon prompt",description:"On feature-y prompts in a Beacon-wired repo, remind the agent to run the context\u2192propose\u2192describe loop (no-op otherwise)."},{event:"Stop",matcher:"*",command:"beacon stop-hook",description:"When the agent ends a turn asking for plan approval in prose, nudge it to present the plan on Beacon's /plan canvas."}];z9=`${I5}
|
|
218
|
-
[mcp_servers.beacon]
|
|
219
|
-
command = "beacon"
|
|
220
|
-
args = ["mcp"]
|
|
221
|
-
${L5}
|
|
222
|
-
`});import{existsSync as m9}from"fs";import{homedir as p9}from"os";import{join as A0}from"path";function c9(){return process.env.HOME||process.env.USERPROFILE||p9()}function l9($,Q){return w0(n0(),$,Q)}function x5($){return a(n0(),$)}function d9($){return C0(n0(),$)}function s9($){return B0(a0(),$)}function o9($){return K0(a0(),$)}function n9($){return N0(a0(),$)}function a9($){M0(r0(),i0,y5,$)}function h5(){return n(r0(),i0)}function r9(){return q0(r0(),i0,y5)}function vQ(){let $={};for(let Z of g)$[Z]=x5(Z);let Q={};for(let Z of t0)Q[Z.event]=o9({event:Z.event,command:Z.command});return{homeExists:m9(E0()),skills:$,hooks:Q,claudeMdBlock:h5()}}async function i9(){let{INIT_SKILL:$,REFRESH_SKILL:Q,PLAN_SKILL:Z}=await Promise.resolve().then(() => (S0(),z0)),Y={"beacon-init":$,"beacon-refresh":Q,"beacon-plan":Z},X=[];for(let G of g){if(!x5(G))X.push(G);l9(G,Y[G])}let H=0;for(let G of t0)if(s9({event:G.event,matcher:G.matcher,command:G.command}))H++;let W=h5();return a9(s0),{skillsAdded:X,hooksAdded:H,claudeMdBlockTouched:!W}}async function z5(){let $;try{$={ok:!0,...await i9()}}catch(Q){$={ok:!1,error:Q instanceof Error?Q.message:String(Q),skillsAdded:[],hooksAdded:0,claudeMdBlockTouched:!1}}try{let Q=await Promise.resolve().then(() => (g5(),k5));if(Q.codexDetected())$.codex={ok:!0,...await Q.setupCodexAssets()}}catch(Q){$.codex={ok:!1,error:Q instanceof Error?Q.message:String(Q),skillsAdded:[],hooksAdded:0,agentsMdBlockTouched:!1,mcp:{added:!1}}}return $}function OQ(){let $=[];for(let Y of g)if(d9(Y))$.push(Y);let Q=0;for(let Y of t0)if(n9(Y))Q++;let Z=r9();return{skillsRemoved:$,hooksRemoved:Q,claudeMdBlockRemoved:Z}}var E0=()=>A0(c9(),".claude"),n0=()=>A0(E0(),"skills"),a0=()=>A0(E0(),"settings.json"),r0=()=>A0(E0(),"CLAUDE.md"),i0="<!-- beacon:global:start -->",y5="<!-- beacon:global:end -->",g,t0,s0=`## Beacon (visual planning panel)
|
|
209
|
+
`).trimStart();return P0($,H),!0}function w0($,Q,Z){let Y=j0($,Q);u0(Y,{recursive:!0});let X=j0(Y,"SKILL.md");return P0(X,Z),X}function a($,Q){return v5(j0($,Q,"SKILL.md"))}function C0($,Q){let Z=j0($,Q);if(!v5(Z))return!1;return T9(Z,{recursive:!0,force:!0}),!0}var b0=()=>{};import{mkdirSync as _9,renameSync as k9,rmSync as g9,writeFileSync as y9}from"fs";import{dirname as x9}from"path";function m0($,Q){_9(x9($),{recursive:!0});let Z=`${$}.tmp`;try{y9(Z,Q),k9(Z,$)}catch(Y){throw g9(Z,{force:!0}),Y}}var R5=()=>{};import{existsSync as h9}from"fs";import{homedir as z9}from"os";import{join as v0}from"path";function S9(){return process.env.HOME||process.env.USERPROFILE||z9()}function u9($,Q){return w0(p0(),$,Q)}function I5($){return a(p0(),$)}function f9($){return C0(p0(),$)}function b9($){return B0(c0(),$)}function m9($){return K0(c0(),$)}function p9($){return N0(c0(),$)}function c9($){M0(l0(),d0,E5,$)}function L5(){return n(l0(),d0)}function l9(){return q0(l0(),d0,E5)}function KQ(){let $={};for(let Z of g)$[Z]=I5(Z);let Q={};for(let Z of s0)Q[Z.event]=m9({event:Z.event,command:Z.command});return{homeExists:h9(O0()),skills:$,hooks:Q,claudeMdBlock:L5()}}async function d9(){let{INIT_SKILL:$,REFRESH_SKILL:Q,PLAN_SKILL:Z}=await Promise.resolve().then(() => (S0(),z0)),Y={"beacon-init":$,"beacon-refresh":Q,"beacon-plan":Z},X=[];for(let G of g){if(!I5(G))X.push(G);u9(G,Y[G])}let H=0;for(let G of s0)if(b9({event:G.event,matcher:G.matcher,command:G.command}))H++;let W=L5();return c9(o0),{skillsAdded:X,hooksAdded:H,claudeMdBlockTouched:!W}}async function T5(){let $;try{$={ok:!0,...await d9()}}catch(Q){$={ok:!1,error:Q instanceof Error?Q.message:String(Q),skillsAdded:[],hooksAdded:0,claudeMdBlockTouched:!1}}try{let Q=await Promise.resolve().then(() => (A5(),D5));if(Q.codexDetected())$.codex={ok:!0,...await Q.setupCodexAssets()}}catch(Q){$.codex={ok:!1,error:Q instanceof Error?Q.message:String(Q),skillsAdded:[],hooksAdded:0,agentsMdBlockTouched:!1,mcp:{added:!1}}}return $}function NQ(){let $=[];for(let Y of g)if(f9(Y))$.push(Y);let Q=0;for(let Y of s0)if(p9(Y))Q++;let Z=l9();return{skillsRemoved:$,hooksRemoved:Q,claudeMdBlockRemoved:Z}}var O0=()=>v0(S9(),".claude"),p0=()=>v0(O0(),"skills"),c0=()=>v0(O0(),"settings.json"),l0=()=>v0(O0(),"CLAUDE.md"),d0="<!-- beacon:global:start -->",E5="<!-- beacon:global:end -->",g,s0,o0=`## Beacon (visual planning panel)
|
|
223
210
|
|
|
224
211
|
This machine has Beacon installed \u2014 a local visual planning surface for the terminal-side
|
|
225
212
|
agent. Beacon proposes feature plans (roadmap features + DB schema + endpoints) via MCP,
|
|
@@ -240,14 +227,27 @@ the user reviews on a canvas at /plan, and feedback flows back as the next round
|
|
|
240
227
|
Feedback bundles inline annotations on the markdown PLUS any edits the user made directly
|
|
241
228
|
on the /map and /db boards (added features, attached subtasks, edited columns, new
|
|
242
229
|
endpoints). Treat board edits as the user's revision intent \u2014 re-propose matching them
|
|
243
|
-
verbatim. Do NOT implement until the tool returns approval.`;var o0=f(()=>{b0();g=["beacon-init","beacon-refresh","beacon-plan"],t0=[{event:"PostToolUse",matcher:"Edit|Write|MultiEdit",command:"beacon hook",description:"Report file edits to Beacon's active feature so the map stays fresh."},{event:"PermissionRequest",matcher:"ExitPlanMode",command:"beacon plan",description:"Pipe the agent's plan markdown into Beacon's /plan canvas for review."},{event:"UserPromptSubmit",matcher:"*",command:"beacon prompt",description:"On feature-y prompts in a Beacon-wired repo, remind the agent to run the context\u2192propose\u2192describe loop (no-op otherwise)."},{event:"Stop",matcher:"*",command:"beacon stop-hook",description:"When the agent ends a turn asking for plan approval in prose (instead of presenting it), nudge it to present the plan on Beacon's /plan canvas. Bounded by stop_hook_active \u2014 at most one nudge."}]});var u5={};o(u5,{provisionDb:()=>U$});import{createClient as t9}from"@libsql/client";import{drizzle as e9}from"drizzle-orm/libsql";import{migrate as $$}from"drizzle-orm/libsql/migrator";import{readMigrationFiles as Q$}from"drizzle-orm/migrator";import{dirname as e0,join as Z$}from"path";import{fileURLToPath as J$}from"url";async function I0($,Q){return(await $.execute({sql:"SELECT 1 FROM sqlite_master WHERE type='table' AND name = ?",args:[Q]})).rows.length>0}async function H$($,Q){let Z=await $.execute(`PRAGMA table_info("${Q}")`);return new Set(Z.rows.map((Y)=>String(Y.name)))}async function S5($){if(!await I0($,"__drizzle_migrations"))return 0;let Q=await $.execute('SELECT count(*) AS n FROM "__drizzle_migrations"');return Number(Q.rows[0]?.n??0)}async function W$($){for(let[Q,Z]of Object.entries(X$)){if(!await I0($,Q))continue;let Y=await H$($,Q);for(let X of Z){if(!Y.has(X))continue;await $.execute(`UPDATE "${Q}" SET "${X}" = CAST((julianday("${X}") - 2440587.5) * 86400000 AS INTEGER) WHERE typeof("${X}") = 'text'`)}}}async function U$($,Q=V$){let Z=t9({url:$});try{await Z.execute("PRAGMA journal_mode = WAL;"),await Z.execute("PRAGMA foreign_keys = ON;");let Y=await I0(Z,"__drizzle_migrations"),X=await I0(Z,"Node"),H=!1;if(X&&!Y){let G=Q$({migrationsFolder:Q})[0];if(G)await Z.execute('CREATE TABLE IF NOT EXISTS "__drizzle_migrations" (id SERIAL PRIMARY KEY, hash text NOT NULL, created_at numeric)'),await Z.execute({sql:'INSERT INTO "__drizzle_migrations" ("hash", "created_at") VALUES (?, ?)',args:[G.hash,G.folderMillis]}),H=!0}let W=await S5(Z);if(await $$(e9(Z),{migrationsFolder:Q}),await S5(Z)>W)H=!0;return await W$(Z),{migrated:H}}finally{Z.close()}}var Y$,V$,X$;var f5=f(async()=>{Y$=e0(e0(e0(J$(import.meta.url)))),V$=process.env.BEACON_MIGRATIONS_DIR||Z$(Y$,"drizzle"),X$={Node:["createdAt","updatedAt"],Note:["createdAt","updatedAt"],DbTable:["createdAt","updatedAt"],Endpoint:["createdAt","updatedAt"],DraftTable:["createdAt"],SyncState:["codeGraphSyncedAt","updatedAt"],AppSetting:["updatedAt"],ProjectMeta:["updatedAt"],CodeFile:["updatedAt"]}});import{AsyncLocalStorage as j$}from"async_hooks";import{spawnSync as G$}from"child_process";import{createHash as P$}from"crypto";import{existsSync as m5,mkdirSync as L0,readFileSync as p5,writeFileSync as c5}from"fs";import{homedir as B$}from"os";import{basename as K$,join as p}from"path";function e(){return process.env.BEACON_HOME||p(B$(),".beacon")}function $5(){return p(e(),"workspaces.json")}function T0($){return P$("sha256").update($).digest("hex").slice(0,12)}function l5($=process.cwd()){let Q=G$("git",["rev-parse","--show-toplevel"],{cwd:$,stdio:["ignore","pipe","ignore"]});if(Q.status===0){let Z=Q.stdout?.toString().trim();if(Z)return Z}return $}function Q5($){return p(e(),$)}function Z5($){return`file:${p(Q5($),"db.sqlite")}`}function $0(){try{let $=JSON.parse(p5($5(),"utf8"));return Array.isArray($)?$:[]}catch{return[]}}function J5($){L0(e(),{recursive:!0}),c5($5(),JSON.stringify($,null,2))}function N$(){return $0().sort(($,Q)=>Q.lastOpenedAt.localeCompare($.lastOpenedAt))}function y($){return $0().find((Q)=>Q.id===$)??null}function Y5($,Q,Z=new Date().toISOString()){let Y=T0($),X=$0(),H=X.find((U)=>U.id===Y),W={id:Y,path:$,name:Q||H?.name||K$($),lastOpenedAt:Z},G=[W,...X.filter((U)=>U.id!==Y)];return L0(Q5(Y),{recursive:!0}),J5(G),W}function hQ($,Q=new Date().toISOString()){let Z=$0(),Y=Z.find((X)=>X.id===$);if(!Y)return;Y.lastOpenedAt=Q,J5(Z)}function zQ($){if(J5($0().filter((Q)=>Q.id!==$)),Q0()===$)M$(N$()[0]?.id??null)}function d5(){return p(e(),"active")}function Q0(){try{return p5(d5(),"utf8").trim()||null}catch{return null}}function M$($){L0(e(),{recursive:!0}),c5(d5(),$??"")}function SQ(){let $=Q0();return $?y($):null}function uQ(){let $=X5()??Q0();return $?y($):null}function fQ($){return y($)?.path??null}function bQ(){return m5($5())}var s5="beacon_ws";function o5($,Q){let Z=$.headers.get("cookie");if(!Z)return null;for(let Y of Z.split(";")){let X=Y.indexOf("=");if(X===-1)continue;if(Y.slice(0,X).trim()===Q)return decodeURIComponent(Y.slice(X+1).trim())}return null}function mQ($){let Q=$.headers.get("x-beacon-workspace");if(Q&&y(Q))return Q;let Z=o5($,s5);if(Z&&y(Z))return Z;return null}var V5="x-beacon-workspace-path";async function pQ($){let Q=$.headers.get("x-beacon-workspace");if(Q&&y(Q))return Q;let Z=$.headers.get(V5);if(Z&&(!Q||T0(Z)===Q)){let X=Y5(Z);return await H5(X.id),X.id}let Y=o5($,s5);if(Y&&y(Y))return Y;return null}var n5=new j$;function q$($,Q){return $?n5.run($,Q):Q()}function X5(){return n5.getStore()??null}var b5=new Set;async function H5($){let Q=Q5($),Z=p(Q,"db.sqlite"),Y=m5(Z);if(Y&&b5.has(Z))return{ok:!0,created:!1,migrated:!1};try{L0(Q,{recursive:!0});let{provisionDb:X}=await f5().then(() => u5),H=await X(Z5($));return b5.add(Z),{ok:!0,created:!Y,migrated:Y&&H.migrated}}catch(X){return{ok:!1,created:!1,migrated:!1,error:X instanceof Error?X.message:String(X)}}}o0();import{McpServer as e$,ResourceTemplate as N5}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as $Q}from"@modelcontextprotocol/sdk/server/stdio.js";import{z as J}from"zod";import{z as P}from"zod";var w$=new Set(["GET","HEAD","OPTIONS"]);function a5($){return w$.has($.trim().toUpperCase())?"read":"write"}var C$=P.preprocess(($)=>{if(typeof $==="string"){let[Q,...Z]=$.trim().split(/\s+/);return{name:Q,type:Z.join(" ")||"text"}}return $},P.object({name:P.string().trim().min(1),type:P.string().trim().min(1),isPk:P.boolean().optional(),isFk:P.boolean().optional(),nullable:P.boolean().optional(),note:P.string().nullish()})),r5=P.object({name:P.string().trim().min(1),domain:P.string().nullish(),description:P.string().nullish(),columns:P.array(C$).default([])}),i5=P.object({fromTable:P.string(),fromColumn:P.string(),toTable:P.string(),toColumn:P.string(),label:P.string().nullish()}),t5=P.object({method:P.string().trim().min(1),path:P.string().trim().min(1),domain:P.string().nullish(),description:P.string().nullish(),uses:P.array(P.object({table:P.string().trim().min(1),access:P.string().optional()})).default([])}).transform(($)=>({...$,uses:$.uses.map((Q)=>({...Q,access:Q.access??a5($.method)}))})),oQ=P.object({tables:P.array(r5).default([]),relations:P.array(i5).default([]),endpoints:P.array(t5).default([])});import{z as A}from"zod";import{and as KZ,eq as NZ,inArray as MZ}from"drizzle-orm";import{drizzle as c$}from"drizzle-orm/libsql";import{createClient as l$}from"@libsql/client";var W5={};o(W5,{tag:()=>c,syncState:()=>D$,projectMeta:()=>E$,note:()=>F$,nodeTags:()=>x,nodeFile:()=>Z0,node:()=>K,endpointTable:()=>z,endpoint:()=>l,edge:()=>k,draftTable:()=>D,draftRelation:()=>S,draftColumn:()=>V0,dbTable:()=>v,dbRelation:()=>h,dbColumn:()=>Y0,codeFileEdge:()=>u,codeFile:()=>T,bugFlag:()=>J0,boardAnnotation:()=>R$,appSetting:()=>A$});import{sqliteTable as q,index as N,foreignKey as v$,text as V,integer as j,real as R,uniqueIndex as _,primaryKey as O$}from"drizzle-orm/sqlite-core";import{createId as O}from"@paralleldrive/cuid2";var K=q("Node",{id:V().primaryKey().$defaultFn(()=>O()),view:V().notNull(),kind:V().default("FEATURE").notNull(),cluster:V(),title:V().notNull(),role:V(),plain:V(),status:V().default("PENDING").notNull(),priority:j().default(2).notNull(),progress:j().default(0).notNull(),x:R().default(0).notNull(),y:R().default(0).notNull(),sourceRef:V(),externalId:V(),source:V().default("MANUAL").notNull(),parentId:V(),createdAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date),updatedAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date).$onUpdate(()=>new Date)},($)=>[N("Node_cluster_idx").on($.cluster),N("Node_parentId_idx").on($.parentId),N("Node_view_idx").on($.view),v$(()=>({columns:[$.parentId],foreignColumns:[$.id],name:"Node_parentId_Node_id_fk"})).onUpdate("cascade").onDelete("cascade")]),Z0=q("NodeFile",{id:V().primaryKey().$defaultFn(()=>O()),nodeId:V().notNull().references(()=>K.id,{onDelete:"cascade",onUpdate:"cascade"}),path:V().notNull()},($)=>[_("NodeFile_nodeId_path_key").on($.nodeId,$.path),N("NodeFile_nodeId_idx").on($.nodeId)]),c=q("Tag",{id:V().primaryKey().$defaultFn(()=>O()),label:V().notNull(),color:V()},($)=>[_("Tag_label_key").on($.label)]),k=q("Edge",{id:V().primaryKey().$defaultFn(()=>O()),fromId:V().notNull().references(()=>K.id,{onDelete:"cascade",onUpdate:"cascade"}),toId:V().notNull().references(()=>K.id,{onDelete:"cascade",onUpdate:"cascade"}),kind:V().default("DEPENDS").notNull(),label:V(),sourceHandle:V(),targetHandle:V()},($)=>[_("Edge_fromId_toId_kind_key").on($.fromId,$.toId,$.kind),N("Edge_toId_idx").on($.toId),N("Edge_fromId_idx").on($.fromId)]),x=q("_NodeTags",{a:V("A").notNull().references(()=>K.id,{onDelete:"cascade",onUpdate:"cascade"}),b:V("B").notNull().references(()=>c.id,{onDelete:"cascade",onUpdate:"cascade"})},($)=>[_("_NodeTags_AB_unique").on($.a,$.b),N("_NodeTags_B_index").on($.b)]),F$=q("Note",{id:V().primaryKey().$defaultFn(()=>O()),title:V().default("Untitled").notNull(),body:V().default("").notNull(),ord:R().default(0).notNull(),pinned:j({mode:"boolean"}).default(!1).notNull(),createdAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date),updatedAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date).$onUpdate(()=>new Date)},($)=>[N("Note_updatedAt_idx").on($.updatedAt)]),R$=q("BoardAnnotation",{id:V().primaryKey().$defaultFn(()=>O()),targetKind:V().notNull(),targetId:V().notNull(),columnName:V(),body:V().default("").notNull(),x:R(),y:R(),createdAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date),updatedAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date).$onUpdate(()=>new Date)},($)=>[N("BoardAnnotation_target_idx").on($.targetId)]),J0=q("BugFlag",{id:V().primaryKey().$defaultFn(()=>O()),nodeId:V().notNull().references(()=>K.id,{onDelete:"cascade",onUpdate:"cascade"}),by:V().notNull(),note:V().notNull(),resolvedAt:j({mode:"timestamp_ms"}),createdAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date)},($)=>[N("BugFlag_nodeId_idx").on($.nodeId)]),v=q("DbTable",{id:V().primaryKey().$defaultFn(()=>O()),name:V().notNull(),domain:V(),description:V(),source:V().default("MANUAL").notNull(),x:R().default(0).notNull(),y:R().default(0).notNull(),createdAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date),updatedAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date).$onUpdate(()=>new Date)},($)=>[N("DbTable_domain_idx").on($.domain),_("DbTable_name_key").on($.name)]),Y0=q("DbColumn",{id:V().primaryKey().$defaultFn(()=>O()),tableId:V().notNull().references(()=>v.id,{onDelete:"cascade",onUpdate:"cascade"}),name:V().notNull(),type:V().notNull(),isPk:j({mode:"boolean"}).default(!1).notNull(),isFk:j({mode:"boolean"}).default(!1).notNull(),nullable:j({mode:"boolean"}).default(!0).notNull(),note:V(),ord:j().default(0).notNull()},($)=>[_("DbColumn_tableId_name_key").on($.tableId,$.name),N("DbColumn_tableId_idx").on($.tableId)]),h=q("DbRelation",{id:V().primaryKey().$defaultFn(()=>O()),fromTableId:V().notNull().references(()=>v.id,{onDelete:"cascade",onUpdate:"cascade"}),toTableId:V().notNull().references(()=>v.id,{onDelete:"cascade",onUpdate:"cascade"}),fromColumn:V().notNull(),toColumn:V().notNull(),label:V()},($)=>[N("DbRelation_toTableId_idx").on($.toTableId),N("DbRelation_fromTableId_idx").on($.fromTableId)]),l=q("Endpoint",{id:V().primaryKey().$defaultFn(()=>O()),method:V().notNull(),path:V().notNull(),domain:V(),description:V(),source:V().default("MANUAL").notNull(),x:R().default(0).notNull(),y:R().default(0).notNull(),createdAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date),updatedAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date).$onUpdate(()=>new Date)},($)=>[_("Endpoint_method_path_key").on($.method,$.path),N("Endpoint_domain_idx").on($.domain)]),z=q("EndpointTable",{id:V().primaryKey().$defaultFn(()=>O()),endpointId:V().notNull().references(()=>l.id,{onDelete:"cascade",onUpdate:"cascade"}),tableId:V().notNull().references(()=>v.id,{onDelete:"cascade",onUpdate:"cascade"}),access:V().default("read").notNull()},($)=>[_("EndpointTable_endpointId_tableId_key").on($.endpointId,$.tableId),N("EndpointTable_tableId_idx").on($.tableId)]),D=q("DraftTable",{id:V().primaryKey().$defaultFn(()=>O()),name:V().notNull(),domain:V(),description:V(),x:R().default(0).notNull(),y:R().default(0).notNull(),createdAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date)},($)=>[_("DraftTable_name_key").on($.name)]),V0=q("DraftColumn",{id:V().primaryKey().$defaultFn(()=>O()),tableId:V().notNull().references(()=>D.id,{onDelete:"cascade",onUpdate:"cascade"}),name:V().notNull(),type:V().notNull(),isPk:j({mode:"boolean"}).default(!1).notNull(),isFk:j({mode:"boolean"}).default(!1).notNull(),nullable:j({mode:"boolean"}).default(!0).notNull(),note:V(),ord:j().default(0).notNull()},($)=>[N("DraftColumn_tableId_idx").on($.tableId)]),S=q("DraftRelation",{id:V().primaryKey().$defaultFn(()=>O()),fromTableId:V().notNull().references(()=>D.id,{onDelete:"cascade",onUpdate:"cascade"}),toTableId:V().notNull().references(()=>D.id,{onDelete:"cascade",onUpdate:"cascade"}),fromColumn:V().notNull(),toColumn:V().notNull(),label:V()},($)=>[N("DraftRelation_toTableId_idx").on($.toTableId),N("DraftRelation_fromTableId_idx").on($.fromTableId)]),T=q("CodeFile",{path:V().primaryKey(),root:V(),lang:V(),x:R().default(0).notNull(),y:R().default(0).notNull(),mtimeMs:R(),size:j(),inDegree:j().default(0).notNull(),outDegree:j().default(0).notNull(),updatedAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date).$onUpdate(()=>new Date)}),u=q("CodeFileEdge",{fromPath:V().notNull().references(()=>T.path,{onDelete:"cascade",onUpdate:"cascade"}),toPath:V().notNull().references(()=>T.path,{onDelete:"cascade",onUpdate:"cascade"}),circular:j({mode:"boolean"}).default(!1).notNull()},($)=>[N("CodeFileEdge_circular_idx").on($.circular),N("CodeFileEdge_toPath_idx").on($.toPath),N("CodeFileEdge_fromPath_idx").on($.fromPath),O$({columns:[$.fromPath,$.toPath],name:"CodeFileEdge_fromPath_toPath_pk"})]),D$=q("SyncState",{id:V().primaryKey().default("singleton"),version:j().default(0).notNull(),codeGraphSyncedAt:j({mode:"timestamp_ms"}),updatedAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date).$onUpdate(()=>new Date)}),A$=q("AppSetting",{id:V().primaryKey().default("singleton"),editor:V().default("auto").notNull(),currentFeatureId:V(),updatedAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date).$onUpdate(()=>new Date)}),E$=q("ProjectMeta",{id:V().primaryKey().default("singleton"),overview:V(),conventions:V().default("[]").notNull(),updatedAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date).$onUpdate(()=>new Date)});var U5={};o(U5,{tagRelations:()=>_$,nodeTagsRelations:()=>k$,nodeRelations:()=>I$,nodeFileRelations:()=>L$,endpointTableRelations:()=>S$,endpointRelations:()=>z$,edgeRelations:()=>g$,draftTableRelations:()=>u$,draftRelationRelations:()=>b$,draftColumnRelations:()=>f$,dbTableRelations:()=>y$,dbRelationRelations:()=>h$,dbColumnRelations:()=>x$,codeFileRelations:()=>m$,codeFileEdgeRelations:()=>p$,bugFlagRelations:()=>T$});import{relations as C}from"drizzle-orm";var I$=C(K,({one:$,many:Q})=>({files:Q(Z0),bugFlags:Q(J0),nodeTags:Q(x),edgesOut:Q(k,{relationName:"EdgeFrom"}),edgesIn:Q(k,{relationName:"EdgeTo"}),parent:$(K,{fields:[K.parentId],references:[K.id],relationName:"NodeTree"}),children:Q(K,{relationName:"NodeTree"})})),L$=C(Z0,({one:$})=>({node:$(K,{fields:[Z0.nodeId],references:[K.id]})})),T$=C(J0,({one:$})=>({node:$(K,{fields:[J0.nodeId],references:[K.id]})})),_$=C(c,({many:$})=>({nodeTags:$(x)})),k$=C(x,({one:$})=>({node:$(K,{fields:[x.a],references:[K.id]}),tag:$(c,{fields:[x.b],references:[c.id]})})),g$=C(k,({one:$})=>({from:$(K,{fields:[k.fromId],references:[K.id],relationName:"EdgeFrom"}),to:$(K,{fields:[k.toId],references:[K.id],relationName:"EdgeTo"})})),y$=C(v,({many:$})=>({columns:$(Y0),fksOut:$(h,{relationName:"FkFrom"}),fksIn:$(h,{relationName:"FkTo"}),usages:$(z)})),x$=C(Y0,({one:$})=>({table:$(v,{fields:[Y0.tableId],references:[v.id]})})),h$=C(h,({one:$})=>({fromTable:$(v,{fields:[h.fromTableId],references:[v.id],relationName:"FkFrom"}),toTable:$(v,{fields:[h.toTableId],references:[v.id],relationName:"FkTo"})})),z$=C(l,({many:$})=>({tables:$(z)})),S$=C(z,({one:$})=>({endpoint:$(l,{fields:[z.endpointId],references:[l.id]}),table:$(v,{fields:[z.tableId],references:[v.id]})})),u$=C(D,({many:$})=>({columns:$(V0),fksOut:$(S,{relationName:"DraftFkFrom"}),fksIn:$(S,{relationName:"DraftFkTo"})})),f$=C(V0,({one:$})=>({table:$(D,{fields:[V0.tableId],references:[D.id]})})),b$=C(S,({one:$})=>({fromTable:$(D,{fields:[S.fromTableId],references:[D.id],relationName:"DraftFkFrom"}),toTable:$(D,{fields:[S.toTableId],references:[D.id],relationName:"DraftFkTo"})})),m$=C(T,({many:$})=>({edgesOut:$(u,{relationName:"CFEFrom"}),edgesIn:$(u,{relationName:"CFETo"})})),p$=C(u,({one:$})=>({fromFile:$(T,{fields:[u.fromPath],references:[T.path],relationName:"CFEFrom"}),toFile:$(T,{fields:[u.toPath],references:[T.path],relationName:"CFETo"})}));var d$={...W5,...U5};function s$(){let $=process.env.DATABASE_URL;if($&&/^(file:|libsql:|wss?:|https?:|:memory:)/i.test($))return $;return"file:./dev.db"}var o$=s$();function $9($){let Q=l$({url:$});return Q.execute("PRAGMA foreign_keys = ON;"),c$(Q,{schema:d$})}var G5=globalThis,j5=G5.dzDefault??$9(o$);G5.dzDefault=j5;var e5=G5.dzByUrl??=new Map;function n$($){let Q=e5.get($);if(!Q)Q=$9($),e5.set($,Q);return Q}function a$(){if(process.env.BEACON_REPO)return j5;let $=X5()??Q0();if(!$)return j5;return n$(Z5($))}var r$=new Proxy({},{get($,Q){let Z=a$(),Y=Z[Q];return typeof Y==="function"?Y.bind(Z):Y}});import{forceCenter as VZ,forceCollide as XZ,forceLink as HZ,forceManyBody as WZ,forceSimulation as UZ}from"d3-force";var Q9=A.object({title:A.string().trim().min(1),role:A.string().nullish(),plain:A.string().nullish(),cluster:A.string().nullish(),category:A.string().nullish(),domain:A.string().nullish(),priority:A.number().nullish(),dependsOn:A.array(A.string()).nullish()}).transform(({category:$,domain:Q,priority:Z,...Y})=>({...Y,cluster:Y.cluster??$??Q??null,priority:Z==null?null:Math.max(0,Math.min(3,Math.round(Z)))})),vZ=A.object({features:A.array(Q9).default([])});var i$=/(\bmigrations?\b|\balembic\b|make revision|prisma migrate|unique\s?constraint|foreign\s?keys?|primary\s?keys?|\bFKs?\b|\bJSONB\b|create\s+table|alter\s+table|add\s+(a\s+)?column|new\s+(table|model|column)|app\/models\/|\bBaseModel\b|DeclarativeBase|schema\.prisma|@@unique|natural\s+keys?|\bpgvector\b|\bTSVECTOR\b|\bDbTable\b)/i;function Z9($){return!!$&&i$.test($)}function t$($){return $.cluster??$.category??$.domain??null}function J9($){let Q=$.map((Z)=>{let Y=[],X=t$(Z);if(!X||!X.trim())Y.push("category");if(Z.priority==null)Y.push("priority");return Y.length?` \u2022 "${Z.title?.trim()||"(untitled)"}" \u2014 missing ${Y.join(" + ")}`:null}).filter((Z)=>Z!==null);if(Q.length===0)return null;return"\u26D4 Every roadmap feature needs a category AND a priority \u2014 they drive grouping and ordering "+`on the board, and the user shouldn't have to add them by hand. Missing:
|
|
230
|
+
verbatim. Do NOT implement until the tool returns approval.`;var n0=f(()=>{b0();g=["beacon-init","beacon-refresh","beacon-plan"],s0=[{event:"PostToolUse",matcher:"Edit|Write|MultiEdit",command:"beacon hook",description:"Report file edits to Beacon's active feature so the map stays fresh."},{event:"PermissionRequest",matcher:"ExitPlanMode",command:"beacon plan",description:"Pipe the agent's plan markdown into Beacon's /plan canvas for review."},{event:"UserPromptSubmit",matcher:"*",command:"beacon prompt",description:"On feature-y prompts in a Beacon-wired repo, remind the agent to run the context\u2192propose\u2192describe loop (no-op otherwise)."},{event:"Stop",matcher:"*",command:"beacon stop-hook",description:"When the agent ends a turn asking for plan approval in prose (instead of presenting it), nudge it to present the plan on Beacon's /plan canvas. Bounded by stop_hook_active \u2014 at most one nudge."}]});var D5={};o(D5,{setupCodexAssets:()=>a9,removeCodexMcp:()=>z5,removeCodexArtifacts:()=>i9,hasCodexMcp:()=>t0,ensureCodexMcp:()=>h5,codexMcpProblem:()=>n9,codexDetected:()=>g5,auditCodex:()=>r9,CODEX_HOOKS:()=>E0});import{readFileSync as A0}from"fs";import{homedir as s9}from"os";import{join as t}from"path";function _5(){return process.env.HOME||process.env.USERPROFILE||s9()}function g5(){if(process.env.BEACON_CODEX==="1")return!0;if(process.env.BEACON_CODEX==="0")return!1;if(a0===void 0)a0=Bun.which("codex")!==null;return a0}function i($){try{return Bun.TOML.parse($)}catch{return null}}function t0(){try{return Boolean(i(A0(m(),"utf8"))?.mcp_servers?.beacon)}catch{return!1}}function n9(){let $="";try{$=A0(m(),"utf8")}catch{return null}let Q=i($);if(!Q)return`~/.codex/config.toml does not parse \u2014 ${r}`;if(Q.mcp_servers?.beacon)return null;if(/^\s*mcp_servers\s*=/m.test($))return`mcp_servers is an inline table \u2014 ${r}`;return null}function h5(){let $="",Q=!1;try{$=A0(m(),"utf8"),Q=!0}catch{}if(Q){let H=i($);if(!H)return{added:!1,error:`~/.codex/config.toml does not parse \u2014 ${r}`};if(H.mcp_servers?.beacon)return{added:!1};if(/^\s*mcp_servers\s*=/m.test($))return{added:!1,error:`mcp_servers is an inline table \u2014 ${r}`}}let Z=!$?"":$.endsWith(`
|
|
231
|
+
`)?`
|
|
232
|
+
`:`
|
|
233
|
+
|
|
234
|
+
`,Y=$+Z+o9;if(i(Y)?.mcp_servers?.beacon?.command!=="beacon")return{added:!1,error:`could not safely append [mcp_servers.beacon] \u2014 ${r}`};return m0(m(),Y),{added:!0}}function z5(){let $="";try{$=A0(m(),"utf8")}catch{return{removed:!1}}let Q=$.split(`
|
|
235
|
+
`),Z=Q.indexOf(y5);if(Z===-1)return{removed:!1,skipped:t0()};let Y=Q.indexOf(x5,Z);if(Y===-1)return{removed:!1,skipped:!0};Q.splice(Z,Y-Z+1);let X=Q.join(`
|
|
236
|
+
`).replace(/\n{3,}/g,`
|
|
237
|
+
|
|
238
|
+
`).replace(/^\n+/,"");if(i(X)===null)return{removed:!1,skipped:!0};return m0(m(),X),{removed:!0}}async function a9(){let{INIT_SKILL:$,REFRESH_SKILL:Q,PLAN_SKILL:Z}=await Promise.resolve().then(() => (S0(),z0)),Y={"beacon-init":$,"beacon-refresh":Q,"beacon-plan":Z},X=[];for(let U of g){if(!a(R0(),U))X.push(U);w0(R0(),U,Y[U])}let H=0;for(let U of E0)if(B0(i0(),{event:U.event,matcher:U.matcher,command:U.command}))H++;let W=n(F0(),D0);M0(F0(),D0,k5,o0);let G=h5();return{skillsAdded:X,hooksAdded:H,agentsMdBlockTouched:!W,mcp:G}}function r9(){let $={};for(let Z of g)$[Z]=a(R0(),Z);let Q={};for(let Z of E0)Q[Z.event]=K0(i0(),{event:Z.event,command:Z.command});return{detected:g5(),skills:$,hooks:Q,agentsMdBlock:n(F0(),D0),mcp:t0()}}function i9(){let $=[];for(let X of g)if(C0(R0(),X))$.push(X);let Q=0;for(let X of E0)if(N0(i0(),{event:X.event,command:X.command}))Q++;let Z=q0(F0(),D0,k5),Y=z5();return{skillsRemoved:$,hooksRemoved:Q,agentsMdBlockRemoved:Z,mcpRemoved:Y.removed,mcpSkipped:Y.skipped}}var r0=()=>t(_5(),".codex"),i0=()=>t(r0(),"hooks.json"),m=()=>t(r0(),"config.toml"),F0=()=>t(r0(),"AGENTS.md"),R0=()=>t(_5(),".agents","skills"),D0="<!-- beacon:global:start -->",k5="<!-- beacon:global:end -->",E0,a0,y5="# beacon:start (managed by Beacon \u2014 `beacon uninstall` removes this block)",x5="# beacon:end",o9,r="add it manually: codex mcp add beacon -- beacon mcp";var A5=f(()=>{b0();R5();n0();E0=[{event:"PostToolUse",matcher:"apply_patch",command:"beacon hook",description:"Report file edits to Beacon's active feature so the map stays fresh."},{event:"UserPromptSubmit",matcher:"*",command:"beacon prompt",description:"On feature-y prompts in a Beacon-wired repo, remind the agent to run the context\u2192propose\u2192describe loop (no-op otherwise)."},{event:"Stop",matcher:"*",command:"beacon stop-hook",description:"When the agent ends a turn asking for plan approval in prose, nudge it to present the plan on Beacon's /plan canvas."}];o9=`${y5}
|
|
239
|
+
[mcp_servers.beacon]
|
|
240
|
+
command = "beacon"
|
|
241
|
+
args = ["mcp"]
|
|
242
|
+
${x5}
|
|
243
|
+
`});var u5={};o(u5,{provisionDb:()=>U$});import{createClient as t9}from"@libsql/client";import{drizzle as e9}from"drizzle-orm/libsql";import{migrate as $$}from"drizzle-orm/libsql/migrator";import{readMigrationFiles as Q$}from"drizzle-orm/migrator";import{dirname as e0,join as Z$}from"path";import{fileURLToPath as J$}from"url";async function I0($,Q){return(await $.execute({sql:"SELECT 1 FROM sqlite_master WHERE type='table' AND name = ?",args:[Q]})).rows.length>0}async function H$($,Q){let Z=await $.execute(`PRAGMA table_info("${Q}")`);return new Set(Z.rows.map((Y)=>String(Y.name)))}async function S5($){if(!await I0($,"__drizzle_migrations"))return 0;let Q=await $.execute('SELECT count(*) AS n FROM "__drizzle_migrations"');return Number(Q.rows[0]?.n??0)}async function W$($){for(let[Q,Z]of Object.entries(X$)){if(!await I0($,Q))continue;let Y=await H$($,Q);for(let X of Z){if(!Y.has(X))continue;await $.execute(`UPDATE "${Q}" SET "${X}" = CAST((julianday("${X}") - 2440587.5) * 86400000 AS INTEGER) WHERE typeof("${X}") = 'text'`)}}}async function U$($,Q=V$){let Z=t9({url:$});try{await Z.execute("PRAGMA journal_mode = WAL;"),await Z.execute("PRAGMA foreign_keys = ON;");let Y=await I0(Z,"__drizzle_migrations"),X=await I0(Z,"Node"),H=!1;if(X&&!Y){let G=Q$({migrationsFolder:Q})[0];if(G)await Z.execute('CREATE TABLE IF NOT EXISTS "__drizzle_migrations" (id SERIAL PRIMARY KEY, hash text NOT NULL, created_at numeric)'),await Z.execute({sql:'INSERT INTO "__drizzle_migrations" ("hash", "created_at") VALUES (?, ?)',args:[G.hash,G.folderMillis]}),H=!0}let W=await S5(Z);if(await $$(e9(Z),{migrationsFolder:Q}),await S5(Z)>W)H=!0;return await W$(Z),{migrated:H}}finally{Z.close()}}var Y$,V$,X$;var f5=f(async()=>{Y$=e0(e0(e0(J$(import.meta.url)))),V$=process.env.BEACON_MIGRATIONS_DIR||Z$(Y$,"drizzle"),X$={Node:["createdAt","updatedAt"],Note:["createdAt","updatedAt"],DbTable:["createdAt","updatedAt"],Endpoint:["createdAt","updatedAt"],DraftTable:["createdAt"],SyncState:["codeGraphSyncedAt","updatedAt"],AppSetting:["updatedAt"],ProjectMeta:["updatedAt"],CodeFile:["updatedAt"]}});import{AsyncLocalStorage as j$}from"async_hooks";import{spawnSync as G$}from"child_process";import{createHash as P$}from"crypto";import{existsSync as m5,mkdirSync as L0,readFileSync as p5,writeFileSync as c5}from"fs";import{homedir as B$}from"os";import{basename as K$,join as p}from"path";function e(){return process.env.BEACON_HOME||p(B$(),".beacon")}function $5(){return p(e(),"workspaces.json")}function T0($){return P$("sha256").update($).digest("hex").slice(0,12)}function l5($=process.cwd()){let Q=G$("git",["rev-parse","--show-toplevel"],{cwd:$,stdio:["ignore","pipe","ignore"]});if(Q.status===0){let Z=Q.stdout?.toString().trim();if(Z)return Z}return $}function Q5($){return p(e(),$)}function Z5($){return`file:${p(Q5($),"db.sqlite")}`}function $0(){try{let $=JSON.parse(p5($5(),"utf8"));return Array.isArray($)?$:[]}catch{return[]}}function J5($){L0(e(),{recursive:!0}),c5($5(),JSON.stringify($,null,2))}function N$(){return $0().sort(($,Q)=>Q.lastOpenedAt.localeCompare($.lastOpenedAt))}function y($){return $0().find((Q)=>Q.id===$)??null}function Y5($,Q,Z=new Date().toISOString()){let Y=T0($),X=$0(),H=X.find((U)=>U.id===Y),W={id:Y,path:$,name:Q||H?.name||K$($),lastOpenedAt:Z},G=[W,...X.filter((U)=>U.id!==Y)];return L0(Q5(Y),{recursive:!0}),J5(G),W}function hQ($,Q=new Date().toISOString()){let Z=$0(),Y=Z.find((X)=>X.id===$);if(!Y)return;Y.lastOpenedAt=Q,J5(Z)}function zQ($){if(J5($0().filter((Q)=>Q.id!==$)),Q0()===$)M$(N$()[0]?.id??null)}function d5(){return p(e(),"active")}function Q0(){try{return p5(d5(),"utf8").trim()||null}catch{return null}}function M$($){L0(e(),{recursive:!0}),c5(d5(),$??"")}function SQ(){let $=Q0();return $?y($):null}function uQ(){let $=X5()??Q0();return $?y($):null}function fQ($){return y($)?.path??null}function bQ(){return m5($5())}var s5="beacon_ws";function o5($,Q){let Z=$.headers.get("cookie");if(!Z)return null;for(let Y of Z.split(";")){let X=Y.indexOf("=");if(X===-1)continue;if(Y.slice(0,X).trim()===Q)return decodeURIComponent(Y.slice(X+1).trim())}return null}function mQ($){let Q=$.headers.get("x-beacon-workspace");if(Q&&y(Q))return Q;let Z=o5($,s5);if(Z&&y(Z))return Z;return null}var V5="x-beacon-workspace-path";async function pQ($){let Q=$.headers.get("x-beacon-workspace");if(Q&&y(Q))return Q;let Z=$.headers.get(V5);if(Z&&(!Q||T0(Z)===Q)){let X=Y5(Z);return await H5(X.id),X.id}let Y=o5($,s5);if(Y&&y(Y))return Y;return null}var n5=new j$;function q$($,Q){return $?n5.run($,Q):Q()}function X5(){return n5.getStore()??null}var b5=new Set;async function H5($){let Q=Q5($),Z=p(Q,"db.sqlite"),Y=m5(Z);if(Y&&b5.has(Z))return{ok:!0,created:!1,migrated:!1};try{L0(Q,{recursive:!0});let{provisionDb:X}=await f5().then(() => u5),H=await X(Z5($));return b5.add(Z),{ok:!0,created:!Y,migrated:Y&&H.migrated}}catch(X){return{ok:!1,created:!1,migrated:!1,error:X instanceof Error?X.message:String(X)}}}n0();import{McpServer as e$,ResourceTemplate as N5}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as $Q}from"@modelcontextprotocol/sdk/server/stdio.js";import{z as J}from"zod";import{z as P}from"zod";var w$=new Set(["GET","HEAD","OPTIONS"]);function a5($){return w$.has($.trim().toUpperCase())?"read":"write"}var C$=P.preprocess(($)=>{if(typeof $==="string"){let[Q,...Z]=$.trim().split(/\s+/);return{name:Q,type:Z.join(" ")||"text"}}return $},P.object({name:P.string().trim().min(1),type:P.string().trim().min(1),isPk:P.boolean().optional(),isFk:P.boolean().optional(),nullable:P.boolean().optional(),note:P.string().nullish()})),r5=P.object({name:P.string().trim().min(1),domain:P.string().nullish(),description:P.string().nullish(),columns:P.array(C$).default([])}),i5=P.object({fromTable:P.string(),fromColumn:P.string(),toTable:P.string(),toColumn:P.string(),label:P.string().nullish()}),t5=P.object({method:P.string().trim().min(1),path:P.string().trim().min(1),domain:P.string().nullish(),description:P.string().nullish(),uses:P.array(P.object({table:P.string().trim().min(1),access:P.string().optional()})).default([])}).transform(($)=>({...$,uses:$.uses.map((Q)=>({...Q,access:Q.access??a5($.method)}))})),oQ=P.object({tables:P.array(r5).default([]),relations:P.array(i5).default([]),endpoints:P.array(t5).default([])});import{z as A}from"zod";import{and as KZ,eq as NZ,inArray as MZ}from"drizzle-orm";import{drizzle as c$}from"drizzle-orm/libsql";import{createClient as l$}from"@libsql/client";var W5={};o(W5,{tag:()=>c,syncState:()=>D$,projectMeta:()=>E$,note:()=>F$,nodeTags:()=>x,nodeFile:()=>Z0,node:()=>K,endpointTable:()=>z,endpoint:()=>l,edge:()=>k,draftTable:()=>D,draftRelation:()=>S,draftColumn:()=>V0,dbTable:()=>v,dbRelation:()=>h,dbColumn:()=>Y0,codeFileEdge:()=>u,codeFile:()=>T,bugFlag:()=>J0,boardAnnotation:()=>R$,appSetting:()=>A$});import{sqliteTable as q,index as N,foreignKey as v$,text as V,integer as j,real as R,uniqueIndex as _,primaryKey as O$}from"drizzle-orm/sqlite-core";import{createId as O}from"@paralleldrive/cuid2";var K=q("Node",{id:V().primaryKey().$defaultFn(()=>O()),view:V().notNull(),kind:V().default("FEATURE").notNull(),cluster:V(),title:V().notNull(),role:V(),plain:V(),status:V().default("PENDING").notNull(),priority:j().default(2).notNull(),progress:j().default(0).notNull(),x:R().default(0).notNull(),y:R().default(0).notNull(),sourceRef:V(),externalId:V(),source:V().default("MANUAL").notNull(),parentId:V(),createdAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date),updatedAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date).$onUpdate(()=>new Date)},($)=>[N("Node_cluster_idx").on($.cluster),N("Node_parentId_idx").on($.parentId),N("Node_view_idx").on($.view),v$(()=>({columns:[$.parentId],foreignColumns:[$.id],name:"Node_parentId_Node_id_fk"})).onUpdate("cascade").onDelete("cascade")]),Z0=q("NodeFile",{id:V().primaryKey().$defaultFn(()=>O()),nodeId:V().notNull().references(()=>K.id,{onDelete:"cascade",onUpdate:"cascade"}),path:V().notNull()},($)=>[_("NodeFile_nodeId_path_key").on($.nodeId,$.path),N("NodeFile_nodeId_idx").on($.nodeId)]),c=q("Tag",{id:V().primaryKey().$defaultFn(()=>O()),label:V().notNull(),color:V()},($)=>[_("Tag_label_key").on($.label)]),k=q("Edge",{id:V().primaryKey().$defaultFn(()=>O()),fromId:V().notNull().references(()=>K.id,{onDelete:"cascade",onUpdate:"cascade"}),toId:V().notNull().references(()=>K.id,{onDelete:"cascade",onUpdate:"cascade"}),kind:V().default("DEPENDS").notNull(),label:V(),sourceHandle:V(),targetHandle:V()},($)=>[_("Edge_fromId_toId_kind_key").on($.fromId,$.toId,$.kind),N("Edge_toId_idx").on($.toId),N("Edge_fromId_idx").on($.fromId)]),x=q("_NodeTags",{a:V("A").notNull().references(()=>K.id,{onDelete:"cascade",onUpdate:"cascade"}),b:V("B").notNull().references(()=>c.id,{onDelete:"cascade",onUpdate:"cascade"})},($)=>[_("_NodeTags_AB_unique").on($.a,$.b),N("_NodeTags_B_index").on($.b)]),F$=q("Note",{id:V().primaryKey().$defaultFn(()=>O()),title:V().default("Untitled").notNull(),body:V().default("").notNull(),ord:R().default(0).notNull(),pinned:j({mode:"boolean"}).default(!1).notNull(),createdAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date),updatedAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date).$onUpdate(()=>new Date)},($)=>[N("Note_updatedAt_idx").on($.updatedAt)]),R$=q("BoardAnnotation",{id:V().primaryKey().$defaultFn(()=>O()),targetKind:V().notNull(),targetId:V().notNull(),columnName:V(),body:V().default("").notNull(),x:R(),y:R(),createdAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date),updatedAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date).$onUpdate(()=>new Date)},($)=>[N("BoardAnnotation_target_idx").on($.targetId)]),J0=q("BugFlag",{id:V().primaryKey().$defaultFn(()=>O()),nodeId:V().notNull().references(()=>K.id,{onDelete:"cascade",onUpdate:"cascade"}),by:V().notNull(),note:V().notNull(),resolvedAt:j({mode:"timestamp_ms"}),createdAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date)},($)=>[N("BugFlag_nodeId_idx").on($.nodeId)]),v=q("DbTable",{id:V().primaryKey().$defaultFn(()=>O()),name:V().notNull(),domain:V(),description:V(),source:V().default("MANUAL").notNull(),x:R().default(0).notNull(),y:R().default(0).notNull(),createdAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date),updatedAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date).$onUpdate(()=>new Date)},($)=>[N("DbTable_domain_idx").on($.domain),_("DbTable_name_key").on($.name)]),Y0=q("DbColumn",{id:V().primaryKey().$defaultFn(()=>O()),tableId:V().notNull().references(()=>v.id,{onDelete:"cascade",onUpdate:"cascade"}),name:V().notNull(),type:V().notNull(),isPk:j({mode:"boolean"}).default(!1).notNull(),isFk:j({mode:"boolean"}).default(!1).notNull(),nullable:j({mode:"boolean"}).default(!0).notNull(),note:V(),ord:j().default(0).notNull()},($)=>[_("DbColumn_tableId_name_key").on($.tableId,$.name),N("DbColumn_tableId_idx").on($.tableId)]),h=q("DbRelation",{id:V().primaryKey().$defaultFn(()=>O()),fromTableId:V().notNull().references(()=>v.id,{onDelete:"cascade",onUpdate:"cascade"}),toTableId:V().notNull().references(()=>v.id,{onDelete:"cascade",onUpdate:"cascade"}),fromColumn:V().notNull(),toColumn:V().notNull(),label:V()},($)=>[N("DbRelation_toTableId_idx").on($.toTableId),N("DbRelation_fromTableId_idx").on($.fromTableId)]),l=q("Endpoint",{id:V().primaryKey().$defaultFn(()=>O()),method:V().notNull(),path:V().notNull(),domain:V(),description:V(),source:V().default("MANUAL").notNull(),x:R().default(0).notNull(),y:R().default(0).notNull(),createdAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date),updatedAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date).$onUpdate(()=>new Date)},($)=>[_("Endpoint_method_path_key").on($.method,$.path),N("Endpoint_domain_idx").on($.domain)]),z=q("EndpointTable",{id:V().primaryKey().$defaultFn(()=>O()),endpointId:V().notNull().references(()=>l.id,{onDelete:"cascade",onUpdate:"cascade"}),tableId:V().notNull().references(()=>v.id,{onDelete:"cascade",onUpdate:"cascade"}),access:V().default("read").notNull()},($)=>[_("EndpointTable_endpointId_tableId_key").on($.endpointId,$.tableId),N("EndpointTable_tableId_idx").on($.tableId)]),D=q("DraftTable",{id:V().primaryKey().$defaultFn(()=>O()),name:V().notNull(),domain:V(),description:V(),x:R().default(0).notNull(),y:R().default(0).notNull(),createdAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date)},($)=>[_("DraftTable_name_key").on($.name)]),V0=q("DraftColumn",{id:V().primaryKey().$defaultFn(()=>O()),tableId:V().notNull().references(()=>D.id,{onDelete:"cascade",onUpdate:"cascade"}),name:V().notNull(),type:V().notNull(),isPk:j({mode:"boolean"}).default(!1).notNull(),isFk:j({mode:"boolean"}).default(!1).notNull(),nullable:j({mode:"boolean"}).default(!0).notNull(),note:V(),ord:j().default(0).notNull()},($)=>[N("DraftColumn_tableId_idx").on($.tableId)]),S=q("DraftRelation",{id:V().primaryKey().$defaultFn(()=>O()),fromTableId:V().notNull().references(()=>D.id,{onDelete:"cascade",onUpdate:"cascade"}),toTableId:V().notNull().references(()=>D.id,{onDelete:"cascade",onUpdate:"cascade"}),fromColumn:V().notNull(),toColumn:V().notNull(),label:V()},($)=>[N("DraftRelation_toTableId_idx").on($.toTableId),N("DraftRelation_fromTableId_idx").on($.fromTableId)]),T=q("CodeFile",{path:V().primaryKey(),root:V(),lang:V(),x:R().default(0).notNull(),y:R().default(0).notNull(),mtimeMs:R(),size:j(),inDegree:j().default(0).notNull(),outDegree:j().default(0).notNull(),updatedAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date).$onUpdate(()=>new Date)}),u=q("CodeFileEdge",{fromPath:V().notNull().references(()=>T.path,{onDelete:"cascade",onUpdate:"cascade"}),toPath:V().notNull().references(()=>T.path,{onDelete:"cascade",onUpdate:"cascade"}),circular:j({mode:"boolean"}).default(!1).notNull()},($)=>[N("CodeFileEdge_circular_idx").on($.circular),N("CodeFileEdge_toPath_idx").on($.toPath),N("CodeFileEdge_fromPath_idx").on($.fromPath),O$({columns:[$.fromPath,$.toPath],name:"CodeFileEdge_fromPath_toPath_pk"})]),D$=q("SyncState",{id:V().primaryKey().default("singleton"),version:j().default(0).notNull(),codeGraphSyncedAt:j({mode:"timestamp_ms"}),updatedAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date).$onUpdate(()=>new Date)}),A$=q("AppSetting",{id:V().primaryKey().default("singleton"),editor:V().default("auto").notNull(),currentFeatureId:V(),updatedAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date).$onUpdate(()=>new Date)}),E$=q("ProjectMeta",{id:V().primaryKey().default("singleton"),overview:V(),conventions:V().default("[]").notNull(),updatedAt:j({mode:"timestamp_ms"}).notNull().$defaultFn(()=>new Date).$onUpdate(()=>new Date)});var U5={};o(U5,{tagRelations:()=>_$,nodeTagsRelations:()=>k$,nodeRelations:()=>I$,nodeFileRelations:()=>L$,endpointTableRelations:()=>S$,endpointRelations:()=>z$,edgeRelations:()=>g$,draftTableRelations:()=>u$,draftRelationRelations:()=>b$,draftColumnRelations:()=>f$,dbTableRelations:()=>y$,dbRelationRelations:()=>h$,dbColumnRelations:()=>x$,codeFileRelations:()=>m$,codeFileEdgeRelations:()=>p$,bugFlagRelations:()=>T$});import{relations as C}from"drizzle-orm";var I$=C(K,({one:$,many:Q})=>({files:Q(Z0),bugFlags:Q(J0),nodeTags:Q(x),edgesOut:Q(k,{relationName:"EdgeFrom"}),edgesIn:Q(k,{relationName:"EdgeTo"}),parent:$(K,{fields:[K.parentId],references:[K.id],relationName:"NodeTree"}),children:Q(K,{relationName:"NodeTree"})})),L$=C(Z0,({one:$})=>({node:$(K,{fields:[Z0.nodeId],references:[K.id]})})),T$=C(J0,({one:$})=>({node:$(K,{fields:[J0.nodeId],references:[K.id]})})),_$=C(c,({many:$})=>({nodeTags:$(x)})),k$=C(x,({one:$})=>({node:$(K,{fields:[x.a],references:[K.id]}),tag:$(c,{fields:[x.b],references:[c.id]})})),g$=C(k,({one:$})=>({from:$(K,{fields:[k.fromId],references:[K.id],relationName:"EdgeFrom"}),to:$(K,{fields:[k.toId],references:[K.id],relationName:"EdgeTo"})})),y$=C(v,({many:$})=>({columns:$(Y0),fksOut:$(h,{relationName:"FkFrom"}),fksIn:$(h,{relationName:"FkTo"}),usages:$(z)})),x$=C(Y0,({one:$})=>({table:$(v,{fields:[Y0.tableId],references:[v.id]})})),h$=C(h,({one:$})=>({fromTable:$(v,{fields:[h.fromTableId],references:[v.id],relationName:"FkFrom"}),toTable:$(v,{fields:[h.toTableId],references:[v.id],relationName:"FkTo"})})),z$=C(l,({many:$})=>({tables:$(z)})),S$=C(z,({one:$})=>({endpoint:$(l,{fields:[z.endpointId],references:[l.id]}),table:$(v,{fields:[z.tableId],references:[v.id]})})),u$=C(D,({many:$})=>({columns:$(V0),fksOut:$(S,{relationName:"DraftFkFrom"}),fksIn:$(S,{relationName:"DraftFkTo"})})),f$=C(V0,({one:$})=>({table:$(D,{fields:[V0.tableId],references:[D.id]})})),b$=C(S,({one:$})=>({fromTable:$(D,{fields:[S.fromTableId],references:[D.id],relationName:"DraftFkFrom"}),toTable:$(D,{fields:[S.toTableId],references:[D.id],relationName:"DraftFkTo"})})),m$=C(T,({many:$})=>({edgesOut:$(u,{relationName:"CFEFrom"}),edgesIn:$(u,{relationName:"CFETo"})})),p$=C(u,({one:$})=>({fromFile:$(T,{fields:[u.fromPath],references:[T.path],relationName:"CFEFrom"}),toFile:$(T,{fields:[u.toPath],references:[T.path],relationName:"CFETo"})}));var d$={...W5,...U5};function s$(){let $=process.env.DATABASE_URL;if($&&/^(file:|libsql:|wss?:|https?:|:memory:)/i.test($))return $;return"file:./dev.db"}var o$=s$();function $9($){let Q=l$({url:$});return Q.execute("PRAGMA foreign_keys = ON;"),c$(Q,{schema:d$})}var G5=globalThis,j5=G5.dzDefault??$9(o$);G5.dzDefault=j5;var e5=G5.dzByUrl??=new Map;function n$($){let Q=e5.get($);if(!Q)Q=$9($),e5.set($,Q);return Q}function a$(){if(process.env.BEACON_REPO)return j5;let $=X5()??Q0();if(!$)return j5;return n$(Z5($))}var r$=new Proxy({},{get($,Q){let Z=a$(),Y=Z[Q];return typeof Y==="function"?Y.bind(Z):Y}});import{forceCenter as VZ,forceCollide as XZ,forceLink as HZ,forceManyBody as WZ,forceSimulation as UZ}from"d3-force";var Q9=A.object({title:A.string().trim().min(1),role:A.string().nullish(),plain:A.string().nullish(),cluster:A.string().nullish(),category:A.string().nullish(),domain:A.string().nullish(),priority:A.number().nullish(),dependsOn:A.array(A.string()).nullish()}).transform(({category:$,domain:Q,priority:Z,...Y})=>({...Y,cluster:Y.cluster??$??Q??null,priority:Z==null?null:Math.max(0,Math.min(3,Math.round(Z)))})),vZ=A.object({features:A.array(Q9).default([])});var i$=/(\bmigrations?\b|\balembic\b|make revision|prisma migrate|unique\s?constraint|foreign\s?keys?|primary\s?keys?|\bFKs?\b|\bJSONB\b|create\s+table|alter\s+table|add\s+(a\s+)?column|new\s+(table|model|column)|app\/models\/|\bBaseModel\b|DeclarativeBase|schema\.prisma|@@unique|natural\s+keys?|\bpgvector\b|\bTSVECTOR\b|\bDbTable\b)/i;function Z9($){return!!$&&i$.test($)}function t$($){return $.cluster??$.category??$.domain??null}function J9($){let Q=$.map((Z)=>{let Y=[],X=t$(Z);if(!X||!X.trim())Y.push("category");if(Z.priority==null)Y.push("priority");return Y.length?` \u2022 "${Z.title?.trim()||"(untitled)"}" \u2014 missing ${Y.join(" + ")}`:null}).filter((Z)=>Z!==null);if(Q.length===0)return null;return"\u26D4 Every roadmap feature needs a category AND a priority \u2014 they drive grouping and ordering "+`on the board, and the user shouldn't have to add them by hand. Missing:
|
|
244
244
|
`+Q.join(`
|
|
245
245
|
`)+"\n\nRe-present with each feature carrying its category as `category` (or `cluster` \u2014 both "+"work; e.g. AUTH, SEARCH, DATA, INTEL, BILLING \u2026) and `priority` (0 = P0 critical, 1 = P1 "+"high, 2 = P2 medium, 3 = P3 low). Set BOTH on EVERY feature; don't rely on defaults."}function P5($){if(!$?.length)return"";let Q=$.map((Y)=>Y.id?` \u2022 ${Y.title} \u2014 id: ${Y.id}`:` \u2022 ${Y.title}`),Z=$.some((Y)=>Y.id);return`
|
|
246
246
|
|
|
247
247
|
This plan created these roadmap feature(s):
|
|
248
248
|
`+Q.join(`
|
|
249
249
|
`)+"\n\nWhen the work ships, register them in ONE call: `beacon_describe_feature` with a "+"`features` array \u2014 one entry per feature"+(Z?", each keyed by the `id` above (no title-matching needed)":"")+", each with the files you touched + a short markdown summary. Do them all in that single "+"batched call so every feature flips to Done \u2014 do NOT register only the umbrella, and do "+"NOT make one call per feature."}var B5=1500,_Z=345600000,K5=1800000,Y9=3000;function X0($){return $.toLowerCase().normalize("NFD").replace(/[\u0300-\u036F]/g,"").replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,50)||"item"}function V9($){return`${X0($.title)}-${$.id.slice(-6)}`}function X9($){return{resources:$.map((Q)=>({uri:`note://${V9(Q)}`,name:Q.title||"Untitled",description:`${Q.title||"Untitled"}${Q.pinned?" \xB7 pinned":""} \xB7 note`,mimeType:"text/markdown"}))}}function H9($,Q){return $.find((Z)=>V9(Z)===Q)}function W9($){let Q=$.body.trim()||"(this note is empty)";return[`# ${$.title||"Untitled"}`,"","_User note from Beacon. To turn it into roadmap work, call `beacon_propose_plan` \u2014"+" checkbox `- [ ]` / `- [x]` items become subtasks, and order the features with `dependsOn`. Do NOT implement until it returns approval._","","---","",Q].join(`
|
|
250
|
-
`)}await z5();var M5=process.env.BEACON_URL||`http://localhost:${process.env.PORT||4319}`,q5=l5(),g0=T0(q5);try{Y5(q5);let $=await H5(g0);if(!$.ok)console.error(`[beacon mcp] db provisioning failed: ${$.error}`)}catch($){console.error(`[beacon mcp] workspace registration failed: ${$ instanceof Error?$.message:$}`)}async function E($,Q){let Z=new Headers(Q?.headers);Z.set("x-beacon-workspace",g0),Z.set(V5,q5);let Y=await fetch(`${M5}${$}`,{...Q,headers:Z}),X=await Y.text();if(!Y.ok)throw Error(`Beacon ${$} -> ${Y.status} ${X}`);return X?JSON.parse(X):null}function d($,Q){return E($,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(Q)})}function G9($){let Q=$ instanceof Error?$.message:String($),Z=Q.match(/\{[\s\S]*\}$/);if(Z)try{let Y=JSON.parse(Z[0]);if(Y?.error)return{content:[{type:"text",text:Y.error}],isError:!0}}catch{}return{content:[{type:"text",text:Q}],isError:!0}}var F=new e$({name:"beacon",version:"0.1.0"});F.registerTool("beacon_map",{description:"List existing features on the roadmap. Call before starting work."},async()=>{let $=await E("/api/map");return{content:[{type:"text",text:JSON.stringify($)}]}});F.registerTool("beacon_start_feature",{description:"Flag that you're working on a feature. If the title matches an existing feature it just marks it IN_PROGRESS (no category needed); if it's NEW it creates the node \u2014 and a new feature REQUIRES a `category`. Call beacon_map first so you reuse an existing feature/category instead of duplicating one.",inputSchema:{title:J.string(),id:J.string().optional().describe("node id from beacon_map (preferred)"),category:J.string().optional().describe("Domain lane for a NEW feature: AUTH | SEARCH | DATA | INTEL | BILLING | INFRA | UI | \u2026 REQUIRED when this creates a new top-level feature; reuse a category already on the board. Ignored when flagging an existing feature or nesting under a `front` (inherits the parent's)."),front:J.string().optional().describe("Title of an EXISTING parent feature to nest this under (draws the parent \u2192 child edge). It must match a real feature \u2014 it is NOT a domain tag (use `category` for the domain). A `front` that matches nothing is REJECTED; create the parent first via beacon_propose_plan."),detail:J.string().optional().describe("One-line plain-language description shown on the canvas card. Replaced later by beacon_describe_feature's markdown when the work is done.")}},async({title:$,id:Q,front:Z,detail:Y,category:X})=>{try{let H=await d("/api/map/start",{title:$,id:Q,front:Z,detail:Y,category:X});return{content:[{type:"text",text:JSON.stringify(H)}]}}catch(H){return G9(H)}});F.registerTool("beacon_add_subtasks",{description:"Add N sub-tasks under an existing feature in one call. Use when the user says 'add these as subtasks to <feature>' or you want to record follow-ups discovered during work. Parent resolves by `parentId` (preferred \u2014 get it from beacon_map / beacon_entities) or by `parentTitle` (fuzzy-matched against top-level features). Children inherit the parent's view and cluster and land in a row beneath it; bumps the sync version so an open /map canvas refreshes.",inputSchema:{parentId:J.string().optional().describe("node id of the parent feature (preferred)"),parentTitle:J.string().optional().describe("fuzzy title of the parent feature; ignored if parentId is provided"),items:J.array(J.object({title:J.string().describe("short sub-task title"),plain:J.string().optional().describe("one-paragraph description / why / acceptance hint")})).describe("the sub-tasks to add")}},async({parentId:$,parentTitle:Q,items:Z})=>{try{let Y=await d("/api/nodes/subtasks",{parentId:$,parentTitle:Q,items:Z});return{content:[{type:"text",text:JSON.stringify(Y)}]}}catch(Y){return G9(Y)}});var U9=J.array(J.object({title:J.string().describe("real component/subsystem name (e.g. 'Plan review loop') \u2014 NEVER a file"),domain:J.string().describe("uppercase lane: PLAN | DATA | UI | MCP | INTEL | \u2026"),role:J.string().optional().describe("one-line technical role"),plain:J.string().optional().describe("one plain-language sentence"),status:J.enum(["KEEP","REBUILD","REPLACE","DROP"]).optional(),files:J.array(J.string()).optional(),depends:J.array(J.string()).optional().describe("titles of components this one depends on"),bugs:J.array(J.object({note:J.string().describe("what was found / worth investigating")})).optional().describe("bugs or things worth investigating you found in this component's code \u2014 flagged on the node (by=agent); identical open flags are not duplicated")})).optional().describe("Only when the feature adds/changes a REAL architectural component \u2014 upserts curated nodes, never one-per-file");F.registerTool("beacon_describe_feature",{description:"Register shipped feature(s) at the end of the work: marks status=DONE, records the files touched (kept on the FEATURE for context), and replaces each node's description with your markdown. Subsumes touch_files + finish_feature. A feature's unfinished SUB-TASKS are completed along with it (cascade; reported as `subtasksCompleted`) \u2014 if a sub-task is genuinely NOT done, set it BLOCKED or CANCELLED via the nodes API/board FIRST, those are left alone (`subtasksBlocked` lists what stayed). REGISTER ALL FEATURES A PLAN CREATED IN ONE CALL via the `features` array (one entry per feature) \u2014 do NOT call this once per feature. Pass each feature's `id` (returned to you at plan approval) so no title-matching is needed. For a single feature you may pass the top-level fields instead. Pass `architecture` only when a feature added/changed a REAL subsystem (never a file).",inputSchema:{features:J.array(J.object({id:J.string().optional().describe("node id from plan approval / beacon_map (preferred over title)"),title:J.string().optional().describe("feature title (fuzzy-matched if no id)"),description:J.string().describe("Markdown: ### Overview ... ### Files - `path` \u2014 what it does"),files:J.array(J.string()).optional().describe("repo-relative files this feature touches"),architecture:U9})).optional().describe("Register many features at once \u2014 one entry per feature, each id-keyed. Use this instead of N separate calls."),description:J.string().optional().describe("Single-feature markdown (omit when using `features`): ### Overview ... ### Files - `path` \u2014 what it does"),files:J.array(J.string()).optional().describe("repo-relative files this feature touches (single form)"),id:J.string().optional().describe("node id from plan approval / beacon_map (preferred over title)"),title:J.string().optional().describe("feature title (fuzzy-matched if no id)"),architecture:U9}},async({features:$,description:Q,files:Z,id:Y,title:X,architecture:H})=>{let W=$?.length?{features:$}:{description:Q,files:Z,id:Y,title:X,architecture:H},G=await d("/api/map/describe",W);return{content:[{type:"text",text:JSON.stringify(G)}]}});F.registerTool("beacon_init_persist",{description:"Use ONLY inside the `beacon-init` skill. After YOU (Claude Code) have read the repo and built the architecture analysis, call this once to persist it into Beacon. Replaces any prior init-derived map. Same DB shape as `beacon_propose_plan` for tables/endpoints, but it commits directly (no /plan review step) because the user explicitly invoked init.",inputSchema:{overview:J.string().optional().describe("one-paragraph summary of the project \u2014 written to ProjectMeta + AGENTS.md"),conventions:J.array(J.string()).optional().describe("3-8 concrete conventions/gotchas a contributor must follow"),components:J.array(J.object({title:J.string(),domain:J.string().describe("short UPPERCASE area: AUTH, API, DATA, UI, JOBS, INFRA, \u2026"),role:J.string().optional().describe("one-line technical role"),plain:J.string().optional().describe("one plain-language sentence"),files:J.array(J.string()).optional().describe("repo-relative key files"),depends:J.array(J.string()).optional().describe("titles of other components it depends on"),bugs:J.array(J.object({note:J.string().describe("what was found / worth investigating")})).optional().describe("bugs or things worth investigating you found while examining this component \u2014 flagged on the node (by=agent)")})).describe("8-25 main building blocks, not every file"),roadmap:J.array(J.object({title:J.string(),why:J.string().optional(),category:J.string().optional().describe("category for the board (AUTH | SEARCH | DATA | INTEL | \u2026) \u2014 set it so the item isn't category-less"),priority:J.number().int().min(0).max(3).optional().describe("0=P0 critical .. 3=P3 low")})).optional().describe("3-6 broad strategic directions (NOT detailed tasks); each with a `category` + `priority`. Re-runs DEDUPE roadmap features by title, so re-persisting won't double up existing ones."),snapshot:J.object({tables:J.array(J.object({name:J.string(),domain:J.string().optional(),description:J.string().optional(),columns:J.array(J.object({name:J.string(),type:J.string(),isPk:J.boolean().optional(),isFk:J.boolean().optional(),nullable:J.boolean().optional(),note:J.string().optional()}))})).optional(),relations:J.array(J.object({fromTable:J.string(),fromColumn:J.string(),toTable:J.string(),toColumn:J.string(),label:J.string().optional()})).optional(),endpoints:J.array(J.object({method:J.string(),path:J.string(),domain:J.string().optional(),description:J.string().optional(),uses:J.array(J.object({table:J.string(),access:J.string().optional()})).optional()})).optional()}).optional().describe("optional: also seed /db with the schema you discovered from prisma/SQLAlchemy/etc.")}},async($)=>{let Q=await d("/api/init",$);return{content:[{type:"text",text:JSON.stringify(Q)}]}});F.registerTool("beacon_context_for_feature",{description:"Use BEFORE Glob/Grep/Read when starting work on a feature. Returns a single bundle of everything Beacon knows about it: attached files, what those files import + what imports them (1-hop blast radius from the live code graph), endpoints in the feature's domain + the tables each touches, those tables' FK relations, sibling architecture components, and the project's conventions. Saves an entire discovery-phase round of file reads. Match by id (preferred), exact title, or a natural-language query.",inputSchema:{id:J.string().optional().describe("node id from beacon_map (preferred)"),title:J.string().optional().describe("feature title (case-insensitive contains)"),query:J.string().optional().describe("natural-language phrase \u2014 OR-matched against title + plain description")}},async({id:$,title:Q,query:Z})=>{let Y=new URLSearchParams;if($)Y.set("id",$);if(Q)Y.set("title",Q);if(Z)Y.set("query",Z);let X=await E(`/api/context/feature?${Y.toString()}`);return{content:[{type:"text",text:JSON.stringify(X)}]}});F.registerTool("beacon_blast_radius",{description:"For 'if I change this file, what else cares?' \u2014 returns the file's 1-hop imports + importedBy, the TRANSITIVE blast radius both directions (downstream = who depends on it, upstream = what it depends on, grouped by depth), hub/centrality scoring (inDegree/outDegree + isHub), and every feature/component that has the file attached. Use mid-feature when deciding the impact of a change, or before refactoring a hub file.",inputSchema:{path:J.string().describe("repo-relative POSIX file path"),depth:J.number().optional().describe("how far to walk the transitive graph (default 2, capped at 5)")}},async({path:$,depth:Q})=>{let Z=new URLSearchParams({path:$});if(Q!=null)Z.set("depth",String(Q));let Y=await E(`/api/context/file?${Z.toString()}`);return{content:[{type:"text",text:JSON.stringify(Y)}]}});F.registerTool("beacon_entities",{description:"Read planning data. `features` = roadmap, `architecture` = components, `tables`/`endpoints` = DB map.",inputSchema:{kind:J.enum(["features","architecture","tables","endpoints"])}},async({kind:$})=>{let Q=await E(`/api/entities?kind=${$}`);return{content:[{type:"text",text:JSON.stringify(Q)}]}});F.registerTool("beacon_propose_plan",{description:"BLOCKS until the user reviews. Pushes a feature plan (top-level roadmap features + DB tables + endpoints) to Beacon's /plan page. Use when the user asks you to plan a feature. EVERY feature MUST include `cluster` (its category) and `priority` (0=P0 critical .. 3=P3 low) \u2014 the tool REJECTS a plan whose features omit either, so set both on every feature. Do not implement code or migrations until this returns approval. If it returns inline feedback, revise and call again.",inputSchema:{description:J.string().describe("Short summary the user will see in the review header"),features:J.array(J.object({title:J.string(),role:J.string().optional().describe("one-line technical role"),plain:J.string().optional().describe("one plain-language sentence for the user"),category:J.string().optional().describe("REQUIRED category for the board (AUTH | SEARCH | BILLING | DATA | INTEL | \u2026)"),cluster:J.string().optional().describe("alias for `category`"),domain:J.string().optional().describe("alias for `category`"),priority:J.number().int().min(0).max(3).optional().describe("REQUIRED priority: 0=P0 critical, 1=P1 high, 2=P2 medium, 3=P3 low"),dependsOn:J.array(J.string()).optional().describe("titles of other features in THIS plan that must ship first \u2014 drawn as 'depends on' links so the board shows the dependency chain, not loose cards")})).optional().describe("the top-level roadmap features this plan adds"),tables:J.array(J.object({name:J.string(),domain:J.string().optional(),description:J.string().optional(),columns:J.array(J.object({name:J.string(),type:J.string(),isPk:J.boolean().optional(),isFk:J.boolean().optional(),nullable:J.boolean().optional(),note:J.string().optional()}))})).optional(),relations:J.array(J.object({fromTable:J.string(),fromColumn:J.string(),toTable:J.string(),toColumn:J.string(),label:J.string().optional()})).optional(),endpoints:J.array(J.object({method:J.string().describe("GET|POST|PUT|PATCH|DELETE"),path:J.string(),domain:J.string().optional(),description:J.string().optional(),uses:J.array(J.object({table:J.string(),access:J.string().optional()})).optional()})).optional()}},async({description:$,features:Q,tables:Z,relations:Y,endpoints:X})=>{let H=(M)=>new Promise((M9)=>setTimeout(M9,M)),W=(M)=>({content:[{type:"text",text:M}]}),G=(Z?.length??0)>0,U=(Q??[]).map((M)=>`${M.title} ${M.role??""} ${M.plain??""}`).join(`
|
|
250
|
+
`)}await T5();var M5=process.env.BEACON_URL||`http://localhost:${process.env.PORT||4319}`,q5=l5(),g0=T0(q5);try{Y5(q5);let $=await H5(g0);if(!$.ok)console.error(`[beacon mcp] db provisioning failed: ${$.error}`)}catch($){console.error(`[beacon mcp] workspace registration failed: ${$ instanceof Error?$.message:$}`)}async function E($,Q){let Z=new Headers(Q?.headers);Z.set("x-beacon-workspace",g0),Z.set(V5,q5);let Y=await fetch(`${M5}${$}`,{...Q,headers:Z}),X=await Y.text();if(!Y.ok)throw Error(`Beacon ${$} -> ${Y.status} ${X}`);return X?JSON.parse(X):null}function d($,Q){return E($,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(Q)})}function G9($){let Q=$ instanceof Error?$.message:String($),Z=Q.match(/\{[\s\S]*\}$/);if(Z)try{let Y=JSON.parse(Z[0]);if(Y?.error)return{content:[{type:"text",text:Y.error}],isError:!0}}catch{}return{content:[{type:"text",text:Q}],isError:!0}}var F=new e$({name:"beacon",version:"0.1.0"});F.registerTool("beacon_map",{description:"List existing features on the roadmap. Call before starting work."},async()=>{let $=await E("/api/map");return{content:[{type:"text",text:JSON.stringify($)}]}});F.registerTool("beacon_start_feature",{description:"Flag that you're working on a feature. If the title matches an existing feature it just marks it IN_PROGRESS (no category needed); if it's NEW it creates the node \u2014 and a new feature REQUIRES a `category`. Call beacon_map first so you reuse an existing feature/category instead of duplicating one.",inputSchema:{title:J.string(),id:J.string().optional().describe("node id from beacon_map (preferred)"),category:J.string().optional().describe("Domain lane for a NEW feature: AUTH | SEARCH | DATA | INTEL | BILLING | INFRA | UI | \u2026 REQUIRED when this creates a new top-level feature; reuse a category already on the board. Ignored when flagging an existing feature or nesting under a `front` (inherits the parent's)."),front:J.string().optional().describe("Title of an EXISTING parent feature to nest this under (draws the parent \u2192 child edge). It must match a real feature \u2014 it is NOT a domain tag (use `category` for the domain). A `front` that matches nothing is REJECTED; create the parent first via beacon_propose_plan."),detail:J.string().optional().describe("One-line plain-language description shown on the canvas card. Replaced later by beacon_describe_feature's markdown when the work is done.")}},async({title:$,id:Q,front:Z,detail:Y,category:X})=>{try{let H=await d("/api/map/start",{title:$,id:Q,front:Z,detail:Y,category:X});return{content:[{type:"text",text:JSON.stringify(H)}]}}catch(H){return G9(H)}});F.registerTool("beacon_add_subtasks",{description:"Add N sub-tasks under an existing feature in one call. Use when the user says 'add these as subtasks to <feature>' or you want to record follow-ups discovered during work. Parent resolves by `parentId` (preferred \u2014 get it from beacon_map / beacon_entities) or by `parentTitle` (fuzzy-matched against top-level features). Children inherit the parent's view and cluster and land in a row beneath it; bumps the sync version so an open /map canvas refreshes.",inputSchema:{parentId:J.string().optional().describe("node id of the parent feature (preferred)"),parentTitle:J.string().optional().describe("fuzzy title of the parent feature; ignored if parentId is provided"),items:J.array(J.object({title:J.string().describe("short sub-task title"),plain:J.string().optional().describe("one-paragraph description / why / acceptance hint")})).describe("the sub-tasks to add")}},async({parentId:$,parentTitle:Q,items:Z})=>{try{let Y=await d("/api/nodes/subtasks",{parentId:$,parentTitle:Q,items:Z});return{content:[{type:"text",text:JSON.stringify(Y)}]}}catch(Y){return G9(Y)}});var U9=J.array(J.object({title:J.string().describe("real component/subsystem name (e.g. 'Plan review loop') \u2014 NEVER a file"),domain:J.string().describe("uppercase lane: PLAN | DATA | UI | MCP | INTEL | \u2026"),role:J.string().optional().describe("one-line technical role"),plain:J.string().optional().describe("one plain-language sentence"),status:J.enum(["KEEP","REBUILD","REPLACE","DROP"]).optional(),files:J.array(J.string()).optional(),depends:J.array(J.string()).optional().describe("titles of components this one depends on"),bugs:J.array(J.object({note:J.string().describe("what was found / worth investigating")})).optional().describe("bugs or things worth investigating you found in this component's code \u2014 flagged on the node (by=agent); identical open flags are not duplicated")})).optional().describe("Only when the feature adds/changes a REAL architectural component \u2014 upserts curated nodes, never one-per-file");F.registerTool("beacon_describe_feature",{description:"Register shipped feature(s) at the end of the work: marks status=DONE, records the files touched (kept on the FEATURE for context), and replaces each node's description with your markdown. Subsumes touch_files + finish_feature. A feature's unfinished SUB-TASKS are completed along with it (cascade; reported as `subtasksCompleted`) \u2014 if a sub-task is genuinely NOT done, set it BLOCKED or CANCELLED via the nodes API/board FIRST, those are left alone (`subtasksBlocked` lists what stayed). REGISTER ALL FEATURES A PLAN CREATED IN ONE CALL via the `features` array (one entry per feature) \u2014 do NOT call this once per feature. Pass each feature's `id` (returned to you at plan approval) so no title-matching is needed. For a single feature you may pass the top-level fields instead. Pass `architecture` only when a feature added/changed a REAL subsystem (never a file).",inputSchema:{features:J.array(J.object({id:J.string().optional().describe("node id from plan approval / beacon_map (preferred over title)"),title:J.string().optional().describe("feature title (fuzzy-matched if no id)"),description:J.string().describe("Markdown: ### Overview ... ### Files - `path` \u2014 what it does"),files:J.array(J.string()).optional().describe("repo-relative files this feature touches"),architecture:U9})).optional().describe("Register many features at once \u2014 one entry per feature, each id-keyed. Use this instead of N separate calls."),description:J.string().optional().describe("Single-feature markdown (omit when using `features`): ### Overview ... ### Files - `path` \u2014 what it does"),files:J.array(J.string()).optional().describe("repo-relative files this feature touches (single form)"),id:J.string().optional().describe("node id from plan approval / beacon_map (preferred over title)"),title:J.string().optional().describe("feature title (fuzzy-matched if no id)"),architecture:U9}},async({features:$,description:Q,files:Z,id:Y,title:X,architecture:H})=>{let W=$?.length?{features:$}:{description:Q,files:Z,id:Y,title:X,architecture:H},G=await d("/api/map/describe",W);return{content:[{type:"text",text:JSON.stringify(G)}]}});F.registerTool("beacon_init_persist",{description:"Use ONLY inside the `beacon-init` skill. After YOU (Claude Code) have read the repo and built the architecture analysis, call this once to persist it into Beacon. Replaces any prior init-derived map. Same DB shape as `beacon_propose_plan` for tables/endpoints, but it commits directly (no /plan review step) because the user explicitly invoked init.",inputSchema:{overview:J.string().optional().describe("one-paragraph summary of the project \u2014 written to ProjectMeta + AGENTS.md"),conventions:J.array(J.string()).optional().describe("3-8 concrete conventions/gotchas a contributor must follow"),components:J.array(J.object({title:J.string(),domain:J.string().describe("short UPPERCASE area: AUTH, API, DATA, UI, JOBS, INFRA, \u2026"),role:J.string().optional().describe("one-line technical role"),plain:J.string().optional().describe("one plain-language sentence"),files:J.array(J.string()).optional().describe("repo-relative key files"),depends:J.array(J.string()).optional().describe("titles of other components it depends on"),bugs:J.array(J.object({note:J.string().describe("what was found / worth investigating")})).optional().describe("bugs or things worth investigating you found while examining this component \u2014 flagged on the node (by=agent)")})).describe("8-25 main building blocks, not every file"),roadmap:J.array(J.object({title:J.string(),why:J.string().optional(),category:J.string().optional().describe("category for the board (AUTH | SEARCH | DATA | INTEL | \u2026) \u2014 set it so the item isn't category-less"),priority:J.number().int().min(0).max(3).optional().describe("0=P0 critical .. 3=P3 low")})).optional().describe("3-6 broad strategic directions (NOT detailed tasks); each with a `category` + `priority`. Re-runs DEDUPE roadmap features by title, so re-persisting won't double up existing ones."),snapshot:J.object({tables:J.array(J.object({name:J.string(),domain:J.string().optional(),description:J.string().optional(),columns:J.array(J.object({name:J.string(),type:J.string(),isPk:J.boolean().optional(),isFk:J.boolean().optional(),nullable:J.boolean().optional(),note:J.string().optional()}))})).optional(),relations:J.array(J.object({fromTable:J.string(),fromColumn:J.string(),toTable:J.string(),toColumn:J.string(),label:J.string().optional()})).optional(),endpoints:J.array(J.object({method:J.string(),path:J.string(),domain:J.string().optional(),description:J.string().optional(),uses:J.array(J.object({table:J.string(),access:J.string().optional()})).optional()})).optional()}).optional().describe("optional: also seed /db with the schema you discovered from prisma/SQLAlchemy/etc.")}},async($)=>{let Q=await d("/api/init",$);return{content:[{type:"text",text:JSON.stringify(Q)}]}});F.registerTool("beacon_context_for_feature",{description:"Use BEFORE Glob/Grep/Read when starting work on a feature. Returns a single bundle of everything Beacon knows about it: attached files, what those files import + what imports them (1-hop blast radius from the live code graph), endpoints in the feature's domain + the tables each touches, those tables' FK relations, sibling architecture components, and the project's conventions. Saves an entire discovery-phase round of file reads. Match by id (preferred), exact title, or a natural-language query.",inputSchema:{id:J.string().optional().describe("node id from beacon_map (preferred)"),title:J.string().optional().describe("feature title (case-insensitive contains)"),query:J.string().optional().describe("natural-language phrase \u2014 OR-matched against title + plain description")}},async({id:$,title:Q,query:Z})=>{let Y=new URLSearchParams;if($)Y.set("id",$);if(Q)Y.set("title",Q);if(Z)Y.set("query",Z);let X=await E(`/api/context/feature?${Y.toString()}`);return{content:[{type:"text",text:JSON.stringify(X)}]}});F.registerTool("beacon_blast_radius",{description:"For 'if I change this file, what else cares?' \u2014 returns the file's 1-hop imports + importedBy, the TRANSITIVE blast radius both directions (downstream = who depends on it, upstream = what it depends on, grouped by depth), hub/centrality scoring (inDegree/outDegree + isHub), and every feature/component that has the file attached. Use mid-feature when deciding the impact of a change, or before refactoring a hub file.",inputSchema:{path:J.string().describe("repo-relative POSIX file path"),depth:J.number().optional().describe("how far to walk the transitive graph (default 2, capped at 5)")}},async({path:$,depth:Q})=>{let Z=new URLSearchParams({path:$});if(Q!=null)Z.set("depth",String(Q));let Y=await E(`/api/context/file?${Z.toString()}`);return{content:[{type:"text",text:JSON.stringify(Y)}]}});F.registerTool("beacon_entities",{description:"Read planning data. `features` = roadmap, `architecture` = components, `tables`/`endpoints` = DB map.",inputSchema:{kind:J.enum(["features","architecture","tables","endpoints"])}},async({kind:$})=>{let Q=await E(`/api/entities?kind=${$}`);return{content:[{type:"text",text:JSON.stringify(Q)}]}});F.registerTool("beacon_propose_plan",{description:"BLOCKS until the user reviews. Pushes a feature plan (top-level roadmap features + DB tables + endpoints) to Beacon's /plan page. Use when the user asks you to plan a feature. EVERY feature MUST include `cluster` (its category) and `priority` (0=P0 critical .. 3=P3 low) \u2014 the tool REJECTS a plan whose features omit either, so set both on every feature. Do not implement code or migrations until this returns approval. If it returns inline feedback, revise and call again.",inputSchema:{description:J.string().describe("Short summary the user will see in the review header"),features:J.array(J.object({title:J.string(),role:J.string().optional().describe("one-line technical role"),plain:J.string().optional().describe("one plain-language sentence for the user"),category:J.string().optional().describe("REQUIRED category for the board (AUTH | SEARCH | BILLING | DATA | INTEL | \u2026)"),cluster:J.string().optional().describe("alias for `category`"),domain:J.string().optional().describe("alias for `category`"),priority:J.number().int().min(0).max(3).optional().describe("REQUIRED priority: 0=P0 critical, 1=P1 high, 2=P2 medium, 3=P3 low"),dependsOn:J.array(J.string()).optional().describe("titles of other features in THIS plan that must ship first \u2014 drawn as 'depends on' links so the board shows the dependency chain, not loose cards")})).optional().describe("the top-level roadmap features this plan adds"),tables:J.array(J.object({name:J.string(),domain:J.string().optional(),description:J.string().optional(),columns:J.array(J.object({name:J.string(),type:J.string(),isPk:J.boolean().optional(),isFk:J.boolean().optional(),nullable:J.boolean().optional(),note:J.string().optional()}))})).optional(),relations:J.array(J.object({fromTable:J.string(),fromColumn:J.string(),toTable:J.string(),toColumn:J.string(),label:J.string().optional()})).optional(),endpoints:J.array(J.object({method:J.string().describe("GET|POST|PUT|PATCH|DELETE"),path:J.string(),domain:J.string().optional(),description:J.string().optional(),uses:J.array(J.object({table:J.string(),access:J.string().optional()})).optional()})).optional()}},async({description:$,features:Q,tables:Z,relations:Y,endpoints:X})=>{let H=(M)=>new Promise((M9)=>setTimeout(M9,M)),W=(M)=>({content:[{type:"text",text:M}]}),G=(Z?.length??0)>0,U=(Q??[]).map((M)=>`${M.title} ${M.role??""} ${M.plain??""}`).join(`
|
|
251
251
|
`),w=(X?.length??0)>0||Z9(`${$}
|
|
252
252
|
${U}`);if(!G&&w)return W("\u26D4 This plan touches the database \u2014 it declares endpoints and/or its text describes "+"models/tables/migrations \u2014 but you passed NO `tables`. Beacon's schema board renders "+"ONLY from structured `tables`; prose is never parsed, so the /db tab would be empty and nothing would persist on approve.\n\nRe-call `beacon_propose_plan` with every table in `tables` (each with its `columns`), the `relations` (FKs), and keep the `endpoints` (each with `uses:[{table,access}]`). Mirror EVERY database entity your plan mentions into the structured fields.");if(Q?.length){let M=J9(Q);if(M)return W(M)}let s=(Z?.length??0)+(X?.length??0)>0;await d("/api/plan",{description:$,draft:s?{tables:Z??[],relations:Y??[],endpoints:X??[]}:void 0,features:Q?.length?Q:void 0}),await fetch(`${M5}/api/workspace/activate?id=${g0}`).catch(()=>{});let N9=Date.now()+K5;while(Date.now()<N9){await H(B5);let M=await E("/api/plan/verdict").catch(()=>null);if(!M)continue;if(M.kind==="feedback")return W("\uD83D\uDCAC The user left feedback on the plan in Beacon \u2014 text comments and/or edits they "+"made directly on the /map and /db boards. Read everything below, revise the plan accordingly (matching the board changes verbatim), and call `beacon_propose_plan` "+`again with the revised version \u2014 DO NOT implement yet:
|
|
253
253
|
|