feat(cli): pic projects ls + §7 M3/track-complete docs
§7 M3 (part 3) — the ownership track becomes inspectable, completing M1–M3. - server: GET /api/v1/admin/projects (projects_api) lists every project + its owned-group count (projects repo list_with_counts, one GROUP BY); behind the /admin middleware, like the groups list. - CLI: pic projects ls (cmds/projects.rs + client projects_list); the apply_ownership plan-preview journey now also asserts projects ls (plat owns exactly 1 group; teamb listed). - docs: design §7 + CLAUDE.md record M3 shipped and the whole §7 multi-repo ownership track (M1 claim · M2 attach ceiling · M3 preview + projects ls) COMPLETE; deferred = structural-divergence + declarative tree shape + per-env approval gating. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,7 @@ pub mod logout;
|
||||
pub mod logs;
|
||||
pub mod members;
|
||||
pub mod plan;
|
||||
pub mod projects;
|
||||
pub mod pull;
|
||||
pub mod queues;
|
||||
pub mod routes;
|
||||
|
||||
29
crates/picloud-cli/src/cmds/projects.rs
Normal file
29
crates/picloud-cli/src/cmds/projects.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
//! `pic projects` — read-only view of §7 multi-repo ownership projects.
|
||||
//!
|
||||
//! A project is the repo-root that declaratively owns a slice of the group
|
||||
//! tree. Ownership is CLAIMED by `pic apply` (first apply with a `[project]`
|
||||
//! slug registers it); this command only lists what exists.
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::client::Client;
|
||||
use crate::config;
|
||||
use crate::output::{OutputMode, Table};
|
||||
|
||||
/// `pic projects ls` — every project + how many group nodes it owns.
|
||||
pub async fn ls(mode: OutputMode) -> Result<()> {
|
||||
let creds = config::resolve()?;
|
||||
let client = Client::from_creds(&creds)?;
|
||||
let projects = client.projects_list().await?;
|
||||
let mut table = Table::new(["slug", "name", "owned_groups", "created_at"]);
|
||||
for p in &projects {
|
||||
table.row([
|
||||
p.slug.clone(),
|
||||
p.name.clone(),
|
||||
p.owned_groups.to_string(),
|
||||
p.created_at.to_rfc3339(),
|
||||
]);
|
||||
}
|
||||
table.print(mode);
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user