@dendelion/paper-camp 0.11.0 → 0.12.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/dist/app/assets/index-B6eOrr41.js +4 -0
- package/dist/app/assets/index-B6eOrr41.js.map +1 -0
- package/dist/app/assets/index-BajRXbXg.js +2 -0
- package/dist/app/assets/index-BajRXbXg.js.map +1 -0
- package/dist/app/assets/index-DAexv1XS.js +3 -0
- package/dist/app/assets/index-DAexv1XS.js.map +1 -0
- package/dist/app/assets/{index-CwotynaS.js → index-DFJlDY3W.js} +2 -2
- package/dist/app/assets/{index-CwotynaS.js.map → index-DFJlDY3W.js.map} +1 -1
- package/dist/app/assets/main-Bno8vU-0.js +288 -0
- package/dist/app/assets/main-Bno8vU-0.js.map +1 -0
- package/dist/app/assets/{main-B7k4s_9g.css → main-RP3LpwgH.css} +1 -1
- package/dist/app/assets/{sidebar-section-DVSoUVEe.js → sidebar-section-BrJbBK_b.js} +2 -2
- package/dist/app/assets/{sidebar-section-DVSoUVEe.js.map → sidebar-section-BrJbBK_b.js.map} +1 -1
- package/dist/app/index.html +2 -2
- package/dist/chunks/{roadmap.HCld8rN3.js → scaffold.B_3sY6Rg.js} +1857 -1601
- package/dist/chunks/scaffold.B_3sY6Rg.js.map +1 -0
- package/dist/cli/index.js +8114 -7252
- package/dist/cli/index.js.map +1 -1
- package/dist/core/git-pr/pr.d.ts.map +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +94 -87
- package/dist/core/parse/parser.d.ts +2 -3
- package/dist/core/parse/parser.d.ts.map +1 -1
- package/dist/core/parse/schemas.d.ts +1 -0
- package/dist/core/parse/schemas.d.ts.map +1 -1
- package/dist/core/readers.d.ts.map +1 -1
- package/dist/core/roadmap.d.ts +5 -1
- package/dist/core/roadmap.d.ts.map +1 -1
- package/dist/core/run-order-file.d.ts +8 -0
- package/dist/core/run-order-file.d.ts.map +1 -0
- package/dist/core/run-order-file.test.d.ts +2 -0
- package/dist/core/run-order-file.test.d.ts.map +1 -0
- package/dist/core/run-order.d.ts +28 -9
- package/dist/core/run-order.d.ts.map +1 -1
- package/dist/core/scaffold/templates.d.ts +1 -1
- package/dist/core/scaffold/templates.d.ts.map +1 -1
- package/dist/core/sections.d.ts +3 -1
- package/dist/core/sections.d.ts.map +1 -1
- package/dist/core/serialize/serializer.d.ts +7 -3
- package/dist/core/serialize/serializer.d.ts.map +1 -1
- package/dist/core/trail.d.ts +7 -0
- package/dist/core/trail.d.ts.map +1 -0
- package/dist/core/trail.test.d.ts +2 -0
- package/dist/core/trail.test.d.ts.map +1 -0
- package/dist/types/index.d.ts +169 -10
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/package.json +4 -3
- package/dist/app/assets/index-DHHPg0hQ.js +0 -4
- package/dist/app/assets/index-DHHPg0hQ.js.map +0 -1
- package/dist/app/assets/index-DyLHu3dg.js +0 -2
- package/dist/app/assets/index-DyLHu3dg.js.map +0 -1
- package/dist/app/assets/index-DzMK8ayh.js +0 -3
- package/dist/app/assets/index-DzMK8ayh.js.map +0 -1
- package/dist/app/assets/main-BNLbBO0E.js +0 -233
- package/dist/app/assets/main-BNLbBO0E.js.map +0 -1
- package/dist/chunks/roadmap.HCld8rN3.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-DyLHu3dg.js","sources":["../../../src/app/features/settings/components/setup-section.tsx","../../../src/app/features/settings/components/subjects-section.tsx","../../../src/app/features/settings/settings-page.tsx","../../../src/app/features/settings/components/settings-sidebar.tsx"],"sourcesContent":["import { fetchCapabilities, fetchConfig, saveConfig } from '@/app/services/system';\nimport { fontSize, space } from '@/app/styles/tokens';\nimport {\n AGENT_LABELS,\n type AgentId,\n type CapabilityResult,\n type CapabilityStatus,\n} from '@/types/index';\nimport { Alert, Button, Card, Divider, Stamp, useToast } from '@dendelion/paper-ui';\nimport { useCallback, useEffect, useState } from 'react';\n\ninterface CapabilityMeta {\n label: string;\n unlocks: string;\n fix: (detail: string) => string;\n}\n\nfunction capabilityMeta(id: string): CapabilityMeta {\n if (id === 'git') {\n return {\n label: 'Git',\n unlocks: 'Commits, phase logging, branch creation',\n fix: (detail) =>\n detail.startsWith('Not inside')\n ? 'git init'\n : 'git config user.name \"Your Name\" && git config user.email you@example.com',\n };\n }\n if (id === 'gh') {\n return {\n label: 'GitHub CLI',\n unlocks: 'PR badges, review flow, fix-review',\n fix: (detail) => {\n if (detail.includes('not found')) return 'Install: https://cli.github.com';\n if (detail.includes('no origin remote')) return 'git remote add origin <url>';\n if (detail.includes('not reachable')) return 'gh repo view';\n return 'gh auth login';\n },\n };\n }\n const agentId = id.slice('agent:'.length) as AgentId;\n return {\n label: `${AGENT_LABELS[agentId]} CLI`,\n unlocks: `Launching ${AGENT_LABELS[agentId]} for phase runs, drafts, and reviews`,\n fix: () => `Install the ${AGENT_LABELS[agentId]} CLI and add it to PATH`,\n };\n}\n\nconst STATUS_STAMP: Record<CapabilityStatus, { fill: string; text: string; label: string }> = {\n ok: { fill: 'rgba(143, 185, 150, 0.25)', text: '#5E8A66', label: 'Ready' },\n warn: { fill: 'rgba(212, 163, 115, 0.25)', text: '#A67B4F', label: 'Needs attention' },\n missing: { fill: 'rgba(201, 139, 139, 0.25)', text: '#6E3A3A', label: 'Missing' },\n};\n\nconst CapabilityRow = ({\n result,\n isLast,\n onRecheck,\n rechecking,\n}: {\n result: CapabilityResult;\n isLast: boolean;\n onRecheck: (id: string) => void;\n rechecking: boolean;\n}) => {\n const meta = capabilityMeta(result.id);\n const stamp = STATUS_STAMP[result.status];\n const fix = result.status !== 'ok' ? meta.fix(result.detail) : null;\n return (\n <>\n <div style={{ paddingBottom: space[3], paddingTop: space[3] }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: space[3] }}>\n <span style={{ flex: 1, fontWeight: 500 }}>{meta.label}</span>\n <Stamp size=\"small\" fillColor={stamp.fill} textColor={stamp.text}>\n {stamp.label}\n </Stamp>\n <Button\n size=\"small\"\n variant=\"secondary\"\n onClick={() => onRecheck(result.id)}\n disabled={rechecking}\n >\n {rechecking ? 'Checking…' : 'Recheck'}\n </Button>\n </div>\n <p style={{ opacity: 0.65, fontSize: fontSize.sm, margin: `${space[1]} 0 0` }}>\n Unlocks: {meta.unlocks}\n </p>\n <p style={{ opacity: 0.5, fontSize: fontSize.sm, margin: `${space[1]} 0 0` }}>\n {result.detail}\n </p>\n {fix && (\n <code\n style={{\n display: 'block',\n marginTop: space[2],\n padding: space[2],\n background: 'rgba(0,0,0,0.06)',\n borderRadius: 4,\n fontSize: fontSize.sm,\n }}\n >\n {fix}\n </code>\n )}\n </div>\n {!isLast && <Divider />}\n </>\n );\n};\n\nexport const SetupSection = () => {\n const [capabilities, setCapabilities] = useState<CapabilityResult[] | null>(null);\n const [loadFailed, setLoadFailed] = useState(false);\n const [reloadingId, setReloadingId] = useState<string | null>(null);\n const [setupDismissed, setSetupDismissed] = useState(false);\n const { toast } = useToast();\n\n const applyCapabilities = useCallback((result: CapabilityResult[] | null) => {\n if (result === null) {\n setLoadFailed(true);\n return;\n }\n setLoadFailed(false);\n setCapabilities(result);\n }, []);\n\n useEffect(() => {\n fetchCapabilities().then(applyCapabilities);\n fetchConfig().then((c) => setSetupDismissed(c?.setupDismissed ?? false));\n }, [applyCapabilities]);\n\n const handleRecheck = async (id: string) => {\n setReloadingId(id);\n applyCapabilities(await fetchCapabilities());\n setReloadingId(null);\n };\n\n const handleDismissToggle = async () => {\n const next = !setupDismissed;\n const { ok } = await saveConfig({ setupDismissed: next });\n if (ok) {\n setSetupDismissed(next);\n toast({ title: 'Saved', variant: 'success' });\n } else {\n toast({ title: 'Failed to save', variant: 'error' });\n }\n };\n\n const allOk = capabilities?.every((c) => c.status === 'ok') ?? true;\n\n return (\n <div>\n <div style={{ marginBottom: space[6] }}>\n <h2 style={{ margin: 0 }}>Setup</h2>\n </div>\n {capabilities === null && !loadFailed && <p>Loading…</p>}\n {loadFailed && (\n <div style={{ marginBottom: space[4] }}>\n <Alert variant=\"warning\">Failed to load capabilities. Try refreshing.</Alert>\n </div>\n )}\n {capabilities && (\n <>\n {!allOk && (\n <div style={{ marginBottom: space[4] }}>\n <Alert variant=\"warning\">\n Some capabilities are incomplete — features that depend on them stay disabled until\n fixed. Run the fix command in your terminal, then recheck.\n </Alert>\n </div>\n )}\n <Card size=\"small\">\n {capabilities.map((c, idx) => (\n <CapabilityRow\n key={c.id}\n result={c}\n isLast={idx === capabilities.length - 1}\n onRecheck={handleRecheck}\n rechecking={reloadingId === c.id}\n />\n ))}\n </Card>\n <div style={{ marginTop: space[4] }}>\n <Button variant=\"secondary\" size=\"small\" onClick={handleDismissToggle}>\n {setupDismissed ? 'Show Setup on open again' : \"Don't show Setup on open\"}\n </Button>\n </div>\n </>\n )}\n </div>\n );\n};\n","import { useProjectSubjects } from '@/app/hooks';\nimport { space } from '@/app/styles/tokens';\nimport { Button, Card, Divider, IconButton, Input, PlusIcon, useToast } from '@dendelion/paper-ui';\nimport { useState } from 'react';\n\nconst SubjectRow = ({\n name,\n isLast,\n onRename,\n onRemove,\n}: {\n name: string;\n isLast: boolean;\n onRename: (from: string, to: string) => Promise<boolean>;\n onRemove: (name: string) => Promise<void>;\n}) => {\n const [value, setValue] = useState(name);\n const { toast } = useToast();\n\n const handleBlur = async () => {\n const trimmed = value.trim();\n if (!trimmed || trimmed === name) {\n setValue(name);\n return;\n }\n const ok = await onRename(name, trimmed);\n if (!ok) {\n setValue(name);\n toast({ title: 'Failed to rename', variant: 'error' });\n }\n };\n\n return (\n <>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: space[3],\n paddingBottom: space[2],\n paddingTop: space[2],\n }}\n >\n <Input\n size=\"small\"\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onBlur={handleBlur}\n style={{ flex: 1 }}\n />\n <IconButton\n icon={<span>×</span>}\n variant=\"ghost\"\n size=\"small\"\n label={`Remove ${name}`}\n onClick={() => onRemove(name)}\n />\n </div>\n {!isLast && <Divider />}\n </>\n );\n};\n\nexport const SubjectsSection = () => {\n const { subjects, loading, addSubject, renameSubject, removeSubject } = useProjectSubjects();\n const [newSubject, setNewSubject] = useState('');\n const { toast } = useToast();\n\n const handleAdd = async () => {\n const trimmed = newSubject.trim();\n if (!trimmed) return;\n const ok = await addSubject(trimmed);\n if (ok) setNewSubject('');\n else toast({ title: 'Failed to add subject', variant: 'error' });\n };\n\n const handleRemove = async (name: string) => {\n const ok = await removeSubject(name);\n if (!ok) toast({ title: 'Failed to remove subject', variant: 'error' });\n };\n\n return (\n <div>\n <div style={{ marginBottom: space[6] }}>\n <h2 style={{ margin: 0 }}>Subjects</h2>\n <p style={{ opacity: 0.5, marginTop: space[1] }}>\n Group ideas by subject. Removing one falls its ideas back to \"No subject\" — file contents\n are untouched.\n </p>\n </div>\n {loading && <p>Loading…</p>}\n {!loading && (\n <Card size=\"small\">\n {subjects.length === 0 && (\n <p style={{ opacity: 0.45, margin: 0, paddingBottom: space[2] }}>No subjects yet.</p>\n )}\n {subjects.map((name, idx) => (\n <SubjectRow\n key={name}\n name={name}\n isLast={idx === subjects.length - 1}\n onRename={renameSubject}\n onRemove={handleRemove}\n />\n ))}\n {subjects.length > 0 && <Divider />}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: space[3],\n paddingTop: space[3],\n }}\n >\n <Input\n size=\"small\"\n placeholder=\"New subject\"\n value={newSubject}\n onChange={(e) => setNewSubject(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleAdd();\n }}\n style={{ flex: 1 }}\n />\n <Button\n variant=\"secondary\"\n size=\"small\"\n onClick={handleAdd}\n disabled={!newSubject.trim()}\n >\n <PlusIcon size={14} /> Add\n </Button>\n </div>\n </Card>\n )}\n </div>\n );\n};\n","import { PageTitle } from '@/app/components/page-title';\nimport { useActiveSettingsSection, useProjectIdentity } from '@/app/hooks';\nimport { fetchConfig, saveConfig, uploadIcon } from '@/app/services/system';\nimport { color, fontFamily, fontSize, space } from '@/app/styles/tokens';\nimport {\n AGENT_IDS,\n AGENT_LABELS,\n AGENT_OPTIONS,\n type AgentConfig,\n type AgentId,\n DEFAULT_AGENTS,\n type DefaultAgentsMap,\n type PaperCampConfig,\n} from '@/types/index';\nimport { Alert, Button, Card, Divider, Input, Select, Stamp, useToast } from '@dendelion/paper-ui';\nimport { useEffect, useRef, useState } from 'react';\nimport { SetupSection } from './components/setup-section';\nimport { SubjectsSection } from './components/subjects-section';\n\nconst TASK_TYPE_KEYS = ['phase', 'planDraft', 'ideaExtend', 'commitSuggest'] as const;\ntype TaskTypeKey = (typeof TASK_TYPE_KEYS)[number];\n\nconst TASK_TYPE_LABELS: Record<TaskTypeKey, string> = {\n phase: 'Phase run',\n planDraft: 'Plan draft',\n ideaExtend: 'Idea extend',\n commitSuggest: 'Commit suggest',\n};\n\ninterface AgentTaskRowProps {\n taskKey: TaskTypeKey;\n agentConfig: AgentConfig;\n isLast: boolean;\n onSave: (key: TaskTypeKey, config: AgentConfig) => Promise<void>;\n}\n\nconst TASK_COLUMN_WIDTH = 110;\nconst AGENT_COLUMN_WIDTH = 140;\nconst MODEL_COLUMN_WIDTH = 160;\nconst EFFORT_COLUMN_WIDTH = 110;\n\nconst AgentTaskRowHeader = () => (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: space[3],\n paddingBottom: space[1],\n }}\n >\n <span style={{ width: TASK_COLUMN_WIDTH, flexShrink: 0, fontSize: fontSize.sm, opacity: 0.45 }}>\n Task\n </span>\n <span\n style={{ width: AGENT_COLUMN_WIDTH, flexShrink: 0, fontSize: fontSize.sm, opacity: 0.45 }}\n >\n Agent\n </span>\n <span\n style={{ width: MODEL_COLUMN_WIDTH, flexShrink: 0, fontSize: fontSize.sm, opacity: 0.45 }}\n >\n Model\n </span>\n <span\n style={{ width: EFFORT_COLUMN_WIDTH, flexShrink: 0, fontSize: fontSize.sm, opacity: 0.45 }}\n >\n Effort\n </span>\n </div>\n);\n\nconst AgentTaskRow = ({ taskKey, agentConfig, isLast, onSave }: AgentTaskRowProps) => {\n // Fall back if the config carries an unknown agent id — never white-screen the page.\n const opts = AGENT_OPTIONS[agentConfig.agent] ?? AGENT_OPTIONS['claude-code'];\n const modelOpts = opts.model;\n const effortOpts = opts.effort;\n const [localModel, setLocalModel] = useState(agentConfig.model ?? '');\n\n useEffect(() => {\n setLocalModel(agentConfig.model ?? '');\n }, [agentConfig.model]);\n\n const handleAgentChange = (v: string) => {\n const newId = v as AgentId;\n const newOpts = AGENT_OPTIONS[newId];\n const newConfig: AgentConfig = { agent: newId };\n // Only carry the model over if the new agent accepts it — otherwise a claude\n // model like 'opus' would leak into opencode and fail at launch.\n if (\n agentConfig.model &&\n (newOpts.model === null || newOpts.model?.includes(agentConfig.model))\n ) {\n newConfig.model = agentConfig.model;\n }\n if (agentConfig.effort && Array.isArray(newOpts.effort)) newConfig.effort = agentConfig.effort;\n onSave(taskKey, newConfig);\n };\n\n const handleModelSelectChange = (v: string) => {\n onSave(taskKey, { ...agentConfig, model: v || undefined });\n };\n\n const handleModelInputBlur = () => {\n onSave(taskKey, { ...agentConfig, model: localModel || undefined });\n };\n\n const handleEffortChange = (v: string) => {\n onSave(taskKey, { ...agentConfig, effort: v || undefined });\n };\n\n return (\n <>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: space[3],\n paddingBottom: space[2],\n paddingTop: space[2],\n }}\n >\n <span\n style={{ width: TASK_COLUMN_WIDTH, flexShrink: 0, fontSize: fontSize.sm, opacity: 0.65 }}\n >\n {TASK_TYPE_LABELS[taskKey]}\n </span>\n <Select\n size=\"small\"\n width={AGENT_COLUMN_WIDTH}\n value={agentConfig.agent}\n onChange={handleAgentChange}\n options={AGENT_IDS.map((id) => ({ value: id, label: AGENT_LABELS[id] }))}\n />\n {Array.isArray(modelOpts) ? (\n <Select\n size=\"small\"\n width={MODEL_COLUMN_WIDTH}\n value={agentConfig.model ?? ''}\n onChange={handleModelSelectChange}\n options={[\n { value: '', label: 'Default' },\n ...modelOpts.map((m) => ({ value: m, label: m })),\n ]}\n />\n ) : modelOpts === null ? (\n <Input\n size=\"small\"\n style={{ width: MODEL_COLUMN_WIDTH }}\n value={localModel}\n placeholder=\"Default model\"\n onChange={(e) => setLocalModel(e.target.value)}\n onBlur={handleModelInputBlur}\n />\n ) : null}\n {/* Reserve the effort slot even when the agent has no effort options, so\n switching agents doesn't change the control count and shift the row. */}\n <div style={{ visibility: Array.isArray(effortOpts) ? 'visible' : 'hidden' }}>\n <Select\n size=\"small\"\n width={EFFORT_COLUMN_WIDTH}\n value={agentConfig.effort ?? ''}\n onChange={handleEffortChange}\n options={[\n { value: '', label: 'Default' },\n ...(Array.isArray(effortOpts) ? effortOpts : []).map((e) => ({ value: e, label: e })),\n ]}\n />\n </div>\n </div>\n {!isLast && <Divider />}\n </>\n );\n};\n\nconst GeneralSection = () => {\n const fileRef = useRef<HTMLInputElement>(null);\n const [config, setConfig] = useState<PaperCampConfig | null | undefined>(undefined);\n const { iconDataUri: fetchedIconDataUri, loading: identityLoading } = useProjectIdentity();\n const [uploadedIconDataUri, setUploadedIconDataUri] = useState<string | null>(null);\n const iconDataUri = uploadedIconDataUri ?? fetchedIconDataUri;\n const [uploading, setUploading] = useState(false);\n const [portInput, setPortInput] = useState('');\n const [nameInput, setNameInput] = useState('');\n const { toast } = useToast();\n\n useEffect(() => {\n fetchConfig().then((c) => {\n setConfig(c);\n if (c?.port !== undefined) setPortInput(String(c.port));\n if (c?.projectName !== undefined) setNameInput(c.projectName);\n });\n }, []);\n\n const handleSaveAgentConfig = async (key: TaskTypeKey, newEntry: AgentConfig) => {\n const current = config?.defaultAgents;\n const updated: DefaultAgentsMap = {\n phase: current?.phase ?? DEFAULT_AGENTS.phase,\n planDraft: current?.planDraft ?? DEFAULT_AGENTS.planDraft,\n ideaExtend: current?.ideaExtend ?? DEFAULT_AGENTS.ideaExtend,\n commitSuggest: current?.commitSuggest ?? DEFAULT_AGENTS.commitSuggest,\n [key]: newEntry,\n };\n const { ok, error } = await saveConfig({ defaultAgents: updated });\n if (ok) {\n setConfig((prev) => (prev ? { ...prev, defaultAgents: updated } : prev));\n toast({ title: 'Saved', variant: 'success' });\n } else {\n toast({ title: 'Failed to save', description: error, variant: 'error' });\n }\n };\n\n const handleSavePort = async () => {\n const port = Number(portInput);\n if (!config || !Number.isInteger(port) || port <= 0 || port === config.port) return;\n const { ok, error } = await saveConfig({ port });\n if (ok) {\n setConfig((prev) => (prev ? { ...prev, port } : prev));\n toast({ title: 'Saved', variant: 'success' });\n } else {\n toast({ title: 'Failed to save', description: error, variant: 'error' });\n }\n };\n\n const handleSaveName = async () => {\n const projectName = nameInput.trim();\n if (!config || !projectName || projectName === config.projectName) return;\n const { ok, error } = await saveConfig({ projectName });\n if (ok) {\n setConfig((prev) => (prev ? { ...prev, projectName } : prev));\n setNameInput(projectName);\n toast({ title: 'Saved', variant: 'success' });\n } else {\n toast({ title: 'Failed to save', description: error, variant: 'error' });\n }\n };\n\n const handleFile = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n setUploading(true);\n const reader = new FileReader();\n reader.onloadend = async () => {\n const dataUri = reader.result as string;\n const ok = await uploadIcon(dataUri);\n setUploading(false);\n if (ok) {\n setUploadedIconDataUri(dataUri);\n toast({ title: 'Saved', variant: 'success' });\n } else {\n toast({ title: 'Failed to save', variant: 'error' });\n }\n };\n reader.readAsDataURL(file);\n };\n\n return (\n <div>\n <div style={{ marginBottom: space[6] }}>\n <h2 style={{ margin: 0 }}>Project Info</h2>\n </div>\n {config === undefined && <p>Loading…</p>}\n {config === null && (\n <Alert variant=\"warning\">\n No papercamp/config.json found — run <code>paper-camp init</code> in this directory first.\n </Alert>\n )}\n {config && (\n <Card size=\"small\">\n <div\n style={{\n display: 'flex',\n alignItems: 'flex-end',\n gap: space[3],\n paddingBottom: space[3],\n }}\n >\n <Input\n value={nameInput}\n onChange={(e) => setNameInput(e.target.value)}\n onBlur={handleSaveName}\n label=\"Project Name\"\n />\n <Stamp\n size=\"small\"\n fillColor=\"rgba(143, 185, 150, 0.25)\"\n textColor={color.accentGreenDark}\n >\n v{config.version}\n </Stamp>\n </div>\n <Divider />\n\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: space[3],\n paddingBottom: space[3],\n paddingTop: space[3],\n }}\n >\n {iconDataUri && (\n <img\n src={iconDataUri}\n alt=\"Project icon\"\n style={{\n width: 40,\n height: 40,\n objectFit: 'contain',\n flexShrink: 0,\n borderRadius: 4,\n }}\n />\n )}\n <div>\n {/* paper-ui has no file-input component, so this raw input is intentional */}\n <input\n ref={fileRef}\n type=\"file\"\n accept=\".svg,.png,.jpg,.jpeg,.gif,.webp\"\n onChange={handleFile}\n style={{ display: 'none' }}\n />\n <Button\n variant=\"secondary\"\n size=\"small\"\n onClick={() => fileRef.current?.click()}\n disabled={uploading}\n >\n {uploading ? 'Uploading…' : 'Choose File'}\n </Button>\n {identityLoading && (\n <p className=\"text-sm\" style={{ opacity: 0.5, margin: `${space[1]} 0 0` }}>\n Loading…\n </p>\n )}\n {!identityLoading && !iconDataUri && !uploading && (\n <p className=\"text-sm\" style={{ opacity: 0.45, margin: `${space[1]} 0 0` }}>\n No icon set.\n </p>\n )}\n </div>\n </div>\n <Divider />\n\n <div\n style={{\n display: 'flex',\n alignItems: 'flex-end',\n gap: space[3],\n paddingBottom: space[3],\n paddingTop: space[3],\n }}\n >\n <Input\n type=\"number\"\n value={portInput}\n onChange={(e) => setPortInput(e.target.value)}\n onBlur={handleSavePort}\n label=\"Port\"\n helperText=\"Default for `paper-camp dev`. Does not affect the running server.\"\n />\n </div>\n <Divider />\n\n <AgentTaskRowHeader />\n {TASK_TYPE_KEYS.map((key, idx) => (\n <AgentTaskRow\n key={key}\n taskKey={key}\n agentConfig={config.defaultAgents?.[key] ?? DEFAULT_AGENTS[key]}\n isLast={idx === TASK_TYPE_KEYS.length - 1}\n onSave={handleSaveAgentConfig}\n />\n ))}\n </Card>\n )}\n\n <p style={{ opacity: 0.45, fontSize: fontSize.sm, marginTop: space[4] }}>\n <strong>Initialized:</strong>{' '}\n {config ? new Date(config.initializedAt).toLocaleString() : '—'}\n </p>\n </div>\n );\n};\n\nexport const SettingsPage = () => {\n const section = useActiveSettingsSection();\n return (\n <div>\n <PageTitle>Settings</PageTitle>\n {section === 'subjects' ? (\n <SubjectsSection />\n ) : section === 'setup' ? (\n <SetupSection />\n ) : (\n <GeneralSection />\n )}\n </div>\n );\n};\n","import { useActiveSettingsSection } from '@/app/hooks';\nimport { ListItem } from '@dendelion/paper-ui';\nimport { useNavigate } from '@tanstack/react-router';\nimport { SidebarSection } from '../../plans/components/sidebar-section';\n\nexport const SettingsSidebar = () => {\n const section = useActiveSettingsSection();\n const navigate = useNavigate();\n\n return (\n <>\n <SidebarSection label=\"General\">\n <ListItem\n size=\"small\"\n active={section === null}\n onClick={() => navigate({ to: '/settings' })}\n >\n Project Info\n </ListItem>\n <ListItem\n size=\"small\"\n active={section === 'setup'}\n onClick={() => navigate({ to: '/settings/$section', params: { section: 'setup' } })}\n >\n Setup\n </ListItem>\n </SidebarSection>\n <SidebarSection label=\"Ideas\">\n <ListItem\n size=\"small\"\n active={section === 'subjects'}\n onClick={() => navigate({ to: '/settings/$section', params: { section: 'subjects' } })}\n >\n Subjects\n </ListItem>\n </SidebarSection>\n </>\n );\n};\n"],"names":["capabilityMeta","id","detail","agentId","AGENT_LABELS","STATUS_STAMP","CapabilityRow","result","isLast","onRecheck","rechecking","meta","stamp","fix","jsxs","Fragment","space","jsx","Stamp","Button","fontSize","Divider","SetupSection","capabilities","setCapabilities","useState","loadFailed","setLoadFailed","reloadingId","setReloadingId","setupDismissed","setSetupDismissed","toast","useToast","applyCapabilities","useCallback","useEffect","fetchCapabilities","fetchConfig","c","handleRecheck","handleDismissToggle","next","ok","saveConfig","allOk","Alert","Card","idx","SubjectRow","name","onRename","onRemove","value","setValue","handleBlur","trimmed","Input","e","IconButton","SubjectsSection","subjects","loading","addSubject","renameSubject","removeSubject","useProjectSubjects","newSubject","setNewSubject","handleAdd","handleRemove","PlusIcon","TASK_TYPE_KEYS","TASK_TYPE_LABELS","TASK_COLUMN_WIDTH","AGENT_COLUMN_WIDTH","MODEL_COLUMN_WIDTH","EFFORT_COLUMN_WIDTH","AgentTaskRowHeader","AgentTaskRow","taskKey","agentConfig","onSave","opts","AGENT_OPTIONS","modelOpts","effortOpts","localModel","setLocalModel","handleAgentChange","v","newId","newOpts","newConfig","_a","handleModelSelectChange","handleModelInputBlur","handleEffortChange","Select","AGENT_IDS","m","GeneralSection","fileRef","useRef","config","setConfig","fetchedIconDataUri","identityLoading","useProjectIdentity","uploadedIconDataUri","setUploadedIconDataUri","iconDataUri","uploading","setUploading","portInput","setPortInput","nameInput","setNameInput","handleSaveAgentConfig","key","newEntry","current","updated","DEFAULT_AGENTS","error","prev","handleSavePort","port","handleSaveName","projectName","handleFile","file","reader","dataUri","uploadIcon","color","SettingsPage","section","useActiveSettingsSection","PageTitle","SettingsSidebar","navigate","useNavigate","SidebarSection","ListItem"],"mappings":"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"}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{u as m,C as w,r as l,j as e,P as v,s as f,p as x,b as g,A as S,f as j,O as L,c as y,E as D}from"./main-BNLbBO0E.js";const N={phase:"Phase run",audit:"Audit","batch-reconcile":"Batch reconcile","run-all":"Run all phases",draft:"Draft",extend:"Extend",suggest:"Suggest ideas","commit-suggest":"Commit suggest","overlap-check":"Overlap check",prioritise:"Prioritise queue",sync:"Sync",reconcile:"Reconcile","fix-review":"Fix review"},p=s=>String(s).padStart(2,"0"),A=s=>{const t=new Date(s);return`${t.getFullYear()}-${p(t.getMonth()+1)}-${p(t.getDate())}`},T=s=>new Date(s).toLocaleDateString(void 0,{weekday:"long",year:"numeric",month:"long",day:"numeric"}),k=s=>{const t=new Date(s);return`${p(t.getHours())}:${p(t.getMinutes())}:${p(t.getSeconds())}`},c={fontSize:g.sm,fontWeight:600,opacity:.6,whiteSpace:"nowrap",overflow:"hidden"},E=({id:s})=>{const[t,o]=l.useState(null);return l.useEffect(()=>{o(null),D(s).then(r=>o(r.lines)).catch(()=>o([]))},[s]),t===null?e.jsx("p",{style:{opacity:.5,margin:0},children:"Loading…"}):t.length===0?e.jsx("p",{style:{opacity:.5,margin:0},children:"No output recorded."}):e.jsx("pre",{style:{fontFamily:j.mono,fontSize:g.xs,margin:0,maxHeight:320,overflowY:"auto",whiteSpace:"pre-wrap"},children:t.join(`
|
|
2
|
-
`)})},b=({size:s=14})=>e.jsx("svg",{width:s,height:s,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:e.jsx("polyline",{points:"9 18 15 12 9 6"})}),R=({entry:s,highlighted:t})=>{const[o,r]=l.useState(t);l.useEffect(()=>{t&&r(!0)},[t]);const d=()=>r(i=>!i);return e.jsxs("div",{className:t?"task-row-highlighted":void 0,style:{display:"flex",flexDirection:"column",gap:f[1],borderRadius:10},children:[e.jsx("div",{role:"button",tabIndex:0,onClick:d,onKeyDown:i=>{(i.key==="Enter"||i.key===" ")&&(i.preventDefault(),d())},style:{cursor:"pointer",borderRadius:10},children:e.jsx(x,{size:"small",texture:"canvas",className:"plan-row-card",children:e.jsxs("div",{className:"task-rows-grid",children:[e.jsx("span",{className:"task-rows-chevron","aria-expanded":o,style:{display:"inline-flex",alignItems:"center",opacity:.5},children:e.jsx(b,{})}),e.jsx("span",{style:{fontWeight:600,whiteSpace:"nowrap",overflow:"hidden"},children:N[s.taskKind]}),e.jsx("span",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",opacity:.7},children:s.planTitle}),e.jsx("span",{className:"text-sm",style:{opacity:.5,whiteSpace:"nowrap"},children:S[s.agentId]}),e.jsxs("span",{className:"task-rows-cell-time",style:{fontFamily:j.mono,fontSize:g.xs,opacity:.55,whiteSpace:"nowrap"},children:[k(s.startedAt),"–",k(s.endedAt)]}),e.jsx("div",{style:{display:"flex",alignItems:"center"},children:e.jsx(L,{size:"small",fillColor:s.outcome==="done"?"rgba(143, 185, 150, 0.25)":"rgba(201, 139, 139, 0.25)",textColor:s.outcome==="done"?y.accentGreenDark:y.accentRoseDark,children:s.outcome})})]})})}),o&&e.jsx(x,{size:"small",texture:"kraft",className:"plan-row-card",children:e.jsx(E,{id:s.id})})]})},C=()=>{const s=m(a=>a.taskLog),t=m(a=>a.taskLogLoading),o=m(a=>a.loadTaskLog),{taskId:r}=w({from:"/tasks"}),d=l.useRef(null);l.useEffect(()=>{o()},[o]),l.useEffect(()=>{var n;if(!r)return;const a=(n=d.current)==null?void 0:n.querySelector(".task-row-highlighted");a==null||a.scrollIntoView({behavior:"smooth",block:"center"})},[r]);const i=[...s].sort((a,n)=>n.endedAt.localeCompare(a.endedAt)),u=[];for(const a of i){const n=A(a.endedAt),h=u.at(-1);(h==null?void 0:h.key)===n?h.entries.push(a):u.push({key:n,entries:[a]})}return e.jsxs("div",{ref:d,children:[e.jsx(v,{children:"Tasks"}),t&&e.jsx("p",{style:{opacity:.5},children:"Loading…"}),!t&&i.length===0&&e.jsx("p",{style:{opacity:.5},children:"No tasks have run yet."}),!t&&i.length>0&&e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:f[1]},children:[e.jsx(x,{size:"small",texture:"kraft",className:"plan-row-card",children:e.jsxs("div",{className:"task-rows-grid",children:[e.jsx("span",{}),e.jsx("span",{style:c,children:"Task"}),e.jsx("span",{style:c,children:"Plan"}),e.jsx("span",{style:c,children:"Agent"}),e.jsx("span",{className:"task-rows-cell-time",style:c,children:"Time"}),e.jsx("span",{style:c,children:"Outcome"})]})}),u.map(a=>e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:f[1]},children:[e.jsx(x,{size:"small",texture:"kraft",className:"plan-row-card",children:e.jsx("span",{style:{...c,opacity:.75},children:T(a.entries[0].endedAt)})}),a.entries.map(n=>e.jsx(R,{entry:n,highlighted:n.id===r},n.id))]},a.key))]})]})};export{C as TasksPage};
|
|
3
|
-
//# sourceMappingURL=index-DzMK8ayh.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-DzMK8ayh.js","sources":["../../../src/app/features/tasks/tasks-page.tsx"],"sourcesContent":["import { PageTitle } from '@/app/components/page-title';\nimport { fetchTaskLogLines } from '@/app/services/content/docs-api';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { color, fontFamily, fontSize, space } from '@/app/styles/tokens';\nimport { AGENT_LABELS, type TaskKind, type TaskLogEntry } from '@/types/index';\nimport { Card, Stamp } from '@dendelion/paper-ui';\nimport { useSearch } from '@tanstack/react-router';\nimport { useEffect, useRef, useState } from 'react';\n\nconst TASK_KIND_LABELS: Record<TaskKind, string> = {\n phase: 'Phase run',\n audit: 'Audit',\n 'batch-reconcile': 'Batch reconcile',\n 'run-all': 'Run all phases',\n draft: 'Draft',\n extend: 'Extend',\n suggest: 'Suggest ideas',\n 'commit-suggest': 'Commit suggest',\n 'overlap-check': 'Overlap check',\n prioritise: 'Prioritise queue',\n sync: 'Sync',\n reconcile: 'Reconcile',\n 'fix-review': 'Fix review',\n};\n\nconst pad = (n: number) => String(n).padStart(2, '0');\n\nconst dayKey = (iso: string) => {\n const d = new Date(iso);\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;\n};\n\nconst formatDayHeader = (iso: string) =>\n new Date(iso).toLocaleDateString(undefined, {\n weekday: 'long',\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n });\n\nconst formatTime = (iso: string) => {\n const d = new Date(iso);\n return `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;\n};\n\nconst headerLabelStyle: React.CSSProperties = {\n fontSize: fontSize.sm,\n fontWeight: 600,\n opacity: 0.6,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n};\n\nconst TaskLogLines = ({ id }: { id: string }) => {\n const [lines, setLines] = useState<string[] | null>(null);\n\n useEffect(() => {\n setLines(null);\n fetchTaskLogLines(id)\n .then((data) => setLines(data.lines))\n .catch(() => setLines([]));\n }, [id]);\n\n if (lines === null) return <p style={{ opacity: 0.5, margin: 0 }}>Loading…</p>;\n if (lines.length === 0) return <p style={{ opacity: 0.5, margin: 0 }}>No output recorded.</p>;\n return (\n <pre\n style={{\n fontFamily: fontFamily.mono,\n fontSize: fontSize.xs,\n margin: 0,\n maxHeight: 320,\n overflowY: 'auto',\n whiteSpace: 'pre-wrap',\n }}\n >\n {lines.join('\\n')}\n </pre>\n );\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\nconst TaskRow = ({ entry, highlighted }: { entry: TaskLogEntry; highlighted: boolean }) => {\n const [expanded, setExpanded] = useState(highlighted);\n useEffect(() => {\n if (highlighted) setExpanded(true);\n }, [highlighted]);\n const toggle = () => setExpanded((v) => !v);\n\n return (\n <div\n className={highlighted ? 'task-row-highlighted' : undefined}\n style={{ display: 'flex', flexDirection: 'column', gap: space[1], borderRadius: 10 }}\n >\n {/* biome-ignore lint/a11y/useSemanticElements: the clickable row wraps a Card whose block layout a native <button> would break; keyboard toggling is wired on the div. */}\n <div\n role=\"button\"\n tabIndex={0}\n onClick={toggle}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n toggle();\n }\n }}\n style={{ cursor: 'pointer', borderRadius: 10 }}\n >\n <Card size=\"small\" texture=\"canvas\" className=\"plan-row-card\">\n <div className=\"task-rows-grid\">\n <span\n className=\"task-rows-chevron\"\n aria-expanded={expanded}\n style={{ display: 'inline-flex', alignItems: 'center', opacity: 0.5 }}\n >\n <ChevronRightIcon />\n </span>\n <span style={{ fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden' }}>\n {TASK_KIND_LABELS[entry.taskKind]}\n </span>\n <span\n style={{\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n opacity: 0.7,\n }}\n >\n {entry.planTitle}\n </span>\n <span className=\"text-sm\" style={{ opacity: 0.5, whiteSpace: 'nowrap' }}>\n {AGENT_LABELS[entry.agentId]}\n </span>\n <span\n className=\"task-rows-cell-time\"\n style={{\n fontFamily: fontFamily.mono,\n fontSize: fontSize.xs,\n opacity: 0.55,\n whiteSpace: 'nowrap',\n }}\n >\n {formatTime(entry.startedAt)}–{formatTime(entry.endedAt)}\n </span>\n <div style={{ display: 'flex', alignItems: 'center' }}>\n <Stamp\n size=\"small\"\n fillColor={\n entry.outcome === 'done'\n ? 'rgba(143, 185, 150, 0.25)'\n : 'rgba(201, 139, 139, 0.25)'\n }\n textColor={entry.outcome === 'done' ? color.accentGreenDark : color.accentRoseDark}\n >\n {entry.outcome}\n </Stamp>\n </div>\n </div>\n </Card>\n </div>\n {expanded && (\n <Card size=\"small\" texture=\"kraft\" className=\"plan-row-card\">\n <TaskLogLines id={entry.id} />\n </Card>\n )}\n </div>\n );\n};\n\nexport const TasksPage = () => {\n const taskLog = useAppStore((s) => s.taskLog);\n const taskLogLoading = useAppStore((s) => s.taskLogLoading);\n const loadTaskLog = useAppStore((s) => s.loadTaskLog);\n const { taskId } = useSearch({ from: '/tasks' });\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n loadTaskLog();\n }, [loadTaskLog]);\n\n useEffect(() => {\n if (!taskId) return;\n const row = containerRef.current?.querySelector('.task-row-highlighted');\n row?.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }, [taskId]);\n\n const sorted = [...taskLog].sort((a, b) => b.endedAt.localeCompare(a.endedAt));\n\n const groups: { key: string; entries: TaskLogEntry[] }[] = [];\n for (const entry of sorted) {\n const key = dayKey(entry.endedAt);\n const group = groups.at(-1);\n if (group?.key === key) group.entries.push(entry);\n else groups.push({ key, entries: [entry] });\n }\n\n return (\n <div ref={containerRef}>\n <PageTitle>Tasks</PageTitle>\n {taskLogLoading && <p style={{ opacity: 0.5 }}>Loading…</p>}\n {!taskLogLoading && sorted.length === 0 && (\n <p style={{ opacity: 0.5 }}>No tasks have run yet.</p>\n )}\n {!taskLogLoading && sorted.length > 0 && (\n <div style={{ display: 'flex', flexDirection: 'column', gap: space[1] }}>\n <Card size=\"small\" texture=\"kraft\" className=\"plan-row-card\">\n <div className=\"task-rows-grid\">\n <span />\n <span style={headerLabelStyle}>Task</span>\n <span style={headerLabelStyle}>Plan</span>\n <span style={headerLabelStyle}>Agent</span>\n <span className=\"task-rows-cell-time\" style={headerLabelStyle}>\n Time\n </span>\n <span style={headerLabelStyle}>Outcome</span>\n </div>\n </Card>\n {groups.map((group) => (\n <div\n key={group.key}\n style={{ display: 'flex', flexDirection: 'column', gap: space[1] }}\n >\n <Card size=\"small\" texture=\"kraft\" className=\"plan-row-card\">\n <span style={{ ...headerLabelStyle, opacity: 0.75 }}>\n {formatDayHeader(group.entries[0].endedAt)}\n </span>\n </Card>\n {group.entries.map((entry) => (\n <TaskRow key={entry.id} entry={entry} highlighted={entry.id === taskId} />\n ))}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n};\n"],"names":["TASK_KIND_LABELS","pad","n","dayKey","iso","d","formatDayHeader","formatTime","headerLabelStyle","fontSize","TaskLogLines","id","lines","setLines","useState","useEffect","fetchTaskLogLines","data","jsx","fontFamily","ChevronRightIcon","size","TaskRow","entry","highlighted","expanded","setExpanded","toggle","v","jsxs","space","e","Card","AGENT_LABELS","Stamp","color","TasksPage","taskLog","useAppStore","s","taskLogLoading","loadTaskLog","taskId","useSearch","containerRef","useRef","row","_a","sorted","b","groups","key","group","PageTitle"],"mappings":"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"}
|