Skip to main content

systemprompt_cli/presentation/tables/
entities.rs

1//! Listing tables for stored artifacts, contexts, and database tables.
2//!
3//! Copyright (c) systemprompt.io — Business Source License 1.1.
4//! See <https://systemprompt.io> for licensing details.
5
6use tabled::{Table, Tabled};
7
8use crate::commands::core::artifacts::ArtifactSummary;
9use crate::commands::core::contexts::ContextSummary;
10use crate::commands::infrastructure::db::TableInfo;
11use crate::shared::truncate_with_ellipsis;
12
13use super::dash;
14
15#[derive(Tabled)]
16struct ArtifactListRow {
17    #[tabled(rename = "ID")]
18    id: String,
19    #[tabled(rename = "Name")]
20    name: String,
21    #[tabled(rename = "Type")]
22    artifact_type: String,
23    #[tabled(rename = "Tool")]
24    tool_name: String,
25    #[tabled(rename = "Created")]
26    created_at: String,
27}
28
29#[must_use]
30pub fn artifact_list_table(artifacts: &[ArtifactSummary]) -> String {
31    let rows: Vec<ArtifactListRow> = artifacts
32        .iter()
33        .map(|a| ArtifactListRow {
34            id: truncate_with_ellipsis(a.artifact_id.as_str(), 12),
35            name: a.name.clone().unwrap_or_else(dash),
36            artifact_type: a.artifact_type.clone(),
37            tool_name: a.tool_name.clone().unwrap_or_else(dash),
38            created_at: a.created_at.format("%Y-%m-%d %H:%M").to_string(),
39        })
40        .collect();
41    Table::new(rows).to_string()
42}
43
44#[derive(Tabled)]
45struct ContextListRow {
46    #[tabled(rename = "ID")]
47    id: String,
48    #[tabled(rename = "Name")]
49    name: String,
50    #[tabled(rename = "Tasks")]
51    task_count: i64,
52    #[tabled(rename = "Messages")]
53    message_count: i64,
54    #[tabled(rename = "Updated")]
55    updated_at: String,
56    #[tabled(rename = "Active")]
57    active: String,
58}
59
60#[must_use]
61pub fn context_list_table(contexts: &[ContextSummary]) -> String {
62    let rows: Vec<ContextListRow> = contexts
63        .iter()
64        .map(|c| ContextListRow {
65            id: c.id.as_str().chars().take(8).collect(),
66            name: truncate_with_ellipsis(&c.name, 40),
67            task_count: c.task_count,
68            message_count: c.message_count,
69            updated_at: c.updated_at.format("%Y-%m-%d %H:%M").to_string(),
70            active: if c.is_active {
71                "*".to_owned()
72            } else {
73                String::new()
74            },
75        })
76        .collect();
77    Table::new(rows).to_string()
78}
79
80#[derive(Tabled)]
81struct DbTableRow {
82    #[tabled(rename = "Table")]
83    name: String,
84    #[tabled(rename = "Rows")]
85    row_count: i64,
86    #[tabled(rename = "Size")]
87    size: String,
88}
89
90#[must_use]
91pub fn db_tables_table(tables: &[TableInfo]) -> String {
92    let rows: Vec<DbTableRow> = tables
93        .iter()
94        .map(|t| DbTableRow {
95            name: t.name.clone(),
96            row_count: t.row_count,
97            size: crate::commands::infrastructure::db::format_bytes(t.size_bytes),
98        })
99        .collect();
100    Table::new(rows).to_string()
101}