feat(me): improve dashboard rendering with dynamic layout and table-based activity
Overhaul the `lore me` human-mode renderer for better terminal adaptation and visual clarity: Layout: - Add terminal_width() detection (COLUMNS env -> stderr ioctl -> 80 fallback) - Replace hardcoded column widths with dynamic title_width() that adapts to terminal size, clamped to [20, 80] - Section dividers now span the full terminal width Activity feed: - Replace manual println! formatting with Table-based rendering for proper column alignment across variable-width content - Split event_badge() into activity_badge_label() + activity_badge_style() for table cell compatibility - Add system_event_style() (#555555 dark gray) to visually suppress non-note events (label, assign, status, milestone, review changes) - Own actions use dim styling; others' notes render at full color MR display: - Add humanize_merge_status() to convert GitLab API values like "not_approved" -> "needs approval", "ci_must_pass" -> "CI pending" Table infrastructure (render.rs): - Add Table::columns() for headerless tables - Add Table::indent() for row-level indentation - Add truncate_pad() for fixed-width cell formatting - Table::render() now supports headerless mode (no separator line) Other: - Default activity lookback changed from 30d to 1d (more useful default) - Robot-docs schema added for `me` command - AGENTS.md and CLAUDE.md updated with `lore me` examples Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -28,7 +28,15 @@ fn insert_project(conn: &Connection, id: i64, path: &str) {
|
||||
}
|
||||
|
||||
fn insert_issue(conn: &Connection, id: i64, project_id: i64, iid: i64, author: &str) {
|
||||
insert_issue_with_state(conn, id, project_id, iid, author, "opened");
|
||||
insert_issue_with_status(
|
||||
conn,
|
||||
id,
|
||||
project_id,
|
||||
iid,
|
||||
author,
|
||||
"opened",
|
||||
Some("In Progress"),
|
||||
);
|
||||
}
|
||||
|
||||
fn insert_issue_with_state(
|
||||
@@ -38,11 +46,30 @@ fn insert_issue_with_state(
|
||||
iid: i64,
|
||||
author: &str,
|
||||
state: &str,
|
||||
) {
|
||||
// For closed issues, don't set status_name (they won't appear in dashboard anyway)
|
||||
let status_name = if state == "opened" {
|
||||
Some("In Progress")
|
||||
} else {
|
||||
None
|
||||
};
|
||||
insert_issue_with_status(conn, id, project_id, iid, author, state, status_name);
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn insert_issue_with_status(
|
||||
conn: &Connection,
|
||||
id: i64,
|
||||
project_id: i64,
|
||||
iid: i64,
|
||||
author: &str,
|
||||
state: &str,
|
||||
status_name: Option<&str>,
|
||||
) {
|
||||
let ts = now_ms();
|
||||
conn.execute(
|
||||
"INSERT INTO issues (id, gitlab_id, project_id, iid, title, state, author_username, created_at, updated_at, last_seen_at)
|
||||
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)",
|
||||
"INSERT INTO issues (id, gitlab_id, project_id, iid, title, state, status_name, author_username, created_at, updated_at, last_seen_at)
|
||||
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11)",
|
||||
rusqlite::params![
|
||||
id,
|
||||
id * 10,
|
||||
@@ -50,6 +77,7 @@ fn insert_issue_with_state(
|
||||
iid,
|
||||
format!("Issue {iid}"),
|
||||
state,
|
||||
status_name,
|
||||
author,
|
||||
ts,
|
||||
ts,
|
||||
@@ -552,7 +580,9 @@ fn activity_since_filter() {
|
||||
let since = now_ms() - 50_000;
|
||||
let results = query_activity(&conn, "alice", &[], since).unwrap();
|
||||
assert_eq!(results.len(), 1);
|
||||
assert_eq!(results[0].body_preview, Some("new comment".to_string()));
|
||||
// Notes no longer duplicate body into body_preview (summary carries the content)
|
||||
assert_eq!(results[0].body_preview, None);
|
||||
assert_eq!(results[0].summary, "new comment");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user