- Accordion
- Alert
- Alert Dialog
- Aspect Ratio
- Attachment
- Autocomplete
- Avatar
- Badge
- Breadcrumb
- Bubble
- Button
- Button Group
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Code Block
- Collapsible
- Combobox
- Command
- Context Menu
- Data Table
- Date Picker
- Dialog
- Drawer
- Dropdown Menu
- Empty
- Field
- Hover Card
- Input Group
- Input OTP
- Input
- Item
- Kbd
- Label
- Marker
- Menubar
- Message
- Message Scroller
- Native Select
- Navigation Menu
- Pagination
- Popover
- Progress
- Questionnaire
- Radio Group
- Resizable
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner (Toast)
- Spinner
- Switch
- Table
- Tabs
- Textarea
- Toggle
- Toggle Group
- Tooltip
- Trace
Trace
The building block for reasoning, tool calls, sources and more.
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)The last commit bumped a version in package.json without updating pnpm-lock.yaml, so the frozen install fails. Run pnpm install locally and commit the lockfile.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideArrowUpRight, lucideCircleAlert, lucideCircleCheck, lucideGlobe } from '@ng-icons/lucide';
import { HlmBubbleImports } from '@spartan-ng/helm/bubble';
import { HlmCodeBlockImports } from '@spartan-ng/helm/code-block';
import { HlmMessageImports } from '@spartan-ng/helm/message';
import { HlmTraceImports } from '@spartan-ng/helm/trace';
@Component({
selector: 'spartan-trace-preview',
imports: [HlmTraceImports, HlmCodeBlockImports, NgIcon, HlmMessageImports, HlmBubbleImports],
providers: [provideIcons({ lucideCircleCheck, lucideCircleAlert, lucideGlobe, lucideArrowUpRight })],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="flex min-h-72 w-full max-w-sm flex-col gap-4 py-6 text-sm">
<hlm-message align="end">
<hlm-message-content>
<hlm-bubble align="end" variant="muted">
<hlm-bubble-content>Why does pnpm install fail in CI?</hlm-bubble-content>
</hlm-bubble>
</hlm-message-content>
</hlm-message>
<hlm-message>
<hlm-message-content>
<hlm-trace class="max-w-sm">
<hlm-trace-collapsible>
<button hlmTraceCollapsibleTrigger>
<hlm-trace-line>
<hlm-trace-icon>
<ng-icon name="lucideCircleCheck" />
</hlm-trace-icon>
<hlm-trace-title>Thought for 5s</hlm-trace-title>
</hlm-trace-line>
</button>
<hlm-trace-collapsible-content>
The frozen install fails because package.json was bumped without the lockfile. I'll check the last
commit.
</hlm-trace-collapsible-content>
</hlm-trace-collapsible>
<hlm-trace-line>
<hlm-trace-icon>
<ng-icon name="lucideCircleCheck" />
</hlm-trace-icon>
<hlm-trace-title>Ran pnpm --version</hlm-trace-title>
</hlm-trace-line>
<hlm-trace-collapsible [expanded]="true">
<button hlmTraceCollapsibleTrigger>
<hlm-trace-line>
<hlm-trace-icon>
<ng-icon name="lucideCircleCheck" />
</hlm-trace-icon>
<hlm-trace-title>Ran git diff --stat HEAD~1 -- package.json pnpm-lock.yaml</hlm-trace-title>
</hlm-trace-line>
</button>
<hlm-trace-collapsible-content>
<hlm-code-block size="sm">
<pre hlmCodeBlockContent [code]="_diff"></pre>
</hlm-code-block>
</hlm-trace-collapsible-content>
</hlm-trace-collapsible>
<hlm-trace-line status="error">
<hlm-trace-icon>
<ng-icon name="lucideCircleAlert" />
</hlm-trace-icon>
<hlm-trace-title>Failed to run pnpm install --frozen-lockfile</hlm-trace-title>
</hlm-trace-line>
<hlm-trace-collapsible>
<button hlmTraceCollapsibleTrigger>
<hlm-trace-line>
<hlm-trace-icon>
<ng-icon name="lucideGlobe" />
</hlm-trace-icon>
<hlm-trace-title>Used 2 sources</hlm-trace-title>
</hlm-trace-line>
</button>
<hlm-trace-collapsible-content>
<hlm-trace>
<a hlmTraceLine href="https://pnpm.io/settings#minimumreleaseage" target="_blank" rel="noreferrer">
<hlm-trace-icon>
<ng-icon name="lucideGlobe" />
</hlm-trace-icon>
<hlm-trace-title>
Settings: minimumReleaseAge | pnpm.io
<span class="sr-only">(opens in a new tab)</span>
</hlm-trace-title>
<hlm-trace-icon>
<ng-icon name="lucideArrowUpRight" />
</hlm-trace-icon>
</a>
<a hlmTraceLine href="https://angular.dev/guide/signals" target="_blank" rel="noreferrer">
<hlm-trace-icon>
<ng-icon name="lucideGlobe" />
</hlm-trace-icon>
<hlm-trace-title>
Angular signals | angular.dev
<span class="sr-only">(opens in a new tab)</span>
</hlm-trace-title>
<hlm-trace-icon>
<ng-icon name="lucideArrowUpRight" />
</hlm-trace-icon>
</a>
</hlm-trace>
</hlm-trace-collapsible-content>
</hlm-trace-collapsible>
</hlm-trace>
<p>
The last commit bumped a version in package.json without updating pnpm-lock.yaml, so the frozen install
fails. Run pnpm install locally and commit the lockfile.
</p>
</hlm-message-content>
</hlm-message>
</div>
`,
})
export class TracePreview {
protected readonly _diff = ` package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)`;
}Installation
ng g @spartan-ng/cli:ui trace
npx nx g @spartan-ng/cli:ui trace
Usage
import { HlmTraceImports } from '@spartan-ng/helm/trace';<hlm-trace>
<hlm-trace-line>
<hlm-trace-icon>
<ng-icon name="lucideSearch" />
</hlm-trace-icon>
<hlm-trace-title>Searched for minimumReleaseAge</hlm-trace-title>
</hlm-trace-line>
</hlm-trace>Examples
Trace Line
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideGitBranch } from '@ng-icons/lucide';
import { HlmTraceImports } from '@spartan-ng/helm/trace';
@Component({
selector: 'spartan-trace-line',
imports: [HlmTraceImports, NgIcon],
providers: [provideIcons({ lucideGitBranch })],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<hlm-trace class="max-w-sm">
<hlm-trace-line>
<hlm-trace-icon>
<ng-icon name="lucideGitBranch" />
</hlm-trace-icon>
<hlm-trace-title>Created branch fix/frozen-lockfile</hlm-trace-title>
</hlm-trace-line>
</hlm-trace>
`,
})
export class TraceLine {}Status
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideCircle, lucideCircleAlert, lucideCircleCheck, lucideLoaderCircle } from '@ng-icons/lucide';
import { HlmTraceImports } from '@spartan-ng/helm/trace';
@Component({
selector: 'spartan-trace-status',
imports: [HlmTraceImports, NgIcon],
providers: [provideIcons({ lucideCircleCheck, lucideCircleAlert, lucideLoaderCircle, lucideCircle })],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<hlm-trace class="max-w-sm">
<hlm-trace-line>
<hlm-trace-icon>
<ng-icon name="lucideCircleCheck" />
</hlm-trace-icon>
<hlm-trace-title>Ran pnpm install</hlm-trace-title>
</hlm-trace-line>
<hlm-trace-line status="error">
<hlm-trace-icon>
<ng-icon name="lucideCircleAlert" />
</hlm-trace-icon>
<hlm-trace-title>Failed to run pnpm lint</hlm-trace-title>
</hlm-trace-line>
<hlm-trace-line status="running">
<hlm-trace-icon>
<ng-icon name="lucideLoaderCircle" class="motion-safe:animate-spin" />
</hlm-trace-icon>
<hlm-trace-title>Running pnpm build</hlm-trace-title>
</hlm-trace-line>
<hlm-trace-line status="pending">
<hlm-trace-icon>
<ng-icon name="lucideCircle" />
</hlm-trace-icon>
<hlm-trace-title>Run pnpm test</hlm-trace-title>
</hlm-trace-line>
</hlm-trace>
`,
})
export class TraceStatus {}Description
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideFilePen, lucideSearch, lucideTerminal } from '@ng-icons/lucide';
import { HlmTraceImports } from '@spartan-ng/helm/trace';
@Component({
selector: 'spartan-trace-description',
imports: [HlmTraceImports, NgIcon],
providers: [provideIcons({ lucideFilePen, lucideTerminal, lucideSearch })],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<hlm-trace class="max-w-sm">
<hlm-trace-line>
<hlm-trace-icon>
<ng-icon name="lucideFilePen" />
</hlm-trace-icon>
<hlm-trace-title>Edited components/settings/notification-preferences-form.tsx</hlm-trace-title>
<hlm-trace-description class="font-mono">+48 -12</hlm-trace-description>
</hlm-trace-line>
<hlm-trace-line>
<hlm-trace-icon>
<ng-icon name="lucideTerminal" />
</hlm-trace-icon>
<hlm-trace-title>Ran pnpm test</hlm-trace-title>
<hlm-trace-description>14s</hlm-trace-description>
</hlm-trace-line>
<hlm-trace-line>
<hlm-trace-icon>
<ng-icon name="lucideSearch" />
</hlm-trace-icon>
<hlm-trace-title>Searched for useChat</hlm-trace-title>
<hlm-trace-description>8 results</hlm-trace-description>
</hlm-trace-line>
</hlm-trace>
`,
})
export class TraceDescription {}Collapsible
$ node --version
v24.18.0import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideTerminal } from '@ng-icons/lucide';
import { HlmCodeBlockImports } from '@spartan-ng/helm/code-block';
import { HlmTraceImports } from '@spartan-ng/helm/trace';
@Component({
selector: 'spartan-trace-collapsible',
imports: [HlmTraceImports, HlmCodeBlockImports, NgIcon],
providers: [provideIcons({ lucideTerminal })],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="w-full max-w-sm">
<hlm-trace-collapsible>
<button hlmTraceCollapsibleTrigger>
<hlm-trace-line>
<hlm-trace-icon>
<ng-icon name="lucideTerminal" />
</hlm-trace-icon>
<hlm-trace-title>Ran node --version</hlm-trace-title>
</hlm-trace-line>
</button>
<hlm-trace-collapsible-content>
<hlm-code-block size="sm">
<pre hlmCodeBlockContent wrap [code]="_output" class="max-h-64"></pre>
</hlm-code-block>
</hlm-trace-collapsible-content>
</hlm-trace-collapsible>
</div>
`,
})
export class TraceCollapsible {
protected readonly _output = `$ node --version
v24.18.0`;
}Open Status
$ node --version
v24.18.0$ pnpm --version
10.33.4import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideTerminal } from '@ng-icons/lucide';
import { HlmButton } from '@spartan-ng/helm/button';
import { HlmCodeBlockImports } from '@spartan-ng/helm/code-block';
import { HlmTraceImports } from '@spartan-ng/helm/trace';
@Component({
selector: 'spartan-trace-open-status',
imports: [HlmTraceImports, HlmCodeBlockImports, HlmButton, NgIcon],
providers: [provideIcons({ lucideTerminal })],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="flex w-full max-w-sm flex-col items-start gap-4">
<hlm-trace-collapsible [expanded]="true">
<button hlmTraceCollapsibleTrigger>
<hlm-trace-line>
<hlm-trace-icon>
<ng-icon name="lucideTerminal" />
</hlm-trace-icon>
<hlm-trace-title>Ran node --version</hlm-trace-title>
</hlm-trace-line>
</button>
<hlm-trace-collapsible-content>
<hlm-code-block size="sm">
<pre hlmCodeBlockContent wrap [code]="_nodeOutput" class="max-h-64"></pre>
</hlm-code-block>
</hlm-trace-collapsible-content>
</hlm-trace-collapsible>
<hlm-trace-collapsible [(expanded)]="_open">
<button hlmTraceCollapsibleTrigger>
<hlm-trace-line>
<hlm-trace-icon>
<ng-icon name="lucideTerminal" />
</hlm-trace-icon>
<hlm-trace-title>Ran pnpm --version</hlm-trace-title>
</hlm-trace-line>
</button>
<hlm-trace-collapsible-content>
<hlm-code-block size="sm">
<pre hlmCodeBlockContent wrap [code]="_pnpmOutput" class="max-h-64"></pre>
</hlm-code-block>
</hlm-trace-collapsible-content>
</hlm-trace-collapsible>
<button hlmBtn variant="outline" size="sm" (click)="_open.set(!_open())">
{{ _open() ? 'Hide' : 'Show' }} the pnpm output
</button>
</div>
`,
})
export class TraceOpenStatus {
protected readonly _open = signal(false);
protected readonly _nodeOutput = `$ node --version
v24.18.0`;
protected readonly _pnpmOutput = `$ pnpm --version
10.33.4`;
}Link
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { RouterLink } from '@angular/router';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideArrowUpRight, lucideChevronRight, lucideFileText, lucideGlobe } from '@ng-icons/lucide';
import { HlmTraceImports } from '@spartan-ng/helm/trace';
@Component({
selector: 'spartan-trace-link',
imports: [HlmTraceImports, NgIcon, RouterLink],
providers: [provideIcons({ lucideFileText, lucideChevronRight, lucideGlobe, lucideArrowUpRight })],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<hlm-trace class="max-w-sm">
<a hlmTraceLine routerLink=".">
<hlm-trace-icon>
<ng-icon name="lucideFileText" />
</hlm-trace-icon>
<hlm-trace-title>Read apps/v4/lib/docs.ts</hlm-trace-title>
<hlm-trace-icon>
<ng-icon name="lucideChevronRight" />
</hlm-trace-icon>
</a>
<a hlmTraceLine href="https://spartan.ng/documentation/installation" target="_blank" rel="noreferrer">
<hlm-trace-icon>
<ng-icon name="lucideGlobe" />
</hlm-trace-icon>
<hlm-trace-title>
Install spartan/ui | spartan.ng
<span class="sr-only">(opens in a new tab)</span>
</hlm-trace-title>
<hlm-trace-icon>
<ng-icon name="lucideArrowUpRight" />
</hlm-trace-icon>
</a>
</hlm-trace>
`,
})
export class TraceLink {}Dialog
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideArrowUpRight, lucideChevronRight, lucideGlobe } from '@ng-icons/lucide';
import { HlmDialogImports } from '@spartan-ng/helm/dialog';
import { HlmTraceImports } from '@spartan-ng/helm/trace';
@Component({
selector: 'spartan-trace-dialog',
imports: [HlmTraceImports, HlmDialogImports, NgIcon],
providers: [provideIcons({ lucideGlobe, lucideChevronRight, lucideArrowUpRight })],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<hlm-trace class="max-w-sm">
<hlm-dialog>
<button hlmDialogTrigger hlmTraceLine>
<hlm-trace-icon>
<ng-icon name="lucideGlobe" />
</hlm-trace-icon>
<hlm-trace-title>Searched the web for cache keys</hlm-trace-title>
<hlm-trace-icon>
<ng-icon name="lucideChevronRight" />
</hlm-trace-icon>
</button>
<hlm-dialog-content *hlmDialogPortal="let ctx" class="sm:w-7xl">
<hlm-dialog-header>
<h3 hlmDialogTitle>Searched the web for cache keys</h3>
<p hlmDialogDescription>Three results were used in the response.</p>
</hlm-dialog-header>
<hlm-trace>
@for (item of _results; track $index) {
<a hlmTraceLine [href]="item.url" target="_blank" rel="noreferrer">
<hlm-trace-icon>
<ng-icon name="lucideGlobe" />
</hlm-trace-icon>
<hlm-trace-title>
{{ item.title }}
<span class="sr-only">(opens in a new tab)</span>
</hlm-trace-title>
<hlm-trace-icon>
<ng-icon name="lucideArrowUpRight" />
</hlm-trace-icon>
</a>
}
</hlm-trace>
</hlm-dialog-content>
</hlm-dialog>
</hlm-trace>
`,
})
export class TraceDialog {
protected readonly _results = [
{
title: 'Angular components',
url: 'https://angular.dev/guide/components',
},
{
title: 'Angular signals',
url: 'https://angular.dev/guide/signals',
},
{
title: 'Analog content',
url: 'https://analogjs.org/docs/features/routing/content',
},
];
}Sheet
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideArrowUpRight, lucideChevronRight, lucideFolderSearch } from '@ng-icons/lucide';
import { HlmSheetImports } from '@spartan-ng/helm/sheet';
import { HlmTraceImports } from '@spartan-ng/helm/trace';
@Component({
selector: 'spartan-trace-sheet',
imports: [HlmTraceImports, HlmSheetImports, NgIcon],
providers: [provideIcons({ lucideFolderSearch, lucideChevronRight, lucideArrowUpRight })],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<hlm-trace class="max-w-sm">
<hlm-sheet>
<button hlmSheetTrigger side="right" hlmTraceLine>
<hlm-trace-icon>
<ng-icon name="lucideFolderSearch" />
</hlm-trace-icon>
<hlm-trace-title>Explored 4 files</hlm-trace-title>
<hlm-trace-icon>
<ng-icon name="lucideChevronRight" />
</hlm-trace-icon>
</button>
<hlm-sheet-content *hlmSheetPortal="let ctx" class="sm:w-7xl">
<hlm-sheet-header>
<h3 hlmSheetTitle>Explored 4 files</h3>
<p hlmSheetDescription>Files read while preparing the response.</p>
</hlm-sheet-header>
<ul class="flex flex-col gap-2 px-6 font-mono text-xs">
<li>apps/v4/lib/docs.ts</li>
<li>apps/v4/lib/components.ts</li>
<li>apps/v4/angular.json</li>
<li>apps/v4/package.json</li>
</ul>
</hlm-sheet-content>
</hlm-sheet>
</hlm-trace>
`,
})
export class TraceSheet {}Group
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideFileText, lucideSearch, lucideTerminal } from '@ng-icons/lucide';
import { HlmTraceImports } from '@spartan-ng/helm/trace';
@Component({
selector: 'spartan-trace-group',
imports: [HlmTraceImports, NgIcon],
providers: [provideIcons({ lucideSearch, lucideFileText, lucideTerminal })],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<hlm-trace class="max-w-sm">
<hlm-trace-line>
<hlm-trace-icon>
<ng-icon name="lucideSearch" />
</hlm-trace-icon>
<hlm-trace-title>Searched for minimumReleaseAge</hlm-trace-title>
</hlm-trace-line>
<hlm-trace-line>
<hlm-trace-icon>
<ng-icon name="lucideFileText" />
</hlm-trace-icon>
<hlm-trace-title>Read pnpm-workspace.yaml</hlm-trace-title>
</hlm-trace-line>
<hlm-trace-line>
<hlm-trace-icon>
<ng-icon name="lucideTerminal" />
</hlm-trace-icon>
<hlm-trace-title>Ran pnpm install</hlm-trace-title>
</hlm-trace-line>
</hlm-trace>
`,
})
export class TraceGroup {}Sources
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideArrowUpRight, lucideGlobe } from '@ng-icons/lucide';
import { HlmTraceImports } from '@spartan-ng/helm/trace';
@Component({
selector: 'spartan-trace-sources',
imports: [HlmTraceImports, NgIcon],
providers: [provideIcons({ lucideGlobe, lucideArrowUpRight })],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="w-full max-w-sm">
<hlm-trace-collapsible [expanded]="true">
<button hlmTraceCollapsibleTrigger>
<hlm-trace-line>
<hlm-trace-icon>
<ng-icon name="lucideGlobe" />
</hlm-trace-icon>
<hlm-trace-title>Used {{ _sources.length }} sources</hlm-trace-title>
</hlm-trace-line>
</button>
<hlm-trace-collapsible-content>
<hlm-trace>
@for (item of _sources; track $index) {
<a hlmTraceLine [href]="item.href" target="_blank" rel="noreferrer">
<hlm-trace-icon>
<ng-icon name="lucideGlobe" />
</hlm-trace-icon>
<hlm-trace-title>
{{ item.title }}
<span class="sr-only">(opens in a new tab)</span>
</hlm-trace-title>
<hlm-trace-icon>
<ng-icon name="lucideArrowUpRight" />
</hlm-trace-icon>
</a>
}
</hlm-trace>
</hlm-trace-collapsible-content>
</hlm-trace-collapsible>
</div>
`,
})
export class TraceSources {
protected readonly _sources = [
{
title: 'Angular components | angular.dev',
href: 'https://angular.dev/guide/components',
},
{
title: 'Angular signals | angular.dev',
href: 'https://angular.dev/guide/signals',
},
{
title: 'Settings: minimumReleaseAge | pnpm.io',
href: 'https://pnpm.io/settings#minimumreleaseage',
},
];
}Chain of Thought
cache key image optimizationimport { ChangeDetectionStrategy, Component } from '@angular/core';
import { RouterLink } from '@angular/router';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideChevronRight, lucideFileText, lucideSearch } from '@ng-icons/lucide';
import { HlmBadge } from '@spartan-ng/helm/badge';
import { HlmCodeBlockImports } from '@spartan-ng/helm/code-block';
import { HlmTraceImports } from '@spartan-ng/helm/trace';
@Component({
selector: 'spartan-trace-chain-of-thought',
imports: [HlmTraceImports, HlmCodeBlockImports, NgIcon, HlmBadge, RouterLink],
providers: [provideIcons({ lucideSearch, lucideFileText, lucideChevronRight })],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="w-full max-w-sm">
<hlm-trace-collapsible [expanded]="true">
<button hlmTraceCollapsibleTrigger>
<hlm-trace-line status="running">
<hlm-trace-title>Looking into the slow deploy</hlm-trace-title>
</hlm-trace-line>
</button>
<hlm-trace-collapsible-content>
<hlm-trace>
<hlm-trace-collapsible>
<button hlmTraceCollapsibleTrigger>
<hlm-trace-line>
<hlm-trace-icon>
<ng-icon name="lucideSearch" />
</hlm-trace-icon>
<hlm-trace-title>Searched for the checkout build log</hlm-trace-title>
</hlm-trace-line>
</button>
<hlm-trace-collapsible-content contentInnerClasses="flex flex-wrap gap-1.5">
<span hlmBadge variant="secondary">analogjs.org</span>
<span hlmBadge variant="secondary">github.com</span>
</hlm-trace-collapsible-content>
</hlm-trace-collapsible>
<a routerLink="." fragment="chain-of-thought" hlmTraceLine>
<hlm-trace-icon>
<ng-icon name="lucideFileText" />
</hlm-trace-icon>
<hlm-trace-title>Read the last twelve deploys</hlm-trace-title>
<hlm-trace-icon>
<ng-icon name="lucideChevronRight" />
</hlm-trace-icon>
</a>
<hlm-trace-collapsible>
<button hlmTraceCollapsibleTrigger>
<hlm-trace-line status="running">
<hlm-trace-icon>
<ng-icon name="lucideSearch" />
</hlm-trace-icon>
<hlm-trace-title>Searching for the cache key</hlm-trace-title>
</hlm-trace-line>
</button>
<hlm-trace-collapsible-content>
<hlm-code-block size="sm">
<pre hlmCodeBlockContent wrap [code]="_output"></pre>
</hlm-code-block>
</hlm-trace-collapsible-content>
</hlm-trace-collapsible>
</hlm-trace>
</hlm-trace-collapsible-content>
</hlm-trace-collapsible>
</div>
`,
})
export class TraceChainOfThought {
protected readonly _output = 'cache key image optimization';
}Commit
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideFilePen, lucideFilePlus, lucideGitCommitHorizontal } from '@ng-icons/lucide';
import { HlmSheetImports } from '@spartan-ng/helm/sheet';
import { HlmTraceImports } from '@spartan-ng/helm/trace';
@Component({
selector: 'spartan-trace-commit',
imports: [HlmTraceImports, HlmSheetImports, NgIcon],
providers: [provideIcons({ lucideGitCommitHorizontal, lucideFilePen, lucideFilePlus })],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<hlm-trace class="max-w-sm">
<hlm-trace-collapsible [expanded]="true">
<button hlmTraceCollapsibleTrigger>
<hlm-trace-line>
<hlm-trace-icon>
<ng-icon name="lucideGitCommitHorizontal" />
</hlm-trace-icon>
<hlm-trace-title>Committed a1b2c3: Fix the login redirect</hlm-trace-title>
</hlm-trace-line>
</button>
<hlm-trace-collapsible-content>
<hlm-trace>
@for (file of _files; track file.path) {
<hlm-sheet>
<button hlmSheetTrigger side="right" hlmTraceLine>
<hlm-trace-icon>
<ng-icon [name]="file.icon" />
</hlm-trace-icon>
<hlm-trace-title>{{ file.label }} {{ file.path }}</hlm-trace-title>
<hlm-trace-description class="font-mono">{{ file.stat }}</hlm-trace-description>
</button>
<hlm-sheet-content *hlmSheetPortal="let ctx" class="sm:w-7xl">
<hlm-sheet-header>
<h3 hlmSheetTitle>{{ file.path }}</h3>
<p hlmSheetDescription>{{ file.label }} · {{ file.stat }}</p>
</hlm-sheet-header>
<pre
class="bg-muted text-foreground mx-6 overflow-x-auto rounded-md p-3 font-mono text-xs"
><code>{{ file.diff }}</code></pre>
</hlm-sheet-content>
</hlm-sheet>
}
</hlm-trace>
</hlm-trace-collapsible-content>
</hlm-trace-collapsible>
</hlm-trace>
`,
})
export class TraceCommit {
protected readonly _files = [
{
icon: 'lucideFilePen',
label: 'Edited',
path: 'app/login/page.tsx',
stat: '+2 -2',
diff: `- redirect('/dashboard')
+ redirect('/projects')`,
},
{
icon: 'lucideFilePlus',
label: 'Added',
path: 'lib/auth/redirect.ts',
stat: '+7 -0',
diff: `+ export function redirect(to: string) {
+ return { to };
+ }`,
},
];
}Whole Turn
command not found: pnpmNode is installed and pnpm is not. Reading the docs config.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { RouterLink } from '@angular/router';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideBrain, lucideChevronRight, lucideCircleAlert, lucideFileText, lucideTerminal } from '@ng-icons/lucide';
import { HlmCodeBlockImports } from '@spartan-ng/helm/code-block';
import { HlmTraceImports } from '@spartan-ng/helm/trace';
@Component({
selector: 'spartan-trace-whole-turn',
imports: [HlmTraceImports, HlmCodeBlockImports, NgIcon, RouterLink],
providers: [provideIcons({ lucideBrain, lucideTerminal, lucideCircleAlert, lucideFileText, lucideChevronRight })],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<hlm-trace class="max-w-sm">
<hlm-trace-collapsible [expanded]="true">
<button hlmTraceCollapsibleTrigger>
<hlm-trace-line status="error">
<hlm-trace-title>Worked for 2m 4s, 1 command failed</hlm-trace-title>
</hlm-trace-line>
</button>
<hlm-trace-collapsible-content>
<hlm-trace>
<hlm-trace-collapsible>
<button hlmTraceCollapsibleTrigger>
<hlm-trace-line>
<hlm-trace-icon>
<ng-icon name="lucideBrain" />
</hlm-trace-icon>
<hlm-trace-title>Thought</hlm-trace-title>
<hlm-trace-description>12s</hlm-trace-description>
</hlm-trace-line>
</button>
<hlm-trace-collapsible-content>
I'll check the installed Node and pnpm versions before touching the lockfile.
</hlm-trace-collapsible-content>
</hlm-trace-collapsible>
<hlm-trace-collapsible [expanded]="true">
<button hlmTraceCollapsibleTrigger>
<hlm-trace-line status="error">
<hlm-trace-icon>
<ng-icon name="lucideTerminal" />
</hlm-trace-icon>
<hlm-trace-title>Ran 2 commands, 1 failed</hlm-trace-title>
</hlm-trace-line>
</button>
<hlm-trace-collapsible-content>
<hlm-trace>
<hlm-trace-line>
<hlm-trace-icon>
<ng-icon name="lucideTerminal" />
</hlm-trace-icon>
<hlm-trace-title>Ran node --version</hlm-trace-title>
</hlm-trace-line>
<hlm-trace-collapsible>
<button hlmTraceCollapsibleTrigger>
<hlm-trace-line status="error">
<hlm-trace-icon>
<ng-icon name="lucideCircleAlert" />
</hlm-trace-icon>
<hlm-trace-title>Failed to run pnpm --version</hlm-trace-title>
</hlm-trace-line>
</button>
<hlm-trace-collapsible-content>
<hlm-code-block variant="destructive" size="sm">
<pre hlmCodeBlockContent wrap [code]="_pnpmError" class="max-h-64"></pre>
</hlm-code-block>
</hlm-trace-collapsible-content>
</hlm-trace-collapsible>
</hlm-trace>
</hlm-trace-collapsible-content>
</hlm-trace-collapsible>
<p class="text-muted-foreground text-sm">Node is installed and pnpm is not. Reading the docs config.</p>
<a hlmTraceLine routerLink="." fragment="whole-turn">
<hlm-trace-icon>
<ng-icon name="lucideFileText" />
</hlm-trace-icon>
<hlm-trace-title>Read apps/v4/lib/docs.ts</hlm-trace-title>
<hlm-trace-icon>
<ng-icon name="lucideChevronRight" />
</hlm-trace-icon>
</a>
</hlm-trace>
</hlm-trace-collapsible-content>
</hlm-trace-collapsible>
</hlm-trace>
`,
})
export class TraceWholeTurn {
protected readonly _pnpmError = 'command not found: pnpm';
}Helm API
HlmTraceCollapsibleContent
Selector: hlm-trace-collapsible-content
ExportAs: hlmTraceCollapsibleContent
Inputs
| Prop | Type | Default | Description |
|---|---|---|---|
| contentInnerClasses | ClassValue | - | - |
| id | string | null | undefined | - | The id of the collapsible content element. |
HlmTraceCollapsibleTrigger
Selector: button[hlmTraceCollapsibleTrigger]
ExportAs: hlmTraceCollapsibleTrigger
Inputs
| Prop | Type | Default | Description |
|---|---|---|---|
| type | 'button' | 'submit' | 'reset' | 'button' | - |
HlmTraceCollapsible
Selector: [hlmTraceCollapsible],hlm-trace-collapsible
ExportAs: hlmTraceCollapsible
Inputs
| Prop | Type | Default | Description |
|---|---|---|---|
| expanded | boolean | false | The expanded or collapsed state of the collapsible component. |
| disabled | boolean | false | The disabled state of the collapsible component. |
Outputs
| Prop | Type | Default | Description |
|---|---|---|---|
| expandedChange | boolean | - | The expanded or collapsed state of the collapsible component. |
HlmTraceDescription
Selector: [hlmTraceDescription],hlm-trace-description
ExportAs: hlmTraceDescription
HlmTraceIcon
Selector: [hlmTraceIcon],hlm-trace-icon
ExportAs: hlmTraceIcon
HlmTraceLine
Selector: [hlmTraceLine],hlm-trace-line
ExportAs: hlmTraceLine
Inputs
| Prop | Type | Default | Description |
|---|---|---|---|
| status | 'running' | 'error' | 'pending' | - | - |
HlmTraceTitle
Selector: [hlmTraceTitle],hlm-trace-title
ExportAs: hlmTraceTitle
HlmTrace
Selector: [hlmTrace],hlm-trace
ExportAs: hlmTrace
On This Page