@dendelion/paper-camp 0.23.2 → 0.24.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.
Files changed (29) hide show
  1. package/dist/app/assets/{index-D_2SBGCS.js → index-B5TCF8_a.js} +2 -2
  2. package/dist/app/assets/{index-D_2SBGCS.js.map → index-B5TCF8_a.js.map} +1 -1
  3. package/dist/app/assets/{index-Do4T60UL.js → index-BY8Yo_l0.js} +2 -2
  4. package/dist/app/assets/{index-Do4T60UL.js.map → index-BY8Yo_l0.js.map} +1 -1
  5. package/dist/app/assets/{index-BHPCJror.js → index-BxRIu8zx.js} +2 -2
  6. package/dist/app/assets/{index-BHPCJror.js.map → index-BxRIu8zx.js.map} +1 -1
  7. package/dist/app/assets/{index-SD_x9Z5F.js → index-C1ORGbU3.js} +2 -2
  8. package/dist/app/assets/{index-SD_x9Z5F.js.map → index-C1ORGbU3.js.map} +1 -1
  9. package/dist/app/assets/{index-DePKcR5b.js → index-C3R9IAt7.js} +2 -2
  10. package/dist/app/assets/{index-DePKcR5b.js.map → index-C3R9IAt7.js.map} +1 -1
  11. package/dist/app/assets/{index-DxehIB14.js → index-CR8PI9q6.js} +2 -2
  12. package/dist/app/assets/{index-DxehIB14.js.map → index-CR8PI9q6.js.map} +1 -1
  13. package/dist/app/assets/{index-DG2ri3IF.js → index-Ddz2TPW1.js} +2 -2
  14. package/dist/app/assets/{index-DG2ri3IF.js.map → index-Ddz2TPW1.js.map} +1 -1
  15. package/dist/app/assets/{index-mmzETz6G.js → index-rxWn42R9.js} +2 -2
  16. package/dist/app/assets/{index-mmzETz6G.js.map → index-rxWn42R9.js.map} +1 -1
  17. package/dist/app/assets/{main-DiplEwD3.js → main-DkQCGPBX.js} +119 -119
  18. package/dist/app/assets/main-DkQCGPBX.js.map +1 -0
  19. package/dist/app/assets/main-o2BbWpF4.css +1 -0
  20. package/dist/app/assets/{sidebar-section-RSOrdZKe.js → sidebar-section-Cqk2bPNP.js} +2 -2
  21. package/dist/app/assets/{sidebar-section-RSOrdZKe.js.map → sidebar-section-Cqk2bPNP.js.map} +1 -1
  22. package/dist/app/index.html +2 -2
  23. package/dist/app/toolbar.js +3030 -2968
  24. package/dist/app/toolbar.js.map +1 -1
  25. package/dist/cli/index.js +2299 -2293
  26. package/dist/cli/index.js.map +1 -1
  27. package/package.json +1 -1
  28. package/dist/app/assets/main-DiplEwD3.js.map +0 -1
  29. package/dist/app/assets/main-DoJre3S-.css +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index-mmzETz6G.js","sources":["../../../src/app/features/roadmap/hooks/use-roadmap-page.ts","../../../src/app/features/roadmap/hooks/use-roadmap-sidebar.ts","../../../src/app/features/roadmap/modals/add-roadmap-item-modal.tsx","../../../src/app/features/roadmap/modals/promote-roadmap-item-modal.tsx","../../../src/app/features/roadmap/views/add-candidate-form.tsx","../../../src/app/features/roadmap/views/candidate-row.tsx","../../../src/app/features/roadmap/views/goal-banner.tsx","../../../src/app/features/roadmap/constants.ts","../../../src/app/features/roadmap/views/idea-row.tsx","../../../src/app/features/roadmap/views/progress-bar.tsx","../../../src/app/features/roadmap/views/roadmap-item-row.tsx","../../../src/app/features/roadmap/views/horizon-section.tsx","../../../src/app/features/roadmap/roadmap-page.tsx","../../../src/app/features/roadmap/roadmap-sidebar.tsx"],"sourcesContent":["import { useOpenEntity } from '@/app/hooks';\nimport { addRoadmapCandidate } from '@/app/services/content/docs-api';\nimport { useAppStore } from '@/app/stores/app-store';\nimport type { PlanEntry, ResolvedRoadmapItem } from '@/types/index';\nimport { useSearch } from '@tanstack/react-router';\nimport { useEffect, useRef, useState } from 'react';\nimport { filterHorizons } from '../helpers';\n\ninterface Promoting {\n horizonTitle: string;\n item: ResolvedRoadmapItem;\n candidateName?: string;\n}\n\nexport const useRoadmapPage = () => {\n const roadmap = useAppStore((s) => s.roadmap);\n const roadmapError = useAppStore((s) => s.roadmapError);\n const loadRoadmap = useAppStore((s) => s.loadRoadmap);\n const filters = useAppStore((s) => s.roadmapFilters);\n const plans = useAppStore((s) => s.plans);\n const openEntity = useOpenEntity();\n const { item: highlightedItem } = useSearch({ from: '/roadmap' });\n const containerRef = useRef<HTMLDivElement>(null);\n const [promoting, setPromoting] = useState<Promoting | null>(null);\n\n useEffect(() => {\n loadRoadmap();\n }, [loadRoadmap]);\n\n useEffect(() => {\n if (!highlightedItem || !roadmap) return;\n const row = containerRef.current?.querySelector('.roadmap-item-highlighted');\n row?.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }, [highlightedItem, roadmap]);\n\n const graduatedByItem = (item: ResolvedRoadmapItem): PlanEntry[] =>\n plans?.entries.filter((p) => p.subject === item.name) ?? [];\n\n const handleAddCandidate = async (horizonTitle: string, itemName: string, name: string) => {\n await addRoadmapCandidate(horizonTitle, itemName, name);\n await loadRoadmap();\n };\n\n const handlePromote = (\n horizonTitle: string,\n item: ResolvedRoadmapItem,\n candidateName?: string,\n ) => {\n setPromoting({ horizonTitle, item, candidateName });\n };\n\n const horizons = roadmap ? filterHorizons(roadmap, filters) : [];\n const totalVisible = horizons.reduce((count, horizon) => count + horizon.items.length, 0);\n const hasActiveFilters = filters.horizons.length > 0 || filters.statuses.length > 0;\n\n return {\n roadmap,\n roadmapError,\n loadRoadmap,\n horizons,\n totalVisible,\n hasActiveFilters,\n highlightedItem,\n containerRef,\n promoting,\n setPromoting,\n graduatedByItem,\n handleAddCandidate,\n handlePromote,\n onOpenGraduated: openEntity,\n };\n};\n","import { useAppStore } from '@/app/stores/app-store';\nimport type { PlanStatus } from '@/types/index';\nimport { useState } from 'react';\nimport { horizonItemCounts, statusItemCounts } from '../helpers';\n\nconst STATUS_CHIP_ORDER: PlanStatus[] = [\n 'in-progress',\n 'review',\n 'planned',\n 'idea',\n 'done',\n 'dropped',\n];\n\nexport const useRoadmapSidebar = () => {\n const roadmap = useAppStore((s) => s.roadmap);\n const filters = useAppStore((s) => s.roadmapFilters);\n const toggleRoadmapHorizon = useAppStore((s) => s.toggleRoadmapHorizon);\n const toggleRoadmapStatus = useAppStore((s) => s.toggleRoadmapStatus);\n const [addOpen, setAddOpen] = useState(false);\n\n const horizonTitles = roadmap?.horizons.map((horizon) => horizon.title) ?? [];\n const horizonCounts = roadmap ? horizonItemCounts(roadmap, filters) : {};\n const statusCounts = roadmap ? statusItemCounts(roadmap, filters) : {};\n const activeHorizons = new Set(filters.horizons);\n const activeStatuses = new Set(filters.statuses);\n const visibleStatuses = STATUS_CHIP_ORDER.filter(\n (status) => (statusCounts[status] ?? 0) > 0 || activeStatuses.has(status),\n );\n\n return {\n roadmap,\n horizonTitles,\n horizonCounts,\n statusCounts,\n activeHorizons,\n activeStatuses,\n visibleStatuses,\n addOpen,\n setAddOpen,\n toggleRoadmapHorizon,\n toggleRoadmapStatus,\n };\n};\n","import { addRoadmapItem } from '@/app/services/content/docs-api';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { Button, Input, Modal, Select } from '@dendelion/paper-ui';\nimport { useEffect, useRef, useState } from 'react';\n\ninterface AddRoadmapItemModalProps {\n open: boolean;\n horizonTitles: string[];\n onClose: () => void;\n}\n\nexport const AddRoadmapItemModal = ({ open, horizonTitles, onClose }: AddRoadmapItemModalProps) => {\n const loadRoadmap = useAppStore((s) => s.loadRoadmap);\n const [horizon, setHorizon] = useState(horizonTitles[0] ?? '');\n const [name, setName] = useState('');\n const [description, setDescription] = useState('');\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const horizonTitlesRef = useRef(horizonTitles);\n horizonTitlesRef.current = horizonTitles;\n\n useEffect(() => {\n if (open) {\n setHorizon(horizonTitlesRef.current[0] ?? '');\n setName('');\n setDescription('');\n setError(null);\n setSaving(false);\n }\n }, [open]);\n\n const handleAdd = async () => {\n if (!name.trim() || !horizon) return;\n setSaving(true);\n setError(null);\n try {\n await addRoadmapItem(horizon, name.trim(), description.trim());\n await loadRoadmap();\n onClose();\n } catch (err) {\n setError((err as Error).message);\n } finally {\n setSaving(false);\n }\n };\n\n return (\n <Modal open={open} onClose={onClose} title=\"Add roadmap item\" size=\"small\">\n <div className=\"flex flex-col gap-4\">\n <Select\n size=\"small\"\n value={horizon}\n onChange={setHorizon}\n disabled={saving}\n options={horizonTitles.map((title) => ({ value: title, label: title }))}\n />\n <Input\n size=\"small\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"Item name…\"\n disabled={saving}\n autoFocus\n />\n <Input\n size=\"small\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleAdd();\n }}\n placeholder=\"Description…\"\n disabled={saving}\n />\n {error && <p className=\"m-0 text-watercolor-rose-dark text-sm\">{error}</p>}\n <div className=\"flex justify-end gap-2\">\n <Button type=\"button\" variant=\"ghost\" onClick={onClose} disabled={saving}>\n Cancel\n </Button>\n <Button\n type=\"button\"\n variant=\"primary\"\n onClick={handleAdd}\n disabled={saving || !name.trim() || !horizon}\n >\n {saving ? 'Adding…' : 'Add item'}\n </Button>\n </div>\n </div>\n </Modal>\n );\n};\n","import { buildRoadmapPromotePrompt } from '@/app/features/plans/prompts';\nimport { useSubjectVocabulary } from '@/app/hooks/use-subject-vocabulary';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { oneLineErrorSummary } from '@/app/utils/error-summary';\nimport type { RoadmapItem } from '@/types/index';\nimport { Button, Modal, Select, useToast } from '@dendelion/paper-ui';\nimport { useEffect, useState } from 'react';\n\nconst NO_SUBJECT = '__no-subject__';\n\ninterface PromoteRoadmapItemModalProps {\n horizonTitle: string | null;\n item: RoadmapItem | null;\n candidateName?: string | null;\n onClose: () => void;\n onPromoted: () => void;\n}\n\nexport const PromoteRoadmapItemModal = ({\n horizonTitle,\n item,\n candidateName,\n onClose,\n onPromoted,\n}: PromoteRoadmapItemModalProps) => {\n const promoteRoadmapItem = useAppStore((s) => s.promoteRoadmapItem);\n const launchIdeaExtend = useAppStore((s) => s.launchIdeaExtend);\n const { subjects, available: subjectsAvailable } = useSubjectVocabulary();\n const [subject, setSubject] = useState(NO_SUBJECT);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const { toast } = useToast();\n\n useEffect(() => {\n if (item) {\n // A candidate defaults to its parent item's name — the \"big bet becomes a\n // Subject\" rule — but the picker still lets the user override it.\n setSubject(candidateName ? item.name : NO_SUBJECT);\n setLoading(false);\n setError(null);\n }\n }, [item, candidateName]);\n\n const handlePromote = async () => {\n if (!item || !horizonTitle) return;\n setLoading(true);\n setError(null);\n try {\n const id = await promoteRoadmapItem(\n horizonTitle,\n item,\n subject === NO_SUBJECT ? undefined : subject,\n candidateName ?? undefined,\n );\n const idea = useAppStore.getState().ideaEntries.find((e) => e.id === id);\n if (idea) {\n try {\n await launchIdeaExtend(id, buildRoadmapPromotePrompt(idea, horizonTitle));\n } catch (err) {\n // The idea was created either way — a failed refine launch just means\n // no background research ran, not that the promotion itself failed.\n toast({\n title: 'Idea created, but the refine agent failed to launch',\n description: oneLineErrorSummary((err as Error).message),\n variant: 'error',\n });\n }\n }\n onPromoted();\n onClose();\n } catch (err) {\n setError((err as Error).message);\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <Modal\n open={item !== null}\n onClose={onClose}\n title={candidateName ?? item?.name ?? ''}\n size=\"small\"\n >\n <div className=\"flex flex-col gap-4\">\n {!candidateName && <p className=\"m-0 opacity-80\">{item?.description}</p>}\n <div>\n <Select\n size=\"small\"\n value={subject}\n onChange={setSubject}\n disabled={loading || !subjectsAvailable}\n options={[\n { value: NO_SUBJECT, label: 'No subject' },\n ...(!subjectsAvailable && subject !== NO_SUBJECT\n ? [{ value: subject, label: subject }]\n : []),\n ...subjects.map((s) => ({ value: s, label: s })),\n ]}\n />\n </div>\n {error && <p className=\"m-0 text-watercolor-rose-dark text-sm\">{error}</p>}\n <div className=\"flex justify-end gap-2\">\n <Button type=\"button\" variant=\"ghost\" onClick={onClose} disabled={loading}>\n Cancel\n </Button>\n <Button type=\"button\" variant=\"primary\" onClick={handlePromote} disabled={loading}>\n {loading ? 'Promoting…' : 'Promote to idea'}\n </Button>\n </div>\n </div>\n </Modal>\n );\n};\n","import { Button, Input } from '@dendelion/paper-ui';\nimport { useState } from 'react';\n\ninterface AddCandidateFormProps {\n onAdd: (name: string) => Promise<void>;\n}\n\nexport const AddCandidateForm = ({ onAdd }: AddCandidateFormProps) => {\n const [name, setName] = useState('');\n const [saving, setSaving] = useState(false);\n\n const handleAdd = async () => {\n if (!name.trim()) return;\n setSaving(true);\n try {\n await onAdd(name.trim());\n setName('');\n } finally {\n setSaving(false);\n }\n };\n\n return (\n <div className=\"flex gap-2\">\n <Input\n size=\"small\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleAdd();\n }}\n placeholder=\"Add option…\"\n disabled={saving}\n className=\"flex-1\"\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"small\"\n onClick={handleAdd}\n disabled={saving || !name.trim()}\n >\n Add\n </Button>\n </div>\n );\n};\n","import { Button, Card } from '@dendelion/paper-ui';\n\ninterface CandidateRowProps {\n name: string;\n onPromote: () => void;\n}\n\nexport const CandidateRow = ({ name, onPromote }: CandidateRowProps) => (\n <Card size=\"small\" texture=\"kraft\" className=\"plan-row-card\">\n <div className=\"flex items-center gap-3\">\n <span className=\"flex-1\">{name}</span>\n <Button type=\"button\" variant=\"ghost\" size=\"small\" onClick={onPromote}>\n Promote to idea\n </Button>\n </div>\n </Card>\n);\n","import { Markdown } from '@/app/components/markdown';\nimport { useState } from 'react';\n\ninterface GoalBannerProps {\n goal: string;\n}\n\nexport const GoalBanner = ({ goal }: GoalBannerProps) => {\n const [expanded, setExpanded] = useState(false);\n const [firstParagraph, ...restParagraphs] = goal.split(/\\n{2,}/);\n const hasMore = restParagraphs.length > 0;\n\n return (\n <div className=\"mb-6 pb-4 border-b border-black/[8%]\">\n <span className=\"font-handwritten text-xs font-semibold opacity-[0.55]\">The goal</span>\n <div className=\"text-sm leading-relaxed opacity-80 mt-2\">\n <Markdown>{firstParagraph}</Markdown>\n {expanded && hasMore && <Markdown>{restParagraphs.join('\\n\\n')}</Markdown>}\n </div>\n {hasMore && (\n <button\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n className=\"bg-transparent border-none p-0 mt-2 cursor-pointer text-2xs opacity-[0.65] underline\"\n >\n {expanded ? 'Show less' : 'Show more'}\n </button>\n )}\n </div>\n );\n};\n","export const HIGHLIGHT_OUTLINE_CLASS = 'outline-[rgba(200,154,90,0.5)]';\n\nexport const CANDIDATE_STAMP = {\n fill: 'rgba(0, 0, 0, 0.06)',\n text: 'rgba(0, 0, 0, 0.55)',\n};\n","import { PrBadge } from '@/app/features/plans/components/pr-badge';\nimport { STATUS_LABEL, STATUS_STAMP } from '@/app/features/plans/constants';\nimport type { PlanEntry, PlanStatus, PrInfo, RoadmapLink } from '@/types/index';\nimport { Card, Stamp } from '@dendelion/paper-ui';\n\nexport interface MergedIdea {\n key: string;\n label: string;\n status: PlanStatus;\n pr?: PrInfo;\n planId?: string;\n planTitle?: string;\n}\n\nexport const mergeIdeas = (links: RoadmapLink[], graduated: PlanEntry[]): MergedIdea[] => {\n const represented = new Set<string>();\n const merged: MergedIdea[] = graduated.map((plan) => {\n if (plan.id) represented.add(plan.id);\n if (plan.idea) represented.add(plan.idea);\n return {\n key: plan.title,\n label: plan.title,\n status: plan.status,\n pr: plan.pr,\n planId: plan.id,\n planTitle: plan.title,\n };\n });\n for (const link of links) {\n if (represented.has(link.id)) continue;\n merged.push({ key: link.id, label: link.id, status: link.status, pr: link.pr });\n }\n return merged;\n};\n\ninterface IdeaRowProps {\n idea: MergedIdea;\n onOpen?: () => void;\n}\n\nexport const IdeaRow = ({ idea, onOpen }: IdeaRowProps) => (\n <Card size=\"small\" texture=\"kraft\" className=\"plan-row-card\">\n <div className=\"flex items-center gap-3\">\n {onOpen ? (\n <button\n type=\"button\"\n onClick={onOpen}\n className=\"flex-1 min-w-0 overflow-hidden text-ellipsis whitespace-nowrap bg-transparent border-none p-0 cursor-pointer [font:inherit] text-inherit text-left\"\n >\n {idea.label}\n </button>\n ) : (\n <span className=\"flex-1 min-w-0 overflow-hidden text-ellipsis whitespace-nowrap\">\n {idea.label}\n </span>\n )}\n {idea.pr && <PrBadge pr={idea.pr} />}\n <Stamp\n size=\"small\"\n fillColor={STATUS_STAMP[idea.status].fill}\n textColor={STATUS_STAMP[idea.status].text}\n >\n {STATUS_LABEL[idea.status]}\n </Stamp>\n </div>\n </Card>\n);\n","interface ProgressBarProps {\n done: number;\n total: number;\n}\n\nexport const ProgressBar = ({ done, total }: ProgressBarProps) => {\n const percent = total > 0 ? Math.round((done / total) * 100) : 0;\n return (\n <div className=\"w-24 h-1.5 rounded-full bg-black/[0.08] overflow-hidden shrink-0\">\n <div\n className={`h-full rounded-full ${total > 0 ? 'bg-watercolor-green' : 'bg-transparent'}`}\n style={{ width: `${percent}%` }}\n />\n </div>\n );\n};\n","import { STATUS_STAMP } from '@/app/features/plans/constants';\nimport type { PlanEntry, ResolvedRoadmapItem } from '@/types/index';\nimport { Button, Stamp } from '@dendelion/paper-ui';\nimport { useEffect, useState } from 'react';\nimport { CANDIDATE_STAMP, HIGHLIGHT_OUTLINE_CLASS } from '../constants';\nimport { AddCandidateForm } from './add-candidate-form';\nimport { CandidateRow } from './candidate-row';\nimport { IdeaRow, mergeIdeas } from './idea-row';\nimport { ProgressBar } from './progress-bar';\n\nconst graduationCounts = (graduated: PlanEntry[]) => ({\n shipped: graduated.filter((p) => p.status === 'done').length,\n queued: graduated.filter((p) => p.status !== 'done' && p.status !== 'dropped').length,\n});\n\nconst ChevronRightIcon = ({ size = 14 }: { size?: number }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n);\n\ninterface RoadmapItemRowProps {\n item: ResolvedRoadmapItem;\n graduated: PlanEntry[];\n highlighted: boolean;\n onPromote: () => void;\n onPromoteCandidate: (candidateName: string) => void;\n onAddCandidate: (name: string) => Promise<void>;\n onOpenGraduated: (id: string | undefined, title: string) => void;\n}\n\nexport const RoadmapItemRow = ({\n item,\n graduated,\n highlighted,\n onPromote,\n onPromoteCandidate,\n onAddCandidate,\n onOpenGraduated,\n}: RoadmapItemRowProps) => {\n const [expanded, setExpanded] = useState(highlighted);\n const { shipped, queued } = graduationCounts(graduated);\n const candidates = item.candidates.length;\n const ideas = mergeIdeas(item.links, graduated);\n\n useEffect(() => {\n if (highlighted) setExpanded(true);\n }, [highlighted]);\n\n return (\n <div\n className={`border-b border-black/10 last:border-b-0 ${highlighted ? `roadmap-item-highlighted outline outline-2 outline-offset-[-2px] ${HIGHLIGHT_OUTLINE_CLASS}` : ''}`}\n >\n <button\n type=\"button\"\n aria-expanded={expanded}\n onClick={() => setExpanded((v) => !v)}\n className=\"flex w-full items-center gap-3 py-2.5 px-0 bg-transparent border-none cursor-pointer text-left [font:inherit] text-inherit\"\n >\n <span\n className={`inline-flex items-center opacity-50 shrink-0 ${expanded ? 'rotate-90' : ''}`}\n >\n <ChevronRightIcon />\n </span>\n <span className=\"font-semibold flex-1 min-w-0 truncate\">{item.name}</span>\n <ProgressBar done={item.rollup.done} total={item.rollup.total} />\n {queued > 0 && (\n <Stamp\n size=\"small\"\n fillColor={STATUS_STAMP.planned.fill}\n textColor={STATUS_STAMP.planned.text}\n >\n {queued} in queue\n </Stamp>\n )}\n {shipped > 0 && (\n <Stamp size=\"small\" fillColor={STATUS_STAMP.done.fill} textColor={STATUS_STAMP.done.text}>\n {shipped} shipped\n </Stamp>\n )}\n {candidates > 0 && (\n <Stamp size=\"small\" fillColor={CANDIDATE_STAMP.fill} textColor={CANDIDATE_STAMP.text}>\n {candidates} candidate{candidates === 1 ? '' : 's'}\n </Stamp>\n )}\n </button>\n {expanded && (\n <div className=\"flex flex-col gap-1 pl-6 pb-4\">\n <span className=\"text-sm opacity-70\">{item.description}</span>\n {ideas.map((idea) => (\n <IdeaRow\n key={idea.key}\n idea={idea}\n onOpen={\n idea.planTitle\n ? () => onOpenGraduated(idea.planId, idea.planTitle as string)\n : undefined\n }\n />\n ))}\n {item.candidates.map((candidateName) => (\n <CandidateRow\n key={candidateName}\n name={candidateName}\n onPromote={() => onPromoteCandidate(candidateName)}\n />\n ))}\n <AddCandidateForm onAdd={onAddCandidate} />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"small\"\n onClick={onPromote}\n className=\"self-start\"\n >\n Promote to idea\n </Button>\n </div>\n )}\n </div>\n );\n};\n","import type { PlanEntry, ResolvedRoadmapHorizon, ResolvedRoadmapItem } from '@/types/index';\nimport { RoadmapItemRow } from './roadmap-item-row';\n\nconst HORIZON_HEADER_CLASSES =\n 'font-handwritten text-md font-semibold opacity-70 leading-none pt-2 px-1 pb-0';\n\ninterface HorizonSectionProps {\n horizon: ResolvedRoadmapHorizon;\n highlightedItem: string | undefined;\n graduatedByItem: (item: ResolvedRoadmapItem) => PlanEntry[];\n onPromote: (item: ResolvedRoadmapItem, candidateName?: string) => void;\n onAddCandidate: (itemName: string, name: string) => Promise<void>;\n onOpenGraduated: (id: string | undefined, title: string) => void;\n}\n\nexport const HorizonSection = ({\n horizon,\n highlightedItem,\n graduatedByItem,\n onPromote,\n onAddCandidate,\n onOpenGraduated,\n}: HorizonSectionProps) => (\n <div className=\"flex flex-col gap-1\">\n <div className={HORIZON_HEADER_CLASSES}>{horizon.title}</div>\n <div className=\"flex flex-col\">\n {horizon.items.map((item) => (\n <RoadmapItemRow\n key={item.name}\n item={item}\n graduated={graduatedByItem(item)}\n highlighted={item.name === highlightedItem}\n onPromote={() => onPromote(item)}\n onPromoteCandidate={(candidateName) => onPromote(item, candidateName)}\n onAddCandidate={(name) => onAddCandidate(item.name, name)}\n onOpenGraduated={onOpenGraduated}\n />\n ))}\n </div>\n </div>\n);\n","import { PageTitle } from '@/app/components/page-title';\nimport { useRoadmapPage } from './hooks';\nimport { PromoteRoadmapItemModal } from './modals';\nimport { GoalBanner, HorizonSection } from './views';\n\nexport const RoadmapPage = () => {\n const {\n roadmap,\n roadmapError,\n loadRoadmap,\n horizons,\n totalVisible,\n hasActiveFilters,\n highlightedItem,\n containerRef,\n promoting,\n setPromoting,\n graduatedByItem,\n handleAddCandidate,\n handlePromote,\n onOpenGraduated,\n } = useRoadmapPage();\n\n if (roadmapError) {\n return (\n <div>\n <PageTitle>Roadmap</PageTitle>\n <p className=\"opacity-50\">\n Couldn't load the roadmap — the server may need a restart to pick up new routes.\n </p>\n </div>\n );\n }\n\n if (!roadmap) {\n return (\n <div>\n <PageTitle>Roadmap</PageTitle>\n <p className=\"opacity-50\">Loading…</p>\n </div>\n );\n }\n\n if (roadmap.horizons.length === 0) {\n return (\n <div>\n <PageTitle>Roadmap</PageTitle>\n <p className=\"opacity-50\">No `ROADMAP.md` found at the project root.</p>\n </div>\n );\n }\n\n return (\n <div ref={containerRef}>\n <PageTitle>Roadmap</PageTitle>\n <GoalBanner goal={roadmap.goal} />\n {totalVisible === 0 ? (\n <p className=\"opacity-50 py-6 px-0 text-center\">\n {hasActiveFilters\n ? 'Nothing matches these filters — clear one from the sidebar to see more.'\n : 'No roadmap items yet — add one from the sidebar.'}\n </p>\n ) : (\n <div className=\"flex flex-col gap-6\">\n {horizons\n .filter((horizon) => horizon.items.length > 0)\n .map((horizon) => (\n <HorizonSection\n key={horizon.title}\n horizon={horizon}\n highlightedItem={highlightedItem}\n graduatedByItem={graduatedByItem}\n onPromote={(item, candidateName) =>\n handlePromote(horizon.title, item, candidateName)\n }\n onAddCandidate={(itemName, name) =>\n handleAddCandidate(horizon.title, itemName, name)\n }\n onOpenGraduated={onOpenGraduated}\n />\n ))}\n </div>\n )}\n <PromoteRoadmapItemModal\n horizonTitle={promoting?.horizonTitle ?? null}\n item={promoting?.item ?? null}\n candidateName={promoting?.candidateName}\n onClose={() => setPromoting(null)}\n onPromoted={loadRoadmap}\n />\n </div>\n );\n};\n","import { STATUS_LABEL, STATUS_STAMP } from '@/app/features/plans/constants';\nimport { Button, ListItem } from '@dendelion/paper-ui';\nimport { useRoadmapSidebar } from './hooks';\nimport { AddRoadmapItemModal } from './modals';\n\n// Matches SidebarSection — handwritten, no caps, one grid cell.\nconst sectionLabelClass = 'pc-row-label font-handwritten text-xs font-semibold opacity-[0.45]';\n\nexport const RoadmapSidebar = () => {\n const {\n roadmap,\n horizonTitles,\n horizonCounts,\n statusCounts,\n activeHorizons,\n activeStatuses,\n visibleStatuses,\n addOpen,\n setAddOpen,\n toggleRoadmapHorizon,\n toggleRoadmapStatus,\n } = useRoadmapSidebar();\n\n if (!roadmap) return null;\n\n return (\n <div className=\"flex flex-col\">\n <div className=\"flex h-[64px] items-center\">\n <Button\n type=\"button\"\n variant=\"primary\"\n size=\"small\"\n onClick={() => setAddOpen(true)}\n disabled={horizonTitles.length === 0}\n >\n + Add item\n </Button>\n </div>\n\n <div>\n <div className={sectionLabelClass}>Horizon</div>\n <div className=\"flex flex-col\">\n {horizonTitles.map((title) => (\n <ListItem\n key={title}\n size=\"small\"\n active={activeHorizons.has(title)}\n onClick={() => toggleRoadmapHorizon(title)}\n className=\"pc-row text-xs\"\n action={<span className=\"text-2xs text-ink-500\">{horizonCounts[title] ?? 0}</span>}\n >\n {title}\n </ListItem>\n ))}\n </div>\n </div>\n\n <div>\n <div className={sectionLabelClass}>Status</div>\n <div className=\"flex flex-col\">\n {visibleStatuses.length === 0 && (\n <span className=\"opacity-50 text-2xs\">No linked ideas</span>\n )}\n {visibleStatuses.map((status) => (\n <ListItem\n key={status}\n size=\"small\"\n active={activeStatuses.has(status)}\n onClick={() => toggleRoadmapStatus(status)}\n className=\"pc-row text-xs\"\n icon={\n <span\n className=\"w-[9px] h-[9px] rounded-full shrink-0\"\n style={{ background: STATUS_STAMP[status].text }}\n />\n }\n action={<span className=\"text-2xs text-ink-500\">{statusCounts[status] ?? 0}</span>}\n >\n {STATUS_LABEL[status]}\n </ListItem>\n ))}\n </div>\n </div>\n\n <AddRoadmapItemModal\n open={addOpen}\n horizonTitles={horizonTitles}\n onClose={() => setAddOpen(false)}\n />\n </div>\n );\n};\n"],"names":["useRoadmapPage","roadmap","useAppStore","s","roadmapError","loadRoadmap","filters","plans","openEntity","useOpenEntity","highlightedItem","useSearch","containerRef","useRef","promoting","setPromoting","useState","useEffect","row","_a","graduatedByItem","item","p","handleAddCandidate","horizonTitle","itemName","name","addRoadmapCandidate","handlePromote","candidateName","horizons","filterHorizons","totalVisible","count","horizon","hasActiveFilters","STATUS_CHIP_ORDER","useRoadmapSidebar","toggleRoadmapHorizon","toggleRoadmapStatus","addOpen","setAddOpen","horizonTitles","horizonCounts","horizonItemCounts","statusCounts","statusItemCounts","activeHorizons","activeStatuses","visibleStatuses","status","AddRoadmapItemModal","open","onClose","setHorizon","setName","description","setDescription","saving","setSaving","error","setError","horizonTitlesRef","handleAdd","addRoadmapItem","err","jsx","Modal","jsxs","Select","title","Input","e","Button","NO_SUBJECT","PromoteRoadmapItemModal","onPromoted","promoteRoadmapItem","launchIdeaExtend","subjects","subjectsAvailable","useSubjectVocabulary","subject","setSubject","loading","setLoading","toast","useToast","id","idea","buildRoadmapPromotePrompt","oneLineErrorSummary","AddCandidateForm","onAdd","CandidateRow","onPromote","Card","GoalBanner","goal","expanded","setExpanded","firstParagraph","restParagraphs","hasMore","Markdown","v","HIGHLIGHT_OUTLINE_CLASS","CANDIDATE_STAMP","mergeIdeas","links","graduated","represented","merged","plan","link","IdeaRow","onOpen","PrBadge","Stamp","STATUS_STAMP","STATUS_LABEL","ProgressBar","done","total","percent","graduationCounts","ChevronRightIcon","size","RoadmapItemRow","highlighted","onPromoteCandidate","onAddCandidate","onOpenGraduated","shipped","queued","candidates","ideas","HORIZON_HEADER_CLASSES","HorizonSection","RoadmapPage","PageTitle","sectionLabelClass","RoadmapSidebar","ListItem"],"mappings":"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"}
1
+ {"version":3,"file":"index-rxWn42R9.js","sources":["../../../src/app/features/roadmap/hooks/use-roadmap-page.ts","../../../src/app/features/roadmap/hooks/use-roadmap-sidebar.ts","../../../src/app/features/roadmap/modals/add-roadmap-item-modal.tsx","../../../src/app/features/roadmap/modals/promote-roadmap-item-modal.tsx","../../../src/app/features/roadmap/views/add-candidate-form.tsx","../../../src/app/features/roadmap/views/candidate-row.tsx","../../../src/app/features/roadmap/views/goal-banner.tsx","../../../src/app/features/roadmap/constants.ts","../../../src/app/features/roadmap/views/idea-row.tsx","../../../src/app/features/roadmap/views/progress-bar.tsx","../../../src/app/features/roadmap/views/roadmap-item-row.tsx","../../../src/app/features/roadmap/views/horizon-section.tsx","../../../src/app/features/roadmap/roadmap-page.tsx","../../../src/app/features/roadmap/roadmap-sidebar.tsx"],"sourcesContent":["import { useOpenEntity } from '@/app/hooks';\nimport { addRoadmapCandidate } from '@/app/services/content/docs-api';\nimport { useAppStore } from '@/app/stores/app-store';\nimport type { PlanEntry, ResolvedRoadmapItem } from '@/types/index';\nimport { useSearch } from '@tanstack/react-router';\nimport { useEffect, useRef, useState } from 'react';\nimport { filterHorizons } from '../helpers';\n\ninterface Promoting {\n horizonTitle: string;\n item: ResolvedRoadmapItem;\n candidateName?: string;\n}\n\nexport const useRoadmapPage = () => {\n const roadmap = useAppStore((s) => s.roadmap);\n const roadmapError = useAppStore((s) => s.roadmapError);\n const loadRoadmap = useAppStore((s) => s.loadRoadmap);\n const filters = useAppStore((s) => s.roadmapFilters);\n const plans = useAppStore((s) => s.plans);\n const openEntity = useOpenEntity();\n const { item: highlightedItem } = useSearch({ from: '/roadmap' });\n const containerRef = useRef<HTMLDivElement>(null);\n const [promoting, setPromoting] = useState<Promoting | null>(null);\n\n useEffect(() => {\n loadRoadmap();\n }, [loadRoadmap]);\n\n useEffect(() => {\n if (!highlightedItem || !roadmap) return;\n const row = containerRef.current?.querySelector('.roadmap-item-highlighted');\n row?.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }, [highlightedItem, roadmap]);\n\n const graduatedByItem = (item: ResolvedRoadmapItem): PlanEntry[] =>\n plans?.entries.filter((p) => p.subject === item.name) ?? [];\n\n const handleAddCandidate = async (horizonTitle: string, itemName: string, name: string) => {\n await addRoadmapCandidate(horizonTitle, itemName, name);\n await loadRoadmap();\n };\n\n const handlePromote = (\n horizonTitle: string,\n item: ResolvedRoadmapItem,\n candidateName?: string,\n ) => {\n setPromoting({ horizonTitle, item, candidateName });\n };\n\n const horizons = roadmap ? filterHorizons(roadmap, filters) : [];\n const totalVisible = horizons.reduce((count, horizon) => count + horizon.items.length, 0);\n const hasActiveFilters = filters.horizons.length > 0 || filters.statuses.length > 0;\n\n return {\n roadmap,\n roadmapError,\n loadRoadmap,\n horizons,\n totalVisible,\n hasActiveFilters,\n highlightedItem,\n containerRef,\n promoting,\n setPromoting,\n graduatedByItem,\n handleAddCandidate,\n handlePromote,\n onOpenGraduated: openEntity,\n };\n};\n","import { useAppStore } from '@/app/stores/app-store';\nimport type { PlanStatus } from '@/types/index';\nimport { useState } from 'react';\nimport { horizonItemCounts, statusItemCounts } from '../helpers';\n\nconst STATUS_CHIP_ORDER: PlanStatus[] = [\n 'in-progress',\n 'review',\n 'planned',\n 'idea',\n 'done',\n 'dropped',\n];\n\nexport const useRoadmapSidebar = () => {\n const roadmap = useAppStore((s) => s.roadmap);\n const filters = useAppStore((s) => s.roadmapFilters);\n const toggleRoadmapHorizon = useAppStore((s) => s.toggleRoadmapHorizon);\n const toggleRoadmapStatus = useAppStore((s) => s.toggleRoadmapStatus);\n const [addOpen, setAddOpen] = useState(false);\n\n const horizonTitles = roadmap?.horizons.map((horizon) => horizon.title) ?? [];\n const horizonCounts = roadmap ? horizonItemCounts(roadmap, filters) : {};\n const statusCounts = roadmap ? statusItemCounts(roadmap, filters) : {};\n const activeHorizons = new Set(filters.horizons);\n const activeStatuses = new Set(filters.statuses);\n const visibleStatuses = STATUS_CHIP_ORDER.filter(\n (status) => (statusCounts[status] ?? 0) > 0 || activeStatuses.has(status),\n );\n\n return {\n roadmap,\n horizonTitles,\n horizonCounts,\n statusCounts,\n activeHorizons,\n activeStatuses,\n visibleStatuses,\n addOpen,\n setAddOpen,\n toggleRoadmapHorizon,\n toggleRoadmapStatus,\n };\n};\n","import { addRoadmapItem } from '@/app/services/content/docs-api';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { Button, Input, Modal, Select } from '@dendelion/paper-ui';\nimport { useEffect, useRef, useState } from 'react';\n\ninterface AddRoadmapItemModalProps {\n open: boolean;\n horizonTitles: string[];\n onClose: () => void;\n}\n\nexport const AddRoadmapItemModal = ({ open, horizonTitles, onClose }: AddRoadmapItemModalProps) => {\n const loadRoadmap = useAppStore((s) => s.loadRoadmap);\n const [horizon, setHorizon] = useState(horizonTitles[0] ?? '');\n const [name, setName] = useState('');\n const [description, setDescription] = useState('');\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const horizonTitlesRef = useRef(horizonTitles);\n horizonTitlesRef.current = horizonTitles;\n\n useEffect(() => {\n if (open) {\n setHorizon(horizonTitlesRef.current[0] ?? '');\n setName('');\n setDescription('');\n setError(null);\n setSaving(false);\n }\n }, [open]);\n\n const handleAdd = async () => {\n if (!name.trim() || !horizon) return;\n setSaving(true);\n setError(null);\n try {\n await addRoadmapItem(horizon, name.trim(), description.trim());\n await loadRoadmap();\n onClose();\n } catch (err) {\n setError((err as Error).message);\n } finally {\n setSaving(false);\n }\n };\n\n return (\n <Modal open={open} onClose={onClose} title=\"Add roadmap item\" size=\"small\">\n <div className=\"flex flex-col gap-4\">\n <Select\n size=\"small\"\n value={horizon}\n onChange={setHorizon}\n disabled={saving}\n options={horizonTitles.map((title) => ({ value: title, label: title }))}\n />\n <Input\n size=\"small\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"Item name…\"\n disabled={saving}\n autoFocus\n />\n <Input\n size=\"small\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleAdd();\n }}\n placeholder=\"Description…\"\n disabled={saving}\n />\n {error && <p className=\"m-0 text-watercolor-rose-dark text-sm\">{error}</p>}\n <div className=\"flex justify-end gap-2\">\n <Button type=\"button\" variant=\"ghost\" onClick={onClose} disabled={saving}>\n Cancel\n </Button>\n <Button\n type=\"button\"\n variant=\"primary\"\n onClick={handleAdd}\n disabled={saving || !name.trim() || !horizon}\n >\n {saving ? 'Adding…' : 'Add item'}\n </Button>\n </div>\n </div>\n </Modal>\n );\n};\n","import { buildRoadmapPromotePrompt } from '@/app/features/plans/prompts';\nimport { useSubjectVocabulary } from '@/app/hooks/use-subject-vocabulary';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { oneLineErrorSummary } from '@/app/utils/error-summary';\nimport type { RoadmapItem } from '@/types/index';\nimport { Button, Modal, Select, useToast } from '@dendelion/paper-ui';\nimport { useEffect, useState } from 'react';\n\nconst NO_SUBJECT = '__no-subject__';\n\ninterface PromoteRoadmapItemModalProps {\n horizonTitle: string | null;\n item: RoadmapItem | null;\n candidateName?: string | null;\n onClose: () => void;\n onPromoted: () => void;\n}\n\nexport const PromoteRoadmapItemModal = ({\n horizonTitle,\n item,\n candidateName,\n onClose,\n onPromoted,\n}: PromoteRoadmapItemModalProps) => {\n const promoteRoadmapItem = useAppStore((s) => s.promoteRoadmapItem);\n const launchIdeaExtend = useAppStore((s) => s.launchIdeaExtend);\n const { subjects, available: subjectsAvailable } = useSubjectVocabulary();\n const [subject, setSubject] = useState(NO_SUBJECT);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const { toast } = useToast();\n\n useEffect(() => {\n if (item) {\n // A candidate defaults to its parent item's name — the \"big bet becomes a\n // Subject\" rule — but the picker still lets the user override it.\n setSubject(candidateName ? item.name : NO_SUBJECT);\n setLoading(false);\n setError(null);\n }\n }, [item, candidateName]);\n\n const handlePromote = async () => {\n if (!item || !horizonTitle) return;\n setLoading(true);\n setError(null);\n try {\n const id = await promoteRoadmapItem(\n horizonTitle,\n item,\n subject === NO_SUBJECT ? undefined : subject,\n candidateName ?? undefined,\n );\n const idea = useAppStore.getState().ideaEntries.find((e) => e.id === id);\n if (idea) {\n try {\n await launchIdeaExtend(id, buildRoadmapPromotePrompt(idea, horizonTitle));\n } catch (err) {\n // The idea was created either way — a failed refine launch just means\n // no background research ran, not that the promotion itself failed.\n toast({\n title: 'Idea created, but the refine agent failed to launch',\n description: oneLineErrorSummary((err as Error).message),\n variant: 'error',\n });\n }\n }\n onPromoted();\n onClose();\n } catch (err) {\n setError((err as Error).message);\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <Modal\n open={item !== null}\n onClose={onClose}\n title={candidateName ?? item?.name ?? ''}\n size=\"small\"\n >\n <div className=\"flex flex-col gap-4\">\n {!candidateName && <p className=\"m-0 opacity-80\">{item?.description}</p>}\n <div>\n <Select\n size=\"small\"\n value={subject}\n onChange={setSubject}\n disabled={loading || !subjectsAvailable}\n options={[\n { value: NO_SUBJECT, label: 'No subject' },\n ...(!subjectsAvailable && subject !== NO_SUBJECT\n ? [{ value: subject, label: subject }]\n : []),\n ...subjects.map((s) => ({ value: s, label: s })),\n ]}\n />\n </div>\n {error && <p className=\"m-0 text-watercolor-rose-dark text-sm\">{error}</p>}\n <div className=\"flex justify-end gap-2\">\n <Button type=\"button\" variant=\"ghost\" onClick={onClose} disabled={loading}>\n Cancel\n </Button>\n <Button type=\"button\" variant=\"primary\" onClick={handlePromote} disabled={loading}>\n {loading ? 'Promoting…' : 'Promote to idea'}\n </Button>\n </div>\n </div>\n </Modal>\n );\n};\n","import { Button, Input } from '@dendelion/paper-ui';\nimport { useState } from 'react';\n\ninterface AddCandidateFormProps {\n onAdd: (name: string) => Promise<void>;\n}\n\nexport const AddCandidateForm = ({ onAdd }: AddCandidateFormProps) => {\n const [name, setName] = useState('');\n const [saving, setSaving] = useState(false);\n\n const handleAdd = async () => {\n if (!name.trim()) return;\n setSaving(true);\n try {\n await onAdd(name.trim());\n setName('');\n } finally {\n setSaving(false);\n }\n };\n\n return (\n <div className=\"flex gap-2\">\n <Input\n size=\"small\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleAdd();\n }}\n placeholder=\"Add option…\"\n disabled={saving}\n className=\"flex-1\"\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"small\"\n onClick={handleAdd}\n disabled={saving || !name.trim()}\n >\n Add\n </Button>\n </div>\n );\n};\n","import { Button, Card } from '@dendelion/paper-ui';\n\ninterface CandidateRowProps {\n name: string;\n onPromote: () => void;\n}\n\nexport const CandidateRow = ({ name, onPromote }: CandidateRowProps) => (\n <Card size=\"small\" texture=\"kraft\" className=\"plan-row-card\">\n <div className=\"flex items-center gap-3\">\n <span className=\"flex-1\">{name}</span>\n <Button type=\"button\" variant=\"ghost\" size=\"small\" onClick={onPromote}>\n Promote to idea\n </Button>\n </div>\n </Card>\n);\n","import { Markdown } from '@/app/components/markdown';\nimport { useState } from 'react';\n\ninterface GoalBannerProps {\n goal: string;\n}\n\nexport const GoalBanner = ({ goal }: GoalBannerProps) => {\n const [expanded, setExpanded] = useState(false);\n const [firstParagraph, ...restParagraphs] = goal.split(/\\n{2,}/);\n const hasMore = restParagraphs.length > 0;\n\n return (\n <div className=\"mb-6 pb-4 border-b border-black/[8%]\">\n <span className=\"font-handwritten text-xs font-semibold opacity-[0.55]\">The goal</span>\n <div className=\"text-sm leading-relaxed opacity-80 mt-2\">\n <Markdown>{firstParagraph}</Markdown>\n {expanded && hasMore && <Markdown>{restParagraphs.join('\\n\\n')}</Markdown>}\n </div>\n {hasMore && (\n <button\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n className=\"bg-transparent border-none p-0 mt-2 cursor-pointer text-2xs opacity-[0.65] underline\"\n >\n {expanded ? 'Show less' : 'Show more'}\n </button>\n )}\n </div>\n );\n};\n","export const HIGHLIGHT_OUTLINE_CLASS = 'outline-[rgba(200,154,90,0.5)]';\n\nexport const CANDIDATE_STAMP = {\n fill: 'rgba(0, 0, 0, 0.06)',\n text: 'rgba(0, 0, 0, 0.55)',\n};\n","import { PrBadge } from '@/app/features/plans/components/pr-badge';\nimport { STATUS_LABEL, STATUS_STAMP } from '@/app/features/plans/constants';\nimport type { PlanEntry, PlanStatus, PrInfo, RoadmapLink } from '@/types/index';\nimport { Card, Stamp } from '@dendelion/paper-ui';\n\nexport interface MergedIdea {\n key: string;\n label: string;\n status: PlanStatus;\n pr?: PrInfo;\n planId?: string;\n planTitle?: string;\n}\n\nexport const mergeIdeas = (links: RoadmapLink[], graduated: PlanEntry[]): MergedIdea[] => {\n const represented = new Set<string>();\n const merged: MergedIdea[] = graduated.map((plan) => {\n if (plan.id) represented.add(plan.id);\n if (plan.idea) represented.add(plan.idea);\n return {\n key: plan.title,\n label: plan.title,\n status: plan.status,\n pr: plan.pr,\n planId: plan.id,\n planTitle: plan.title,\n };\n });\n for (const link of links) {\n if (represented.has(link.id)) continue;\n merged.push({ key: link.id, label: link.id, status: link.status, pr: link.pr });\n }\n return merged;\n};\n\ninterface IdeaRowProps {\n idea: MergedIdea;\n onOpen?: () => void;\n}\n\nexport const IdeaRow = ({ idea, onOpen }: IdeaRowProps) => (\n <Card size=\"small\" texture=\"kraft\" className=\"plan-row-card\">\n <div className=\"flex items-center gap-3\">\n {onOpen ? (\n <button\n type=\"button\"\n onClick={onOpen}\n className=\"flex-1 min-w-0 overflow-hidden text-ellipsis whitespace-nowrap bg-transparent border-none p-0 cursor-pointer [font:inherit] text-inherit text-left\"\n >\n {idea.label}\n </button>\n ) : (\n <span className=\"flex-1 min-w-0 overflow-hidden text-ellipsis whitespace-nowrap\">\n {idea.label}\n </span>\n )}\n {idea.pr && <PrBadge pr={idea.pr} />}\n <Stamp\n size=\"small\"\n fillColor={STATUS_STAMP[idea.status].fill}\n textColor={STATUS_STAMP[idea.status].text}\n >\n {STATUS_LABEL[idea.status]}\n </Stamp>\n </div>\n </Card>\n);\n","interface ProgressBarProps {\n done: number;\n total: number;\n}\n\nexport const ProgressBar = ({ done, total }: ProgressBarProps) => {\n const percent = total > 0 ? Math.round((done / total) * 100) : 0;\n return (\n <div className=\"w-24 h-1.5 rounded-full bg-black/[0.08] overflow-hidden shrink-0\">\n <div\n className={`h-full rounded-full ${total > 0 ? 'bg-watercolor-green' : 'bg-transparent'}`}\n style={{ width: `${percent}%` }}\n />\n </div>\n );\n};\n","import { STATUS_STAMP } from '@/app/features/plans/constants';\nimport type { PlanEntry, ResolvedRoadmapItem } from '@/types/index';\nimport { Button, Stamp } from '@dendelion/paper-ui';\nimport { useEffect, useState } from 'react';\nimport { CANDIDATE_STAMP, HIGHLIGHT_OUTLINE_CLASS } from '../constants';\nimport { AddCandidateForm } from './add-candidate-form';\nimport { CandidateRow } from './candidate-row';\nimport { IdeaRow, mergeIdeas } from './idea-row';\nimport { ProgressBar } from './progress-bar';\n\nconst graduationCounts = (graduated: PlanEntry[]) => ({\n shipped: graduated.filter((p) => p.status === 'done').length,\n queued: graduated.filter((p) => p.status !== 'done' && p.status !== 'dropped').length,\n});\n\nconst ChevronRightIcon = ({ size = 14 }: { size?: number }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n);\n\ninterface RoadmapItemRowProps {\n item: ResolvedRoadmapItem;\n graduated: PlanEntry[];\n highlighted: boolean;\n onPromote: () => void;\n onPromoteCandidate: (candidateName: string) => void;\n onAddCandidate: (name: string) => Promise<void>;\n onOpenGraduated: (id: string | undefined, title: string) => void;\n}\n\nexport const RoadmapItemRow = ({\n item,\n graduated,\n highlighted,\n onPromote,\n onPromoteCandidate,\n onAddCandidate,\n onOpenGraduated,\n}: RoadmapItemRowProps) => {\n const [expanded, setExpanded] = useState(highlighted);\n const { shipped, queued } = graduationCounts(graduated);\n const candidates = item.candidates.length;\n const ideas = mergeIdeas(item.links, graduated);\n\n useEffect(() => {\n if (highlighted) setExpanded(true);\n }, [highlighted]);\n\n return (\n <div\n className={`border-b border-black/10 last:border-b-0 ${highlighted ? `roadmap-item-highlighted outline outline-2 outline-offset-[-2px] ${HIGHLIGHT_OUTLINE_CLASS}` : ''}`}\n >\n <button\n type=\"button\"\n aria-expanded={expanded}\n onClick={() => setExpanded((v) => !v)}\n className=\"flex w-full items-center gap-3 py-2.5 px-0 bg-transparent border-none cursor-pointer text-left [font:inherit] text-inherit\"\n >\n <span\n className={`inline-flex items-center opacity-50 shrink-0 ${expanded ? 'rotate-90' : ''}`}\n >\n <ChevronRightIcon />\n </span>\n <span className=\"font-semibold flex-1 min-w-0 truncate\">{item.name}</span>\n <ProgressBar done={item.rollup.done} total={item.rollup.total} />\n {queued > 0 && (\n <Stamp\n size=\"small\"\n fillColor={STATUS_STAMP.planned.fill}\n textColor={STATUS_STAMP.planned.text}\n >\n {queued} in queue\n </Stamp>\n )}\n {shipped > 0 && (\n <Stamp size=\"small\" fillColor={STATUS_STAMP.done.fill} textColor={STATUS_STAMP.done.text}>\n {shipped} shipped\n </Stamp>\n )}\n {candidates > 0 && (\n <Stamp size=\"small\" fillColor={CANDIDATE_STAMP.fill} textColor={CANDIDATE_STAMP.text}>\n {candidates} candidate{candidates === 1 ? '' : 's'}\n </Stamp>\n )}\n </button>\n {expanded && (\n <div className=\"flex flex-col gap-1 pl-6 pb-4\">\n <span className=\"text-sm opacity-70\">{item.description}</span>\n {ideas.map((idea) => (\n <IdeaRow\n key={idea.key}\n idea={idea}\n onOpen={\n idea.planTitle\n ? () => onOpenGraduated(idea.planId, idea.planTitle as string)\n : undefined\n }\n />\n ))}\n {item.candidates.map((candidateName) => (\n <CandidateRow\n key={candidateName}\n name={candidateName}\n onPromote={() => onPromoteCandidate(candidateName)}\n />\n ))}\n <AddCandidateForm onAdd={onAddCandidate} />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"small\"\n onClick={onPromote}\n className=\"self-start\"\n >\n Promote to idea\n </Button>\n </div>\n )}\n </div>\n );\n};\n","import type { PlanEntry, ResolvedRoadmapHorizon, ResolvedRoadmapItem } from '@/types/index';\nimport { RoadmapItemRow } from './roadmap-item-row';\n\nconst HORIZON_HEADER_CLASSES =\n 'font-handwritten text-md font-semibold opacity-70 leading-none pt-2 px-1 pb-0';\n\ninterface HorizonSectionProps {\n horizon: ResolvedRoadmapHorizon;\n highlightedItem: string | undefined;\n graduatedByItem: (item: ResolvedRoadmapItem) => PlanEntry[];\n onPromote: (item: ResolvedRoadmapItem, candidateName?: string) => void;\n onAddCandidate: (itemName: string, name: string) => Promise<void>;\n onOpenGraduated: (id: string | undefined, title: string) => void;\n}\n\nexport const HorizonSection = ({\n horizon,\n highlightedItem,\n graduatedByItem,\n onPromote,\n onAddCandidate,\n onOpenGraduated,\n}: HorizonSectionProps) => (\n <div className=\"flex flex-col gap-1\">\n <div className={HORIZON_HEADER_CLASSES}>{horizon.title}</div>\n <div className=\"flex flex-col\">\n {horizon.items.map((item) => (\n <RoadmapItemRow\n key={item.name}\n item={item}\n graduated={graduatedByItem(item)}\n highlighted={item.name === highlightedItem}\n onPromote={() => onPromote(item)}\n onPromoteCandidate={(candidateName) => onPromote(item, candidateName)}\n onAddCandidate={(name) => onAddCandidate(item.name, name)}\n onOpenGraduated={onOpenGraduated}\n />\n ))}\n </div>\n </div>\n);\n","import { PageTitle } from '@/app/components/page-title';\nimport { useRoadmapPage } from './hooks';\nimport { PromoteRoadmapItemModal } from './modals';\nimport { GoalBanner, HorizonSection } from './views';\n\nexport const RoadmapPage = () => {\n const {\n roadmap,\n roadmapError,\n loadRoadmap,\n horizons,\n totalVisible,\n hasActiveFilters,\n highlightedItem,\n containerRef,\n promoting,\n setPromoting,\n graduatedByItem,\n handleAddCandidate,\n handlePromote,\n onOpenGraduated,\n } = useRoadmapPage();\n\n if (roadmapError) {\n return (\n <div>\n <PageTitle>Roadmap</PageTitle>\n <p className=\"opacity-50\">\n Couldn't load the roadmap — the server may need a restart to pick up new routes.\n </p>\n </div>\n );\n }\n\n if (!roadmap) {\n return (\n <div>\n <PageTitle>Roadmap</PageTitle>\n <p className=\"opacity-50\">Loading…</p>\n </div>\n );\n }\n\n if (roadmap.horizons.length === 0) {\n return (\n <div>\n <PageTitle>Roadmap</PageTitle>\n <p className=\"opacity-50\">No `ROADMAP.md` found at the project root.</p>\n </div>\n );\n }\n\n return (\n <div ref={containerRef}>\n <PageTitle>Roadmap</PageTitle>\n <GoalBanner goal={roadmap.goal} />\n {totalVisible === 0 ? (\n <p className=\"opacity-50 py-6 px-0 text-center\">\n {hasActiveFilters\n ? 'Nothing matches these filters — clear one from the sidebar to see more.'\n : 'No roadmap items yet — add one from the sidebar.'}\n </p>\n ) : (\n <div className=\"flex flex-col gap-6\">\n {horizons\n .filter((horizon) => horizon.items.length > 0)\n .map((horizon) => (\n <HorizonSection\n key={horizon.title}\n horizon={horizon}\n highlightedItem={highlightedItem}\n graduatedByItem={graduatedByItem}\n onPromote={(item, candidateName) =>\n handlePromote(horizon.title, item, candidateName)\n }\n onAddCandidate={(itemName, name) =>\n handleAddCandidate(horizon.title, itemName, name)\n }\n onOpenGraduated={onOpenGraduated}\n />\n ))}\n </div>\n )}\n <PromoteRoadmapItemModal\n horizonTitle={promoting?.horizonTitle ?? null}\n item={promoting?.item ?? null}\n candidateName={promoting?.candidateName}\n onClose={() => setPromoting(null)}\n onPromoted={loadRoadmap}\n />\n </div>\n );\n};\n","import { STATUS_LABEL, STATUS_STAMP } from '@/app/features/plans/constants';\nimport { Button, ListItem } from '@dendelion/paper-ui';\nimport { useRoadmapSidebar } from './hooks';\nimport { AddRoadmapItemModal } from './modals';\n\n// Matches SidebarSection — handwritten, no caps, one grid cell.\nconst sectionLabelClass = 'pc-row-label font-handwritten text-xs font-semibold opacity-[0.45]';\n\nexport const RoadmapSidebar = () => {\n const {\n roadmap,\n horizonTitles,\n horizonCounts,\n statusCounts,\n activeHorizons,\n activeStatuses,\n visibleStatuses,\n addOpen,\n setAddOpen,\n toggleRoadmapHorizon,\n toggleRoadmapStatus,\n } = useRoadmapSidebar();\n\n if (!roadmap) return null;\n\n return (\n <div className=\"flex flex-col\">\n <div className=\"flex h-[64px] items-center\">\n <Button\n type=\"button\"\n variant=\"primary\"\n size=\"small\"\n onClick={() => setAddOpen(true)}\n disabled={horizonTitles.length === 0}\n >\n + Add item\n </Button>\n </div>\n\n <div>\n <div className={sectionLabelClass}>Horizon</div>\n <div className=\"flex flex-col\">\n {horizonTitles.map((title) => (\n <ListItem\n key={title}\n size=\"small\"\n active={activeHorizons.has(title)}\n onClick={() => toggleRoadmapHorizon(title)}\n className=\"pc-row text-xs\"\n action={<span className=\"text-2xs text-ink-500\">{horizonCounts[title] ?? 0}</span>}\n >\n {title}\n </ListItem>\n ))}\n </div>\n </div>\n\n <div>\n <div className={sectionLabelClass}>Status</div>\n <div className=\"flex flex-col\">\n {visibleStatuses.length === 0 && (\n <span className=\"opacity-50 text-2xs\">No linked ideas</span>\n )}\n {visibleStatuses.map((status) => (\n <ListItem\n key={status}\n size=\"small\"\n active={activeStatuses.has(status)}\n onClick={() => toggleRoadmapStatus(status)}\n className=\"pc-row text-xs\"\n icon={\n <span\n className=\"w-[9px] h-[9px] rounded-full shrink-0\"\n style={{ background: STATUS_STAMP[status].text }}\n />\n }\n action={<span className=\"text-2xs text-ink-500\">{statusCounts[status] ?? 0}</span>}\n >\n {STATUS_LABEL[status]}\n </ListItem>\n ))}\n </div>\n </div>\n\n <AddRoadmapItemModal\n open={addOpen}\n horizonTitles={horizonTitles}\n onClose={() => setAddOpen(false)}\n />\n </div>\n );\n};\n"],"names":["useRoadmapPage","roadmap","useAppStore","s","roadmapError","loadRoadmap","filters","plans","openEntity","useOpenEntity","highlightedItem","useSearch","containerRef","useRef","promoting","setPromoting","useState","useEffect","row","_a","graduatedByItem","item","p","handleAddCandidate","horizonTitle","itemName","name","addRoadmapCandidate","handlePromote","candidateName","horizons","filterHorizons","totalVisible","count","horizon","hasActiveFilters","STATUS_CHIP_ORDER","useRoadmapSidebar","toggleRoadmapHorizon","toggleRoadmapStatus","addOpen","setAddOpen","horizonTitles","horizonCounts","horizonItemCounts","statusCounts","statusItemCounts","activeHorizons","activeStatuses","visibleStatuses","status","AddRoadmapItemModal","open","onClose","setHorizon","setName","description","setDescription","saving","setSaving","error","setError","horizonTitlesRef","handleAdd","addRoadmapItem","err","jsx","Modal","jsxs","Select","title","Input","e","Button","NO_SUBJECT","PromoteRoadmapItemModal","onPromoted","promoteRoadmapItem","launchIdeaExtend","subjects","subjectsAvailable","useSubjectVocabulary","subject","setSubject","loading","setLoading","toast","useToast","id","idea","buildRoadmapPromotePrompt","oneLineErrorSummary","AddCandidateForm","onAdd","CandidateRow","onPromote","Card","GoalBanner","goal","expanded","setExpanded","firstParagraph","restParagraphs","hasMore","Markdown","v","HIGHLIGHT_OUTLINE_CLASS","CANDIDATE_STAMP","mergeIdeas","links","graduated","represented","merged","plan","link","IdeaRow","onOpen","PrBadge","Stamp","STATUS_STAMP","STATUS_LABEL","ProgressBar","done","total","percent","graduationCounts","ChevronRightIcon","size","RoadmapItemRow","highlighted","onPromoteCandidate","onAddCandidate","onOpenGraduated","shipped","queued","candidates","ideas","HORIZON_HEADER_CLASSES","HorizonSection","RoadmapPage","PageTitle","sectionLabelClass","RoadmapSidebar","ListItem"],"mappings":"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"}