mirror of
https://github.com/harivansh-afk/clanker-agent.git
synced 2026-04-20 13:02:14 +00:00
move pi-mono into companion-cloud as apps/companion-os
- Copy all pi-mono source into apps/companion-os/ - Update Dockerfile to COPY pre-built binary instead of downloading from GitHub Releases - Update deploy-staging.yml to build pi from source (bun compile) before Docker build - Add apps/companion-os/** to path triggers - No more cross-repo dispatch needed Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
commit
0250f72976
579 changed files with 206942 additions and 0 deletions
144
packages/web-ui/src/tools/renderer-registry.ts
Normal file
144
packages/web-ui/src/tools/renderer-registry.ts
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
import { icon } from "@mariozechner/mini-lit";
|
||||
import { html, type TemplateResult } from "lit";
|
||||
import type { Ref } from "lit/directives/ref.js";
|
||||
import { ref } from "lit/directives/ref.js";
|
||||
import { ChevronsUpDown, ChevronUp, Loader } from "lucide";
|
||||
import type { ToolRenderer } from "./types.js";
|
||||
|
||||
// Registry of tool renderers
|
||||
export const toolRenderers = new Map<string, ToolRenderer>();
|
||||
|
||||
/**
|
||||
* Register a custom tool renderer
|
||||
*/
|
||||
export function registerToolRenderer(
|
||||
toolName: string,
|
||||
renderer: ToolRenderer,
|
||||
): void {
|
||||
toolRenderers.set(toolName, renderer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a tool renderer by name
|
||||
*/
|
||||
export function getToolRenderer(toolName: string): ToolRenderer | undefined {
|
||||
return toolRenderers.get(toolName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to render a header for tool renderers
|
||||
* Shows icon on left when complete/error, spinner on right when in progress
|
||||
*/
|
||||
export function renderHeader(
|
||||
state: "inprogress" | "complete" | "error",
|
||||
toolIcon: any,
|
||||
text: string | TemplateResult,
|
||||
): TemplateResult {
|
||||
const statusIcon = (iconComponent: any, color: string) =>
|
||||
html`<span class="inline-block ${color}"
|
||||
>${icon(iconComponent, "sm")}</span
|
||||
>`;
|
||||
|
||||
switch (state) {
|
||||
case "inprogress":
|
||||
return html`
|
||||
<div
|
||||
class="flex items-center justify-between gap-2 text-sm text-muted-foreground"
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
${statusIcon(toolIcon, "text-foreground")} ${text}
|
||||
</div>
|
||||
${statusIcon(Loader, "text-foreground animate-spin")}
|
||||
</div>
|
||||
`;
|
||||
case "complete":
|
||||
return html`
|
||||
<div class="flex items-center gap-2 text-sm text-muted-foreground">
|
||||
${statusIcon(toolIcon, "text-green-600 dark:text-green-500")} ${text}
|
||||
</div>
|
||||
`;
|
||||
case "error":
|
||||
return html`
|
||||
<div class="flex items-center gap-2 text-sm text-muted-foreground">
|
||||
${statusIcon(toolIcon, "text-destructive")} ${text}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to render a collapsible header for tool renderers
|
||||
* Same as renderHeader but with a chevron button that toggles visibility of content
|
||||
*/
|
||||
export function renderCollapsibleHeader(
|
||||
state: "inprogress" | "complete" | "error",
|
||||
toolIcon: any,
|
||||
text: string | TemplateResult,
|
||||
contentRef: Ref<HTMLElement>,
|
||||
chevronRef: Ref<HTMLElement>,
|
||||
defaultExpanded = false,
|
||||
): TemplateResult {
|
||||
const statusIcon = (iconComponent: any, color: string) =>
|
||||
html`<span class="inline-block ${color}"
|
||||
>${icon(iconComponent, "sm")}</span
|
||||
>`;
|
||||
|
||||
const toggleContent = (e: Event) => {
|
||||
e.preventDefault();
|
||||
const content = contentRef.value;
|
||||
const chevron = chevronRef.value;
|
||||
if (content && chevron) {
|
||||
const isCollapsed = content.classList.contains("max-h-0");
|
||||
if (isCollapsed) {
|
||||
content.classList.remove("max-h-0");
|
||||
content.classList.add("max-h-[2000px]", "mt-3");
|
||||
// Show ChevronUp, hide ChevronsUpDown
|
||||
const upIcon = chevron.querySelector(".chevron-up");
|
||||
const downIcon = chevron.querySelector(".chevrons-up-down");
|
||||
if (upIcon && downIcon) {
|
||||
upIcon.classList.remove("hidden");
|
||||
downIcon.classList.add("hidden");
|
||||
}
|
||||
} else {
|
||||
content.classList.remove("max-h-[2000px]", "mt-3");
|
||||
content.classList.add("max-h-0");
|
||||
// Show ChevronsUpDown, hide ChevronUp
|
||||
const upIcon = chevron.querySelector(".chevron-up");
|
||||
const downIcon = chevron.querySelector(".chevrons-up-down");
|
||||
if (upIcon && downIcon) {
|
||||
upIcon.classList.add("hidden");
|
||||
downIcon.classList.remove("hidden");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const toolIconColor =
|
||||
state === "complete"
|
||||
? "text-green-600 dark:text-green-500"
|
||||
: state === "error"
|
||||
? "text-destructive"
|
||||
: "text-foreground";
|
||||
|
||||
return html`
|
||||
<button
|
||||
@click=${toggleContent}
|
||||
class="flex items-center justify-between gap-2 text-sm text-muted-foreground w-full text-left hover:text-foreground transition-colors cursor-pointer"
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
${state === "inprogress"
|
||||
? statusIcon(Loader, "text-foreground animate-spin")
|
||||
: ""}
|
||||
${statusIcon(toolIcon, toolIconColor)} ${text}
|
||||
</div>
|
||||
<span class="inline-block text-muted-foreground" ${ref(chevronRef)}>
|
||||
<span class="chevron-up ${defaultExpanded ? "" : "hidden"}"
|
||||
>${icon(ChevronUp, "sm")}</span
|
||||
>
|
||||
<span class="chevrons-up-down ${defaultExpanded ? "hidden" : ""}"
|
||||
>${icon(ChevronsUpDown, "sm")}</span
|
||||
>
|
||||
</span>
|
||||
</button>
|
||||
`;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue