Developer tools¶
Elements for coding agents: terminals, stack traces, tests, files, commits and more.
Terminal¶
Command output as a terminal shows it: colours, progress bars, links.

| API | Terminal(output, title, status, exitCode) |
| AI Elements | Terminal |
| Artifact | ai-elements-ui |
| Reference | Terminal |
Pass accumulated command output. ANSI styling is supported, with bounded scrollback; this is an output view, not an interactive shell.
import androidx.compose.runtime.Composable
import dev.ai.elements.ui.code.Terminal
import dev.ai.elements.ui.code.TerminalStatus
@Composable
fun TerminalExample() {
Terminal("Tests passed\n", title = "Test output", status = TerminalStatus.SUCCESS, exitCode = 0)
}
Stack trace¶
A stack trace with app frames first and library frames folded.

| API | StackTrace(trace) |
| AI Elements | StackTrace |
| Artifact | ai-elements-ui |
| Reference | StackTrace |
Takes raw trace text. App frames and dependency frames can be folded; this view does not upload crash reports.
@Composable
fun StackTraceExample() {
StackTrace("java.lang.IllegalStateException: Missing input\n at example.App.run(App.kt:12)")
}
Test results¶
Test suites with passed, failed and skipped cases.

| API | TestResults(suites, durationMs) |
| AI Elements | TestResults |
| Artifact | ai-elements-ui |
| Reference | TestResults |
Supply actual test results and durations in milliseconds; the component does not run tests.
import androidx.compose.runtime.Composable
import dev.ai.elements.ui.code.TestCaseResult
import dev.ai.elements.ui.code.TestResults
import dev.ai.elements.ui.code.TestStatus
import dev.ai.elements.ui.code.TestSuiteResult
@Composable
fun TestResultsExample() {
TestResults(listOf(TestSuiteResult("Example", listOf(TestCaseResult("loads", TestStatus.PASSED, 25)))), durationMs = 25)
}
File tree¶
A project's files, with change badges.

| API | FileTree(nodes, expanded, selectedPath, onSelect) |
| AI Elements | FileTree |
| Artifact | ai-elements-ui |
| Reference | FileTree |
The caller provides file nodes; selecting a node does not read it. Pass expanded paths when you need initial folder expansion.
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import dev.ai.elements.ui.code.FileNode
import dev.ai.elements.ui.code.FileTree
@Composable
fun FileTreeExample() {
var selected by rememberSaveable { mutableStateOf<String?>(null) }
FileTree(listOf(FileNode("README.md", "README.md")), selectedPath = selected, onSelect = { selected = it.path })
}
Commit¶
A commit with its message and changed files.

| API | Commit(hash, message, author, timestampMs, files) |
| AI Elements | Commit |
| Artifact | ai-elements-ui |
| Reference | Commit |
Metadata display only. Hash/message/files come from your source control tool; no git operation is performed.
import androidx.compose.runtime.Composable
import dev.ai.elements.ui.code.Commit
import dev.ai.elements.ui.code.CommitFile
import dev.ai.elements.ui.code.FileChange
@Composable
fun CommitExample() {
Commit(hash = "abcdef1234", message = "Document the API", files = listOf(CommitFile("README.md", FileChange.MODIFIED, 10, 2)))
}
Schema display¶
An API endpoint: parameters, request and response.

| API | SchemaDisplay(method, path, parameters, requestBody, responseBody) |
| AI Elements | SchemaDisplay |
| Artifact | ai-elements-ui |
| Reference | SchemaDisplay |
Displays a schema summary; it does not validate or invoke the endpoint. requestBody/responseBody are example text.
import androidx.compose.runtime.Composable
import dev.ai.elements.ui.code.SchemaDisplay
import dev.ai.elements.ui.code.SchemaParameter
@Composable
fun SchemaDisplayExample() {
SchemaDisplay(method = "POST", path = "/chat", parameters = listOf(SchemaParameter("messages", "array", required = true)))
}
Package info¶
A dependency change and its size.

| API | PackageInfo(name, fromVersion, toVersion, change) |
| AI Elements | PackageInfo |
| Artifact | ai-elements-ui |
| Reference | PackageInfo |
The app supplies the change classification and size metadata. No dependency resolution or update is performed.
import androidx.compose.runtime.Composable
import dev.ai.elements.ui.code.PackageChange
import dev.ai.elements.ui.code.PackageInfo
@Composable
fun PackageInfoExample() {
PackageInfo("example:library", fromVersion = "1.0.0", toVersion = "1.1.0", change = PackageChange.MINOR)
}
Environment variables¶
Environment variables with secrets masked until revealed.

| API | EnvironmentVariables(variables) |
| AI Elements | EnvironmentVariables |
| Artifact | ai-elements-ui |
| Reference | EnvironmentVariables |
Values marked secret are visually masked, not encrypted. Do not put real credentials in examples or screenshots.
import androidx.compose.runtime.Composable
import dev.ai.elements.ui.code.EnvironmentVariable
import dev.ai.elements.ui.code.EnvironmentVariables
@Composable
fun EnvironmentVariablesExample() {
EnvironmentVariables(listOf(EnvironmentVariable("MODEL", "local", secret = false)))
}
Sandbox¶
Code and its output in tabs.

| API | Sandbox(title, tabs) |
| AI Elements | Sandbox |
| Artifact | ai-elements-ui |
| Reference | Sandbox |
This is a tabbed presentation of code and results. Execution is supplied separately by harness-shell or your backend.
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import dev.ai.elements.ui.code.Sandbox
import dev.ai.elements.ui.code.SandboxTab
import dev.ai.elements.ui.markdown.CodeBlock
@Composable
fun SandboxExample() {
Sandbox("Example", listOf(SandboxTab("Code") { CodeBlock("println(42)", "kotlin") }, SandboxTab("Output") { Text("42") }))
}
Snippet¶
A one-line command to copy.

| API | Snippet(text, prefix) |
| AI Elements | Snippet |
| Artifact | ai-elements-ui |
| Reference | Snippet |
Displays a copyable command; clicking copy does not execute it.