{"version":3,"file":"widget.d.ts","sourceRoot":"","sources":["../src/widget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAA0B,KAAK,EAAE,MAAM,iCAAiC,CAAC;AACvG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,YAAY,CAAC;AAMzD,qBAAa,UAAW,YAAW,SAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAe;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAE9B,YAAY,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAG3C;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAE9B;IAED,UAAU,IAAI,IAAI,CAAG;CACrB;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAiBzF;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,YAAY,GAAG,SAAS,GAAG,IAAI,CAM5F","sourcesContent":["import type { ExtensionContext, ExtensionWidgetOptions, Theme } from \"@earendil-works/pi-coding-agent\";\nimport type { Component } from \"@earendil-works/pi-tui\";\nimport { truncateToWidth } from \"@earendil-works/pi-tui\";\nimport type { TodoListView, TodoTask } from \"./types.ts\";\n\nconst BAR_WIDTH = 10;\nconst WIDGET_KEY = \"pi-todo\";\nconst WIDGET_OPTIONS = { placement: \"aboveStatus\" } as unknown as ExtensionWidgetOptions;\n\nexport class TodoWidget implements Component {\n\tprivate readonly view: TodoListView;\n\tprivate readonly theme: Theme;\n\n\tconstructor(view: TodoListView, theme: Theme) {\n\t\tthis.view = view;\n\t\tthis.theme = theme;\n\t}\n\n\trender(width: number): string[] {\n\t\treturn renderTodoLines(this.view, this.theme, width);\n\t}\n\n\tinvalidate(): void {}\n}\n\nexport function renderTodoLines(view: TodoListView, theme: Theme, width: number): string[] {\n\tconst { summary } = view;\n\tconst filled = summary.total === 0 ? 0 : Math.round((summary.completed / summary.total) * BAR_WIDTH);\n\tconst bar = theme.fg(\"success\", \"█\".repeat(filled)) + theme.fg(\"dim\", \"░\".repeat(BAR_WIDTH - filled));\n\tconst lines = [truncateToWidth(`${theme.bold(\"pi-todo\")} [${bar}] ${summary.completed}/${summary.total}`, width)];\n\tappendSection(\n\t\tlines,\n\t\t\"Active\",\n\t\tview.list.tasks.filter((task) => task.status === \"in_progress\"),\n\t\ttheme,\n\t\twidth,\n\t);\n\tappendSection(lines, \"Ready\", view.ready, theme, width);\n\tappendSection(lines, \"Blocked\", view.blocked, theme, width);\n\tconst hidden = summary.total - summary.in_progress - summary.ready - summary.blocked;\n\tif (hidden > 0) lines.push(truncateToWidth(theme.fg(\"dim\", ` Completed ${hidden}`), width));\n\treturn lines.slice(0, 10);\n}\n\nexport function updateTodoWidget(ctx: ExtensionContext, view: TodoListView | undefined): void {\n\tif (!ctx.hasUI || !view || view.summary.total === 0) {\n\t\tctx.ui.setWidget(WIDGET_KEY, undefined);\n\t\treturn;\n\t}\n\tctx.ui.setWidget(WIDGET_KEY, (_tui, theme) => new TodoWidget(view, theme), WIDGET_OPTIONS);\n}\n\nfunction appendSection(lines: string[], label: string, tasks: readonly TodoTask[], theme: Theme, width: number): void {\n\tif (tasks.length === 0) return;\n\tlines.push(truncateToWidth(theme.fg(\"dim\", ` ${label} (${tasks.length})`), width));\n\tfor (const task of tasks.slice(0, 3)) {\n\t\tconst owner = task.owner ? ` @${task.owner}` : \"\";\n\t\tconst dependencies = label === \"Blocked\" ? ` <- ${task.depends_on.join(\",\")}` : \"\";\n\t\tconst symbol = label === \"Active\" ? \"◐\" : label === \"Blocked\" ? \"⊘\" : \"○\";\n\t\tconst subject = label === \"Active\" ? (task.active_form ?? task.subject) : task.subject;\n\t\tlines.push(\n\t\t\ttruncateToWidth(`  ${symbol} ${theme.fg(\"accent\", task.id)} ${subject}${owner}${dependencies}`, width),\n\t\t);\n\t}\n}\n"]}