vibedoc 1.6.1 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +2 -0
- package/.next/build-manifest.json +3 -3
- package/.next/prerender-manifest.json +39 -11
- package/.next/routes-manifest.json +12 -0
- package/.next/server/app/(app)/activity/page.js.nft.json +1 -1
- package/.next/server/app/(app)/activity/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/board/page.js.nft.json +1 -1
- package/.next/server/app/(app)/board/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/chat/page/app-paths-manifest.json +3 -0
- package/.next/server/app/(app)/chat/page/build-manifest.json +20 -0
- package/.next/server/app/(app)/chat/page/next-font-manifest.json +11 -0
- package/.next/server/app/(app)/chat/page/react-loadable-manifest.json +1 -0
- package/.next/server/app/(app)/chat/page/server-reference-manifest.json +4 -0
- package/.next/server/app/(app)/chat/page.js +15 -0
- package/.next/server/app/(app)/chat/page.js.map +5 -0
- package/.next/server/app/(app)/chat/page.js.nft.json +1 -0
- package/.next/server/app/(app)/chat/page_client-reference-manifest.js +3 -0
- package/.next/server/app/(app)/docs/page.js.nft.json +1 -1
- package/.next/server/app/(app)/docs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/explorer/page.js.nft.json +1 -1
- package/.next/server/app/(app)/explorer/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/memory/page.js.nft.json +1 -1
- package/.next/server/app/(app)/memory/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/roadmap/page.js.nft.json +1 -1
- package/.next/server/app/(app)/roadmap/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/settings/page.js.nft.json +1 -1
- package/.next/server/app/(app)/settings/page_client-reference-manifest.js +1 -1
- package/.next/server/app/(app)/setup/page.js.nft.json +1 -1
- package/.next/server/app/(app)/setup/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/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +2 -2
- package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/activity.html +1 -1
- package/.next/server/app/activity.rsc +22 -23
- package/.next/server/app/activity.segments/!KGFwcCk/activity/__PAGE__.segment.rsc +9 -10
- package/.next/server/app/activity.segments/_full.segment.rsc +22 -23
- package/.next/server/app/activity.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/api/activity/route.js.nft.json +1 -1
- package/.next/server/app/api/backlinks/route.js.nft.json +1 -1
- package/.next/server/app/api/chat/route.js.nft.json +1 -1
- package/.next/server/app/api/context/route.js.nft.json +1 -1
- package/.next/server/app/api/conversations/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/conversations/route/build-manifest.json +12 -0
- package/.next/server/app/api/conversations/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/conversations/route.js +9 -0
- package/.next/server/app/api/conversations/route.js.map +5 -0
- package/.next/server/app/api/conversations/route.js.nft.json +1 -0
- package/.next/server/app/api/conversations/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/decisions/route.js.nft.json +1 -1
- package/.next/server/app/api/docs/route.js.nft.json +1 -1
- package/.next/server/app/api/explorer/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/route.js.nft.json +1 -1
- package/.next/server/app/api/memory/route.js.nft.json +1 -1
- package/.next/server/app/api/plan/apply/route.js.nft.json +1 -1
- package/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/.next/server/app/api/registry/route.js.nft.json +1 -1
- package/.next/server/app/api/roadmap/create/route.js.nft.json +1 -1
- package/.next/server/app/api/roadmap/delete/route.js.nft.json +1 -1
- package/.next/server/app/api/roadmap/generate/route.js.nft.json +1 -1
- package/.next/server/app/api/roadmap/layout/route.js.nft.json +1 -1
- package/.next/server/app/api/roadmap/route.js.nft.json +1 -1
- package/.next/server/app/api/roadmap/update/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/route.js.nft.json +1 -1
- package/.next/server/app/api/settings/route.js.nft.json +1 -1
- package/.next/server/app/api/setup/generate/route.js.nft.json +1 -1
- package/.next/server/app/api/setup/write/route.js.nft.json +1 -1
- package/.next/server/app/api/summary/route.js.nft.json +1 -1
- package/.next/server/app/api/tasks/create/route.js.nft.json +1 -1
- package/.next/server/app/api/tasks/route.js.nft.json +1 -1
- package/.next/server/app/board.html +1 -1
- package/.next/server/app/board.rsc +22 -23
- package/.next/server/app/board.segments/!KGFwcCk/board/__PAGE__.segment.rsc +9 -10
- package/.next/server/app/board.segments/_full.segment.rsc +22 -23
- package/.next/server/app/board.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/chat.html +1 -0
- package/.next/server/app/chat.meta +31 -0
- package/.next/server/app/chat.rsc +29 -0
- package/.next/server/app/chat.segments/!KGFwcCk/chat/__PAGE__.segment.rsc +31 -0
- package/.next/server/app/chat.segments/_full.segment.rsc +29 -0
- package/.next/server/app/chat.segments/_tree.segment.rsc +4 -0
- package/.next/server/app/docs.html +1 -1
- package/.next/server/app/docs.rsc +22 -27
- package/.next/server/app/docs.segments/!KGFwcCk/docs/__PAGE__.segment.rsc +6 -6
- package/.next/server/app/docs.segments/_full.segment.rsc +22 -27
- package/.next/server/app/docs.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/explorer.html +1 -1
- package/.next/server/app/explorer.rsc +22 -23
- package/.next/server/app/explorer.segments/!KGFwcCk/explorer/__PAGE__.segment.rsc +9 -10
- package/.next/server/app/explorer.segments/_full.segment.rsc +22 -23
- package/.next/server/app/explorer.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.rsc +2 -2
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/index.segments/_full.segment.rsc +2 -2
- package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/memory.html +1 -1
- package/.next/server/app/memory.rsc +22 -23
- package/.next/server/app/memory.segments/!KGFwcCk/memory/__PAGE__.segment.rsc +9 -10
- package/.next/server/app/memory.segments/_full.segment.rsc +22 -23
- package/.next/server/app/memory.segments/_tree.segment.rsc +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/roadmap.html +1 -1
- package/.next/server/app/roadmap.rsc +22 -26
- package/.next/server/app/roadmap.segments/!KGFwcCk/roadmap/__PAGE__.segment.rsc +9 -11
- package/.next/server/app/roadmap.segments/_full.segment.rsc +22 -26
- package/.next/server/app/roadmap.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings.html +1 -1
- package/.next/server/app/settings.rsc +22 -23
- package/.next/server/app/settings.segments/!KGFwcCk/settings/__PAGE__.segment.rsc +9 -10
- package/.next/server/app/settings.segments/_full.segment.rsc +22 -23
- package/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/setup.html +1 -1
- package/.next/server/app/setup.rsc +22 -23
- package/.next/server/app/setup.segments/!KGFwcCk/setup/__PAGE__.segment.rsc +9 -10
- package/.next/server/app/setup.segments/_full.segment.rsc +22 -23
- package/.next/server/app/setup.segments/_tree.segment.rsc +2 -2
- package/.next/server/app-paths-manifest.json +2 -0
- package/.next/server/chunks/11mp_@anthropic-ai_sdk_1htgzmb._.js +3 -0
- package/.next/server/chunks/11mp_@anthropic-ai_sdk_1htgzmb._.js.map +1 -0
- package/.next/server/chunks/11mp_@anthropic-ai_sdk_index_mjs_0d2_lq6._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1613hjb._.js +4 -4
- package/.next/server/chunks/[root-of-the-server]__1613hjb._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__1jxu2x9._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1jxu2x9._.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_conversations_route_actions_1-pu7gs.js +3 -0
- package/.next/server/chunks/ssr/{0_nd_mermaid_dist_mermaid_core_mjs_1vulg1x._.js → 0_nd_mermaid_dist_mermaid_core_mjs_0vv_0i3._.js} +2 -2
- package/.next/server/chunks/ssr/{1u84_katex_dist_katex_mjs_0mwkb-i._.js → 1u84_katex_dist_katex_mjs_1z0p1bs._.js} +1 -1
- package/.next/server/chunks/ssr/1x05_lucide-react_dist_esm_icons_0cvmffy._.js +3 -0
- package/.next/server/chunks/ssr/1x05_lucide-react_dist_esm_icons_0cvmffy._.js.map +1 -0
- package/.next/server/chunks/ssr/1x05_lucide-react_dist_esm_icons_0u3jxas._.js +3 -0
- package/.next/server/chunks/ssr/1x05_lucide-react_dist_esm_icons_0u3jxas._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__11lfnu0._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__11lfnu0._.js.map +1 -0
- package/.next/server/chunks/ssr/_059qmur._.js +3 -0
- package/.next/server/chunks/ssr/_059qmur._.js.map +1 -0
- package/.next/server/chunks/ssr/_081irea._.js +3 -0
- package/.next/server/chunks/ssr/_081irea._.js.map +1 -0
- package/.next/server/chunks/ssr/_0d8t8l4._.js +3 -0
- package/.next/server/chunks/ssr/_0d8t8l4._.js.map +1 -0
- package/.next/server/chunks/ssr/_0dyvcdg._.js +3 -0
- package/.next/server/chunks/ssr/_0dyvcdg._.js.map +1 -0
- package/.next/server/chunks/ssr/_1-ghqy4._.js +3 -0
- package/.next/server/chunks/ssr/_1-ghqy4._.js.map +1 -0
- package/.next/server/chunks/ssr/_17jy5db._.js +3 -0
- package/.next/server/chunks/ssr/_17jy5db._.js.map +1 -0
- package/.next/server/chunks/ssr/_1c95ems._.js +1 -1
- package/.next/server/chunks/ssr/_1c95ems._.js.map +1 -1
- package/.next/server/chunks/ssr/_1dllfz5._.js +4 -0
- package/.next/server/chunks/ssr/_1dllfz5._.js.map +1 -0
- package/.next/server/chunks/ssr/_next-internal_server_app_(app)_chat_page_actions_0g4tbzt.js +3 -0
- package/.next/server/chunks/ssr/node_modules__pnpm_006_c8z._.js +3 -0
- package/.next/server/chunks/ssr/node_modules__pnpm_006_c8z._.js.map +1 -0
- package/.next/server/chunks/ssr/{node_modules__pnpm_00wjhj4._.js → node_modules__pnpm_0286-tg._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules__pnpm_0w9uewb._.js → node_modules__pnpm_04khl_s._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules__pnpm_1zsbfem._.js → node_modules__pnpm_07t_e8c._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules__pnpm_0p10j87._.js → node_modules__pnpm_08sqeu2._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules__pnpm_0cj37c-._.js → node_modules__pnpm_09_i2jk._.js} +1 -1
- package/.next/server/chunks/ssr/node_modules__pnpm_09_i2jk._.js.map +1 -0
- package/.next/server/chunks/ssr/{node_modules__pnpm_19ys1iv._.js → node_modules__pnpm_0a9b2ei._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules__pnpm_0ma8hho._.js → node_modules__pnpm_0ah02mu._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules__pnpm_0kna82c._.js → node_modules__pnpm_0cj8ryj._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules__pnpm_04xoqd9._.js → node_modules__pnpm_0dwi7mu._.js} +2 -2
- package/.next/server/chunks/ssr/node_modules__pnpm_0dwi7mu._.js.map +1 -0
- package/.next/server/chunks/ssr/{node_modules__pnpm_19ejwjv._.js → node_modules__pnpm_0f77_ng._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules__pnpm_11lluiq._.js → node_modules__pnpm_0fd3pr1._.js} +2 -2
- package/.next/server/chunks/ssr/{node_modules__pnpm_1xolwvc._.js → node_modules__pnpm_0gifu-u._.js} +2 -2
- package/.next/server/chunks/ssr/{node_modules__pnpm_1r4w_7k._.js → node_modules__pnpm_0jpv2b6._.js} +2 -2
- package/.next/server/chunks/ssr/{node_modules__pnpm_17o8zbz._.js → node_modules__pnpm_0og06fy._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules__pnpm_042y3e-._.js → node_modules__pnpm_0qc3gsk._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules__pnpm_0yixxj2._.js → node_modules__pnpm_0ts89ne._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules__pnpm_18pu1wl._.js → node_modules__pnpm_0ttvopp._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules__pnpm_1-poetj._.js → node_modules__pnpm_0u3u82f._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules__pnpm_07j8gcu._.js → node_modules__pnpm_0y35hs4._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules__pnpm_1a3fo7j._.js → node_modules__pnpm_104pzhc._.js} +2 -2
- package/.next/server/chunks/ssr/{node_modules__pnpm_00i3mh2._.js → node_modules__pnpm_195j8p_._.js} +1 -1
- package/.next/server/chunks/ssr/node_modules__pnpm_1kcnkjs._.js +3 -0
- package/.next/server/chunks/ssr/node_modules__pnpm_1kcnkjs._.js.map +1 -0
- package/.next/server/chunks/ssr/{node_modules__pnpm_1_34wt2._.js → node_modules__pnpm_1l8k8w1._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules__pnpm_0nbxdp_._.js → node_modules__pnpm_1w0f1m5._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules__pnpm_1l-posw._.js → node_modules__pnpm_1woddr6._.js} +2 -2
- package/.next/server/chunks/ssr/{node_modules__pnpm_0fk-8nl._.js → node_modules__pnpm_1x0t5_z._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules__pnpm_1o30a9w._.js → node_modules__pnpm_1xzf8g_._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules__pnpm_0--x5-5._.js → node_modules__pnpm_1yq90z7._.js} +1 -1
- package/.next/server/chunks/ssr/node_modules__pnpm_1yq90z7._.js.map +1 -0
- package/.next/server/chunks/ssr/src_app_(app)_chat_page_tsx_0c3e4l4._.js +3 -0
- package/.next/server/chunks/ssr/src_app_(app)_chat_page_tsx_0c3e4l4._.js.map +1 -0
- package/.next/server/chunks/ssr/src_app_(app)_layout_tsx_1yu5hom._.js +3 -0
- package/.next/server/chunks/ssr/src_app_(app)_layout_tsx_1yu5hom._.js.map +1 -0
- package/.next/server/chunks/ssr/src_app_(app)_roadmap_page_tsx_0vcq3jr._.js +5 -0
- package/.next/server/chunks/ssr/src_app_(app)_roadmap_page_tsx_0vcq3jr._.js.map +1 -0
- package/.next/server/chunks/ssr/src_context_ChatContext_tsx_0lowp8p._.js +5 -0
- package/.next/server/chunks/ssr/src_context_ChatContext_tsx_0lowp8p._.js.map +1 -0
- package/.next/server/chunks/ssr/{_1wf14_u._.js → src_lib_templates_index_ts_1s61uk7._.js} +2 -2
- package/.next/server/chunks/ssr/{_1wf14_u._.js.map → src_lib_templates_index_ts_1s61uk7._.js.map} +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/next-font-manifest.js +1 -1
- package/.next/server/next-font-manifest.json +4 -0
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/prefetch-hints.json +19 -0
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/050mq8l4e1ubn.js +1 -0
- package/.next/static/chunks/098le48845_fg.js +3 -0
- package/.next/static/chunks/0cw4-ebkoufdc.js +1 -0
- package/.next/static/chunks/0feo-go1w5nct.js +1 -0
- package/.next/static/chunks/14sefb904pl64.js +21 -0
- package/.next/static/chunks/1fer-wulyrjrs.js +3 -0
- package/.next/static/chunks/1o7b1x4umy8a6.js +1 -0
- package/.next/static/chunks/1q_io1j58aukw.js +1 -0
- package/.next/static/chunks/1t-cgh4477hfo.js +1 -0
- package/.next/static/chunks/1u-1po1qesc9f.js +1 -0
- package/.next/static/chunks/1u5kegkgm0xoz.js +1 -0
- package/.next/static/chunks/24ygzsgd-moqy.js +1 -0
- package/.next/static/chunks/26folxgplfa9t.js +68 -0
- package/.next/static/chunks/2ocixvjhv34_3.js +1 -0
- package/.next/static/chunks/3_lsdgxa-h7ma.css +10 -0
- package/.next/static/chunks/3rmv-sb9w9i3e.js +1 -0
- package/.next/static/chunks/3ttzomivj48jh.js +2 -0
- package/README.md +1 -1
- package/package.json +1 -1
- package/.next/server/chunks/ssr/1x05_lucide-react_dist_esm_icons_08ca0b4._.js +0 -3
- package/.next/server/chunks/ssr/1x05_lucide-react_dist_esm_icons_08ca0b4._.js.map +0 -1
- package/.next/server/chunks/ssr/1x05_lucide-react_dist_esm_icons_0c1k9is._.js +0 -3
- package/.next/server/chunks/ssr/1x05_lucide-react_dist_esm_icons_0c1k9is._.js.map +0 -1
- package/.next/server/chunks/ssr/_0qyglif._.js +0 -5
- package/.next/server/chunks/ssr/_0qyglif._.js.map +0 -1
- package/.next/server/chunks/ssr/_0skuoxv._.js +0 -6
- package/.next/server/chunks/ssr/_0skuoxv._.js.map +0 -1
- package/.next/server/chunks/ssr/_14i_6yb._.js +0 -3
- package/.next/server/chunks/ssr/_14i_6yb._.js.map +0 -1
- package/.next/server/chunks/ssr/_1cbhuz4._.js +0 -3
- package/.next/server/chunks/ssr/_1cbhuz4._.js.map +0 -1
- package/.next/server/chunks/ssr/_1ewk_mn._.js +0 -3
- package/.next/server/chunks/ssr/_1ewk_mn._.js.map +0 -1
- package/.next/server/chunks/ssr/_1y-ofyw._.js +0 -3
- package/.next/server/chunks/ssr/_1y-ofyw._.js.map +0 -1
- package/.next/server/chunks/ssr/node_modules__pnpm_0bmkw6o._.js +0 -3
- package/.next/server/chunks/ssr/node_modules__pnpm_0bmkw6o._.js.map +0 -1
- package/.next/server/chunks/ssr/src_components_008q3v8._.js +0 -3
- package/.next/server/chunks/ssr/src_components_008q3v8._.js.map +0 -1
- package/.next/static/chunks/0-vk2d2nnzav2.js +0 -3
- package/.next/static/chunks/02sab26ica2x3.js +0 -1
- package/.next/static/chunks/0eggcu0ovk8sd.js +0 -68
- package/.next/static/chunks/0iva6rdtfqpbz.js +0 -1
- package/.next/static/chunks/0qm101bdsxdyh.css +0 -10
- package/.next/static/chunks/0wg9n5zb8mo2p.js +0 -1
- package/.next/static/chunks/0z_y7el6m76yk.js +0 -1
- package/.next/static/chunks/1-ekntoveuxzd.js +0 -4
- package/.next/static/chunks/10neasnz6hhq1.js +0 -1
- package/.next/static/chunks/22dw7r8x0h2sx.js +0 -1
- package/.next/static/chunks/26ee8jsbellqk.js +0 -21
- package/.next/static/chunks/3kkg030rcpz7l.js +0 -1
- package/.next/static/chunks/3pf_4ye6ju8gt.js +0 -1
- /package/.next/server/chunks/{ssr/0_nd_mermaid_dist_mermaid_core_mjs_1vulg1x._.js.map → 11mp_@anthropic-ai_sdk_index_mjs_0d2_lq6._.js.map} +0 -0
- /package/.next/server/chunks/{ssr/1u84_katex_dist_katex_mjs_0mwkb-i._.js.map → _next-internal_server_app_api_conversations_route_actions_1-pu7gs.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_0--x5-5._.js.map → 0_nd_mermaid_dist_mermaid_core_mjs_0vv_0i3._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_04xoqd9._.js.map → 1u84_katex_dist_katex_mjs_1z0p1bs._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_0cj37c-._.js.map → _next-internal_server_app_(app)_chat_page_actions_0g4tbzt.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_00wjhj4._.js.map → node_modules__pnpm_0286-tg._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_0w9uewb._.js.map → node_modules__pnpm_04khl_s._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_1zsbfem._.js.map → node_modules__pnpm_07t_e8c._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_0p10j87._.js.map → node_modules__pnpm_08sqeu2._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_19ys1iv._.js.map → node_modules__pnpm_0a9b2ei._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_0ma8hho._.js.map → node_modules__pnpm_0ah02mu._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_0kna82c._.js.map → node_modules__pnpm_0cj8ryj._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_19ejwjv._.js.map → node_modules__pnpm_0f77_ng._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_11lluiq._.js.map → node_modules__pnpm_0fd3pr1._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_1xolwvc._.js.map → node_modules__pnpm_0gifu-u._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_1r4w_7k._.js.map → node_modules__pnpm_0jpv2b6._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_17o8zbz._.js.map → node_modules__pnpm_0og06fy._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_042y3e-._.js.map → node_modules__pnpm_0qc3gsk._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_0yixxj2._.js.map → node_modules__pnpm_0ts89ne._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_18pu1wl._.js.map → node_modules__pnpm_0ttvopp._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_1-poetj._.js.map → node_modules__pnpm_0u3u82f._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_07j8gcu._.js.map → node_modules__pnpm_0y35hs4._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_1a3fo7j._.js.map → node_modules__pnpm_104pzhc._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_00i3mh2._.js.map → node_modules__pnpm_195j8p_._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_1_34wt2._.js.map → node_modules__pnpm_1l8k8w1._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_0nbxdp_._.js.map → node_modules__pnpm_1w0f1m5._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_1l-posw._.js.map → node_modules__pnpm_1woddr6._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_0fk-8nl._.js.map → node_modules__pnpm_1x0t5_z._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{node_modules__pnpm_1o30a9w._.js.map → node_modules__pnpm_1xzf8g_._.js.map} +0 -0
- /package/.next/static/{gJtrYenzL6_deB-6pdvIL → uJ5RYxgFnE5svAvnuLDXN}/_buildManifest.js +0 -0
- /package/.next/static/{gJtrYenzL6_deB-6pdvIL → uJ5RYxgFnE5svAvnuLDXN}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{gJtrYenzL6_deB-6pdvIL → uJ5RYxgFnE5svAvnuLDXN}/_ssgManifest.js +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/app/%28app%29/roadmap/page.tsx","../../../../src/components/roadmap/RoadmapTimeline.tsx","../../../../src/components/roadmap/RoadmapItemSheet.tsx","../../../../src/components/roadmap/NewItemDialog.tsx","../../../../src/components/roadmap/PlanFromSpecDialog.tsx","../../../../src/components/roadmap/BreakdownEpicsDialog.tsx","../../../../src/components/roadmap/RoadmapTab.tsx","../../../../node_modules/.pnpm/lucide-react%401.48.0_react%4019.3.0/node_modules/lucide-react/src/icons/list-tree.ts","../../../../src/lib/work-queue.ts"],"sourcesContent":["\"use client\"\n\nimport { Suspense } from \"react\"\nimport { RoadmapTab } from \"@/components/roadmap/RoadmapTab\"\n\nexport default function RoadmapPage() {\n // main has no fixed height; the canvas needs one (viewport minus the h-12 AppHeader)\n return (\n <div className=\"flex flex-col h-[calc(100svh-3rem)]\">\n <Suspense>\n <RoadmapTab />\n </Suspense>\n </div>\n )\n}\n","\"use client\"\n\nimport { useEffect, useMemo, useRef } from \"react\"\nimport { cn } from \"@/lib/utils\"\nimport type { RoadmapItem } from \"@/types\"\nimport type { RoadmapProgress } from \"@/lib/roadmap-health\"\nimport { StatusDot } from \"./RoadmapNodes\"\nimport { AgentDot } from \"@/components/chat/AgentMark\"\nimport { LANE_ROW_H, buildTimeline, formatDay } from \"./timeline\"\n\nconst LANE_LABEL_W = 200\nconst HEADER_H = 36\n\ninterface RoadmapTimelineProps {\n items: RoadmapItem[]\n today: string\n onSelect: (id: string) => void\n progressById: Record<string, RoadmapProgress>\n}\n\nexport function RoadmapTimeline({ items, today, onSelect, progressById }: RoadmapTimelineProps) {\n // same chapter numbers as the map: real horizons by order\n const chapters = new Map(items.filter((i) => i.parent === null).sort((a, b) => a.order - b.order).map((h, i) => [h.id, i + 1]))\n const tl = useMemo(() => buildTimeline(items, today), [items, today])\n const scrollRef = useRef<HTMLDivElement>(null)\n\n // open with today about a third from the left\n useEffect(() => {\n const el = scrollRef.current\n if (el) el.scrollLeft = Math.max(0, tl.todayX - (el.clientWidth - LANE_LABEL_W) / 3)\n }, [tl.todayX])\n\n const hasDates = tl.lanes.some((l) => l.markers.length > 0)\n\n return (\n <div className=\"flex flex-1 min-h-0 flex-col\">\n <div ref={scrollRef} className=\"relative flex-1 min-h-0 overflow-auto\">\n <div className=\"relative\" style={{ width: LANE_LABEL_W + tl.width, minHeight: \"100%\" }}>\n {/* month grid + today line, behind the lanes */}\n <div className=\"pointer-events-none absolute inset-y-0\" style={{ left: LANE_LABEL_W, width: tl.width }}>\n {tl.months.map((m) => (\n <div key={m.x} className=\"absolute inset-y-0 border-l border-border\" style={{ left: m.x }} />\n ))}\n <div className=\"absolute inset-y-0 left-0 bg-surface/50\" style={{ width: tl.todayX }} />\n <div className=\"absolute inset-y-0 w-px bg-accent shadow-[0_0_12px_rgb(var(--rgb-accent)/0.8)]\" style={{ left: tl.todayX }}>\n <span\n className=\"absolute -translate-x-1/2 rounded-full bg-accent px-2 py-0.5 font-mono text-[10px] uppercase tracking-wider text-white\"\n style={{ top: HEADER_H + 6 }}\n >\n Today\n </span>\n </div>\n </div>\n\n {/* month header */}\n <div className=\"sticky top-0 z-20 flex border-b border-border bg-bg\" style={{ height: HEADER_H }}>\n <div className=\"sticky left-0 z-10 shrink-0 bg-bg\" style={{ width: LANE_LABEL_W }} />\n <div className=\"relative\">\n {tl.months.map((m) => (\n <span key={m.x} className=\"absolute top-3 whitespace-nowrap pl-2 font-mono text-[10px] uppercase tracking-widest text-muted\" style={{ left: m.x }}>\n {m.label}\n </span>\n ))}\n </div>\n </div>\n\n {tl.lanes.map((lane) => (\n <div key={lane.item.id} className=\"relative flex border-b border-border\">\n <LaneLabel item={lane.item} chapter={chapters.get(lane.item.id)} progress={progressById[lane.item.id]} onSelect={onSelect} />\n <div className=\"relative\" style={{ width: tl.width, height: lane.rows * LANE_ROW_H + 12 }}>\n {lane.markers.map((mk) => (\n <button\n key={mk.item.id}\n type=\"button\"\n onClick={() => onSelect(mk.item.id)}\n title={`${mk.item.id} · ${mk.item.title} · due ${mk.item.due}${mk.state === \"overdue\" ? \" (overdue)\" : \"\"}`}\n className=\"group absolute flex items-center gap-1.5\"\n style={{ left: mk.x - 10, top: 6 + mk.row * LANE_ROW_H }}\n >\n {mk.horizon ? (\n <span\n className={cn(\n \"h-4 w-4 rotate-45 border-2 border-accent\",\n mk.item.status === \"done\" ? \"bg-accent\" : \"bg-bg\",\n mk.state === \"overdue\" && \"border-danger\",\n )}\n />\n ) : (\n <span className={cn(\"rounded-full\", mk.state === \"overdue\" && \"ring-2 ring-danger ring-offset-1 ring-offset-bg\")}>\n <StatusDot status={mk.item.status} />\n </span>\n )}\n <span\n className={cn(\n \"flex max-w-[150px] flex-col rounded-md border px-2 py-0.5 text-left transition-colors\",\n mk.item.status === \"in-progress\" ? \"border-accent/50 bg-surface shadow-[0_6px_18px_-10px_rgb(var(--rgb-accent)/0.7)]\"\n : mk.item.status === \"done\" ? \"border-border bg-surface/60\" : \"border-dashed border-border2 bg-bg\",\n \"group-hover:border-accent\",\n )}\n >\n <span className=\"flex items-center gap-1\">\n <span className={cn(\"truncate text-xs\", mk.item.status === \"done\" ? \"text-muted\" : \"text-txt\", mk.horizon && \"font-semibold\")}>\n {mk.item.title}\n </span>\n <AgentDot attach={{ kind: \"epic\", id: mk.item.id }} />\n </span>\n <span\n className={cn(\n \"font-mono text-[10px]\",\n mk.state === \"overdue\" ? \"text-danger\" : mk.state === \"soon\" ? \"text-amber\" : \"text-muted\",\n )}\n >\n {formatDay(mk.item.due as string)}\n </span>\n </span>\n </button>\n ))}\n </div>\n </div>\n ))}\n\n {!hasDates && (\n <p className=\"px-6 py-8 text-sm text-muted\" style={{ marginLeft: LANE_LABEL_W }}>\n No due dates yet — open an item and set a Due date.\n </p>\n )}\n </div>\n </div>\n\n {tl.undated.length > 0 && (\n <div className=\"max-h-28 shrink-0 overflow-y-auto border-t border-border bg-surface px-4 py-2\">\n <p className=\"mb-2 font-mono text-[10px] uppercase tracking-widest text-muted\">No due date · {tl.undated.length}</p>\n <div className=\"flex flex-wrap gap-1.5\">\n {tl.undated.map((i) => (\n <button\n key={i.id}\n type=\"button\"\n onClick={() => onSelect(i.id)}\n className=\"flex items-center gap-1 rounded-md border border-border px-1.5 py-0.5 text-xs text-muted hover:border-accent hover:text-txt\"\n >\n <StatusDot status={i.status} />\n {i.title}\n <AgentDot attach={{ kind: \"epic\", id: i.id }} />\n </button>\n ))}\n </div>\n </div>\n )}\n </div>\n )\n}\n\nfunction LaneLabel({ item, chapter, progress, onSelect }: {\n item: RoadmapItem\n chapter?: number\n progress?: RoadmapProgress\n onSelect: (id: string) => void\n}) {\n return (\n <button\n type=\"button\"\n onClick={() => onSelect(item.id)}\n className=\"sticky left-0 z-10 flex shrink-0 items-center gap-3 border-r border-border bg-surface px-3 text-left hover:bg-surface2\"\n style={{ width: LANE_LABEL_W }}\n >\n <span\n className={cn(\n \"font-mono text-lg font-semibold tabular-nums\",\n item.status === \"in-progress\" ? \"text-accent\" : item.status === \"done\" ? \"text-teal\" : \"text-muted\",\n )}\n >\n {chapter ? String(chapter).padStart(2, \"0\") : \"··\"}\n </span>\n <span className=\"flex min-w-0 flex-1 flex-col gap-1\">\n <span className=\"line-clamp-2 text-[11px] font-semibold uppercase leading-snug tracking-wider text-txt\">{item.title}</span>\n {progress && (\n <span className=\"h-1 overflow-hidden rounded-full bg-border\">\n <span className=\"block h-full rounded-full bg-teal\" style={{ width: `${(progress.done / progress.total) * 100}%` }} />\n </span>\n )}\n </span>\n </button>\n )\n}\n","\"use client\"\n\nimport { useState } from \"react\"\nimport { Bot, ChevronRight, FileText, MessageSquare, Pencil, Plus } from \"lucide-react\"\nimport { Sheet, SheetContent, SheetDescription, SheetTitle } from \"@/components/ui/sheet\"\nimport { Input } from \"@/components/ui/input\"\nimport { Button } from \"@/components/ui/button\"\nimport { MarkdownRenderer } from \"@/components/docs/MarkdownRenderer\"\nimport { cn } from \"@/lib/utils\"\nimport { askAgent } from \"@/lib/ask-agent\"\nimport { chatFor } from \"@/lib/chats\"\nimport { AgentDot, AgentMark } from \"@/components/chat/AgentMark\"\nimport { useChats } from \"@/context/ChatContext\"\nimport { dueState, localToday, type RoadmapProgress } from \"@/lib/roadmap-health\"\nimport { pickNextTask } from \"@/lib/work-queue\"\nimport { DueChip, SegmentedProgress, StatusDot, StatusPill, TASK_STATUS_BG } from \"./RoadmapNodes\"\nimport type { RoadmapItem, RoadmapStatus, Task, TaskStatus, UpdateRoadmapItemPatch } from \"@/types\"\n\nconst STATUSES: RoadmapStatus[] = [\"planned\", \"in-progress\", \"done\"]\n\nconst FIELD = \"w-full rounded-md border border-border bg-bg px-3 py-2 text-sm text-txt focus:outline-hidden focus:ring-1 focus:ring-accent disabled:opacity-50\"\nconst LABEL = \"text-xs font-medium text-muted\"\nconst SECTION = \"font-mono text-[10px] uppercase tracking-widest text-muted\"\n\ninterface RoadmapItemSheetProps {\n item: RoadmapItem | null\n items: RoadmapItem[]\n onClose: () => void\n /** Each returns an error message, or null on success. */\n onSave: (id: string, patch: UpdateRoadmapItemPatch) => Promise<string | null>\n onDelete: (id: string) => Promise<string | null>\n onAddFeature: (parentId: string) => void\n onEditRaw: (file: string) => void\n onSelect: (id: string) => void\n /** Every task on the board, by id — the epic's linked tasks are looked up here. */\n tasksById: Record<string, Task>\n progressById: Record<string, RoadmapProgress>\n}\n\nexport function RoadmapItemSheet({ item, onClose, ...rest }: RoadmapItemSheetProps) {\n return (\n <Sheet open={!!item} onOpenChange={(v) => { if (!v) onClose() }}>\n <SheetContent className=\"w-[480px] sm:max-w-[480px] gap-0 bg-surface border-border text-txt flex flex-col overflow-y-auto p-0\">\n {/* keyed so view/edit and form state re-initialise when a different item opens */}\n {item && <ItemPanel key={item.id} item={item} onClose={onClose} {...rest} />}\n </SheetContent>\n </Sheet>\n )\n}\n\nfunction ItemPanel(props: RoadmapItemSheetProps & { item: RoadmapItem }) {\n const [editing, setEditing] = useState(false)\n return editing\n ? <ItemForm {...props} onCancel={() => setEditing(false)} />\n : <ItemView {...props} onEdit={() => setEditing(true)} />\n}\n\n/** Read-first view: where it sits, how far along, what's next, and the brief. */\nfunction ItemView({ item, items, onClose, onAddFeature, onEditRaw, onSelect, tasksById, progressById, onEdit }: RoadmapItemSheetProps & { item: RoadmapItem; onEdit: () => void }) {\n const isHorizon = item.parent === null\n const parent = items.find((i) => i.id === item.parent)\n const epics = items.filter((i) => i.parent === item.id).sort((a, b) => a.order - b.order)\n const progress = progressById[item.id]\n const today = localToday()\n const { chats, showAbout } = useChats()\n const chat = isHorizon ? undefined : chatFor(chats, { kind: \"epic\", id: item.id })\n const offerBreakdown = !isHorizon && item.tasks.length === 0 && !chat\n\n return (\n <div className=\"flex min-h-full flex-col\">\n <header className={cn(\"border-b border-border px-6 pb-5 pt-6\", item.status === \"in-progress\" && \"bg-[linear-gradient(180deg,rgb(var(--rgb-accent)/0.08),transparent)]\")}>\n <SheetDescription asChild>\n <div className=\"flex items-center gap-1 pr-8 font-mono text-[11px] text-muted\">\n {parent && (\n <>\n <button type=\"button\" onClick={() => onSelect(parent.id)} className=\"truncate hover:text-txt\">{parent.title}</button>\n <ChevronRight className=\"h-3 w-3 shrink-0\" />\n </>\n )}\n <span className=\"shrink-0\">{item.id} · {isHorizon ? \"horizon\" : \"epic\"}</span>\n </div>\n </SheetDescription>\n <SheetTitle className=\"mt-2 text-xl font-semibold leading-tight text-txt\">{item.title}</SheetTitle>\n <div className=\"mt-3 flex flex-wrap items-center gap-3\">\n <StatusPill status={item.status} />\n <AgentMark attach={{ kind: \"epic\", id: item.id }} />\n <DueChip due={item.due} state={dueState(item.due, item.status, today)} />\n </div>\n {progress && (\n <div className=\"mt-5 flex items-end gap-4\">\n <p className=\"font-mono text-3xl font-semibold leading-none tabular-nums text-txt\">\n {Math.round((progress.done / progress.total) * 100)}<span className=\"text-base text-muted\">%</span>\n </p>\n <div className=\"flex-1 pb-1\">\n <p className=\"mb-1.5 font-mono text-[10px] text-muted\">{progress.done} of {progress.total}{isHorizon ? \"\" : \" tasks\"} done</p>\n {isHorizon ? (\n <div className=\"h-1.5 overflow-hidden rounded-full bg-border\">\n <div className=\"h-full rounded-full bg-teal\" style={{ width: `${(progress.done / progress.total) * 100}%` }} />\n </div>\n ) : (\n <SegmentedProgress statuses={item.tasks.map((id) => tasksById[id]?.status).filter((s): s is TaskStatus => !!s && s !== \"cancelled\")} />\n )}\n </div>\n </div>\n )}\n </header>\n\n <div className=\"flex flex-1 flex-col gap-6 px-6 py-5\">\n {!isHorizon && item.tasks.length > 0 && <LinkedTasks item={item} tasksById={tasksById} onOpen={onEditRaw} />}\n\n {isHorizon && (\n <section className=\"flex flex-col gap-2\">\n <p className={SECTION}>Epics · {epics.length}</p>\n {epics.length === 0 && <p className=\"text-sm text-muted\">No epics yet.</p>}\n <ul className=\"-mx-2 flex flex-col\">\n {epics.map((e) => {\n const p = progressById[e.id]\n return (\n <li key={e.id}>\n <button type=\"button\" onClick={() => onSelect(e.id)} className=\"flex w-full items-center gap-3 rounded-md px-2 py-2 text-left hover:bg-surface2\">\n <StatusDot status={e.status} />\n <span className=\"shrink-0 font-mono text-[11px] text-muted\">{e.id}</span>\n <span className={cn(\"min-w-0 flex-1 truncate text-sm\", e.status === \"done\" ? \"text-muted\" : \"text-txt\")}>{e.title}</span>\n {p && <span className=\"shrink-0 font-mono text-[10px] text-muted\">{p.done}/{p.total}</span>}\n </button>\n </li>\n )\n })}\n </ul>\n </section>\n )}\n\n <section className=\"flex flex-col gap-2\">\n <p className={SECTION}>Brief</p>\n {item.body.trim()\n ? <MarkdownRenderer content={item.body} className=\"text-sm\" />\n : <p className=\"text-sm text-muted\">No description. Edit to add the outcome, scope and “done when”.</p>}\n </section>\n </div>\n\n <footer className=\"sticky bottom-0 flex flex-wrap items-center gap-2 border-t border-border bg-surface px-6 py-3\">\n {offerBreakdown && (\n <Button size=\"sm\" onClick={() => { onClose(); askAgent(`Break down epic ${item.id} into tasks.`) }} className=\"bg-accent text-white hover:bg-accent/90\">\n <Bot /> Break down with agent\n </Button>\n )}\n {!isHorizon && (\n <Button\n size=\"sm\"\n variant={offerBreakdown ? \"outline\" : \"default\"}\n onClick={() => { onClose(); showAbout({ kind: \"epic\", id: item.id }) }}\n className={cn(!offerBreakdown && \"bg-accent text-white hover:bg-accent/90\")}\n >\n <MessageSquare /> {chat ? \"Open chat\" : \"Chat\"}\n </Button>\n )}\n {isHorizon && (\n <Button size=\"sm\" onClick={() => onAddFeature(item.id)} className=\"bg-accent text-white hover:bg-accent/90\">\n <Plus /> Add epic\n </Button>\n )}\n <Button size=\"sm\" variant=\"outline\" onClick={onEdit}>\n <Pencil /> Edit\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => onEditRaw(item.file)} className=\"ml-auto text-muted hover:text-txt\">\n <FileText /> Open file\n </Button>\n </footer>\n </div>\n )\n}\n\nfunction ItemForm({ item, items, onClose, onSave, onDelete, onCancel }: RoadmapItemSheetProps & { item: RoadmapItem; onCancel: () => void }) {\n // snapshot at open: the dirty check diffs against this, not the live (SSE-refreshed) item\n const [base] = useState(item)\n const [title, setTitle] = useState(item.title)\n const [status, setStatus] = useState<RoadmapStatus>(item.status)\n const [parent, setParent] = useState(item.parent ?? \"\")\n const [order, setOrder] = useState(String(item.order))\n const [tasks, setTasks] = useState(item.tasks.join(\", \"))\n const [due, setDue] = useState(item.due ?? \"\")\n const [body, setBody] = useState(item.body)\n const [error, setError] = useState<string | null>(null)\n const [busy, setBusy] = useState(false)\n\n const hasChildren = items.some((i) => i.parent === item.id)\n const horizons = items.filter((i) => i.parent === null && i.id !== item.id)\n const isHorizon = item.parent === null\n const orphanParent = item.parent !== null && !horizons.some((h) => h.id === item.parent)\n\n async function run(fn: () => Promise<string | null>) {\n setBusy(true)\n setError(null)\n const err = await fn()\n setBusy(false)\n if (err) setError(err)\n return !err\n }\n\n async function save() {\n // Send only fields the user changed, so concurrent edits (AI / other tab) to other fields survive.\n const patch: UpdateRoadmapItemPatch = {}\n const nextTitle = title.trim() || base.title\n if (nextTitle !== base.title) patch.title = nextTitle\n if (status !== base.status) patch.status = status\n if ((parent || null) !== base.parent) patch.parent = parent || null\n if (order.trim() !== String(base.order)) {\n const n = Number(order)\n if (order.trim() === \"\" || !Number.isFinite(n)) {\n setError(\"Order must be a number\")\n return\n }\n patch.order = n\n }\n const nextTasks = tasks.split(\",\").map((t) => t.trim()).filter(Boolean)\n if (nextTasks.join(\",\") !== base.tasks.join(\",\")) patch.tasks = nextTasks\n if ((due || null) !== base.due) patch.due = due || null\n if (body !== base.body) patch.body = body\n if (Object.keys(patch).length === 0) {\n onCancel()\n return\n }\n if (await run(() => onSave(item.id, patch))) onClose()\n }\n\n async function remove() {\n if (!window.confirm(`Delete ${item.id}: ${item.title}?`)) return\n if (await run(() => onDelete(item.id))) onClose()\n }\n\n return (\n <div className=\"flex min-h-full flex-col\">\n <div className=\"border-b border-border px-6 pb-4 pt-6 pr-12\">\n <SheetDescription className=\"font-mono text-[11px] text-muted\">Editing {item.id} · {isHorizon ? \"horizon\" : \"epic\"}</SheetDescription>\n <SheetTitle className=\"mt-1 text-base text-txt\">{item.title}</SheetTitle>\n </div>\n\n <div className=\"flex flex-1 flex-col gap-4 px-6 py-5\">\n <label className=\"flex flex-col gap-1\">\n <span className={LABEL}>Title</span>\n <Input value={title} onChange={(e) => setTitle(e.target.value)} className=\"bg-bg border-border text-txt\" />\n </label>\n\n <div className=\"grid grid-cols-3 gap-3\">\n <label className=\"flex flex-col gap-1\">\n <span className={LABEL}>Status</span>\n <select value={status} onChange={(e) => setStatus(e.target.value as RoadmapStatus)} className={FIELD}>\n {STATUSES.map((s) => <option key={s} value={s}>{s}</option>)}\n </select>\n </label>\n <label className=\"flex flex-col gap-1\">\n <span className={LABEL}>Parent</span>\n <select\n value={parent}\n onChange={(e) => setParent(e.target.value)}\n disabled={hasChildren}\n title={hasChildren ? \"Items with children must stay on the spine\" : undefined}\n className={FIELD}\n >\n <option value=\"\">— (horizon)</option>\n {orphanParent && <option value={item.parent ?? \"\"}>{item.parent} · missing</option>}\n {horizons.map((h) => <option key={h.id} value={h.id}>{h.id} · {h.title}</option>)}\n </select>\n </label>\n <label className=\"flex flex-col gap-1\">\n <span className={LABEL}>Order</span>\n <Input\n type=\"number\"\n step={10}\n value={order}\n onChange={(e) => setOrder(e.target.value)}\n title={isHorizon ? \"Position on the spine\" : \"Position within the branch\"}\n className=\"bg-bg border-border text-txt\"\n />\n </label>\n </div>\n\n <label className=\"flex flex-col gap-1\">\n <span className={LABEL}>Due</span>\n <div className=\"flex items-center gap-2\">\n <Input\n type=\"date\"\n value={due}\n onChange={(e) => setDue(e.target.value)}\n className=\"bg-bg border-border text-txt scheme-light dark:scheme-dark\"\n />\n {due && (\n <button type=\"button\" onClick={() => setDue(\"\")} className=\"text-xs text-muted hover:text-txt\">\n Clear\n </button>\n )}\n </div>\n </label>\n\n <label className=\"flex flex-col gap-1\">\n <span className={LABEL}>Tasks</span>\n <Input\n value={tasks}\n onChange={(e) => setTasks(e.target.value)}\n placeholder=\"T001, T012\"\n className=\"bg-bg border-border text-txt font-mono\"\n />\n </label>\n\n <label className=\"flex flex-col gap-1\">\n <span className={LABEL}>Body (markdown)</span>\n <textarea value={body} onChange={(e) => setBody(e.target.value)} rows={12} className={`${FIELD} font-mono resize-y`} />\n </label>\n\n {error && <p className=\"text-xs text-danger\">{error}</p>}\n </div>\n\n <footer className=\"sticky bottom-0 flex items-center gap-2 border-t border-border bg-surface px-6 py-3\">\n <Button size=\"sm\" onClick={save} disabled={busy} className=\"bg-accent text-white hover:bg-accent/90\">\n Save\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={onCancel} disabled={busy} className=\"text-txt\">\n Cancel\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={remove} disabled={busy} className=\"ml-auto text-danger hover:text-danger\">\n Delete\n </Button>\n </footer>\n </div>\n )\n}\n\nfunction LinkedTasks({ item, tasksById, onOpen }: {\n item: RoadmapItem\n tasksById: Record<string, Task>\n onOpen: (file: string) => void\n}) {\n const today = localToday()\n const next = pickNextTask(item, Object.values(tasksById))\n const nextId = next.kind === \"ready\" ? next.taskId : null\n // Todo tasks' \"waits on …\" first: in-progress/blocked rows already say so in their badge.\n const reasons = next.kind === \"waiting\"\n ? [...next.waiting].sort((a, b) => Number(tasksById[b.taskId]?.status === \"todo\") - Number(tasksById[a.taskId]?.status === \"todo\")).map((w) => w.reason)\n : []\n return (\n <section className=\"flex flex-col gap-2\">\n <p className={SECTION}>Tasks · {item.tasks.length}</p>\n <ul className=\"-mx-2 flex flex-col\">\n {item.tasks.map((id) => {\n const t = tasksById[id]\n if (!t) {\n return (\n <li key={id} className=\"px-2 py-2 font-mono text-xs text-danger\">{id} · missing task file</li>\n )\n }\n const isNext = t.id === nextId\n return (\n <li key={id} className={cn(\"group flex items-center rounded-md hover:bg-surface2\", isNext && \"bg-accent/10 hover:bg-accent/15\")}>\n <button\n type=\"button\"\n onClick={() => onOpen(t.file)}\n className=\"flex min-w-0 flex-1 items-center gap-3 px-2 py-2 text-left\"\n >\n <span title={t.status} className={cn(\"h-2 w-2 shrink-0 rounded-full\", TASK_STATUS_BG[t.status])} />\n <span className=\"shrink-0 font-mono text-[11px] text-muted\">{t.id}</span>\n <span className={cn(\"min-w-0 flex-1 truncate text-sm\", t.status === \"cancelled\" ? \"text-muted line-through\" : t.status === \"done\" ? \"text-muted\" : \"text-txt\")}>\n {t.title}\n </span>\n <DueChip due={t.due} state={dueState(t.due, t.status === \"done\" ? \"done\" : \"planned\", today)} />\n {isNext\n ? <span className=\"shrink-0 font-mono text-[10px] uppercase tracking-wider text-accent\">Next up</span>\n : t.size && t.size !== \"—\" && <span className=\"shrink-0 font-mono text-[10px] text-muted\">{t.size.split(\" \")[0]}</span>}\n <AgentDot attach={{ kind: \"task\", id: t.id }} />\n </button>\n <TaskChatButton taskId={t.id} />\n </li>\n )\n })}\n </ul>\n {reasons.length > 0 && (\n <p className=\"truncate text-xs text-muted\" title={reasons.join(\"\\n\")}>\n {reasons[0]}{reasons.length > 1 && ` (+${reasons.length - 1} more)`}\n </p>\n )}\n </section>\n )\n}\n\n/** Per-task chat entry in the epic sheet: always visible when a chat exists, on hover otherwise. */\nfunction TaskChatButton({ taskId }: { taskId: string }) {\n const { chats, showAbout } = useChats()\n const has = !!chatFor(chats, { kind: \"task\", id: taskId })\n return (\n <button\n type=\"button\"\n onClick={() => showAbout({ kind: \"task\", id: taskId })}\n aria-label={`${has ? \"Open chat\" : \"Chat\"} about ${taskId}`}\n title={has ? `Open the chat about ${taskId}` : `Chat about ${taskId}`}\n className={cn(\n \"mr-1 grid size-7 shrink-0 place-items-center rounded-md text-muted transition-[opacity,color] duration-(--duration-fast) hover:bg-surface hover:text-accent focus-visible:opacity-100\",\n has ? \"text-accent opacity-100\" : \"opacity-0 group-hover:opacity-100\",\n )}\n >\n <MessageSquare className=\"size-3.5\" />\n </button>\n )\n}\n","\"use client\"\n\nimport { useState } from \"react\"\nimport { Dialog, DialogContent, DialogTitle } from \"@/components/ui/dialog\"\nimport { Input } from \"@/components/ui/input\"\nimport { Button } from \"@/components/ui/button\"\n\ninterface NewItemDialogProps {\n open: boolean\n heading: string\n onOpenChange: (open: boolean) => void\n /** Returns an error message to show, or null on success. */\n onSubmit: (title: string) => Promise<string | null>\n}\n\nexport function NewItemDialog({ open, heading, onOpenChange, onSubmit }: NewItemDialogProps) {\n const [title, setTitle] = useState(\"\")\n const [error, setError] = useState<string | null>(null)\n const [busy, setBusy] = useState(false)\n\n function close(v: boolean) {\n if (!v) {\n setTitle(\"\")\n setError(null)\n }\n onOpenChange(v)\n }\n\n async function submit(e: React.FormEvent) {\n e.preventDefault()\n if (!title.trim()) return\n setBusy(true)\n const err = await onSubmit(title.trim())\n setBusy(false)\n if (err) setError(err)\n else close(false)\n }\n\n return (\n <Dialog open={open} onOpenChange={close}>\n <DialogContent className=\"max-w-sm bg-surface border-border text-txt\">\n <DialogTitle className=\"text-sm font-semibold text-txt\">{heading}</DialogTitle>\n <form onSubmit={submit} className=\"flex flex-col gap-3\">\n <Input\n autoFocus\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder=\"Title\"\n className=\"bg-bg border-border text-txt\"\n />\n {error && <p className=\"text-xs text-danger\">{error}</p>}\n <div className=\"flex justify-end gap-2\">\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => close(false)}>\n Cancel\n </Button>\n <Button type=\"submit\" size=\"sm\" disabled={busy || !title.trim()} className=\"bg-accent text-white hover:bg-accent/90\">\n Create\n </Button>\n </div>\n </form>\n </DialogContent>\n </Dialog>\n )\n}\n","\"use client\"\n\nimport { useState } from \"react\"\nimport { Dialog, DialogContent, DialogTitle } from \"@/components/ui/dialog\"\nimport { Button } from \"@/components/ui/button\"\nimport { askAgent } from \"@/lib/ask-agent\"\n\ninterface PlanFromSpecDialogProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n}\n\n/** Paste a feature spec → the chat agent breaks it into tasks (new epic, existing epic, or loose). */\nexport function PlanFromSpecDialog({ open, onOpenChange }: PlanFromSpecDialogProps) {\n // Kept after submit (cleared only on Cancel): if the running-agent cap refuses the ask, reopening restores the spec.\n const [spec, setSpec] = useState(\"\")\n\n function submit(e: React.FormEvent) {\n e.preventDefault()\n if (!spec.trim()) return\n onOpenChange(false)\n askAgent(`Break down this spec into tasks:\\n\\n${spec.trim()}`)\n }\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-lg bg-surface border-border text-txt\">\n <DialogTitle className=\"text-sm font-semibold text-txt\">Plan from spec</DialogTitle>\n <form onSubmit={submit} className=\"flex flex-col gap-3\">\n <textarea\n autoFocus\n value={spec}\n onChange={(e) => setSpec(e.target.value)}\n placeholder=\"Paste a feature spec…\"\n rows={12}\n className=\"w-full resize-y rounded-md border border-border bg-bg px-3 py-2 text-sm text-txt placeholder:text-muted focus:outline-none focus:ring-1 focus:ring-accent\"\n />\n <p className=\"text-xs text-muted\">The agent asks where the tasks go (a new epic, an existing epic, or no epic) and shows a plan before writing anything.</p>\n <div className=\"flex justify-end gap-2\">\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => { setSpec(\"\"); onOpenChange(false) }}>\n Cancel\n </Button>\n <Button type=\"submit\" size=\"sm\" disabled={!spec.trim()} className=\"bg-accent text-white hover:bg-accent/90\">\n Break down\n </Button>\n </div>\n </form>\n </DialogContent>\n </Dialog>\n )\n}\n","\"use client\"\n\nimport { useState } from \"react\"\nimport { Dialog, DialogContent, DialogTitle } from \"@/components/ui/dialog\"\nimport { Button } from \"@/components/ui/button\"\nimport { askAgent } from \"@/lib/ask-agent\"\nimport { MAX_RUNNING_CHATS } from \"@/lib/chats\"\nimport { useChats } from \"@/context/ChatContext\"\nimport type { RoadmapItem } from \"@/types\"\n\ninterface BreakdownEpicsDialogProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n items: RoadmapItem[]\n}\n\n/** Not-done epics grouped by horizon (spine order); within a horizon, epics with no tasks first. */\nfunction epicGroups(items: RoadmapItem[]) {\n const byOrder = (a: RoadmapItem, b: RoadmapItem) => a.order - b.order\n return items\n .filter((i) => i.parent === null)\n .sort(byOrder)\n .map((h) => ({\n horizon: h,\n epics: items\n .filter((i) => i.parent === h.id && i.status !== \"done\")\n .sort((a, b) => Number(a.tasks.length > 0) - Number(b.tasks.length > 0) || byOrder(a, b)),\n }))\n .filter((g) => g.epics.length > 0)\n}\n\n/** Tick several epics → one breakdown chat per epic, all running at once (capped by free agent slots). */\nexport function BreakdownEpicsDialog({ open, onOpenChange, items }: BreakdownEpicsDialogProps) {\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-lg bg-surface border-border text-txt\">\n <DialogTitle className=\"text-sm font-semibold text-txt\">Break down epics</DialogTitle>\n {/* Mounted only while open, so the default selection is recomputed on every open */}\n <BreakdownForm items={items} onDone={() => onOpenChange(false)} />\n </DialogContent>\n </Dialog>\n )\n}\n\nfunction BreakdownForm({ items, onDone }: { items: RoadmapItem[]; onDone: () => void }) {\n const groups = epicGroups(items)\n const [checked, setChecked] = useState(\n () => new Set(groups.flatMap((g) => g.epics.filter((e) => e.tasks.length === 0).map((e) => e.id))),\n )\n const running = useChats().runningCount\n const free = Math.max(0, MAX_RUNNING_CHATS - running)\n const over = checked.size > free\n\n function toggle(id: string) {\n setChecked((s) => {\n const next = new Set(s)\n if (!next.delete(id)) next.add(id)\n return next\n })\n }\n\n function submit(e: React.FormEvent) {\n e.preventDefault()\n if (!checked.size || over) return\n onDone()\n // Spine order, same message as the single-epic \"Break down with agent\"\n for (const g of groups) for (const epic of g.epics) {\n if (checked.has(epic.id)) askAgent(`Break down epic ${epic.id} into tasks.`, { newChat: true })\n }\n }\n\n return (\n <form onSubmit={submit} className=\"flex flex-col gap-3\">\n <div className=\"max-h-[50vh] overflow-y-auto rounded-md border border-border\">\n {groups.map((g) => (\n <div key={g.horizon.id}>\n <div className=\"sticky top-0 bg-surface2 px-3 py-1 text-[10px] font-mono uppercase tracking-widest text-muted\">\n {g.horizon.id} · {g.horizon.title}\n </div>\n <ul>\n {g.epics.map((epic) => {\n const on = checked.has(epic.id)\n return (\n <li key={epic.id} className=\"border-b border-border last:border-b-0\">\n <label className=\"flex items-start gap-2 px-3 py-1.5 text-xs cursor-pointer has-[:disabled]:cursor-not-allowed\">\n <input\n type=\"checkbox\"\n checked={on}\n disabled={!on && checked.size >= free}\n onChange={() => toggle(epic.id)}\n className=\"mt-0.5 accent-accent\"\n />\n <span className=\"flex-1 min-w-0 text-txt\">\n <span className=\"font-mono text-muted mr-1\">{epic.id}</span>{epic.title}\n </span>\n {epic.tasks.length > 0 && (\n <span className=\"shrink-0 text-[10px] font-mono text-muted\">has {epic.tasks.length} task{epic.tasks.length === 1 ? \"\" : \"s\"}</span>\n )}\n </label>\n </li>\n )\n })}\n </ul>\n </div>\n ))}\n </div>\n <p className={over || free === 0 ? \"text-xs text-amber\" : \"text-xs text-muted\"}>\n {free === 0\n ? `All ${MAX_RUNNING_CHATS} agent slots are busy. Stop a chat or wait for one to finish.`\n : over\n ? `${checked.size} selected, but only ${free} of ${MAX_RUNNING_CHATS} agent slots ${free === 1 ? \"is\" : \"are\"} free (${running} running). Uncheck some or stop a chat.`\n : `One chat per epic, running at once (${free} of ${MAX_RUNNING_CHATS} agent slots free). Each shows a plan before writing anything.`}\n </p>\n <div className=\"flex justify-end gap-2\">\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={onDone}>\n Cancel\n </Button>\n <Button type=\"submit\" size=\"sm\" disabled={!checked.size || over} className=\"bg-accent text-white hover:bg-accent/90\">\n Break down {checked.size || \"\"} epic{checked.size === 1 ? \"\" : \"s\"}\n </Button>\n </div>\n </form>\n )\n}\n","\"use client\"\n\nimport { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from \"react\"\nimport {\n Background,\n BackgroundVariant,\n Controls,\n Position,\n ReactFlow,\n applyNodeChanges,\n type Edge,\n type NodeChange,\n type ReactFlowInstance,\n} from \"@xyflow/react\"\nimport \"@xyflow/react/dist/style.css\"\n\nconst MIN_INITIAL_ZOOM = 0.75\nconst VIEWPORT_PAD = 40\nimport { AlertTriangle, Bot, FileText, ListTree, Plus, Sparkles } from \"lucide-react\"\nimport { useRouter, useSearchParams } from \"next/navigation\"\nimport { useApp } from \"@/context/AppContext\"\nimport { EmptyState } from \"@/components/shared/EmptyState\"\nimport { Button } from \"@/components/ui/button\"\nimport type { RoadmapItem, RoadmapLayout, RoadmapSource, Task, TaskStatus, UpdateRoadmapItemPatch } from \"@/types\"\nimport { pickNextTask } from \"@/lib/work-queue\"\nimport { dueState, localToday, roadmapHealth, taskDueSummary, type RoadmapDrift, type TaskInfo } from \"@/lib/roadmap-health\"\nimport { cn } from \"@/lib/utils\"\nimport { askAgent } from \"@/lib/ask-agent\"\nimport { RoadmapTimeline } from \"./RoadmapTimeline\"\nimport { FEATURE_W, HORIZON_W, resolvePositions } from \"./layout\"\nimport { STATUS_LABEL, StatusDot, nodeTypes, type RoadmapNode } from \"./RoadmapNodes\"\nimport { RoadmapItemSheet } from \"./RoadmapItemSheet\"\nimport { NewItemDialog } from \"./NewItemDialog\"\nimport { PlanFromSpecDialog } from \"./PlanFromSpecDialog\"\nimport { BreakdownEpicsDialog } from \"./BreakdownEpicsDialog\"\n\ntype ApiResult<T> = { data?: T; error?: string }\n\nasync function api<T>(url: string, body?: unknown): Promise<ApiResult<T>> {\n try {\n const res = await fetch(\n url,\n body === undefined\n ? undefined\n : { method: \"POST\", headers: { \"Content-Type\": \"application/json\" }, body: JSON.stringify(body) },\n )\n const json = await res.json().catch(() => null)\n if (!res.ok) return { error: json?.error ?? `Request failed (${res.status})` }\n return { data: json as T }\n } catch {\n return { error: \"Could not reach the server\" }\n }\n}\n\nfunction taskDueFields(taskIds: string[], tasks: Record<string, TaskInfo>, today: string) {\n const taskDue = taskDueSummary(taskIds, tasks, today)\n return { taskDue, taskDueSoon: !!taskDue?.next && dueState(taskDue.next, \"planned\", today) === \"soon\" }\n}\n\nfunction buildNodes(items: RoadmapItem[], layout: RoadmapLayout, prev: RoadmapNode[]): RoadmapNode[] {\n const pos = resolvePositions(items, layout)\n const prevById = new Map(prev.map((n) => [n.id, n]))\n return items.map((item) => {\n const old = prevById.get(item.id)\n return {\n id: item.id,\n type: item.parent === null ? \"horizon\" : \"feature\",\n position: pos[item.id] ?? { x: 0, y: 0 },\n data: { item },\n // keep React Flow's measurements/selection across rebuilds\n measured: old?.measured,\n selected: old?.selected,\n }\n })\n}\n\n/** Pick the handle sides that face each other. Branches always leave a horizon sideways, like roadmap.sh. */\nfunction sides(a: RoadmapNode, b: RoadmapNode, horizontal: boolean): [Position, Position] {\n const center = (n: RoadmapNode) => ({\n x: n.position.x + (n.measured?.width ?? (n.type === \"horizon\" ? HORIZON_W : FEATURE_W)) / 2,\n y: n.position.y + (n.measured?.height ?? 48) / 2,\n })\n const ca = center(a)\n const cb = center(b)\n const dx = cb.x - ca.x\n const dy = cb.y - ca.y\n if (horizontal || Math.abs(dx) > Math.abs(dy)) return dx > 0 ? [Position.Right, Position.Left] : [Position.Left, Position.Right]\n return dy > 0 ? [Position.Bottom, Position.Top] : [Position.Top, Position.Bottom]\n}\n\n/** Spine: solid up to the current horizon, dashed after. Branch: follows the epic (live = animated accent). */\nfunction edgeStyle(a: RoadmapNode, b: RoadmapNode, spine: boolean): Pick<Edge, \"style\" | \"animated\"> {\n if (spine) {\n return a.data.item.status === \"done\"\n ? { style: { stroke: \"var(--color-accent)\", strokeWidth: 3 } }\n : { style: { stroke: \"var(--color-border2)\", strokeWidth: 3, strokeDasharray: \"6 6\" } }\n }\n const status = b.data.item.status\n if (status === \"in-progress\") return { animated: true, style: { stroke: \"var(--color-accent)\", strokeWidth: 2 } }\n if (status === \"done\") return { style: { stroke: \"var(--color-border2)\", strokeWidth: 1.5 } }\n return { style: { stroke: \"var(--color-border2)\", strokeWidth: 1.5, strokeDasharray: \"2 5\", strokeLinecap: \"round\" } }\n}\n\nfunction edge(id: string, a: RoadmapNode, b: RoadmapNode, spine: boolean): Edge {\n const [s, t] = sides(a, b, !spine)\n return {\n id,\n source: a.id,\n target: b.id,\n sourceHandle: s,\n targetHandle: `${t}-t`,\n type: spine ? \"straight\" : \"default\",\n selectable: false,\n ...edgeStyle(a, b, spine),\n }\n}\n\nfunction subscribeTheme(cb: () => void) {\n const mo = new MutationObserver(cb)\n mo.observe(document.documentElement, { attributes: true, attributeFilter: [\"class\"] })\n return () => mo.disconnect()\n}\n\nconst FLOW_STYLE = { \"--xy-background-color\": \"var(--color-bg)\" } as React.CSSProperties\n\nexport function RoadmapTab() {\n const { rootParam, openDoc, board } = useApp()\n const router = useRouter()\n const searchParams = useSearchParams()\n const view = searchParams.get(\"view\") === \"timeline\" ? \"timeline\" : \"map\"\n const setView = (v: \"map\" | \"timeline\") => {\n const params = new URLSearchParams(searchParams.toString())\n if (v === \"map\") params.delete(\"view\")\n else params.set(\"view\", v)\n const qs = params.toString()\n router.replace(qs ? `/roadmap?${qs}` : \"/roadmap\")\n }\n const today = localToday()\n const [items, setItems] = useState<RoadmapItem[]>([])\n const [layout, setLayout] = useState<RoadmapLayout>({})\n const [nodes, setNodes] = useState<RoadmapNode[]>([])\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n const [selectedId, setSelectedId] = useState<string | null>(null)\n // ?item=R004 (links from a chat) opens that item's sheet; adjusted during render so a new link re-opens it\n const itemParam = searchParams.get(\"item\")\n const [seenItemParam, setSeenItemParam] = useState<string | null>(null)\n if (itemParam !== seenItemParam) {\n setSeenItemParam(itemParam)\n if (itemParam) setSelectedId(itemParam)\n }\n const [generateSource, setGenerateSource] = useState<RoadmapSource | null>(null)\n const [generating, setGenerating] = useState(false)\n // null = closed; \"\" = new horizon; \"R001\" = new feature under R001\n const [createParent, setCreateParent] = useState<string | null>(null)\n const [specOpen, setSpecOpen] = useState(false)\n const [breakdownOpen, setBreakdownOpen] = useState(false)\n const draggingRef = useRef(false)\n const containerRef = useRef<HTMLDivElement>(null)\n\n // Like roadmap.sh: open at readable zoom, centered horizontally, from the top of the map.\n // fitView on a large roadmap shrinks text to unreadable sizes.\n const showTop = useCallback((rf: ReactFlowInstance<RoadmapNode>) => {\n const width = containerRef.current?.clientWidth ?? 0\n const bounds = rf.getNodesBounds(rf.getNodes())\n if (!width || !bounds.width) return\n const zoom = Math.min(1, Math.max(MIN_INITIAL_ZOOM, (width - VIEWPORT_PAD * 2) / bounds.width))\n rf.setViewport({ x: width / 2 - (bounds.x + bounds.width / 2) * zoom, y: VIEWPORT_PAD - bounds.y * zoom, zoom })\n }, [])\n // a roadmap_updated that arrived mid-drag; reloaded once the drag's layout POST lands\n const pendingReloadRef = useRef(false)\n // only the latest load() may apply its response (guards project switches / overlapping SSE reloads)\n const loadSeqRef = useRef(0)\n\n const isDark = useSyncExternalStore(\n subscribeTheme,\n () => document.documentElement.classList.contains(\"dark\"),\n () => true,\n )\n\n const applyData = useCallback((nextItems: RoadmapItem[], nextLayout: RoadmapLayout) => {\n setItems(nextItems)\n setLayout(nextLayout)\n setNodes((prev) => buildNodes(nextItems, nextLayout, prev))\n }, [])\n\n const load = useCallback(() => {\n const seq = ++loadSeqRef.current\n type ListResponse = { items: RoadmapItem[]; layout: RoadmapLayout; generateSource?: RoadmapSource }\n return api<ListResponse>(`/api/roadmap${rootParam}`).then(({ data, error: err }) => {\n if (seq !== loadSeqRef.current) return\n setLoading(false)\n if (err) {\n setError(err)\n // never leave another project's (or stale) items on screen, editable against this root\n applyData([], {})\n setSelectedId(null)\n return\n }\n setError(null)\n setGenerateSource(data?.generateSource ?? null)\n applyData(data?.items ?? [], data?.layout ?? {})\n })\n }, [rootParam, applyData])\n\n useEffect(() => {\n load()\n }, [load])\n\n useEffect(() => {\n const es = new EventSource(\"/api/events\")\n es.onmessage = (e) => {\n try {\n const msg = JSON.parse(e.data)\n if (msg.type !== \"roadmap_updated\") return\n if (draggingRef.current) pendingReloadRef.current = true\n else load()\n } catch {\n // non-JSON keepalive; ignore\n }\n }\n return () => es.close()\n }, [load])\n\n const edges = useMemo(() => {\n const byId = new Map(nodes.map((n) => [n.id, n]))\n const out: Edge[] = []\n const horizons = items.filter((i) => i.parent === null).sort((a, b) => a.order - b.order)\n horizons.forEach((h, i) => {\n const a = byId.get(h.id)\n const next = horizons[i + 1] && byId.get(horizons[i + 1].id)\n if (a && next) out.push(edge(`spine-${h.id}`, a, next, true))\n })\n for (const item of items) {\n const p = item.parent && byId.get(item.parent)\n const c = byId.get(item.id)\n if (p && c && p.type === \"horizon\") out.push(edge(`branch-${item.id}`, p, c, false))\n }\n return out\n }, [items, nodes])\n\n // board is refreshed by AppContext on task_updated, so progress/drift follow task moves live\n const tasksById = useMemo<Record<string, Task>>(\n () => Object.fromEntries(Object.values(board ?? {}).flat().map((t) => [t.id, t])),\n [board],\n )\n const health = useMemo(() => roadmapHealth(items, tasksById, today), [items, tasksById, today])\n\n const shownNodes = useMemo(() => {\n const allTasks = Object.values(tasksById)\n // chapters number real horizons only; orphans on the spine get none\n const chapters = new Map(items.filter((i) => i.parent === null).sort((a, b) => a.order - b.order).map((h, i) => [h.id, i + 1]))\n return nodes.map((n) => {\n const { item } = n.data\n const kids = items.filter((i) => i.parent === item.id)\n const next = n.type === \"feature\" && item.status === \"in-progress\" ? pickNextTask(item, allTasks) : null\n return {\n ...n,\n data: {\n ...n.data,\n progress: health.progress[n.id],\n drift: health.drift.filter((d) => d.id === n.id).map((d) => d.message),\n dueState: dueState(item.due, item.status, today),\n ...(n.type === \"feature\" && {\n ...taskDueFields(item.tasks, tasksById, today),\n taskStatuses: item.tasks.map((id) => tasksById[id]?.status).filter((s): s is TaskStatus => !!s && s !== \"cancelled\"),\n nextTaskId: next?.kind === \"ready\" ? next.taskId : null,\n }),\n ...(n.type === \"horizon\" && {\n chapter: chapters.get(item.id),\n epics: { done: kids.filter((k) => k.status === \"done\").length, total: kids.length },\n }),\n },\n }\n })\n }, [nodes, items, health, today, tasksById])\n\n const onNodesChange = useCallback(\n (changes: NodeChange<RoadmapNode>[]) => setNodes((nds) => applyNodeChanges(changes, nds)),\n [],\n )\n\n function onDragStop(dragged: RoadmapNode[]) {\n draggingRef.current = false\n const positions: RoadmapLayout = Object.fromEntries(\n dragged.map((n) => [n.id, { x: Math.round(n.position.x), y: Math.round(n.position.y) }]),\n )\n // children without a saved position follow their horizon immediately\n applyData(items, { ...layout, ...positions })\n api(`/api/roadmap/layout${rootParam}`, { positions }).then(({ error: err }) => {\n if (err) setError(err)\n if (pendingReloadRef.current) {\n pendingReloadRef.current = false\n load()\n }\n })\n }\n\n async function generate() {\n setGenerating(true)\n setError(null)\n const { data, error: err } = await api<{ items: RoadmapItem[] }>(`/api/roadmap/generate${rootParam}`, {})\n if (err) {\n setError(err)\n setGenerating(false)\n return\n }\n // freeze the generated arrangement so later additions don't shift auto-placed horizons\n const positions: RoadmapLayout = Object.fromEntries(\n Object.entries(resolvePositions(data?.items ?? [], {})).map(([id, p]) => [id, { x: Math.round(p.x), y: Math.round(p.y) }]),\n )\n const { error: layoutErr } = await api(`/api/roadmap/layout${rootParam}`, { positions })\n await load()\n if (layoutErr) setError(layoutErr)\n setGenerating(false)\n }\n\n const openTaskCount = Object.values(board ?? {}).flat().filter((t) => t.status !== \"cancelled\").length\n const sourceLabel =\n generateSource === \"roadmap-md\" ? \"from ROADMAP.md\"\n : generateSource === \"tasks\" ? `from ${openTaskCount} tasks, grouped by phase`\n : \"starter horizons: Shipped · Now · Next · Later\"\n\n async function createItem(title: string): Promise<string | null> {\n const { error: err } = await api(`/api/roadmap/create${rootParam}`, {\n title,\n parent: createParent || null,\n })\n if (err) return err\n await load()\n return null\n }\n\n async function saveItem(id: string, patch: UpdateRoadmapItemPatch): Promise<string | null> {\n const { data, error: err } = await api<{ item: RoadmapItem }>(`/api/roadmap/update${rootParam}`, { id, patch })\n if (err) return err\n const updated = data?.item\n if (updated) applyData(items.map((i) => (i.id === id ? updated : i)), layout)\n else await load()\n return null\n }\n\n async function deleteItem(id: string): Promise<string | null> {\n const { error: err } = await api(`/api/roadmap/delete${rootParam}`, { id })\n if (err) return err\n applyData(items.filter((i) => i.id !== id), layout)\n return null\n }\n\n const selected = items.find((i) => i.id === selectedId) ?? null\n\n const dialog = (\n <>\n <NewItemDialog\n open={createParent !== null}\n heading={createParent ? `New feature under ${createParent}` : \"New horizon\"}\n onOpenChange={(v) => { if (!v) setCreateParent(null) }}\n onSubmit={createItem}\n />\n <PlanFromSpecDialog open={specOpen} onOpenChange={setSpecOpen} />\n <BreakdownEpicsDialog open={breakdownOpen} onOpenChange={setBreakdownOpen} items={items} />\n </>\n )\n\n if (loading) {\n return <div className=\"flex-1 flex items-center justify-center text-sm text-muted\">Loading…</div>\n }\n\n if (items.length === 0) {\n return (\n <div className=\"flex-1 p-6\">\n {error && <p className=\"mb-4 text-sm text-danger\">{error}</p>}\n <EmptyState icon=\"🗺️\" message=\"No roadmap yet\" subMessage=\"Items live in plans/roadmap/R*.md\" bordered />\n <div className=\"mt-4 flex flex-col items-center gap-2\">\n <div className=\"flex gap-2\">\n <Button size=\"sm\" onClick={generate} disabled={generating} className=\"bg-accent text-white hover:bg-accent/90\">\n <Sparkles /> {generating ? \"Generating…\" : \"Generate roadmap\"}\n </Button>\n <Button size=\"sm\" variant=\"outline\" onClick={() => askAgent(\"Plan a roadmap for this project.\")} disabled={generating}>\n <Bot /> Plan with agent\n </Button>\n <Button size=\"sm\" variant=\"outline\" onClick={() => setSpecOpen(true)} disabled={generating}>\n <FileText /> Plan from spec\n </Button>\n <Button size=\"sm\" variant=\"outline\" onClick={() => setCreateParent(\"\")} disabled={generating}>\n <Plus /> Create first horizon\n </Button>\n </div>\n <p className=\"text-xs text-muted\">Generate {sourceLabel}. Existing files are not modified.</p>\n </div>\n {dialog}\n </div>\n )\n }\n\n return (\n <div className=\"relative flex flex-1 min-h-0 flex-col\">\n <div className=\"flex shrink-0 items-center gap-4 border-b border-border px-3 py-2\">\n <div className=\"flex rounded-md border border-border p-0.5 text-xs\">\n {([\"map\", \"timeline\"] as const).map((v) => (\n <button\n key={v}\n type=\"button\"\n onClick={() => setView(v)}\n className={cn(\n \"rounded-sm px-3 py-1 capitalize\",\n view === v ? \"bg-surface2 text-txt\" : \"text-muted hover:text-txt\",\n )}\n >\n {v}\n </button>\n ))}\n </div>\n <RoadmapStats items={items} tasksById={tasksById} />\n <div className=\"ml-auto flex items-center gap-2\">\n {error && <p className=\"text-xs text-danger\">{error}</p>}\n {health.drift.length > 0 && (\n <AttentionMenu\n drift={health.drift}\n onSelect={setSelectedId}\n onApply={(d) => d.suggestedStatus && saveItem(d.id, { status: d.suggestedStatus }).then((err) => { if (err) setError(err) })}\n />\n )}\n <Button size=\"sm\" variant=\"outline\" onClick={() => setSpecOpen(true)}>\n <FileText /> Plan from spec\n </Button>\n {items.some((i) => i.parent !== null && i.status !== \"done\") && (\n <Button size=\"sm\" variant=\"outline\" onClick={() => setBreakdownOpen(true)}>\n <ListTree /> Break down epics…\n </Button>\n )}\n <Button size=\"sm\" onClick={() => setCreateParent(\"\")} className=\"bg-accent text-white hover:bg-accent/90\">\n <Plus /> Horizon\n </Button>\n </div>\n </div>\n\n {view === \"map\" ? (\n <div ref={containerRef} className=\"relative flex-1 min-h-0\">\n <ReactFlow<RoadmapNode>\n nodes={shownNodes}\n edges={edges}\n nodeTypes={nodeTypes}\n onNodesChange={onNodesChange}\n onNodeClick={(_, n) => setSelectedId(n.id)}\n onNodeDragStart={() => { draggingRef.current = true }}\n onNodeDragStop={(_, __, dragged) => onDragStop(dragged)}\n nodesConnectable={false}\n deleteKeyCode={null}\n colorMode={isDark ? \"dark\" : \"light\"}\n onInit={showTop}\n minZoom={0.2}\n style={FLOW_STYLE}\n >\n <Background variant={BackgroundVariant.Dots} gap={20} size={1} />\n <Controls showInteractive={false} />\n </ReactFlow>\n </div>\n ) : (\n <RoadmapTimeline items={items} today={today} onSelect={setSelectedId} progressById={health.progress} />\n )}\n\n <RoadmapItemSheet\n item={selected}\n items={items}\n onClose={() => setSelectedId(null)}\n onSave={saveItem}\n onDelete={deleteItem}\n onAddFeature={(parentId) => { setSelectedId(null); setCreateParent(parentId) }}\n onEditRaw={(file) => { openDoc(file) }}\n tasksById={tasksById}\n progressById={health.progress}\n onSelect={setSelectedId}\n />\n {dialog}\n </div>\n )\n}\n\n/** Epic counts by status double as the legend; tasks = every task linked to an epic. */\nfunction RoadmapStats({ items, tasksById }: { items: RoadmapItem[]; tasksById: Record<string, Task> }) {\n const epics = items.filter((i) => i.parent !== null)\n const count = (st: RoadmapItem[\"status\"]) => epics.filter((e) => e.status === st).length\n const linked = [...new Set(epics.flatMap((e) => e.tasks))].map((id) => tasksById[id]).filter((t) => t && t.status !== \"cancelled\")\n const done = linked.filter((t) => t.status === \"done\").length\n return (\n <div className=\"hidden items-center gap-4 font-mono text-[11px] text-muted md:flex\">\n {([\"in-progress\", \"done\", \"planned\"] as const).map((st) => (\n <span key={st} className=\"flex items-center gap-1.5\">\n <StatusDot status={st} />\n <span className={cn(\"tabular-nums\", st === \"in-progress\" && count(st) > 0 ? \"text-accent\" : \"text-txt\")}>{count(st)}</span>\n {STATUS_LABEL[st].toLowerCase()}\n </span>\n ))}\n {linked.length > 0 && (\n <span className=\"flex items-center gap-2 border-l border-border pl-4\">\n <span className=\"relative h-1 w-20 overflow-hidden rounded-full bg-border\">\n <span className=\"absolute inset-y-0 left-0 rounded-full bg-teal\" style={{ width: `${(done / linked.length) * 100}%` }} />\n </span>\n <span><span className=\"tabular-nums text-txt\">{done}/{linked.length}</span> tasks</span>\n </span>\n )}\n </div>\n )\n}\n\n/** Amber pill with the drift count; opens the list (closed by default so it never covers the map). */\nfunction AttentionMenu({ drift, onSelect, onApply }: {\n drift: RoadmapDrift[]\n onSelect: (id: string) => void\n onApply: (d: RoadmapDrift) => void\n}) {\n return (\n <details className=\"group relative\">\n <summary className=\"flex h-8 cursor-pointer list-none items-center gap-1.5 rounded-md border border-amber/40 bg-amber/10 px-2.5 text-xs font-medium text-txt hover:bg-amber/15 [&::-webkit-details-marker]:hidden\">\n <AlertTriangle className=\"h-3.5 w-3.5 text-amber\" /> {drift.length} need attention\n </summary>\n <ul className=\"absolute right-0 top-full z-30 mt-1.5 max-h-72 w-80 overflow-y-auto rounded-lg border border-border bg-surface text-xs shadow-xl\">\n {drift.map((d) => (\n <li key={`${d.id}-${d.kind}`} className=\"flex items-start gap-2 border-b border-border px-3 py-2.5 last:border-0\">\n <span className=\"mt-1 h-1.5 w-1.5 shrink-0 rounded-full bg-amber\" />\n <button type=\"button\" onClick={() => onSelect(d.id)} className=\"flex-1 text-left leading-relaxed text-muted hover:text-txt\">\n {d.message}\n </button>\n {d.suggestedStatus && (\n <button\n type=\"button\"\n onClick={() => onApply(d)}\n className=\"shrink-0 rounded-sm border border-border px-1.5 py-0.5 font-mono text-[10px] text-txt hover:border-accent hover:text-accent\"\n title={`Set status to ${d.suggestedStatus}`}\n >\n → {d.suggestedStatus}\n </button>\n )}\n </li>\n ))}\n </ul>\n </details>\n )\n}\n","import createLucideIcon from '../createLucideIcon';\nimport type { LucideIconNode, LucideIconData } from '../types';\n\nexport const __iconData: LucideIconData = {\n name: 'list-tree',\n size: 24,\n node: [\n ['path', { d: 'M8 5h13', key: '1pao27' }],\n ['path', { d: 'M13 12h8', key: 'h98zly' }],\n ['path', { d: 'M13 19h8', key: 'c3s6r1' }],\n ['path', { d: 'M3 10a2 2 0 0 0 2 2h3', key: '1npucw' }],\n ['path', { d: 'M3 5v12a2 2 0 0 0 2 2h3', key: 'x1gjn2' }],\n ],\n};\n\n/**\n * @deprecated Access `__iconData` instead.\n */\nexport const __iconNode: LucideIconNode[] = __iconData.node;\n\n/**\n * @component @name ListTree\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/list-tree\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst ListTree = createLucideIcon(__iconData);\n\nexport default ListTree;\n","// Pure next-task picker for an epic's work queue (no fs). Self-check: node src/lib/work-queue.check.mts\nimport type { RoadmapItem, Task } from './core'\n\nexport type QueueTask = Pick<Task, 'id' | 'status' | 'dependsOn'>\nexport type QueueResult =\n | { kind: 'ready'; taskId: string }\n | { kind: 'finished' }\n // needsHuman: no remaining task can move without someone unblocking or creating a task\n | { kind: 'waiting'; waiting: { taskId: string; reason: string }[]; needsHuman: boolean }\n\n/** Every `T\\d+` in a free-text \"Depends on\" line: \"T008, T009 (x)\" → [\"T008\",\"T009\"]. */\nexport function depIds(dependsOn: string): string[] {\n return [...new Set((dependsOn.match(/\\bT\\d+\\b/gi) ?? []).map(d => d.toUpperCase()))]\n}\n\nconst settled = (s: Task['status']) => s === 'done' || s === 'cancelled'\n\nexport function pickNextTask(epic: RoadmapItem, tasks: QueueTask[]): QueueResult {\n const byId = new Map(tasks.map(t => [t.id, t]))\n const linked = epic.tasks.map(id => byId.get(id)).filter((t): t is QueueTask => !!t)\n const unmet = (t: QueueTask) => depIds(t.dependsOn).filter(d => {\n const dep = byId.get(d)\n return !dep || !settled(dep.status)\n })\n\n for (const t of linked) {\n if (t.status === 'todo' && !unmet(t).length) return { kind: 'ready', taskId: t.id }\n }\n if (linked.every(t => settled(t.status))) return { kind: 'finished' }\n\n // Can this task still move without a human? in-progress/settled yes; blocked/missing no;\n // todo only if it's in this epic (the queue never hands out outside tasks) and every unmet dep can.\n // Cycles count as stuck.\n const inEpic = new Set(epic.tasks)\n const memo = new Map<string, boolean>()\n const canMove = (id: string): boolean => {\n if (memo.has(id)) return memo.get(id) ?? false\n memo.set(id, false)\n const t = byId.get(id)\n const ok = !!t && t.status !== 'blocked' && (t.status !== 'todo' || (inEpic.has(id) && unmet(t).every(canMove)))\n memo.set(id, ok)\n return ok\n }\n\n const waiting: { taskId: string; reason: string }[] = []\n for (const id of epic.tasks) {\n const t = byId.get(id)\n if (!t) waiting.push({ taskId: id, reason: `${id} has no task file` })\n else if (t.status === 'in-progress') waiting.push({ taskId: id, reason: `${id} is in progress (claimed)` })\n else if (t.status === 'blocked') waiting.push({ taskId: id, reason: `${id} is blocked` })\n else if (t.status === 'todo') {\n const deps = unmet(t).map(d => `${d} (${byId.get(d)?.status ?? 'missing'})`)\n waiting.push({ taskId: id, reason: `${id} waits on ${deps.join(', ')}` })\n }\n }\n return { kind: 'waiting', waiting, needsHuman: waiting.every(w => !canMove(w.taskId)) }\n}\n"],"names":["__iconData","name","d","node"],"mappings":"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","ignoreList":[7]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
module.exports=[685698,429672,107742,a=>{"use strict";var b=a.i(662145),c=a.i(174897),d=a.i(913975),e=a.i(544394),f=a.i(368114);function g(a){return Array.isArray(a)&&a.length>0&&a.every(a=>!!a&&"object"==typeof a&&"string"==typeof a.question&&"string"==typeof a.header&&Array.isArray(a.options)&&a.options.every(a=>!!a&&"object"==typeof a&&"string"==typeof a.label))}let h="\0other";function i(a,b){return["Answers:",...a.map((a,c)=>`- ${a.header}: ${b[c]}`)].join("\n")}a.s(["QuestionCard",0,function({set:a,disabled:d,onSubmit:e}){let[g,i]=(0,c.useState)(()=>a.questions.map(()=>[])),[j,k]=(0,c.useState)(()=>a.questions.map(()=>"")),l=!!a.answers,m=a.questions.map((a,b)=>{let c=a.options.map(a=>a.label).filter(a=>g[b].includes(a));return g[b].includes(h)&&j[b].trim()&&c.push(`Other: "${j[b].trim()}"`),c.join(", ")}),n=m.every(Boolean);return(0,b.jsxs)("div",{className:"my-2 rounded-md border border-border overflow-hidden","data-question-card":!0,children:[(0,b.jsxs)("div",{className:"flex items-center gap-2 px-2 py-1.5 bg-surface2 border-b border-border",children:[(0,b.jsx)("span",{className:"text-[10px] font-mono uppercase tracking-widest text-muted",children:"Questions"}),l&&(0,b.jsx)("span",{className:"ml-auto text-[10px] font-mono text-accent",children:"✓ Answered"})]}),(0,b.jsxs)("div",{className:"p-2 space-y-3",children:[a.questions.map((c,d)=>(0,b.jsxs)("fieldset",{disabled:l,className:"space-y-1",children:[(0,b.jsxs)("legend",{className:"mb-1",children:[(0,b.jsx)("span",{className:"text-[10px] font-mono px-1.5 py-0.5 rounded-sm bg-surface2 border border-border text-accent mr-1.5",children:c.header}),(0,b.jsx)("span",{className:"text-xs text-txt",children:c.question})]}),l?(0,b.jsx)("p",{className:"text-xs text-txt pl-1",children:a.answers?.[d]}):(0,b.jsxs)(b.Fragment,{children:[[...c.options,{label:"Other",value:h}].map(e=>{let h="value"in e?e.value:e.label,j=g[d].includes(h);return(0,b.jsxs)("label",{className:(0,f.cn)("flex gap-2 items-start rounded-sm px-1 py-0.5 cursor-pointer hover:bg-surface2",j&&"bg-surface2"),children:[(0,b.jsx)("input",{type:c.multiSelect?"checkbox":"radio",name:`${a.id}-${d}`,checked:j,onChange:()=>{var a;return a=c.multiSelect,void i(b=>b.map((b,c)=>c!==d?b:a?b.includes(h)?b.filter(a=>a!==h):[...b,h]:[h]))},className:"mt-0.5 accent-accent"}),(0,b.jsxs)("span",{className:"text-xs",children:[(0,b.jsx)("span",{className:"text-txt",children:e.label}),"description"in e&&e.description&&(0,b.jsx)("span",{className:"block text-muted",children:e.description})]})]},h)}),g[d].includes(h)&&(0,b.jsx)("input",{value:j[d],onChange:a=>k(b=>b.map((b,c)=>c===d?a.target.value:b)),placeholder:"Your answer","aria-label":`Other answer for ${c.header}`,className:"ml-6 w-[calc(100%-1.5rem)] rounded-sm bg-surface2 border border-border px-2 py-1 text-xs text-txt placeholder:text-muted focus:outline-hidden focus:border-accent"})]})]},d)),!l&&(0,b.jsx)("button",{onClick:()=>e(m),disabled:!n||d,className:"text-xs px-2 py-0.5 rounded-sm bg-accent/20 text-accent hover:bg-accent/30 disabled:opacity-50",children:"Submit"})]})]})},"formatAnswers",0,i,"isRenderableQuestions",0,g],429672);let j=a=>!!a&&"object"==typeof a&&!Array.isArray(a),k=a=>"string"==typeof a?a.trim():"";var l=a.i(525395);function m(a,b=Math.random()){return`c-${a.toString(36)}${b.toString(36).slice(2,6)}`}function n(a,b,c={}){var d;let e=c.now??new Date().toISOString();return[...a,{id:b,title:c.title??(c.attach?"epic"===(d=c.attach).kind?`Epic ${d.id}`:`Task ${d.id}`:"New chat"),messages:[],sessionId:null,busy:!1,notes:[],attach:c.attach??null,createdAt:e,updatedAt:e}]}function o(a,b,c){return a.map(a=>a.id===b?c(a):a)}function p(a){return a.messages.reduce((a,b)=>a+b.plans.filter(a=>"pending"===a.status).length+b.proposals.filter(a=>"pending"===a.status).length,0)}function q(a){if(a.busy)return"running";let b=a.messages[a.messages.length-1];if(b?.questions.some(a=>!a.answers))return"needs-answer";if(p(a))return"review";let c=a.messages.findLast(a=>"assistant"===a.role);return c?.error?"error":"idle"}let r=a=>"needs-answer"===a||"review"===a;function s(a,b,c={}){if((c.running??a.filter(a=>a.busy).length)>=4)return{refused:"Too many agents running (4). Stop or close a chat, or wait."};let d=a.find(a=>a.id===b);return!d||d.busy||c.newChat?{newChat:!0}:{chatId:d.id}}let t=a=>`${a.kind}:${a.id}`;function u(a){return a.trim().match(/^Break down epic (R\d+)/i)?.[1].toUpperCase()??null}function v(a,b){return a.filter(a=>{let c;return c=a.attach,!!c&&!!b&&c.kind===b.kind&&c.id===b.id}).sort((a,b)=>b.updatedAt.localeCompare(a.updatedAt))[0]}let w={running:3,"needs-answer":2,review:1};function x(a){let b={};for(let c of a){let a=q(c);if(!c.attach||"idle"===a||"error"===a)continue;let d=t(c.attach),e=b[d];(!e||w[a]>w[e.status])&&(b[d]={status:a,chatId:c.id})}return b}function y(a){return"epic"===a.kind?`[This chat is about epic ${a.id}. Read it with vibedoc_get_roadmap (and its tasks with vibedoc_get_task) before answering.]`:`[This chat is about task ${a.id}. Read it with vibedoc_get_task before answering.]`}function z(a){let b=[...a].sort((a,b)=>b.updatedAt.localeCompare(a.updatedAt)),c={needsYou:[],running:[],recent:[]};for(let a of b){let b=q(a);r(b)?c.needsYou.push(a):"running"===b?c.running.push(a):c.recent.push(a)}return c}function A(a){let b=z(a);return b.needsYou[0]??b.running[0]??b.recent[0]}function B(a){return a.messages.length?{...a,busy:!1}:null}function C(a){if(!a||"string"!=typeof a.id||!Array.isArray(a.messages))return null;let b=a.messages[a.messages.length-1],c=b?.role!=="assistant"||b.text||b.error||b.tools?.length||b.plans?.length||b.proposals?.length||b.questions?.length?a.messages:[...a.messages.slice(0,-1),{...b,error:"Interrupted: the page reloaded while the agent was working."}],d=a.updatedAt??a.createdAt??new Date(0).toISOString();return{...a,messages:c,busy:!1,notes:a.notes??[],attach:a.attach??null,createdAt:a.createdAt??d,updatedAt:d}}function D(a,b){return b.flatMap(b=>{let c=q(b);return r(c)&&a[b.id]!==c?[{chat:b,status:c}]:[]})}function E(a,b){let c=a.replace(/^\(\d+\) /,"");return b>0?`(${b}) ${c}`:c}function F(a){let b=u(a);if(b)return`Break down ${b}`;let c=a.trim().split("\n")[0];return c.length>40?`${c.slice(0,40).trimEnd()}…`:c}a.s(["MAX_RUNNING_CHATS",0,4,"STATUS_LABEL",0,{running:"Running","needs-answer":"Waiting for your answers",review:"Plan or edit to review",error:"Error",idle:"Idle"},"addChat",0,n,"ago",0,function(a,b){let c=Math.max(0,Math.floor((b-Date.parse(a))/6e4));return c<1?"now":c<60?`${c}m`:c<1440?`${Math.floor(c/60)}h`:`${Math.floor(c/1440)}d`},"attachContext",0,y,"attachKey",0,t,"chatFor",0,v,"chatStatus",0,q,"chatTitle",0,F,"defaultChat",0,A,"epicOf",0,u,"fromSaved",0,C,"groupChats",0,z,"isWaiting",0,r,"itemAgents",0,x,"newChatId",0,m,"newlyWaiting",0,D,"patchChat",0,o,"pendingReviews",0,p,"routeAsk",0,s,"suggestions",0,function(a){return a?"epic"===a.kind?[`Break down epic ${a.id} into tasks.`,"Summarize this epic's progress.","What is at risk in this epic?"]:["Refine this task's spec.","Split this task into smaller tasks.","What blocks this task?"]:["What should I work on next?","Plan a roadmap for this project.","What is blocked right now?"]},"toSaved",0,B,"waitingTitle",0,E],107742);let G=(a,b="")=>({role:a,text:b,tools:[],proposals:[],plans:[],questions:[]}),H=(0,c.createContext)(null),I=(0,c.createContext)({});a.s(["ChatProvider",0,function({children:a}){let{rootParam:f,activeProject:h,selectedDoc:t}=(0,e.useApp)(),w=(0,d.usePathname)(),z=(0,d.useRouter)(),[J,K]=(0,c.useState)([]),[L,M]=(0,c.useState)(!1),[N,O]=(0,c.useState)(null),[P,Q]=(0,c.useState)(null),[R,S]=(0,c.useState)(null),T=(0,c.useRef)(new Map),U=(0,c.useRef)(new Set),V=(0,c.useRef)({}),W="/chat"===w,X="/docs"===w?t?.path:void 0;(0,c.useEffect)(()=>{for(let a of T.current.values())a.abort();T.current.clear(),U.current.clear();let a=!1;return fetch(`/api/conversations${f}`).then(a=>a.ok?a.json():{chats:[]}).then(b=>{if(a)return;let c=(b.chats??[]).map(a=>C(a)).filter(a=>!!a);V.current=Object.fromEntries(c.map(a=>[a.id,q(a)])),K(c),O(null),Q(null),M(!0)}).catch(b=>{console.warn("[vibedoc] could not load chats:",b),a||(K([]),M(!0))}),()=>{a=!0}},[h,f]),(0,c.useEffect)(()=>{for(let a of[...U.current]){let b=J.find(b=>b.id===a);U.current.delete(a);let c=b&&B(b);c&&fetch(`/api/conversations${f}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({chat:c})}).catch(b=>console.warn(`[vibedoc] could not save chat ${a}:`,b))}},[J,f]);let Y=(0,c.useRef)({key:"{}",value:{}}),Z=(0,c.useMemo)(()=>{let a=x(J),b=JSON.stringify(a);return b!==Y.current.key&&(Y.current={key:b,value:a}),Y.current.value},[J]),$=J.filter(a=>a.busy).length,_=J.filter(a=>r(q(a))).length;function aa(a){U.current.add(a)}function ab(a){Q(a),W?(O(null),z.replace(`/chat?id=${encodeURIComponent(a)}`,{scroll:!1})):O(a)}function ac(a=null){let b=m(Date.now());return K(c=>n(c,b,{attach:a})),b}function ad(a,b){K(c=>o(c,a,a=>({...a,messages:[...a.messages.slice(0,-1),b(a.messages[a.messages.length-1])]})))}async function ae(a,b){let c=b.trim(),d=J.find(b=>b.id===a);if(!c||d?.busy)return;"Notification"in window&&"default"===Notification.permission&&Notification.requestPermission().catch(()=>{});let e=!d?.messages.length,h=u(c),i=d?.attach??(h?{kind:"epic",id:h}:null);K(b=>o(b,a,a=>({...a,title:a.messages.length?a.title:F(c),attach:a.attach??i,busy:!0,notes:[],updatedAt:new Date().toISOString(),messages:[...a.messages,G("user",c),G("assistant")]}))),aa(a);let k=[...e&&d?.attach?[y(d.attach)]:[],...d?.notes.length?[`[${d.notes.join(" ")}]`]:[]],l=k.length?`${k.join("\n")}
|
|
2
|
+
|
|
3
|
+
${c}`:c,m=new AbortController;T.current.set(a,m);try{let b=await fetch(`/api/chat${f}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:l,sessionId:d?.sessionId??null,docPath:X}),signal:m.signal});if(!b.ok||!b.body){let a=await b.json().catch(()=>null);throw Error(a?.error??`Request failed (${b.status})`)}let c=b.body.getReader(),e=new TextDecoder,h="";for(;;){let{done:b,value:d}=await c.read();if(b)break;let f=(h+=e.decode(d,{stream:!0})).split("\n");for(let b of(h=f.pop()??"",f))if(b.trim())try{!function(a,b){if(b.session_id&&K(c=>o(c,a,a=>a.sessionId===b.session_id?a:{...a,sessionId:b.session_id})),"stream_event"===b.type){let c=b.event;c?.type==="message_start"?ad(a,a=>a.text&&!a.text.endsWith("\n\n")?{...a,text:a.text+"\n\n"}:a):c?.type==="content_block_delta"&&c.delta?.type==="text_delta"&&ad(a,a=>({...a,text:a.text+c.delta.text}))}else if("assistant"===b.type){let c=(b.message?.content??[]).filter(a=>"tool_use"===a.type),d=c.filter(a=>a.name.endsWith("vibedoc_propose_edit")&&"string"==typeof a.input?.path&&Array.isArray(a.input?.edits)).map(a=>({id:a.id,path:a.input.path,edits:a.input.edits,summary:"string"==typeof a.input.summary?a.input.summary:void 0,status:"pending"})),e=c.filter(a=>a.name.endsWith("vibedoc_propose_plan")).flatMap(a=>{let b=function(a){if(!j(a))return null;let b=(a,b)=>Array.isArray(a)&&a.every(a=>j(a)&&b.every(b=>"string"==typeof a[b])&&(void 0===a.dependsOn||Array.isArray(a.dependsOn)));if("breakdown"===a.kind){let c=void 0===a.epic||"string"==typeof a.epic,d=void 0===a.newEpic||j(a.newEpic)&&"string"==typeof a.newEpic.title&&"string"==typeof a.newEpic.parent;return c&&d&&b(a.tasks,["key","title"])&&a.tasks.length>0?a:null}if("roadmap"===a.kind){let c=a.horizons??[],d=a.epics??[];return b(c,["key","title"])&&b(d,["key","title","parent"])?{kind:"roadmap",horizons:c,epics:d}:null}return null}(a.input?.plan);return b?[{id:a.id,plan:b,status:"pending"}]:[]}),f=c.filter(a=>a.name.endsWith("vibedoc_ask_questions")&&g(a.input?.questions)).map(a=>({id:a.id,questions:a.input.questions})),h=["vibedoc_propose_edit","vibedoc_propose_plan","vibedoc_ask_questions"],i=c.filter(a=>!h.some(b=>a.name.endsWith(b))).map(a=>a.name.replace(/^mcp__vibedoc__vibedoc_/,""));(i.length||d.length||e.length||f.length)&&ad(a,a=>({...a,tools:[...a.tools,...i],proposals:[...a.proposals,...d],plans:[...a.plans,...e],questions:[...a.questions,...f]}))}else if("user"===b.type){let c=new Set((b.message?.content??[]).filter(a=>"tool_result"===a.type&&a.is_error).map(a=>a.tool_use_id));c.size&&ad(a,a=>({...a,proposals:a.proposals.filter(a=>!c.has(a.id)),plans:a.plans.filter(a=>!c.has(a.id)),questions:a.questions.filter(a=>!c.has(a.id))}))}else"result"===b.type&&b.is_error?ad(a,a=>({...a,error:b.result??b.subtype??"Agent error"})):"error"===b.type&&ad(a,a=>({...a,error:b.message}))}(a,JSON.parse(b))}catch{}}}catch(b){m.signal.aborted?ad(a,a=>a.text||a.error?a:{...a,error:"Stopped."}):ad(a,a=>({...a,error:b.message}))}finally{T.current.get(a)===m&&(T.current.delete(a),aa(a)),K(b=>o(b,a,a=>({...a,busy:!1,updatedAt:new Date().toISOString()})))}}function af(a){T.current.get(a)?.abort()}function ag(a,b,c){K(d=>o(d,a,a=>({...a,notes:c?[...a.notes,c]:a.notes,messages:a.messages.map(b)}))),aa(a)}return(0,c.useEffect)(()=>{document.title=E(document.title,_)},[_,w]),(0,c.useEffect)(()=>{let a=D(V.current,J);if(V.current=Object.fromEntries(J.map(a=>[a.id,q(a)])),a.length&&document.hidden&&"Notification"in window&&"granted"===Notification.permission)for(let{chat:b,status:c}of a){let a=new Notification("needs-answer"===c?"Agent needs your answer":"Plan ready to review",{body:b.title,tag:b.id});a.onclick=()=>{window.focus(),(0,l.openAgentChat)(b.id),a.close()}}},[J]),(0,c.useEffect)(()=>{function a(a){let{message:b,newChat:c}=a.detail??{};if(!b)return;let d=s(J,P,{newChat:c,running:T.current.size});if("refused"in d)return S(d.refused);S(null);let e=u(b),f="chatId"in d?d.chatId:ac(e?{kind:"epic",id:e}:null);ae(f,b),c||ab(f)}function b(a){let b=a.detail?.chatId;b&&J.some(a=>a.id===b)&&ab(b)}return window.addEventListener(l.ASK_AGENT_EVENT,a),window.addEventListener(l.OPEN_CHAT_EVENT,b),()=>{window.removeEventListener(l.ASK_AGENT_EVENT,a),window.removeEventListener(l.OPEN_CHAT_EVENT,b)}}),(0,b.jsx)(H.Provider,{value:{chats:J,loaded:L,modalId:N,closeModal:function(a={}){a.keep||K(a=>a.filter(a=>a.id!==N||a.messages.length>0)),O(null)},show:ab,showDefault:function(){let a=A(J);ab(a?a.id:ac())},showAbout:function(a){let b=v(J,a);ab(b?b.id:ac(a))},create:ac,send:ae,stop:af,remove:function(a){let b=J.find(b=>b.id===a),c=b?p(b):0;return(!c||!!window.confirm(`Discard ${c} unreviewed proposal${1===c?"":"s"}?`))&&(af(a),T.current.delete(a),U.current.delete(a),K(b=>b.filter(b=>b.id!==a)),N===a&&O(null),P===a&&Q(null),fetch(`/api/conversations${f}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({delete:a})}).catch(b=>console.warn(`[vibedoc] could not delete chat ${a}:`,b)),!0)},resolveProposal:function(a,b,c,d){ag(a,a=>({...a,proposals:a.proposals.map(a=>a.id===b?{...a,status:d}:a)}),`User ${d} your proposed edit to ${c}.`)},resolvePlan:function(a,b,c,d,e){var f;let g="breakdown"===b.plan.kind?k((f=b.plan).epic)?k(f.epic).toUpperCase():f.newEpic?`new epic "${k(f.newEpic.title)}"`:"no epic":"the roadmap";ag(a,a=>({...a,plans:a.plans.map(a=>a.id===b.id?{...a,status:c,created:d}:a)}),"accepted"===c?`User accepted plan for ${g}: created ${d.map(a=>a.id).join(", ")}${e.length?` (unchecked: ${e.join(", ")})`:""}.`:`User rejected the plan for ${g}.`)},answerQuestions:function(a,b,c){J.find(b=>b.id===a)?.busy||(ag(a,a=>({...a,questions:a.questions.map(a=>a.id===b.id?{...a,answers:c}:a)})),ae(a,i(b.questions,c)))},agents:Z,runningCount:$,waitingCount:_,notice:R,dismissNotice:()=>S(null)},children:(0,b.jsx)(I.Provider,{value:Z,children:a})})},"useChats",0,function(){let a=(0,c.useContext)(H);if(!a)throw Error("useChats() must be used inside <ChatProvider>");return a},"useItemAgent",0,function(a){return(0,c.useContext)(I)[t(a)]}],685698)}];
|
|
4
|
+
|
|
5
|
+
//# sourceMappingURL=src_context_ChatContext_tsx_0lowp8p._.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/context/ChatContext.tsx","../../../../src/components/chat/QuestionCard.tsx","../../../../src/lib/plan.ts","../../../../src/lib/chats.ts"],"sourcesContent":["\"use client\"\n\n/**\n * Agent chats: one store for the sidebar list, the chat modal, the /chat page and the roadmap/board markers.\n * Each chat is its own `claude -p` session (POST /api/chat per turn); chats are saved to\n * .vibedoc/chats/<id>.json (/api/conversations) at turn end, card resolution and attach changes.\n */\n\nimport { createContext, useContext, useEffect, useMemo, useRef, useState, type ReactNode } from \"react\"\nimport { usePathname, useRouter } from \"next/navigation\"\nimport { useApp } from \"@/context/AppContext\"\nimport type { Proposal, ProposalStatus } from \"@/components/chat/ProposalCard\"\nimport type { PlanCreated, PlanProposal, PlanStatus } from \"@/components/chat/PlanCard\"\nimport { formatAnswers, isRenderableQuestions, type Question, type QuestionSet } from \"@/components/chat/QuestionCard\"\nimport { asRenderablePlan, planTarget } from \"@/lib/plan\"\nimport type { TextEdit } from \"@/lib/diff\"\nimport { ASK_AGENT_EVENT, OPEN_CHAT_EVENT, openAgentChat, type AskAgentDetail } from \"@/lib/ask-agent\"\nimport {\n addChat, attachContext, attachKey, chatFor, chatStatus, chatTitle, defaultChat, epicOf, fromSaved, isWaiting,\n itemAgents, newChatId, newlyWaiting, patchChat, pendingReviews, routeAsk, toSaved, waitingTitle,\n type Attach, type Chat, type ChatStatus, type ItemAgent,\n} from \"@/lib/chats\"\n\nexport interface ChatMessage {\n role: \"user\" | \"assistant\"\n text: string\n tools: string[]\n proposals: Proposal[]\n plans: PlanProposal[]\n questions: QuestionSet[]\n error?: string\n}\n\nexport type ChatTab = Chat<ChatMessage>\n\nconst blank = (role: ChatMessage[\"role\"], text = \"\"): ChatMessage =>\n ({ role, text, tools: [], proposals: [], plans: [], questions: [] })\n\ninterface ChatApi {\n chats: ChatTab[]\n loaded: boolean\n /** Chat shown in the modal; null = closed */\n modalId: string | null\n /** keep: don't drop an empty chat (it is moving to the /chat page) */\n closeModal: (opts?: { keep?: boolean }) => void\n /** Open a chat: in the modal, or selected in place when already on /chat */\n show: (chatId: string) => void\n /** Header button / `c`: the most urgent or newest chat, else a fresh one */\n showDefault: () => void\n /** Resume the chat attached to `a`, or start one */\n showAbout: (a: Attach) => void\n /** A new empty chat (not saved until its first message); returns its id */\n create: (attach?: Attach | null) => string\n send: (chatId: string, text: string) => void\n stop: (chatId: string) => void\n /** Delete a chat (asks first when cards are unreviewed); returns false if the user cancelled */\n remove: (chatId: string) => boolean\n resolveProposal: (chatId: string, id: string, path: string, status: ProposalStatus) => void\n resolvePlan: (chatId: string, p: PlanProposal, status: PlanStatus, created: PlanCreated[], unchecked: string[]) => void\n answerQuestions: (chatId: string, set: QuestionSet, answers: string[]) => void\n /** attachKey → the most urgent chat working on that epic/task */\n agents: Record<string, ItemAgent>\n runningCount: number\n waitingCount: number\n /** An askAgent() refused at the running-chat cap */\n notice: string | null\n dismissNotice: () => void\n}\n\nconst ChatContext = createContext<ChatApi | null>(null)\n// Split out so roadmap nodes and board cards re-render only when some item's status flips, not per stream delta\nconst ItemAgentsContext = createContext<Record<string, ItemAgent>>({})\n\nexport function useChats(): ChatApi {\n const ctx = useContext(ChatContext)\n if (!ctx) throw new Error(\"useChats() must be used inside <ChatProvider>\")\n return ctx\n}\n\n/** The chat working on an epic/task, if any (roadmap nodes, sheets, board cards). */\nexport function useItemAgent(a: Attach): ItemAgent | undefined {\n return useContext(ItemAgentsContext)[attachKey(a)]\n}\n\nexport function ChatProvider({ children }: { children: ReactNode }) {\n const { rootParam, activeProject, selectedDoc } = useApp()\n const pathname = usePathname()\n const router = useRouter()\n const [chats, setChats] = useState<ChatTab[]>([])\n const [loaded, setLoaded] = useState(false)\n const [modalId, setModalId] = useState<string | null>(null)\n // The chat last shown (modal or page): where an askAgent() goes when that chat is idle\n const [currentId, setCurrentId] = useState<string | null>(null)\n const [notice, setNotice] = useState<string | null>(null)\n // One in-flight request per chat; a stream only ever writes into the chat id it was started for\n const abortsRef = useRef(new Map<string, AbortController>())\n // Chats changed since their last save; saved by the effect below once they aren't busy\n const dirtyRef = useRef(new Set<string>())\n const notifiedRef = useRef<Record<string, ChatStatus>>({})\n\n const onChatPage = pathname === \"/chat\"\n const docPath = pathname === \"/docs\" ? selectedDoc?.path : undefined\n\n // A Claude session belongs to one project: stop everything and load that project's chats\n useEffect(() => {\n for (const ac of abortsRef.current.values()) ac.abort()\n abortsRef.current.clear()\n dirtyRef.current.clear()\n let cancelled = false\n fetch(`/api/conversations${rootParam}`)\n .then((r) => (r.ok ? r.json() : { chats: [] }))\n .then((d: { chats?: unknown[] }) => {\n if (cancelled) return\n const loadedChats = (d.chats ?? []).map((c) => fromSaved<ChatMessage>(c)).filter((c): c is ChatTab => !!c)\n notifiedRef.current = Object.fromEntries(loadedChats.map((c) => [c.id, chatStatus(c)]))\n setChats(loadedChats)\n setModalId(null)\n setCurrentId(null)\n setLoaded(true)\n })\n .catch((e) => {\n console.warn(\"[vibedoc] could not load chats:\", e)\n if (!cancelled) { setChats([]); setLoaded(true) }\n })\n return () => { cancelled = true }\n }, [activeProject, rootParam])\n\n // Save chats marked dirty: at turn start (so a reload shows it as interrupted), turn end and card resolution.\n // Never per stream delta: nothing marks a chat dirty while it streams.\n useEffect(() => {\n for (const id of [...dirtyRef.current]) {\n const chat = chats.find((c) => c.id === id)\n dirtyRef.current.delete(id)\n const saved = chat && toSaved(chat)\n if (!saved) continue\n fetch(`/api/conversations${rootParam}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ chat: saved }),\n }).catch((e) => console.warn(`[vibedoc] could not save chat ${id}:`, e))\n }\n }, [chats, rootParam])\n\n // Reference-stable while no item's status changes (streaming text changes `chats` many times a second)\n const agentsRef = useRef<{ key: string; value: Record<string, ItemAgent> }>({ key: \"{}\", value: {} })\n const agents = useMemo(() => {\n const next = itemAgents(chats)\n const key = JSON.stringify(next)\n if (key !== agentsRef.current.key) agentsRef.current = { key, value: next }\n return agentsRef.current.value\n }, [chats])\n const runningCount = chats.filter((c) => c.busy).length\n const waitingCount = chats.filter((c) => isWaiting(chatStatus(c))).length\n\n // \"(n) VibeDoc\" in the browser tab; pathname is a dep because a navigation can put Next's metadata title back\n useEffect(() => { document.title = waitingTitle(document.title, waitingCount) }, [waitingCount, pathname])\n\n // Desktop notification when a chat starts waiting while this browser tab is in the background\n useEffect(() => {\n const fresh = newlyWaiting(notifiedRef.current, chats)\n notifiedRef.current = Object.fromEntries(chats.map((c) => [c.id, chatStatus(c)]))\n if (!fresh.length || !document.hidden || !(\"Notification\" in window) || Notification.permission !== \"granted\") return\n for (const { chat, status } of fresh) {\n const n = new Notification(status === \"needs-answer\" ? \"Agent needs your answer\" : \"Plan ready to review\", { body: chat.title, tag: chat.id })\n n.onclick = () => { window.focus(); openAgentChat(chat.id); n.close() }\n }\n }, [chats])\n\n function markDirty(id: string) { dirtyRef.current.add(id) }\n\n // A chat closed before its first message was never saved; drop it so empty chats don't pile up\n function closeModal(opts: { keep?: boolean } = {}) {\n if (!opts.keep) setChats((cs) => cs.filter((c) => c.id !== modalId || c.messages.length > 0))\n setModalId(null)\n }\n\n function show(chatId: string) {\n setCurrentId(chatId)\n if (onChatPage) {\n setModalId(null)\n router.replace(`/chat?id=${encodeURIComponent(chatId)}`, { scroll: false })\n } else {\n setModalId(chatId)\n }\n }\n\n function create(attach: Attach | null = null) {\n const id = newChatId(Date.now())\n setChats((cs) => addChat(cs, id, { attach }))\n return id\n }\n\n function showDefault() {\n const c = defaultChat(chats)\n show(c ? c.id : create())\n }\n\n function showAbout(a: Attach) {\n const c = chatFor(chats, a)\n show(c ? c.id : create(a))\n }\n\n // askAgent() from anywhere: into the current chat when it is idle, otherwise into a new one; then show it.\n // No deps on purpose: re-subscribes each render so the handler sees the current `chats`/`send`.\n useEffect(() => {\n function onAsk(e: Event) {\n const { message, newChat } = (e as CustomEvent<AskAgentDetail>).detail ?? {}\n if (!message) return\n // abortsRef is updated synchronously by send(), so it counts asks fired earlier in this same tick\n const route = routeAsk(chats, currentId, { newChat, running: abortsRef.current.size })\n if (\"refused\" in route) return setNotice(route.refused)\n setNotice(null)\n const epic = epicOf(message)\n const id = \"chatId\" in route ? route.chatId : create(epic ? { kind: \"epic\", id: epic } : null)\n send(id, message)\n // newChat asks (the multi-epic breakdown dialog) run in the background: the sidebar and roadmap show them\n if (!newChat) show(id)\n }\n function onOpen(e: Event) {\n const chatId = (e as CustomEvent<{ chatId: string }>).detail?.chatId\n if (chatId && chats.some((c) => c.id === chatId)) show(chatId)\n }\n window.addEventListener(ASK_AGENT_EVENT, onAsk)\n window.addEventListener(OPEN_CHAT_EVENT, onOpen)\n return () => {\n window.removeEventListener(ASK_AGENT_EVENT, onAsk)\n window.removeEventListener(OPEN_CHAT_EVENT, onOpen)\n }\n })\n\n function patchLast(chatId: string, fn: (m: ChatMessage) => ChatMessage) {\n setChats((cs) => patchChat(cs, chatId, (c) => ({ ...c, messages: [...c.messages.slice(0, -1), fn(c.messages[c.messages.length - 1])] })))\n }\n\n // Handles one line of `claude -p --output-format stream-json` for chat `chatId`\n function handleEvent(chatId: string, ev: any) {\n if (ev.session_id) setChats((cs) => patchChat(cs, chatId, (c) => (c.sessionId === ev.session_id ? c : { ...c, sessionId: ev.session_id })))\n if (ev.type === \"stream_event\") {\n const e = ev.event\n if (e?.type === \"message_start\") {\n patchLast(chatId, (m) => (m.text && !m.text.endsWith(\"\\n\\n\") ? { ...m, text: m.text + \"\\n\\n\" } : m))\n } else if (e?.type === \"content_block_delta\" && e.delta?.type === \"text_delta\") {\n patchLast(chatId, (m) => ({ ...m, text: m.text + e.delta.text }))\n }\n } else if (ev.type === \"assistant\") {\n const uses: { type: string; id: string; name: string; input: Record<string, unknown> }[] =\n (ev.message?.content ?? []).filter((b: { type: string }) => b.type === \"tool_use\")\n const proposals: Proposal[] = uses\n .filter((b) => b.name.endsWith(\"vibedoc_propose_edit\") && typeof b.input?.path === \"string\" && Array.isArray(b.input?.edits))\n .map((b) => ({\n id: b.id,\n path: b.input.path as string,\n edits: b.input.edits as TextEdit[],\n summary: typeof b.input.summary === \"string\" ? b.input.summary : undefined,\n status: \"pending\",\n }))\n // Cards render before the server validates the input, so drop shapes they can't draw instead of crashing\n const plans: PlanProposal[] = uses\n .filter((b) => b.name.endsWith(\"vibedoc_propose_plan\"))\n .flatMap((b) => {\n const plan = asRenderablePlan(b.input?.plan)\n return plan ? [{ id: b.id, plan, status: \"pending\" as const }] : []\n })\n const questions: QuestionSet[] = uses\n .filter((b) => b.name.endsWith(\"vibedoc_ask_questions\") && isRenderableQuestions(b.input?.questions))\n .map((b) => ({ id: b.id, questions: b.input.questions as Question[] }))\n const cards = [\"vibedoc_propose_edit\", \"vibedoc_propose_plan\", \"vibedoc_ask_questions\"]\n const tools = uses\n .filter((b) => !cards.some((c) => b.name.endsWith(c)))\n .map((b) => b.name.replace(/^mcp__vibedoc__vibedoc_/, \"\"))\n if (tools.length || proposals.length || plans.length || questions.length) {\n patchLast(chatId, (m) => ({\n ...m,\n tools: [...m.tools, ...tools],\n proposals: [...m.proposals, ...proposals],\n plans: [...m.plans, ...plans],\n questions: [...m.questions, ...questions],\n }))\n }\n } else if (ev.type === \"user\") {\n // A proposal the server rejected (bad old_string) is retried by the agent; don't show it\n const failed = new Set(\n (ev.message?.content ?? [])\n .filter((b: { type: string; is_error?: boolean }) => b.type === \"tool_result\" && b.is_error)\n .map((b: { tool_use_id: string }) => b.tool_use_id),\n )\n if (failed.size) {\n patchLast(chatId, (m) => ({\n ...m,\n proposals: m.proposals.filter((p) => !failed.has(p.id)),\n plans: m.plans.filter((p) => !failed.has(p.id)),\n questions: m.questions.filter((q) => !failed.has(q.id)),\n }))\n }\n } else if (ev.type === \"result\" && ev.is_error) {\n patchLast(chatId, (m) => ({ ...m, error: ev.result ?? ev.subtype ?? \"Agent error\" }))\n } else if (ev.type === \"error\") {\n patchLast(chatId, (m) => ({ ...m, error: ev.message }))\n }\n }\n\n // `chatId` may be a chat create() just queued, so a missing chat means a fresh one.\n async function send(chatId: string, text: string) {\n const message = text.trim()\n const chat = chats.find((c) => c.id === chatId)\n if (!message || chat?.busy) return\n // Ask once, from this click/Enter (browsers want a user gesture), so waiting chats can notify later\n if (\"Notification\" in window && Notification.permission === \"default\") void Notification.requestPermission().catch(() => {})\n const first = !chat?.messages.length\n const epic = epicOf(message)\n const attach: Attach | null = chat?.attach ?? (epic ? { kind: \"epic\", id: epic } : null)\n setChats((cs) => patchChat(cs, chatId, (c) => ({\n ...c,\n // An attached chat keeps its item title until the first message names what it's for\n title: c.messages.length ? c.title : chatTitle(message),\n attach: c.attach ?? attach,\n busy: true,\n notes: [],\n updatedAt: new Date().toISOString(),\n messages: [...c.messages, blank(\"user\", message), blank(\"assistant\")],\n })))\n markDirty(chatId)\n // Context only for a chat opened from an epic/task (showAbout); an ask like \"Break down epic R004…\" names it already\n const prefix = [\n ...(first && chat?.attach ? [attachContext(chat.attach)] : []),\n ...(chat?.notes.length ? [`[${chat.notes.join(\" \")}]`] : []),\n ]\n const outgoing = prefix.length ? `${prefix.join(\"\\n\")}\\n\\n${message}` : message\n const ac = new AbortController()\n abortsRef.current.set(chatId, ac)\n try {\n const res = await fetch(`/api/chat${rootParam}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ message: outgoing, sessionId: chat?.sessionId ?? null, docPath }),\n signal: ac.signal,\n })\n if (!res.ok || !res.body) {\n const data = await res.json().catch(() => null)\n throw new Error(data?.error ?? `Request failed (${res.status})`)\n }\n const reader = res.body.getReader()\n const decoder = new TextDecoder()\n let buf = \"\"\n for (;;) {\n const { done, value } = await reader.read()\n if (done) break\n buf += decoder.decode(value, { stream: true })\n const lines = buf.split(\"\\n\")\n buf = lines.pop() ?? \"\"\n for (const line of lines) {\n if (!line.trim()) continue\n try { handleEvent(chatId, JSON.parse(line)) } catch { /* partial or non-JSON line */ }\n }\n }\n } catch (e) {\n if (!ac.signal.aborted) patchLast(chatId, (m) => ({ ...m, error: (e as Error).message }))\n else patchLast(chatId, (m) => (m.text || m.error ? m : { ...m, error: \"Stopped.\" }))\n } finally {\n // Only save a turn that is still ours: a project switch or delete clears the map first,\n // and saving then would write this chat into the next project (or resurrect a deleted one)\n if (abortsRef.current.get(chatId) === ac) {\n abortsRef.current.delete(chatId)\n markDirty(chatId)\n }\n setChats((cs) => patchChat(cs, chatId, (c) => ({ ...c, busy: false, updatedAt: new Date().toISOString() })))\n }\n }\n\n // Aborting the fetch makes /api/chat kill its `claude -p` child\n function stop(chatId: string) {\n abortsRef.current.get(chatId)?.abort()\n }\n\n function remove(chatId: string) {\n const chat = chats.find((c) => c.id === chatId)\n const n = chat ? pendingReviews(chat) : 0\n if (n && !window.confirm(`Discard ${n} unreviewed proposal${n === 1 ? \"\" : \"s\"}?`)) return false\n stop(chatId)\n abortsRef.current.delete(chatId)\n dirtyRef.current.delete(chatId)\n // Functional update so a stream chunk queued since this render isn't dropped from the other chats\n setChats((cs) => cs.filter((c) => c.id !== chatId))\n if (modalId === chatId) setModalId(null)\n if (currentId === chatId) setCurrentId(null)\n fetch(`/api/conversations${rootParam}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ delete: chatId }),\n }).catch((e) => console.warn(`[vibedoc] could not delete chat ${chatId}:`, e))\n return true\n }\n\n function mapMessages(chatId: string, fn: (m: ChatMessage) => ChatMessage, note?: string) {\n setChats((cs) => patchChat(cs, chatId, (c) => ({\n ...c,\n notes: note ? [...c.notes, note] : c.notes,\n messages: c.messages.map(fn),\n })))\n markDirty(chatId)\n }\n\n function resolveProposal(chatId: string, id: string, path: string, status: ProposalStatus) {\n mapMessages(chatId, (m) => ({\n ...m,\n proposals: m.proposals.map((p) => (p.id === id ? { ...p, status } : p)),\n }), `User ${status} your proposed edit to ${path}.`)\n }\n\n function resolvePlan(chatId: string, p: PlanProposal, status: PlanStatus, created: PlanCreated[], unchecked: string[]) {\n const epic = p.plan.kind === \"breakdown\" ? planTarget(p.plan) : \"the roadmap\"\n mapMessages(chatId, (m) => ({\n ...m,\n plans: m.plans.map((x) => (x.id === p.id ? { ...x, status, created } : x)),\n }), status === \"accepted\"\n ? `User accepted plan for ${epic}: created ${created.map((c) => c.id).join(\", \")}${unchecked.length ? ` (unchecked: ${unchecked.join(\", \")})` : \"\"}.`\n : `User rejected the plan for ${epic}.`)\n }\n\n function answerQuestions(chatId: string, set: QuestionSet, answers: string[]) {\n if (chats.find((c) => c.id === chatId)?.busy) return\n mapMessages(chatId, (m) => ({\n ...m,\n questions: m.questions.map((q) => (q.id === set.id ? { ...q, answers } : q)),\n }))\n send(chatId, formatAnswers(set.questions, answers))\n }\n\n const api: ChatApi = {\n chats, loaded, modalId,\n closeModal,\n show, showDefault, showAbout, create, send, stop, remove,\n resolveProposal, resolvePlan, answerQuestions,\n agents, runningCount, waitingCount,\n notice, dismissNotice: () => setNotice(null),\n }\n return (\n <ChatContext.Provider value={api}>\n <ItemAgentsContext.Provider value={agents}>{children}</ItemAgentsContext.Provider>\n </ChatContext.Provider>\n )\n}\n","\"use client\"\n\nimport { useState } from \"react\"\nimport { cn } from \"@/lib/utils\"\n\nexport interface QuestionOption { label: string; description?: string }\nexport interface Question { question: string; header: string; multiSelect: boolean; options: QuestionOption[] }\n\nexport interface QuestionSet {\n id: string\n questions: Question[]\n /** Set once submitted: one answer string per question, in the same order */\n answers?: string[]\n}\n\n/** Just enough shape to render, checked before the server has validated the tool input. */\nexport function isRenderableQuestions(v: unknown): v is Question[] {\n const isStr = (x: unknown) => typeof x === \"string\"\n return Array.isArray(v) && v.length > 0 && v.every((q) =>\n !!q && typeof q === \"object\" && isStr(q.question) && isStr(q.header) && Array.isArray(q.options) &&\n q.options.every((o: unknown) => !!o && typeof o === \"object\" && isStr((o as QuestionOption).label)))\n}\n\nconst OTHER = \"\\u0000other\"\n\n/** Answer message format the agent parses: one line per question, keyed by header, labels verbatim. */\nexport function formatAnswers(questions: Question[], answers: string[]): string {\n return [\"Answers:\", ...questions.map((q, i) => `- ${q.header}: ${answers[i]}`)].join(\"\\n\")\n}\n\nexport function QuestionCard({ set, disabled, onSubmit }: {\n set: QuestionSet\n disabled?: boolean\n onSubmit: (answers: string[]) => void\n}) {\n const [picked, setPicked] = useState<string[][]>(() => set.questions.map(() => []))\n const [other, setOther] = useState<string[]>(() => set.questions.map(() => \"\"))\n const done = !!set.answers\n\n function toggle(qi: number, value: string, multi: boolean) {\n setPicked((prev) => prev.map((p, i) => {\n if (i !== qi) return p\n if (!multi) return [value]\n return p.includes(value) ? p.filter((v) => v !== value) : [...p, value]\n }))\n }\n\n // Keep the order the options were offered in, with Other last\n const answers = set.questions.map((q, i) => {\n const labels = q.options.map((o) => o.label).filter((l) => picked[i].includes(l))\n if (picked[i].includes(OTHER) && other[i].trim()) labels.push(`Other: \"${other[i].trim()}\"`)\n return labels.join(\", \")\n })\n const complete = answers.every(Boolean)\n\n return (\n <div className=\"my-2 rounded-md border border-border overflow-hidden\" data-question-card>\n <div className=\"flex items-center gap-2 px-2 py-1.5 bg-surface2 border-b border-border\">\n <span className=\"text-[10px] font-mono uppercase tracking-widest text-muted\">Questions</span>\n {done && <span className=\"ml-auto text-[10px] font-mono text-accent\">✓ Answered</span>}\n </div>\n <div className=\"p-2 space-y-3\">\n {set.questions.map((q, qi) => (\n <fieldset key={qi} disabled={done} className=\"space-y-1\">\n <legend className=\"mb-1\">\n <span className=\"text-[10px] font-mono px-1.5 py-0.5 rounded-sm bg-surface2 border border-border text-accent mr-1.5\">{q.header}</span>\n <span className=\"text-xs text-txt\">{q.question}</span>\n </legend>\n {done ? (\n <p className=\"text-xs text-txt pl-1\">{set.answers?.[qi]}</p>\n ) : (\n <>\n {[...q.options, { label: \"Other\", value: OTHER }].map((o) => {\n const value = \"value\" in o ? o.value : o.label\n const checked = picked[qi].includes(value)\n return (\n <label key={value} className={cn(\"flex gap-2 items-start rounded-sm px-1 py-0.5 cursor-pointer hover:bg-surface2\", checked && \"bg-surface2\")}>\n <input\n type={q.multiSelect ? \"checkbox\" : \"radio\"}\n name={`${set.id}-${qi}`}\n checked={checked}\n onChange={() => toggle(qi, value, q.multiSelect)}\n className=\"mt-0.5 accent-accent\"\n />\n <span className=\"text-xs\">\n <span className=\"text-txt\">{o.label}</span>\n {\"description\" in o && o.description && <span className=\"block text-muted\">{o.description}</span>}\n </span>\n </label>\n )\n })}\n {picked[qi].includes(OTHER) && (\n <input\n value={other[qi]}\n onChange={(e) => setOther((prev) => prev.map((v, i) => (i === qi ? e.target.value : v)))}\n placeholder=\"Your answer\"\n aria-label={`Other answer for ${q.header}`}\n className=\"ml-6 w-[calc(100%-1.5rem)] rounded-sm bg-surface2 border border-border px-2 py-1 text-xs text-txt placeholder:text-muted focus:outline-hidden focus:border-accent\"\n />\n )}\n </>\n )}\n </fieldset>\n ))}\n {!done && (\n <button\n onClick={() => onSubmit(answers)}\n disabled={!complete || disabled}\n className=\"text-xs px-2 py-0.5 rounded-sm bg-accent/20 text-accent hover:bg-accent/30 disabled:opacity-50\"\n >\n Submit\n </button>\n )}\n </div>\n </div>\n )\n}\n","// Pure plan model for \"plan from the chat\": the agent proposes, the user reviews, the server applies.\n// No fs here; core.applyPlan() does the writing. Self-check: node src/lib/plan.check.mts\nimport type { RoadmapItem, RoadmapStatus } from './core'\n\nexport interface PlanTask {\n key: string // stable within the plan, e.g. \"t1\"; becomes a T id on apply\n title: string\n size?: string // \"S (~1 hr)\" | \"M (2–3 hrs)\" | \"L (half day)\"\n dependsOn?: string[] // keys in this plan, or existing task ids (\"T030\")\n due?: string // YYYY-MM-DD\n body: string // full markdown below the meta block: Goal, Context, Scope, Files, …\n}\nexport interface PlanHorizon { key: string; title: string; body?: string }\nexport interface PlanEpic { key: string; title: string; parent: string; status?: RoadmapStatus; body: string } // parent: existing horizon id or a horizon key\nexport interface PlanNewEpic { title: string; parent: string; body: string } // parent: existing horizon id\n/** breakdown: exactly one of `epic` (existing) or `newEpic`, or neither (loose tasks, no Phase). */\nexport type Plan =\n | { kind: 'breakdown'; epic?: string; newEpic?: PlanNewEpic; tasks: PlanTask[] }\n | { kind: 'roadmap'; horizons: PlanHorizon[]; epics: PlanEpic[] }\n\nexport interface PlanContext { roadmap: RoadmapItem[]; taskIds: string[] }\n\n/** A real calendar date \"YYYY-MM-DD\" (rejects 2026-02-30), else null. Same rule as core's parseDue. */\nfunction isDate(raw: string): boolean {\n const m = raw.match(/^(\\d{4})-(\\d{2})-(\\d{2})$/)\n if (!m) return false\n return new Date(Date.UTC(+m[1], +m[2] - 1, +m[3])).toISOString().slice(0, 10) === raw\n}\n\nconst isObj = (v: unknown): v is Record<string, unknown> => !!v && typeof v === 'object' && !Array.isArray(v)\nconst str = (v: unknown) => (typeof v === 'string' ? v.trim() : '')\n\n/** Where a breakdown's tasks go, for one-line summaries: \"R002\", `new epic \"X\"`, or \"no epic\". */\nexport function planTarget(plan: Extract<Plan, { kind: 'breakdown' }>): string {\n if (str(plan.epic)) return str(plan.epic).toUpperCase()\n return plan.newEpic ? `new epic \"${str(plan.newEpic.title)}\"` : 'no epic'\n}\n\n/** An existing roadmap item that can parent an epic (a horizon), else the reason it can't. */\nfunction resolveHorizon(parent: string, roadmap: RoadmapItem[], missing = 'is not an existing roadmap item'): { id: string } | { error: string } {\n const p = roadmap.find(r => r.id === parent.toUpperCase())\n if (!p) return { error: `parent \"${parent}\" ${missing}` }\n if (p.parent !== null) return { error: `parent ${p.id} is an epic, not a horizon (max depth is 2)` }\n return { id: p.id }\n}\n\n/** Id of an existing item with this title under `parent` ('' = horizon level), case-insensitive. */\nconst titleTaken = (roadmap: RoadmapItem[], parent: string, title: string) =>\n roadmap.find(i => (i.parent ?? '') === parent && i.title.trim().toLowerCase() === title.toLowerCase())?.id\n\n/**\n * Just enough shape for the chat UI to render a proposal before the server has validated it\n * (the tool_use streams in before its tool_result). Returns null for anything a card can't draw.\n */\nexport function asRenderablePlan(p: unknown): Plan | null {\n if (!isObj(p)) return null\n const items = (v: unknown, need: string[]) => Array.isArray(v) && v.every(x =>\n isObj(x) && need.every(k => typeof x[k] === 'string') && (x.dependsOn === undefined || Array.isArray(x.dependsOn)))\n if (p.kind === 'breakdown') {\n const target = p.epic === undefined || typeof p.epic === 'string'\n const newEpic = p.newEpic === undefined || (isObj(p.newEpic) && typeof p.newEpic.title === 'string' && typeof p.newEpic.parent === 'string')\n return target && newEpic && items(p.tasks, ['key', 'title']) && (p.tasks as unknown[]).length > 0\n ? (p as unknown as Plan) : null\n }\n if (p.kind === 'roadmap') {\n const horizons = p.horizons ?? [], epics = p.epics ?? []\n return items(horizons, ['key', 'title']) && items(epics, ['key', 'title', 'parent'])\n ? ({ kind: 'roadmap', horizons, epics } as Plan) : null\n }\n return null\n}\n\n/** Every problem with the plan against the current files; [] = valid. */\nexport function validatePlan(plan: unknown, ctx: PlanContext): string[] {\n if (!isObj(plan)) return ['plan must be an object']\n if (plan.kind === 'roadmap') return validateRoadmapPlan(plan, ctx)\n if (plan.kind !== 'breakdown') return [`plan.kind must be \"breakdown\" or \"roadmap\" (got ${JSON.stringify(plan.kind)})`]\n\n const errors: string[] = []\n const epicId = str(plan.epic).toUpperCase()\n if (plan.epic !== undefined && typeof plan.epic !== 'string') errors.push('epic must be a string (an epic id)')\n else if (epicId && plan.newEpic !== undefined) errors.push('pass either epic (an existing epic) or newEpic, not both')\n else if (epicId) {\n const epic = ctx.roadmap.find(i => i.id === epicId)\n if (!epic) errors.push(`Epic ${JSON.stringify(plan.epic)} not found`)\n else if (!epic.parent) errors.push(`${epic.id} is a horizon, not an epic; pass an epic id`)\n } else if (plan.newEpic !== undefined) {\n const e = plan.newEpic\n if (!isObj(e)) errors.push('newEpic must be an object { title, parent, body }')\n else {\n const title = str(e.title), parent = str(e.parent)\n if (!title) errors.push('newEpic: title is required')\n if (typeof e.body !== 'string') errors.push('newEpic: body must be a markdown string')\n if (!parent) errors.push('newEpic: parent is required (an existing horizon id)')\n else {\n const h = resolveHorizon(parent, ctx.roadmap)\n if ('error' in h) errors.push(`newEpic: ${h.error}`)\n else if (title) {\n const other = titleTaken(ctx.roadmap, h.id, title)\n if (other) errors.push(`newEpic: \"${title}\" already exists under ${h.id} (${other})`)\n }\n }\n }\n }\n\n if (!Array.isArray(plan.tasks) || plan.tasks.length === 0) {\n errors.push('tasks must be a non-empty array')\n return errors\n }\n const tasks = plan.tasks as unknown[]\n const existing = new Set(ctx.taskIds.map(t => t.toUpperCase()))\n\n const index = new Map<string, number>()\n tasks.forEach((t, i) => {\n const key = isObj(t) ? str(t.key) : ''\n if (!key) errors.push(`task #${i + 1}: key is required`)\n else if (index.has(key)) errors.push(`duplicate key \"${key}\"`)\n else index.set(key, i)\n })\n\n const deps = new Map<string, string[]>() // key → plan keys it depends on\n tasks.forEach((t, i) => {\n if (!isObj(t)) { errors.push(`task #${i + 1} must be an object`); return }\n const label = str(t.key) || `task #${i + 1}`\n if (!str(t.title)) errors.push(`${label}: title is required`)\n if (typeof t.body !== 'string') errors.push(`${label}: body must be a markdown string`)\n if (t.size !== undefined && typeof t.size !== 'string') errors.push(`${label}: size must be a string`)\n if (t.due !== undefined && !(typeof t.due === 'string' && isDate(t.due))) {\n errors.push(`${label}: due must be a date YYYY-MM-DD (got ${JSON.stringify(t.due)})`)\n }\n if (t.dependsOn === undefined) return\n if (!Array.isArray(t.dependsOn)) { errors.push(`${label}: dependsOn must be an array`); return }\n const own: string[] = []\n for (const d of t.dependsOn) {\n const dep = str(d)\n if (index.has(dep)) own.push(dep)\n else if (!existing.has(dep.toUpperCase())) {\n errors.push(`${label}: dependsOn \"${String(d)}\" is neither a key in this plan nor an existing task`)\n }\n }\n if (str(t.key)) deps.set(str(t.key), own)\n })\n\n // Cycles (DFS, report each once), then forward references: apply creates in order,\n // so a dependency must come earlier in the list to already have its T id.\n const state = new Map<string, 'open' | 'done'>()\n const cyclic = new Set<string>()\n const visit = (k: string, stack: string[]) => {\n if (state.get(k) === 'done') return\n if (state.get(k) === 'open') {\n const cycle = [...stack.slice(stack.indexOf(k)), k]\n if (!cycle.some(c => cyclic.has(c))) errors.push(`dependency cycle: ${cycle.join(' → ')}`)\n cycle.forEach(c => cyclic.add(c))\n return\n }\n state.set(k, 'open')\n for (const d of deps.get(k) ?? []) visit(d, [...stack, k])\n state.set(k, 'done')\n }\n for (const k of deps.keys()) visit(k, [])\n for (const [k, ds] of deps) {\n if (cyclic.has(k)) continue\n for (const d of ds) {\n if ((index.get(d) ?? 0) > (index.get(k) ?? 0)) errors.push(`${k} depends on ${d}, which comes later; list ${d} first`)\n }\n }\n return errors\n}\n\nconst STATUSES = ['planned', 'in-progress', 'done']\n\nfunction validateRoadmapPlan(plan: Record<string, unknown>, ctx: PlanContext): string[] {\n const errors: string[] = []\n const horizons = plan.horizons ?? []\n const epics = plan.epics ?? []\n if (!Array.isArray(horizons)) errors.push('horizons must be an array')\n if (!Array.isArray(epics)) errors.push('epics must be an array')\n if (errors.length > 0) return errors\n const hs = horizons as unknown[]\n const es = epics as unknown[]\n if (hs.length + es.length === 0) return ['a roadmap plan needs at least one horizon or epic']\n\n const keys = new Set<string>()\n const horizonKeys = new Set<string>()\n const checkKey = (v: unknown, label: string, isHorizon: boolean) => {\n const key = isObj(v) ? str(v.key) : ''\n if (!key) errors.push(`${label}: key is required`)\n else if (keys.has(key)) errors.push(`duplicate key \"${key}\"`)\n else { keys.add(key); if (isHorizon) horizonKeys.add(key) }\n }\n hs.forEach((h, i) => checkKey(h, `horizon #${i + 1}`, true))\n es.forEach((e, i) => checkKey(e, `epic #${i + 1}`, false))\n\n // Titles are unique per level (spine, or one horizon), against existing items and within the plan.\n const seen = new Map<string, string>() // \"parent\\0title\" → who in this plan has it\n const claimTitle = (parent: string, title: string, label: string) => {\n const k = `${parent}\\0${title.toLowerCase()}`\n const other = titleTaken(ctx.roadmap, parent, title) ?? seen.get(k)\n if (other) errors.push(`${label}: \"${title}\" already exists ${parent ? `under ${parent}` : 'as a horizon'} (${other})`)\n else seen.set(k, label)\n }\n\n hs.forEach((h, i) => {\n if (!isObj(h)) { errors.push(`horizon #${i + 1} must be an object`); return }\n const label = str(h.key) || `horizon #${i + 1}`\n const title = str(h.title)\n if (!title) errors.push(`${label}: title is required`)\n else claimTitle('', title, label)\n if (h.body !== undefined && typeof h.body !== 'string') errors.push(`${label}: body must be a markdown string`)\n })\n\n es.forEach((e, i) => {\n if (!isObj(e)) { errors.push(`epic #${i + 1} must be an object`); return }\n const label = str(e.key) || `epic #${i + 1}`\n const title = str(e.title)\n if (!title) errors.push(`${label}: title is required`)\n if (typeof e.body !== 'string') errors.push(`${label}: body must be a markdown string`)\n if (e.status !== undefined && !STATUSES.includes(e.status as string)) {\n errors.push(`${label}: status must be one of ${STATUSES.join(', ')} (got ${JSON.stringify(e.status)})`)\n }\n const parent = str(e.parent)\n let parentId = ''\n if (!parent) errors.push(`${label}: parent is required (an existing horizon id or a horizon key in this plan)`)\n else if (horizonKeys.has(parent)) parentId = parent\n else if (keys.has(parent)) errors.push(`${label}: parent \"${parent}\" is an epic in this plan; an epic's parent must be a horizon`)\n else {\n const h = resolveHorizon(parent, ctx.roadmap, 'is neither a horizon key in this plan nor an existing roadmap item')\n if ('id' in h) parentId = h.id\n else errors.push(`${label}: ${h.error}`)\n }\n if (title && parentId) claimTitle(parentId, title, label)\n })\n return errors\n}\n\n/** Keep only the selected items. A kept item depending on an unchecked one is an error. */\nexport function selectPlan(plan: Plan, selected: string[]): { plan: Plan; errors: string[] } {\n if (plan.kind === 'roadmap') return selectRoadmapPlan(plan, selected)\n const errors: string[] = []\n // Trim like validatePlan/applyPlan do, or \" t1 \" vs \"t1\" slips past the unchecked-dependency check\n const keys = new Set(plan.tasks.map(t => t.key.trim()))\n const sel = new Set(selected.map(k => k.trim()))\n for (const k of sel) if (!keys.has(k)) errors.push(`unknown key \"${k}\"`)\n const tasks = plan.tasks.filter(t => sel.has(t.key.trim()))\n if (tasks.length === 0) errors.push('nothing selected')\n for (const t of tasks) {\n for (const d of (t.dependsOn ?? []).map(d => d.trim())) {\n if (keys.has(d) && !sel.has(d)) errors.push(`${t.key.trim()} depends on ${d}, which you unchecked`)\n }\n }\n return { plan: { ...plan, tasks }, errors }\n}\n\nfunction selectRoadmapPlan(plan: Extract<Plan, { kind: 'roadmap' }>, selected: string[]): { plan: Plan; errors: string[] } {\n const errors: string[] = []\n const horizons = plan.horizons ?? []\n const epics = plan.epics ?? []\n const hKeys = new Set(horizons.map(h => h.key))\n const keys = new Set([...hKeys, ...epics.map(e => e.key)])\n const sel = new Set(selected)\n for (const k of sel) if (!keys.has(k)) errors.push(`unknown key \"${k}\"`)\n const keptH = horizons.filter(h => sel.has(h.key))\n const keptE = epics.filter(e => sel.has(e.key))\n if (keptH.length + keptE.length === 0) errors.push('nothing selected')\n for (const e of keptE) {\n const p = e.parent.trim()\n if (hKeys.has(p) && !sel.has(p)) errors.push(`${e.key} is under ${p}, which you unchecked; check ${p} or uncheck ${e.key}`)\n }\n return { plan: { ...plan, horizons: keptH, epics: keptE }, errors }\n}\n","// Pure helpers for agent chats (ChatContext, ChatView, sidebar, /chat page). No React, no fs:\n// `node src/lib/chats.check.mts` runs them.\n\n/** What a chat is about: the roadmap/board show its status there, and the first turn tells the agent. */\nexport interface Attach { kind: \"epic\" | \"task\"; id: string }\n\nexport interface Chat<M = unknown> {\n id: string\n title: string\n messages: M[]\n /** Claude session to `--resume`; set by the first `session_id` in the stream */\n sessionId: string | null\n busy: boolean\n /** Accept/reject outcomes the agent hasn't heard about yet; sent with this chat's next message */\n notes: string[]\n attach: Attach | null\n createdAt: string\n updatedAt: string\n}\n\nexport function newChatId(now: number, salt = Math.random()): string {\n return `c-${now.toString(36)}${salt.toString(36).slice(2, 6)}`\n}\n\nexport function addChat<M>(chats: Chat<M>[], id: string, opts: { title?: string; attach?: Attach | null; now?: string } = {}): Chat<M>[] {\n const now = opts.now ?? new Date().toISOString()\n const title = opts.title ?? (opts.attach ? attachTitle(opts.attach) : \"New chat\")\n return [...chats, { id, title, messages: [], sessionId: null, busy: false, notes: [], attach: opts.attach ?? null, createdAt: now, updatedAt: now }]\n}\n\n/** A missing id (e.g. a closed chat whose stream is still unwinding) is a no-op. */\nexport function patchChat<M>(chats: Chat<M>[], id: string, fn: (c: Chat<M>) => Chat<M>): Chat<M>[] {\n return chats.map((c) => (c.id === id ? fn(c) : c))\n}\n\n/** The fields of a chat message the status reads (ChatContext's ChatMessage has more). */\nexport interface StatusMessage {\n role: \"user\" | \"assistant\"\n text?: string\n tools?: unknown[]\n questions: { answers?: unknown }[]\n proposals: { status: string }[]\n plans: { status: string }[]\n error?: string\n}\n\nexport type ChatStatus = \"running\" | \"needs-answer\" | \"review\" | \"idle\" | \"error\"\n\nexport const STATUS_LABEL: Record<ChatStatus, string> = {\n running: \"Running\",\n \"needs-answer\": \"Waiting for your answers\",\n review: \"Plan or edit to review\",\n error: \"Error\",\n idle: \"Idle\",\n}\n\n/** Plan and edit cards the user hasn't accepted or rejected yet, across the whole chat. */\nexport function pendingReviews(chat: Chat<StatusMessage>): number {\n return chat.messages.reduce(\n (n, m) => n + m.plans.filter((p) => p.status === \"pending\").length + m.proposals.filter((p) => p.status === \"pending\").length,\n 0,\n )\n}\n\n/** Precedence: running > needs-answer > review > error > idle. */\nexport function chatStatus(chat: Chat<StatusMessage>): ChatStatus {\n if (chat.busy) return \"running\"\n const last = chat.messages[chat.messages.length - 1]\n // Same rule as the composer hint: only the latest reply's questions block\n if (last?.questions.some((q) => !q.answers)) return \"needs-answer\"\n if (pendingReviews(chat)) return \"review\"\n const lastReply = chat.messages.findLast((m) => m.role === \"assistant\")\n return lastReply?.error ? \"error\" : \"idle\"\n}\n\nexport const isWaiting = (s: ChatStatus): s is \"needs-answer\" | \"review\" => s === \"needs-answer\" || s === \"review\"\n\n/** Each running chat is one `claude -p` process. */\nexport const MAX_RUNNING_CHATS = 4\nexport const TOO_MANY_CHATS = `Too many agents running (${MAX_RUNNING_CHATS}). Stop or close a chat, or wait.`\n\n/**\n * Where an askAgent() message goes: the current chat when it is idle, otherwise a new chat.\n * Refused at the cap. `running` overrides the busy count when `chats` may be stale (several asks in one tick).\n */\nexport function routeAsk(\n chats: Chat[],\n currentId: string | null,\n opts: { newChat?: boolean; running?: number } = {},\n): { chatId: string } | { newChat: true } | { refused: string } {\n if ((opts.running ?? chats.filter((c) => c.busy).length) >= MAX_RUNNING_CHATS) return { refused: TOO_MANY_CHATS }\n const current = chats.find((c) => c.id === currentId)\n return current && !current.busy && !opts.newChat ? { chatId: current.id } : { newChat: true }\n}\n\n// ─── Attachments ──────────────────────────────────────────────────────────────\n\nexport const attachKey = (a: Attach) => `${a.kind}:${a.id}`\nexport const sameAttach = (a: Attach | null, b: Attach | null) => !!a && !!b && a.kind === b.kind && a.id === b.id\n\nexport function attachTitle(a: Attach): string {\n return a.kind === \"epic\" ? `Epic ${a.id}` : `Task ${a.id}`\n}\n\n/** The epic a message asks to break down: the roadmap's \"Break down with agent\" wording, or the same typed by hand. */\nexport function epicOf(message: string): string | null {\n return message.trim().match(/^Break down epic (R\\d+)/i)?.[1].toUpperCase() ?? null\n}\n\n/** The chat to resume for `a`: the most recently updated one attached to it. */\nexport function chatFor<C extends Chat>(chats: C[], a: Attach): C | undefined {\n return chats.filter((c) => sameAttach(c.attach, a)).sort((x, y) => y.updatedAt.localeCompare(x.updatedAt))[0]\n}\n\n/** What the roadmap/board show on an item while a chat works on it. Idle and errored chats show nothing. */\nexport interface ItemAgent { status: \"running\" | \"needs-answer\" | \"review\"; chatId: string }\n\nconst RANK = { running: 3, \"needs-answer\": 2, review: 1 } as const\n\n/** attachKey → the most urgent chat on it (running > needs-answer > review). */\nexport function itemAgents(chats: Chat<StatusMessage>[]): Record<string, ItemAgent> {\n const out: Record<string, ItemAgent> = {}\n for (const c of chats) {\n const status = chatStatus(c)\n if (!c.attach || status === \"idle\" || status === \"error\") continue\n const key = attachKey(c.attach)\n const cur = out[key]\n if (!cur || RANK[status] > RANK[cur.status]) out[key] = { status, chatId: c.id }\n }\n return out\n}\n\n/** First-turn context for an attached chat; later turns resume the Claude session, which remembers it. */\nexport function attachContext(a: Attach): string {\n return a.kind === \"epic\"\n ? `[This chat is about epic ${a.id}. Read it with vibedoc_get_roadmap (and its tasks with vibedoc_get_task) before answering.]`\n : `[This chat is about task ${a.id}. Read it with vibedoc_get_task before answering.]`\n}\n\n/** Starter prompts shown in an empty chat. Each is something the agent can do with only the vibedoc_* tools. */\nexport function suggestions(a: Attach | null): string[] {\n if (!a) return [\"What should I work on next?\", \"Plan a roadmap for this project.\", \"What is blocked right now?\"]\n if (a.kind === \"epic\") return [`Break down epic ${a.id} into tasks.`, \"Summarize this epic's progress.\", \"What is at risk in this epic?\"]\n return [\"Refine this task's spec.\", \"Split this task into smaller tasks.\", \"What blocks this task?\"]\n}\n\n// ─── Lists ────────────────────────────────────────────────────────────────────\n\nexport interface ChatGroups<C> { needsYou: C[]; running: C[]; recent: C[] }\n\n/** Sidebar and /chat list order: waiting on you, then running, then the rest; newest first within a group. */\nexport function groupChats<C extends Chat<StatusMessage>>(chats: C[]): ChatGroups<C> {\n const byNew = [...chats].sort((a, b) => b.updatedAt.localeCompare(a.updatedAt))\n const groups: ChatGroups<C> = { needsYou: [], running: [], recent: [] }\n for (const c of byNew) {\n const s = chatStatus(c)\n if (isWaiting(s)) groups.needsYou.push(c)\n else if (s === \"running\") groups.running.push(c)\n else groups.recent.push(c)\n }\n return groups\n}\n\n/** The chat the header button / `c` opens: the most urgent, else the newest, else none. */\nexport function defaultChat<C extends Chat<StatusMessage>>(chats: C[]): C | undefined {\n const g = groupChats(chats)\n return g.needsYou[0] ?? g.running[0] ?? g.recent[0]\n}\n\n// ─── Persistence (.vibedoc/chats/<id>.json via /api/conversations) ───────────\n\n/** What gets saved: never busy (a running turn can't survive a reload). Empty chats aren't saved. */\nexport function toSaved<M>(c: Chat<M>): Chat<M> | null {\n return c.messages.length ? { ...c, busy: false } : null\n}\n\n/** A saved chat as loaded: a turn that was cut off (empty last reply, no error) gets an \"interrupted\" error. */\nexport function fromSaved<M extends StatusMessage>(raw: unknown): Chat<M> | null {\n const c = raw as Chat<M> | null\n if (!c || typeof c.id !== \"string\" || !Array.isArray(c.messages)) return null\n const last = c.messages[c.messages.length - 1]\n const cut = last?.role === \"assistant\" && !last.text && !last.error && !last.tools?.length && !last.plans?.length && !last.proposals?.length && !last.questions?.length\n const messages = cut ? [...c.messages.slice(0, -1), { ...last, error: \"Interrupted: the page reloaded while the agent was working.\" }] : c.messages\n const at = c.updatedAt ?? c.createdAt ?? new Date(0).toISOString()\n return { ...c, messages, busy: false, notes: c.notes ?? [], attach: c.attach ?? null, createdAt: c.createdAt ?? at, updatedAt: at }\n}\n\n// ─── Waiting on the user: header badge, page title, desktop notification ─────\n\n/** Chats that became waiting since `prev` (id → last status), so each one notifies once per change. */\nexport function newlyWaiting<C extends Chat<StatusMessage>>(prev: Record<string, ChatStatus>, chats: C[]): { chat: C; status: \"needs-answer\" | \"review\" }[] {\n return chats.flatMap((chat) => {\n const status = chatStatus(chat)\n return isWaiting(status) && prev[chat.id] !== status ? [{ chat, status }] : []\n })\n}\n\n/** \"(2) VibeDoc\" while 2 chats wait; the plain title otherwise. Idempotent. */\nexport function waitingTitle(title: string, n: number): string {\n const base = title.replace(/^\\(\\d+\\) /, \"\")\n return n > 0 ? `(${n}) ${base}` : base\n}\n\nexport function chatTitle(firstMessage: string): string {\n const epic = epicOf(firstMessage)\n if (epic) return `Break down ${epic}`\n const line = firstMessage.trim().split(\"\\n\")[0]\n return line.length > 40 ? `${line.slice(0, 40).trimEnd()}…` : line\n}\n\n/** \"now\", \"5m\", \"3h\", \"2d\" since `iso` (list rows). */\nexport function ago(iso: string, nowMs: number): string {\n const min = Math.max(0, Math.floor((nowMs - Date.parse(iso)) / 60_000))\n if (min < 1) return \"now\"\n if (min < 60) return `${min}m`\n if (min < 60 * 24) return `${Math.floor(min / 60)}h`\n return `${Math.floor(min / (60 * 24))}d`\n}\n"],"names":["isRenderableQuestions","v","isStr","x","Array","isArray","length","every","q","question","header","options","o","label","OTHER","formatAnswers","questions","answers","map","i","join","QuestionCard","set","disabled","onSubmit","picked","setPicked","other","setOther","done","toggle","qi","value","multi","prev","p","includes","filter","labels","l","trim","push","complete","Boolean","className","checked","type","multiSelect","name","id","onChange","description","e","target","placeholder","onClick"],"mappings":"wEAQA,EAAA,EAAA,CAAA,CAAA,QACA,EAAA,EAAA,CAAA,CAAA,QACA,EAAA,EAAA,CAAA,CAAA,QCPA,EAAA,EAAA,CAAA,CAAA,QAaO,SAASA,EAAsBC,CAAU,EAE9C,OAAOG,MAAMC,OAAO,CAACJ,IAAMA,EAAEK,MAAM,CAAG,GAAKL,EAAEM,KAAK,CAAC,AAACC,GAClD,CAAC,CAACA,GAAkB,UAAb,EAAyBN,KAAlBM,GAFc,OAAOL,UAEGK,EAAEC,QAAQ,KAAKP,cAAMM,EAAEE,MAAM,EAAKN,MAAMC,OAAO,CAACG,EAAEG,OAAO,GAC/FH,EAAEG,OAAO,CAACJ,KAAK,CAAC,AAACK,GAAe,CAAC,CAACA,GAAkB,UAAb,EAAyBV,KAAlBU,GAHL,iBAG8BA,EAAqBC,KAAK,EACrG,CAEA,IAAMC,EAAQ,UAGP,SAASC,EAAcC,CAAqB,CAAEC,CAAiB,EACpE,MAAO,CAAC,cAAeD,EAAUE,GAAG,CAAC,CAACV,EAAGW,IAAM,CAAC,EAAE,EAAEX,EAAEE,MAAM,CAAC,EAAE,EAAEO,CAAO,CAACE,EAAE,CAAA,CAAE,EAAE,CAACC,IAAI,CAAC,KACvF,uBAEO,SAASC,AAAa,KAAEC,CAAG,UAAEC,CAAQ,UAAEC,CAAQ,CAIrD,EACC,GAAM,CAACC,EAAQC,EAAU,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAa,IAAMJ,EAAIN,SAAS,CAACE,GAAG,CAAC,IAAM,EAAE,GAC3E,CAACS,EAAOC,EAAS,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAW,IAAMN,EAAIN,SAAS,CAACE,GAAG,CAAC,IAAM,KACrEW,EAAO,CAAC,CAACP,EAAIL,OAAO,CAWpBA,EAAUK,EAAIN,SAAS,CAACE,GAAG,CAAC,CAACV,EAAGW,KACpC,IAAMmB,EAAS9B,EAAEG,OAAO,CAACO,GAAG,CAAC,AAACN,GAAMA,EAAEC,KAAK,EAAEwB,MAAM,CAAEE,AAAD,GAAOd,CAAM,CAACN,EAAE,CAACiB,QAAQ,CAACG,IAE9E,OADId,CAAM,CAACN,EAAE,CAACiB,QAAQ,CAACtB,IAAUa,CAAK,CAACR,EAAE,CAACqB,IAAI,IAAIF,EAAOG,IAAI,CAAC,CAAC,QAAQ,EAAEd,CAAK,CAACR,EAAE,CAACqB,IAAI,GAAG,CAAC,CAAC,EACpFF,EAAOlB,IAAI,CAAC,KACrB,GACMsB,EAAWzB,EAAQV,KAAK,CAACoC,SAE/B,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAIC,UAAU,uDAAuD,oBAAkB,CAAA,CAAA,YACtF,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAIA,UAAU,mFACb,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAKA,UAAU,sEAA6D,cAC5Ef,GAAQ,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAKe,UAAU,qDAA4C,kBAEvE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAIA,UAAU,0BACZtB,EAAIN,SAAS,CAACE,GAAG,CAAC,CAACV,EAAGuB,IACrB,CAAA,EAAA,EAAA,IAAA,EAAC,WAAA,CAAkBR,SAAUM,EAAMe,UAAU,sBAC3C,CAAA,EAAA,EAAA,IAAA,EAAC,SAAA,CAAOA,UAAU,iBAChB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAKA,UAAU,8GAAsGpC,EAAEE,MAAM,GAC9H,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAKkC,UAAU,4BAAoBpC,EAAEC,QAAQ,MAE/CoB,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAEe,UAAU,iCAAyBtB,EAAIL,OAAO,EAAE,CAACc,EAAG,GAEvD,CAAA,EAAA,EAAA,IAAA,EAAA,EAAA,QAAA,CAAA,WACG,IAAIvB,EAAEG,OAAO,CAAE,CAAEE,MAAO,QAASmB,MAAOlB,CAAM,EAAE,CAACI,GAAG,CAAC,AAACN,IACrD,IAAMoB,EAAQ,UAAWpB,EAAIA,EAAEoB,KAAK,CAAGpB,EAAEC,KAAK,CACxCgC,EAAUpB,CAAM,CAACM,EAAG,CAACK,QAAQ,CAACJ,GACpC,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,QAAA,CAAkBY,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EAAC,iFAAkFC,GAAW,yBAC5H,CAAA,EAAA,EAAA,GAAA,EAAC,QAAA,CACCC,KAAMtC,EAAEuC,WAAW,CAAG,WAAa,QACnCC,KAAM,CAAA,EAAG1B,EAAI2B,EAAE,CAAC,CAAC,EAAElB,EAAAA,CAAI,CACvBc,QAASA,EACTK,SAAU,IAAMpB,cA1CKG,EA0CazB,EAAEuC,CA1CD,UA0CY,MAzCnErB,EAAU,AAACQ,GAASA,EAAKhB,GAAG,CAAC,CAACiB,EAAGhB,IAC3BA,AAAJ,IAwCyCY,EAxCpBI,AAAXJ,EACLE,EACEE,AAFO,EAELC,GADG,KACK,CAACJ,GAASG,EAAEE,MAAM,CAAEpC,AAAD,GAAOA,IAsCE+B,EAtCIA,CAAS,IAAIG,IAAS,CADpD,GAAO,IAwCRS,UAAU,yBAEZ,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAKA,UAAU,oBACd,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAKA,UAAU,oBAAYhC,EAAEC,KAAK,GAClC,gBAAiBD,GAAKA,EAAEuC,WAAW,EAAI,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAKP,UAAU,4BAAoBhC,EAAEuC,WAAW,QAVjFnB,EAchB,GACCP,CAAM,CAACM,EAAG,CAACK,QAAQ,CAACtB,IACnB,CAAA,EAAA,EAAA,GAAA,EAAC,QAAA,CACCkB,MAAOL,CAAK,CAACI,EAAG,CAChBmB,SAAU,AAACE,GAAMxB,EAAS,AAACM,GAASA,EAAKhB,GAAG,CAAC,CAACjB,EAAGkB,IAAOA,IAAMY,EAAKqB,EAAEC,MAAM,CAACrB,KAAK,CAAG/B,IACpFqD,YAAY,cACZ,aAAY,CAAC,iBAAiB,EAAE9C,EAAEE,MAAM,CAAA,CAAE,CAC1CkC,UAAU,2KAlCLb,IAyChB,CAACF,GACA,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CACC0B,QAAS,IAAM/B,EAASP,GACxBM,SAAU,CAACmB,GAAYnB,EACvBqB,UAAU,0GACX,gBAOX,2DCvFA,IAAM,EAAQ,AAAC,GAA6C,CAAC,CAAC,GAAkB,AAAb,iBAAO,GAAkBR,CAAC,MAAM,OAAO,CAAC,GACrG,EAAM,AAAC,GAA6B,UAAb,OAAO,EAAiB,EAAE,IAAI,GAAK,GFdhE,IAAA,EAAA,EAAA,CAAA,CAAA,QGIO,SAAS,EAAU5B,CAAW,CAAE,EAAO,KAAK,MAAM,EAAE,EACzDE,MAAO,CAAC,EAAE,EAAE,EAAI,QAAQ,CAACF,IAAAA,EAAM,EAAK,QAAQ,CAACG,IAAI,KAAK,CAAC,EAAG,GAAA,CAAI,AAChE,CAEO,SAAS,EAAW,CAAgB,CAAE,CAAU,CAAE,EAAiE,CAAC,CAAC,QAC1H,IAAM,EAAM,EAAK,GAAG,EAAI,IAAI,OAAO,WAAW,GAE9C,MAAO,IAAI,EAAO,CAAE,KAAI,MADV,EAAK,KAAK,GAAK,CAAD,CAAM,MAAM,CA2EjC,AAAW,EA3EyB,QA0EjB,CAAS,CA1EoB,EAAK,MAAM,EA2EzD,IAAI,CAAc,CAAC,KAAK,EAAE,EAAE,EAAEQ,CAAAA,CAAE,CAAG,CAACY,KAAKqB,EAAEC,EAAE,EAAE,CAAA,CAAE,CA3EY,UAAA,CAAU,CACjD,SAAU,EAAE,CAAErC,UAAW,KAAM,MAAM,EAAO,MAAO,EAAE,CAAE,OAAQ,EAAK,MAAM,EAAI,KAAM,UAAW,EAAK,UAAW,CAAI,EAAE,AACtJ,CAGO,SAAS,EAAa,CAAgB,CAAE,CAAU,CAAE,CAA2B,EACpF,OAAO,EAAM,GAAGW,CAAC,AAAC,GAAO,EAAE,EAAE,GAAK,EAAK,EAAG,GAAK,EACjD,CAwBO,SAAS,EAAe,CAAyB,EACtD,OAAO,EAAK,QAAQ,CAAC,MAAM,CACzB,CAAC,EAAG,IAAM,EAAI,EAAE,KAAK,CAAC,MAAMiB,CAAC,AAAC,GAAmB,YAAb,EAAE,MAAM,EAAgB,MAAM,CAAG,EAAE,SAAS,CAAC,MAAM,CAAC,AAAC,GAAmB,AAAb,cAAE,MAAM,EAAgB,MAAM,CAC7H,EAEJ,CAGO,SAAS,EAAW,CAAyB,EAClD,GAAI,EAAK,IAAI,CAAE,MAAO,UACtB,IAAM,EAAO,EAAK,QAAQ,CAAC,EAAK,QAAQ,CAAC,MAAM,CAAG,EAAE,CAEpD,GAAIA,GAAM,UAAU,KAAK,AAAC,GAAM,CAAC,EAAE,OAAO,EAAG,MAAO,eACpD,GAAI,EAAe,GAAO,MAAO,SACjC,IAAM,EAAY,EAAK,QAAQ,CAAC,QAAQ,CAAC,AAAC,GAAiB,cAAX,EAAE,IAAI,EACtD,OAAO,GAAW,MAAQ,QAAU,MACtC,CAEO,IAAM,EAAY,AAAC,GAAkD,AAAM,oBAAwB,WAAN,EAU7F,SAAS,EACd,CAAa,CACb,CAAwB,CACxB,EAAgD,CAAC,CAACE,EAElD,GAAI,CAAC,EAAK,OAAOf,EAAI,EAAM,MAAM,CAAC,AAAC,GAAM,EAAE,IAAIc,EAAE,MAAA,AAAM,GAZxB,EAY6B,AAAmB,MAAO,CAAE,QAX5D,CAWqE,AAXpE,yBAAyB,EAAE,kBAAkB,eAWsCd,EAChHC,IAAM,EAAU,EAAM,IAAI,CAAC,AAAC,GAZ+E,AAYzE,CAZ0E,CAYxE,EAAE,GAAK,GAC3C,OAAO,GAAY,EAAQ,IAAI,EAAb,AAAkB,EAAD,AAAM,OAAO,CAA4B,CAAE,SAAS,CAAK,EAAzC,CAAE,OAAQ,EAAQ,EAAE,AAAC,CAC1E,CAIO,IAAM,EAAY,AAAC,GAAc,CAAA,EAAG,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAA,CAAE,CAQpD,SAAS,EAAO,CAAe,EACpC,OAAO,EAAQ,IAAI,GAAG,KAAK,CAAC,6BAA6B,CAAC,EAAE,CAAC,eAAiB,IAChF,CAGO,SAAS,EAAwB,CAAU,CAAE,CAAS,EAC3D,OAAO,EAAM,MAAM,CAAC,AAAC,IAAM,aAbF,EAaa,CAbK,CAaH,MAAM,CAbkB,CAAC,CAAC,GAAK,CAAC,CAAC,AAazB,GAb8B,EAAE,IAAI,GAAK,EAAE,IAAI,EAAI,EAAE,EAAE,GAAK,EAAEA,EAAE,GAa5D,IAAI,CAAC,CAAC,EAAG,IAAM,EAAE,SAAS,CAAC,aAAa,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,AAC/G,CAKA,IAAM,EAAO,CAAE,QAAS,EAAG,eAAgB,EAAG,OAAQ,CAAE,EAGjD,SAAS,EAAW,CAA4B,EACrD,IAAM,EAAiC,CAAC,EACxC,IAAK,IAAM,KAAK,EAAO,CACrB,IAAM,EAAS,EAAW,GAC1B,GAAI,CAAC,EAAE,MAAM,EAAe,SAAX,GAAgC,AAAX,YAAoB,SAC1D,IAAM,EAAM,EAAU,EAAE,MAAM,EACxB,EAAM,CAAG,CAAC,EAAI,EAChB,CAAC,GAAO,CAAI,CAAC,EAAO,CAAG,CAAI,CAAC,EAAI,OAAM,AAAC,IAAE,CAAG,CAAC,EAAI,CAAG,QAAE,EAAQ,OAAQ,EAAE,EAAE,CAAC,CACjF,CACA,OAAO,CACT,CAGO,SAAS,EAAc,CAAS,EACrC,MAAkB,SAAX,EAAE,IAAI,CACT,CAAC,yBAAyB,EAAE,EAAE,EAAE,CAAC,2FAA2F,CAAC,CAC7H,CAAC,yBAAyB,EAAE,EAAE,EAAE,CAAC,kDAAkD,CAAC,AAC1F,CAcO,SAAS,EAA0C,CAAU,EAClE,IAAM,EAAQ,IAAI,EAAM,CAAC,IAAI,CAAC,CAAC,EAAG,IAAM,EAAE,SAAS,CAAC,aAAa,CAAC,EAAE,SAAS,GACvE,EAAwB,CAAE,SAAU,EAAE,CAAE,QAAS,EAAE,CAAE,OAAQ,EAAE,AAAC,EACtE,IAAK,IAAM,KAAK,EAAO,CACrB,IAAM,EAAI,EAAW,GACjB,EAAU,GAAI,EAAO,QAAQ,CAAC,IAAI,CAAC,GAC9B,AAAM,cAAW,EAAO,OAAO,CAAC,IAAI,CAAC,GACzC,EAAO,MAAM,CAAC,IAAI,CAAC,EAC1B,CACA,OAAO,CACT,CAGO,SAAS,EAA2C,CAAU,EACnE,IAAM,EAAI,EAAW,GACrB,OAAO,EAAE,QAAQ,CAAC,EAAE,EAAI,EAAE,OAAO,CAAC,EAAE,EAAI,EAAE,MAAM,CAAC,EAAE,AACrD,CAKO,SAAS,EAAW,CAAU,EACnC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAG,CAAE,GAAG,CAAC,CAAE,KAAM,EAAM,EAAI,IACrD,CAGO,SAAS,EAAmC,CAAY,EAE7D,GAAI,CAAC,GAAqB,UAAhB,OAAO,EAAE,EAAE,EAAiB,CAAC,MAAM,OAAO,CAD1C,AAC2C,EAAE,QAAQ,EAAG,OAAO,KACzE,IAAM,EAAO,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAG,EAAE,CAExC,EADM,AACK,GADC,OAAS,aAAgB,EAAD,AAAM,IAAI,EAAK,EAAD,AAAM,KAAK,EAAK,EAAD,AAAM,KAAK,EAAE,QAAW,EAAD,AAAM,KAAK,EAAE,QAAW,EAAD,AAAM,SAAS,EAAE,QAAW,EAAK,AAAN,SAAe,EAAE,OACxB,EAAE,QAAQ,CAA5H,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAG,CAAC,GAAI,CAAE,GAAG,CAAI,CAAE,MAAO,6DAA8D,EAAE,CAChI,EAAK,EAAE,SAAS,EAAI,EAAE,SAAS,EAAI,IAAI,KAAK,GAAG,WAAW,GAChE,MAAO,CANG,IAMD,GAAG,CAAC,MAAE,EAAU,MAAM,EAAO,MAAO,EAAE,KAAK,EAAI,EAAE,CAAE,OAAQ,EAAE,MAAM,EAAI,KAAM,UAAW,EAAE,SAAS,EAAI,EAAI,UAAW,CAAG,CACpI,CAKO,SAAS,EAA4C,CAAgC,CAAE,CAAU,EACtG,OAAO,EAAM,OAAO,CAAC,AAAC,IACpB,IAAM,EAAS,EAAW,GAC1B,OAAO,EAAU,IAAW,CAAI,CAAC,EAAK,EAAE,CAAC,GAAK,EAAS,CAAC,MAAE,SAAM,CAAO,EAAE,CAAG,EAAE,AAChF,EACF,CAGO,SAAS,EAAa,CAAa,CAAE,CAAS,EACnD,IAAM,EAAO,EAAM,OAAO,CAAC,YAAa,IACxC,OAAO,EAAI,EAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAA,CAAM,CAAG,CACpC,CAEO,SAAS,EAAU,CAAoB,EAC5C,IAAM,EAAO,EAAO,GACpB,GAAI,EAAM,MAAO,CAAC,WAAW,EAAE,EAAA,CAAM,CACrC,IAAM,EAAO,EAAa,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,CAC/C,OAAO,EAAK,MAAM,CAAG,GAAK,CAAA,EAAG,EAAK,KAAK,CAAC,EAAG,IAAI,OAAO,GAAG,CAAC,CAAC,CAAG,CAChE,+CAhKwDM,CACtD,QAAS,UACT,eAAgB,2BAChBC,OAAQ,yBACR,MAAO,QACP,KAAM,MACR,wBA6JO,SAAS,AAAI,CAAW,CAAE,CAAa,EAC5C,IAAM,EAAM,KAAK,GAAG,CAAC,EAAG,KAAK,KAAK,CAAC,CAAC,EAAQ,KAAK,KAAK,CAAC,EAAA,CAAI,CAAI,aAC/D,AAAI,EAAM,EAAU,CAAP,KACT,EAAM,GAAW,CAAP,AAAO,EAAG,EAAI,CAAC,CAAC,CAC1B,EAAM,KAAK,AAAW,CAAA,EAAG,CAAV,IAAe,KAAK,CAAC,EAAM,IAAI,CAAC,CAAC,CAC7C,CAAA,EAAG,KAAK,KAAK,CAAC,EAAO,IAAD,CAAM,CAAK,CAAH,AAAI,CAAC,AAC1C,6RA7EO,SAAS,AAAY,CAAgB,SAC1C,AAAK,EACU,AAAX,CADI,CAAJ,MACmB,GAAjB,IAAI,CAAoB,CAAC,CAAC,gBAAgB,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,CAAE,kCAAmC,gCAAgC,CAClI,CAAC,2BAA4B,sCAAuC,yBAAyB,CAFrF,CAAC,8BAA+B,mCAAoC,6BAGrF,AAHkH,4CH1GlH,IAAM,EAAQ,CAAC,EAA2B,EAAO,EAAE,GACjD,CAAC,MAAE,OAAM,EAAM,MAAO,EAAE,CAAEb,UAAWQ,EAAE,CAAE,MAAO,EAAE,CAAE,UAAW,EAAE,CAAC,CAAC,CAiC/D,EAAc,CAAA,EAAA,EAAA,aAAA,AAAa,EAAiB,MAE5C,EAAoB,CAAA,EAAA,EAAA,aAAa,AAAb,EAAyC,CAAC,yBAa7D,SAAS,AAAa,UAAE,CAAQ,CAA2B,EAChE,GAAM,WAAE,CAAS,eAAE,CAAa,aAAE,CAAW,CAAE,CAAG,CAAA,EAAA,EAAA,MAAA,AAAM,IAClD,EAAW,CAAA,EAAA,EAAA,WAAA,AAAW,IACtB,EAAS,CAAA,EAAA,EAAA,SAAA,AAAS,IAClB,CAAC,EAAO,EAAS,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAY,EAAE,EAC1C,CAAC,EAAQ,EAAU,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GAC/B,CAAC,EAAS,EAAW,CAAGiB,CAAAA,EAAAA,EAAAA,QAAQ,AAARA,EAAwB,MAEhD,CAAC,EAAW,EAAa,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAgB,MACpD,CAAC,EAAQ,EAAU,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAgB,MAE9C,EAAY,CAAA,EAAA,EAAA,MAAA,AAAM,EAACC,IAAI,KAEvB,EAAW,CAAA,EAAA,EAAA,MAAA,AAAM,EAAC,IAAI,KACtB,EAAc,CAAA,EAAA,EAAA,MAAA,AAAM,EAA6B,CAAC,GAElD,EAAa,AAAa,YAC1B,EAAuB,UAAb,EAAuB,GAAa,UAAO,EAG3D,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACR,IAAK,IAAM,KAAM,EAAU,OAAO,CAAC,MAAM,GAAInC,EAAG,KAAK,GACrD,EAAU,OAAO,CAACyB,KAAK,GACvBnB,EAAS,OAAO,CAAC,KAAKqB,GACtB,IAAI,GAAY,EAgBhB,OAfA,MAAM,CAAC,kBAAkB,EAAE,EAAA,CAAW,EACnC,IAAI,CAAE,AAAD,GAAQ,EAAE,EAAE,CAAG,EAAE,IAAI,GAAK,CAAE,MAAO,EAAE,AAAC,GAC3C,IAAI,CAAC,AAAC,IACL,GAAI,EAAW,OACf,IAAM,EAAc,CAAC,EAAE,KAAK,EAAI,EAAE,AAAF,EAAI,GAAG,CAAC,AAAC,GAAM,EAAuB,IAAI,MAAM,CAAC,AAAC,GAAoB,CAAC,CAAC,GACxG,EAAY,OAAO,CAAG,OAAO,WAAW,CAAC,EAAY,GAAG,CAAC,AAAC,GAAM,CAAC,EAAE,EAAE,CAAE,EAAW,GAAG,GACrF,EAAS,GACT,EAAW,MACX,EAAa,MACb,GAAU,EACZ,GACC,KAAK,CAAC,AAAC,IACN,QAAQ,IAAI,CAAC,kCAAmC,GAC3C,IAAa,EAAS,EAAE,EAAG,CAAhB,EAA0B,GAC5C,GACK,KAAQ,GAAY,CAAK,CAClC,EAAG,CAAC,EAAe,EAAU,EAI7B,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACR,IAAK,IAAM,IAAM,IAAI,EAAS,OAAO,CAAC,CAAE,CACtC,IAAM,EAAO,EAAM,IAAI,CAAC,AAAC,GAAM,EAAE,EAAE,GAAK,GACxC,EAAS,OAAO,CAAC,MAAM,CAAC,GACxB,IAAM,EAAQ,GAAQ,EAAQ,GACzB,GACL,IADY,EACN,CAAC,kBAAkB,EAAE,EAAA,CAAW,CAAE,CACtC,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAmB,EAC9C,KAAM,KAAK,SAAS,CAAC,CAAE,KAAM,CAAM,EACrC,GAAG,KAAK,CAAC,AAAC,GAAM,QAAQ,IAAI,CAAC,CAAC,8BAA8B,EAAE,EAAG,CAAC,CAAC,CAAE,GACvE,CACF,EAAG,CAAC,EAAO,EAAU,EAGrB,IAAM,EAAY,CAAA,EAAA,EAAA,MAAA,AAAM,EAAoD,CAAE,IAAK,KAAM,MAAO,CAAC,CAAE,GAC7F,EAAS,CAAA,EAAA,EAAA,OAAA,AAAO,EAAC,KACrB,IAAM,EAAO,EAAW,GAClB,EAAM,KAAK,SAAS,CAAC,GAE3B,OADI,IAAQ,EAAU,OAAO,CAAC,GAAG,GAAE,EAAU,OAAO,CAAG,KAAE,EAAK,MAAO,EAAK,EACnE,EAAU,OAAO,CAAC,KAC3B,AADgC,EAC7B,CAAC,EAAM,EACJ,EAAe,EAAM,MAAM,CAAC,AAAC,GAAM,EAAE,IAAI,EAAE,MAAM,CACjD,EAAe,EAAM,MAAM,CAAC,AAAC,GAAM,EAAU,EAAW,KAAK,MAAM,CAgBzE,SAAS,GAAU,CAAU,EAAI,EAAS,OAAO,CAAC,GAAG,CAAC,EAAI,CAQ1D,SAAS,GAAK,CAAc,EAC1B,EAAa,GACT,GACF,EAAW,MACX,CAFc,CAEP,OAAO,CAAC,CAAC,SAAS,EAAE,mBAAmB,GAAA,CAAS,CAAE,CAAE,QAAQ,CAAM,IAEzE,EAAW,EAEf,CAEA,SAAS,GAAO,EAAwB,IAAI,EAC1C,IAAM,EAAK,EAAU,KAAK,GAAG,IAE7B,OADA,EAAS,AAAC,GAAO,EAAQ,EAAI,EAAI,QAAE,CAAO,IACnC,CACT,CAwCA,SAAS,GAAU,CAAc,CAAE,CAAmC,EACpE,EAAS,AAAC,GAAO,EAAU,EAAI,EAAQ,AAAC,IAAM,AAAC,CAAE,GAAG,CAAC,CAAE,SAAU,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAG,CAAC,GAAI,EAAG,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAG,EAAE,EAAE,CAAC,CAAC,EACxI,CAsEA,eAAe,GAAK,CAAc,CAAE,CAAY,EAC9C,IAAM,EAAU,EAAK,IAAI,GACnB,EAAO,EAAM,IAAI,CAAC,AAAC,GAAM,EAAE,EAAE,GAAK,GACxC,GAAI,CAAC,GAAW,GAAM,KAAM,OAExB,iBAAkB,QAAsC,WAAW,CAAvC,aAAa,UAAU,EAAqB,aAAa,iBAAiB,GAAG,KAAK,CAAC,KAAO,GAC1H,IAAM,EAAQ,CAAC,GAAM,SAAS,OACxB,EAAO,EAAO,GACd,EAAwB,GAAM,SAAW,CAAD,CAAQ,CAAE,KAAM,OAAQ,GAAI,CAAK,EAAI,IAAA,CAAI,CACvF,EAAS,AAAC,GAAO,EAAU,EAAI,EAAQ,AAAC,IAAM,AAAC,CAC7C,GAAG,CAAC,CAEJ,MAAO,EAAE,QAAQ,CAAC,MAAM,CAAG,EAAE,KAAK,CAAG,EAAU,GAC/C,OAAQ,EAAE,MAAM,EAAI,EACpB,KAAM,GACN,MAAO,EAAE,CACT,UAAW,IAAI,OAAO,WAAW,GACjC,SAAU,IAAI,EAAE,QAAQ,CAAE,EAAM,OAAQ,GAAU,EAAM,aAAa,CACvE,CAAC,GACD,GAAU,GAEV,IAAM,EAAS,IACT,GAAS,GAAM,OAAS,CAAC,EAAc,EAAK,MAAM,EAAE,CAAG,EAAE,IACzD,GAAM,MAAM,OAAS,CAAC,CAAC,CAAC,EAAE,EAAK,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAG,EAAE,CAC5D,CACK,EAAW,EAAO,MAAM,CAAG,CAAA,EAAG,EAAO,IAAI,CAAC,MAAM;AAAA;AAAI,EAAE,EAAA,CAAS,CAAG,EAClE,EAAK,IAAI,gBACf,EAAU,OAAO,CAAC,GAAG,CAAC,EAAQ,GAC9B,GAAI,CACF,IAAM,EAAM,MAAM,MAAM,CAAC,SAAS,EAAE,EAAA,CAAW,CAAE,CAC/C,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAmB,EAC9C,KAAM,KAAK,SAAS,CAAC,CAAE,QAAS,EAAU,UAAW,GAAM,WAAa,aAAM,CAAQ,GACtF,OAAQ,EAAG,MAAM,AACnB,GACA,GAAI,CAAC,EAAI,EAAE,EAAI,CAAC,EAAI,IAAI,CAAE,CACxB,IAAM,EAAO,MAAM,EAAI,IAAI,GAAG,KAAK,CAAC,IAAM,KAC1C,OAAM,AAAI,MAAM,GAAM,OAAS,CAAC,gBAAgB,EAAE,EAAI,MAAM,CAAC,CAAC,CAAC,CACjE,CACA,IAAM,EAAS,EAAI,IAAI,CAAC,SAAS,GAC3B,EAAU,IAAI,YAChB,EAAM,GACV,OAAS,CACP,GAAM,MAAE,CAAI,OAAE,CAAK,CAAE,CAAG,MAAM,EAAO,IAAI,GACzC,GAAI,EAAM,MAEV,IAAM,EAAQ,CADd,GAAO,EAAQ,MAAM,CAAC,EAAO,CAAE,QAAQ,CAAK,EAAA,EAC1B,KAAK,CAAC,MAExB,IAAK,IAAM,KADX,EAAM,EAAM,GAAG,IAAM,GACF,GACjB,GADwB,AACnB,CAAD,CAAM,IAAI,GACd,CADkB,EACd,EAAE,AArHd,SAAS,AAAY,CAAc,CAAE,CAAO,EAE1C,GADI,EAAG,UAAU,EAAE,EAAS,AAAC,GAAO,EAAU,EAAI,EAAQ,AAAC,GAAO,EAAE,SAAS,GAAK,EAAG,UAAU,CAAG,EAAI,CAAE,GAAG,CAAC,CAAE,UAAW,EAAG,UAAU,AAAC,IACvH,iBAAZ,EAAG,IAAI,CAAqB,CAC9B,IAAM,EAAI,EAAG,KAAK,CACd,GAAG,OAAS,gBACd,CAD+B,EACrB,EAAQ,AAAC,GAAO,EAAE,IAAI,EAAI,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAU,CAAE,GAAG,CAAC,CAAE,KAAM,EAAE,IAAI,CAAG,MAAO,EAAI,GACxF,GAAG,OAAS,uBAAyB,EAAE,KAAK,EAAE,OAAS,cAAc,AAC9E,GAAU,EAAQ,AAAC,IAAO,AAAD,CAAG,GAAG,CAAC,CAAE,KAAM,EAAE,IAAI,CAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAEnE,MAAO,GAAgB,cAAZ,EAAG,IAAI,CAAkB,CAClC,IAAM,EACJ,CAAC,EAAG,OAAO,EAAE,SAAW,EAAA,AAAE,EAAE,MAAM,CAAC,AAAC,GAAmC,aAAX,EAAE,IAAI,EAC9D,EAAwB,EAC3B,MAAM,CAAC,AAAC,GAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,yBAAoD,UAAzB,OAAO,EAAE,KAAK,EAAE,MAAqB,MAAM,OAAO,CAAC,EAAE,KAAK,EAAE,QACrH,GAAG,CAAC,AAAC,IAAM,AAAC,CACX,GAAI,EAAE,EAAE,CACR,KAAM,EAAE,KAAK,CAAC,IAAI,CAClB,MAAO,EAAE,KAAK,CAAC,KAAK,CACpB,QAAoC,UAA3B,OAAO,EAAE,KAAK,CAAC,OAAO,CAAgB,EAAE,KAAK,CAAC,OAAO,MAAG,EACjE,OAAQ,UACV,CAAC,EAEG,EAAwB,EAC3B,MAAM,CAAC,AAAC,GAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,yBAC9B,OAAO,CAAC,AAAC,IACR,IAAM,EE9MT,AF8MgB,SE9MP,AAAiB,CAAU,EACzC,GAAI,CAAC,EAAM,GAAI,OAAO,KACtB,IAAM,EAAQ,CAAChC,EAAY,IAAmB,MAAM,OAAO,CAAC,IAAMA,EAAE,KAAK,CAAC,GACxE,EAAM,IAAM,EAAK,KAAK,CAAC,GAAK,AAAgB,aAAa,IAAtB,CAAC,CAAC,EAAEa,SAAmC,IAAhB,EAAE,SAAS,EAAkB,MAAM,OAAO,CAAC,EAAE,UAAS,CAAC,EACnH,GAAe,cAAX,EAAE,IAAI,CAAkB,CAC1B,IAAM,OAAoB,IAAX,EAAE,IAAI,EAAoC,UAAlB,OAAO,EAAE,IAAI,CAC9CoB,OAAwB,IAAd,EAAE,OAAO,EAAmB,EAAM,EAAE,OAAO,GAAgC,UAA3B,OAAO,EAAE,OAAO,CAAC,KAAK,EAA6C,UAA5B,OAAO,EAAE,OAAO,CAAC,MAAM,CAC9H,OAAO,GAAU,GAAW,EAAM,EAAE,KAAK,CAAE,CAAC,MAAO,QAAQA,GAAM,EAAE,KAAK,CAAe,MAAM,CAAG,EAC3F,EAAwB,IAC/B,CACA,GAAe,YAAX,EAAE,IAAI,CAAgB,CACxB,IAAM,EAAW,EAAE,QAAQ,EAAI,EAAE,CAAE,EAAQ,EAAE,KAAK,EAAI,EAAE,CACxD,OAAO,EAAM,EAAU,CAAC,MAAO,QAAQ,GAAK,EAAM,EAAO,CAAC,MAAO,QAAS,SAAS,EAC9E,CAAE,KAAM,mBAAW,EAAU,OAAM,EAAa,IACvD,CACA,OAAO,IACT,EF8LwC,EAAE,KAAK,EAAE,MACvC,OAAO,EAAO,CAAC,CAAE,GAAI,EAAE,EAAE,MAAE,EAAM,OAAQ,SAAmB,EAAE,CAAG,EAAE,AACrE,GACI,EAA2B,EAC9B,MAAM,CAAC,AAAC,GAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,0BAA4B,EAAsB,EAAE,KAAK,EAAE,YACzF,GAAG,CAAC,AAAC,IAAM,AAAC,CAAE,GAAI,EAAE,EAAE,CAAE,UAAW,EAAE,KAAK,CAAC,SAAS,CAAe,CAAC,EACjE,EAAQ,CAAC,uBAAwB,uBAAwB,wBAAwB,CACjF,EAAQ,EACX,MAAM,CAAC,AAAC,GAAM,CAAC,EAAM,IAAI,CAAC,AAAC,GAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,KACjD,GAAG,CAAC,AAAC,GAAM,EAAE,IAAI,CAAC,OAAO,CAAC,0BAA2B,MACpD,EAAM,MAAM,EAAI,EAAU,MAAM,EAAI,EAAM,MAAM,EAAI,EAAU,MAAA,AAAM,EAAE,CACxE,GAAU,EAAQ,AAAC,IAAM,AAAC,CACxB,GAAG,CAAC,CACJ,MAAO,IAAI,EAAE,KAAK,IAAK,EAAM,CAC7B,UAAW,IAAI,EAAE,SAAS,IAAK,EAAU,CACzC,MAAO,IAAI,EAAE,KAAK,IAAK,EAAM,CAC7B,UAAW,IAAI,EAAE,SAAS,IAAK,EAAU,CAC3C,CAAC,CAEL,MAAO,GAAgB,SAAZ,EAAG,IAAI,CAAa,CAE7B,IAAM,EAAS,IAAI,IACjB,CAAC,EAAG,OAAO,EAAE,SAAW,EAAA,AAAE,EACvB,MAAM,CAAC,AAAC,GAAuD,gBAAX,EAAE,IAAI,EAAsB,EAAE,QAAQ,EAC1F,GAAG,CAAC,AAAC,GAA+B,EAAE,WAAW,GAElD,EAAO,IAAI,EAAE,AACf,GAAU,EAAQ,AAAC,IAAM,AAAC,CACxB,GAAG,CAAC,CACJ,UAAW,EAAE,SAAS,CAAC,MAAM,CAAC,AAAC,GAAM,CAAC,EAAO,GAAG,CAAC,EAAE,EAAE,GACrD,MAAO,EAAE,KAAK,CAAC,MAAM,CAAC,AAAC,GAAM,CAAC,EAAO,GAAG,CAAC,EAAE,EAAE,GAC7C,UAAW,EAAE,SAAS,CAAC,MAAM,CAAC,AAAC,GAAM,CAAC,EAAO,GAAG,CAAC,EAAE,EAAE,GACvD,CAAC,CAEL,KAAuB,EAAhB,SAAI,EAAG,IAAI,EAAiB,EAAG,QAAQ,CAC5C,CAD8C,EACpC,EAAS,AAAD,IAAQ,AAAD,CAAG,GAAG,CAAC,CAAE,MAAO,EAAG,MAAM,EAAI,EAAG,OAAO,EAAI,cAAc,CAAC,EAC9D,SAAS,CAArB,EAAG,IAAI,EAChB,GAAU,EAAQ,AAAC,GAAO,CAAD,CAAG,GAAG,CAAC,CAAE,MAAO,EAAG,OAAO,CAAC,CAAC,CAEzD,EAqD0B,EAAQ,KAAK,KAAK,CAAC,GAAO,CAAE,KAAM,CAAiC,CAEzF,CACF,CAAE,MAAO,EAAG,CACL,EAAG,MAAM,CAAC,OAAO,CACjB,GAAU,EAAQ,AAAC,GAAO,EAAE,IAAI,EAAI,EAAE,KAAK,CAAG,EAAI,CAAE,GAAG,CAAC,CAAE,MAAO,UAAW,GADzD,GAAU,EAAQ,AAAC,IAAM,AAAC,CAAE,GAAG,CAAC,CAAE,MAAQ,EAAY,OAAO,CAAC,CAAC,CAEzF,QAAU,CAGJ,EAAU,OAAO,CAAC,GAAG,CAAC,KAAY,IAAI,AACxC,EAAU,OAAO,CAAC,MAAM,CAAC,GACzB,GAAU,IAEZ,EAAS,AAAC,GAAO,EAAU,EAAI,EAAQ,AAAC,IAAM,AAAC,CAAE,GAAG,CAAC,CAAE,MAAM,EAAO,UAAW,IAAI,OAAO,WAAW,EAAG,CAAC,GAC3G,CACF,CAGA,SAAS,GAAK,CAAc,EAC1B,EAAU,OAAO,CAAC,GAAG,CAAC,IAAS,OACjC,CAqBA,SAAS,GAAY,CAAc,CAAE,CAAmC,CAAE,CAAa,EACrF,EAAS,AAAC,GAAO,EAAU,EAAI,EAAQ,AAAC,IAAM,AAAC,CAC7C,GAAG,CAAC,CACJ,MAAO,EAAO,IAAI,EAAE,KAAK,CAAE,EAAK,CAAG,EAAE,KAAK,CAC1C,SAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,GAC3B,CAAC,GACD,GAAU,EACZ,CAoCA,MAzRA,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KAAQ,SAAS,KAAK,CAAG,EAAa,SAAS,KAAK,CAAE,EAAc,EAAG,CAAC,EAAc,EAAS,EAGzG,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACR,IAAM,EAAQ,EAAa,EAAY,OAAO,CAAE,GAEhD,GADA,EAAY,OAAO,CAAG,OAAO,WAAW,CAAC,EAAM,GAAG,CAAC,AAAC,GAAM,CAAC,EAAE,EAAE,CAAE,EAAW,GAAG,GAC1E,AAAD,EAAO,MAAM,EAAK,EAAD,OAAU,MAAM,EAAM,EAAF,CAAC,cAAmB,MAAM,EAAiC,WAAW,CAAvC,aAAa,UAAU,CAC/F,IAAK,GAAM,MAAE,CAAI,QAAE,CAAM,CAAE,GAAI,EAAO,CACpC,IAAM,EAAI,IAAI,aAAwB,iBAAX,EAA4B,0BAA4B,uBAAwB,CAAE,KAAM,EAAK,KAAK,CAAE,IAAK,EAAK,EAAE,AAAC,GAC5I,EAAE,OAAO,CAAG,KAAQ,OAAO,KAAK,GAAI,CAAA,EAAA,EAAA,aAAA,AAAa,EAAC,EAAK,EAAE,EAAG,EAAE,KAAK,EAAG,CACxE,CACF,EAAG,CAAC,EAAM,EAsCV,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACR,SAAS,EAAM,CAAQ,EACrB,GAAM,SAAE,CAAO,CAAE,SAAO,CAAE,CAAI,EAAkC,MAAM,EAAI,CAAC,EAC3E,GAAI,CAAC,EAAS,OAEd,IAAM,EAAQ,EAAS,EAAO,EAAW,SAAE,EAAS,QAAS,EAAU,OAAO,CAAC,IAAI,AAAC,GACpF,GAAI,YAAa,EAAO,OAAO,EAAU,EAAM,OAAO,EACtD,EAAU,MACV,IAAM,EAAO,EAAO,GACd,EAAK,WAAY,EAAQ,EAAM,MAAM,CAAG,GAAO,EAAO,CAAE,KAAM,OAAQ,GAAI,CAAK,EAAI,MACzF,GAAK,EAAI,GAEL,AAAC,GAAS,GAAK,EACrB,CACA,SAAS,EAAO,CAAQ,EACtB,IAAM,EAAU,EAAsC,MAAM,EAAE,OAC1D,GAAU,EAAM,IAAI,CAAC,AAAC,GAAM,EAAE,EAAE,GAAK,IAAS,GAAK,EACzD,CAGA,OAFA,OAAO,gBAAgB,CAAC,EAAA,eAAe,CAAE,GACzC,OAAO,gBAAgB,CAAC,EAAA,eAAe,CAAE,GAClC,KACL,OAAO,mBAAmB,CAAC,EAAA,eAAe,CAAE,GAC5C,OAAO,mBAAmB,CAAC,EAAA,eAAe,CAAE,EAC9C,CACF,GAiNE,CAAA,EAAA,EAAA,GAAA,EAAC,EAAY,QAAQ,CAAA,CAAC,MATH,CASU,MAR7B,SAAO,UAAQ,EACf,WAnQF,SAAS,AAAW,EAA2B,CAAC,CAAC,EAC3C,AAAC,EAAK,IAAI,EAAE,EAAS,AAAC,GAAO,EAAG,MAAM,CAAE,AAAD,GAAO,EAAE,EAAE,GAAK,GAAW,EAAE,QAAQ,CAAC,MAAM,CAAG,IAC1F,EAAW,KACb,OAiQE,GAAM,YA/OR,SAAS,EACP,IAAM,EAAI,EAAY,GACtB,GAAK,EAAI,EAAE,EAAE,CAAG,KAClB,EA4OqB,UA1OrB,SAAS,AAAU,CAAS,EAC1B,IAAM,EAAI,EAAQ,EAAO,GACzB,GAAK,EAAI,EAAE,EAAE,CAAG,GAAO,GACzB,SAuOgC,QAAQ,QAAM,GAAM,OAzDpD,SAAS,AAAO,CAAc,EAC5B,IAAM,EAAO,EAAM,IAAI,CAAC,AAAC,GAAM,EAAE,EAAE,GAAK,GAClC,EAAI,EAAO,EAAe,GAAQ,QACxC,EAAI,IAAK,CAAC,OAAO,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,oBAAoB,EAAQ,IAAN,EAAU,GAAK,IAAI,CAAC,CAAC,GAAG,EACpF,GAAK,EADsF,CAE3F,EAAU,OAAO,CAAC,MAAM,CAAC,GACzB,EAAS,OAAO,CAAC,MAAM,CAAC,GAExB,EAAS,AAAC,GAAO,EAAG,MAAM,CAAC,AAAC,GAAM,EAAE,EAAE,GAAK,IACvC,IAAY,GAAQ,EAAW,MAC/B,IAAc,GAAQ,EAAa,MACvC,MAAM,CAAC,kBAAkB,EAAE,EAAA,CAAW,CAAE,CACtC,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAmB,EAC9C,KAAM,KAAK,SAAS,CAAC,CAAE,OAAQ,CAAO,EACxC,GAAG,KAAK,CAAC,AAAC,GAAM,QAAQ,IAAI,CAAC,CAAC,gCAAgC,EAAE,EAAO,CAAC,CAAC,CAAE,IACpE,GACT,EAyCE,gBA9BF,SAAS,AAAgB,CAAc,CAAE,CAAU,CAAE,CAAY,CAAE,CAAsB,EACvF,GAAY,EAAQ,AAAC,IAAM,AAAC,CAC1B,GAAG,CAAC,CACJ,UAAW,EAAE,SAAS,CAAC,GAAG,CAAC,AAAC,GAAO,EAAE,EAAE,GAAK,EAAK,CAAE,GAAG,CAAC,CAAE,QAAO,EAAI,EACtE,CAAC,EAAG,CAAC,KAAK,EAAE,EAAO,uBAAuB,EAAE,EAAK,CAAC,CAAC,CACrD,EAyBmB,YAvBnB,SAAS,AAAY,CAAc,CAAE,CAAe,CAAE,CAAkB,CAAE,CAAsB,CAAE,CAAmB,QACnH,IAAM,EAAuB,cAAc,AAA9B,EAAE,IAAI,CAAC,IAAI,CExX1B,AAAI,EAAI,CADiB,EFyX+B,EEzXW,AFyXT,IAAI,EExXjD,IAAI,EAAU,CAAP,CAAW,EAAK,IAAI,EAAE,WAAW,GAC9C,EAAK,OAAO,CAAG,CAAC,UAAU,EAAE,EAAI,EAAK,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAG,UFuXE,cAChE,GAAY,EAAQ,AAAC,IAAM,AAAC,CAC1B,GAAG,CAAC,CACJ,MAAO,EAAE,KAAK,CAAC,GAAG,CAAC,AAAC,GAAO,EAAE,EAAE,GAAK,EAAE,EAAE,CAAG,CAAE,GAAG,CAAC,QAAE,UAAQ,CAAQ,EAAI,EACzE,CAAC,EAAc,AAAX,eACA,CAAC,uBAAuB,EAAE,EAAK,UAAU,EAAE,EAAQ,GAAG,CAAC,AAAC,GAAM,EAAE,EAAE,EAAE,IAAI,CAAC,MAAA,EAAQ,EAAU,MAAM,CAAG,CAAC,aAAa,EAAE,EAAU,IAAI,CAAC,MAAM,CAAC,CAAC,CAAG,GAAG,CAAC,CAAC,CACnJ,CAAC,2BAA2B,EAAE,EAAK,CAAC,CAAC,CAC3C,EAegC,gBAbhC,SAAS,AAAgB,CAAc,CAAE,CAAgB,CAAE,CAAiB,EACtE,EAAM,IAAI,CAAC,AAAC,GAAM,EAAE,EAAE,GAAK,IAAS,MAAM,CAC9C,GAAY,EAAQ,AAAC,IAAM,AAAC,CAC1B,GAAG,CAAC,CACJ,UAAW,EAAE,SAAS,CAAC,GAAG,CAAC,AAAC,GAAO,EAAE,EAAE,GAAK,EAAI,EAAE,CAAG,CAAE,GAAG,CAAC,SAAE,CAAQ,EAAI,GAC3E,CAAC,EACD,GAAK,EAAQ,EAAc,EAAI,SAAS,CAAE,IAC5C,SAOE,eAAQ,eAAc,SACtB,EAAQ,cAAe,IAAM,EAAU,KACzC,WAGI,CAAA,EAAA,EAAA,GAAA,EAAC,EAAkB,QAAQ,CAAA,CAAC,MAAO,WAAS,KAGlD,eAhXO,SAAS,EACd,IAAM,EAAM,CAAA,EAAA,EAAA,UAAA,AAAU,EAAC,GACvB,GAAI,CAAC,EAAK,MAAM,AAAI,MAAM,iDAC1B,OAAO,CACT,mBAGO,SAAS,AAAa,CAAS,EACpC,MAAOd,CAAAA,EAAAA,EAAAA,UAAAA,AAAU,EAAC,EAAkB,CAACc,EAAU,GAAG,AACpD"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
module.exports=[
|
|
1
|
+
module.exports=[694194,a=>{"use strict";let b=[{id:"claude-md",name:"CLAUDE.md",description:"AI agent instructions for Claude Code",defaultPath:"CLAUDE.md",category:"ai-agent",content:`# {{PROJECT_NAME}} — Agent Instructions
|
|
2
2
|
|
|
3
3
|
## What this is
|
|
4
4
|
{{DESCRIPTION}}
|
|
@@ -2106,4 +2106,4 @@ readinessProbe:
|
|
|
2106
2106
|
<!-- Key takeaways to share with the wider team -->
|
|
2107
2107
|
`}];a.s(["TEMPLATES",0,f],694194)}];
|
|
2108
2108
|
|
|
2109
|
-
//# sourceMappingURL=
|
|
2109
|
+
//# sourceMappingURL=src_lib_templates_index_ts_1s61uk7._.js.map
|