Separate built-in and config mounts in config output
Add a `builtin` field to `ResolvedMount` to distinguish mounts that
are always present (workspace, pi data, agent, sessions) from
user-configurable mounts loaded from config.kdl.

The `config` command now shows two separate sections:
- Built-in volume mounts (always present)
- Config volume mounts (from config.kdl or fallback defaults)

When there are no config mounts, the section shows '(none)'.
change xnpxrqyxkovvywqvvnuzqzqxwoosrzwp
commit 69f49663385baa40a661e7077dda36a00171aea8
author Alpha Chen <alpha@kejadlen.dev>
date
parent pukqpzzl
diff --git a/src/config.rs b/src/config.rs
index 78be814..c55e055 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -25,6 +25,7 @@ pub struct ResolvedMount {
     pub source: PathBuf,
     pub target: String,
     pub writable: bool,
+    pub builtin: bool,
 }
 
 impl Default for Config {
@@ -104,6 +105,7 @@ impl Mount {
             source: expanded,
             target,
             writable: self.writable,
+            builtin: false,
         })
     }
 }
@@ -239,6 +241,7 @@ mod tests {
         assert_eq!(resolved.source, PathBuf::from("/tmp"));
         assert_eq!(resolved.target, "/container/tmp");
         assert!(!resolved.writable);
+        assert!(!resolved.builtin);
     }
 
     #[test]
@@ -258,6 +261,7 @@ mod tests {
             source: PathBuf::from("/home/user/.config/git"),
             target: "/root/.config/git".into(),
             writable: false,
+            builtin: false,
         };
         assert_eq!(
             m.to_volume_string(),
@@ -271,6 +275,7 @@ mod tests {
             source: PathBuf::from("/home/user/.local/share/ranger"),
             target: "/root/.local/share/ranger".into(),
             writable: true,
+            builtin: false,
         };
         assert_eq!(
             m.to_volume_string(),
@@ -284,6 +289,7 @@ mod tests {
             source: PathBuf::from("/x"),
             target: "/root/.config/git".into(),
             writable: false,
+            builtin: false,
         };
         assert_eq!(m.display_target(), "/root/.config/git (ro)");
     }
@@ -294,6 +300,7 @@ mod tests {
             source: PathBuf::from("/x"),
             target: "/root/.local/share/ranger".into(),
             writable: true,
+            builtin: false,
         };
         assert_eq!(m.display_target(), "/root/.local/share/ranger");
     }
diff --git a/src/main.rs b/src/main.rs
index ec693e1..e8d1c34 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -6,10 +6,10 @@ use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
 
 use clap::{Parser, Subcommand};
-use color_eyre::eyre::{Context, Result, bail};
+use color_eyre::eyre::{bail, Context, Result};
 use serde::Serialize;
 use tracing::{error, info};
-use tracing_subscriber::{EnvFilter, fmt, prelude::*};
+use tracing_subscriber::{fmt, prelude::*, EnvFilter};
 
 const DOCKERFILE: &str = include_str!("../assets/Dockerfile");
 const RAMEKIN_EXTENSION: &str = include_str!("../assets/ramekin.ts");
@@ -135,6 +135,7 @@ impl Ramekin {
                 source: source.clone(),
                 target: target.into(),
                 writable: true,
+                builtin: true,
             })
             .collect();
 
@@ -183,8 +184,8 @@ impl Ramekin {
         );
 
         println!();
-        println!("Volume mounts");
-        for m in &self.mounts {
+        println!("Built-in volume mounts");
+        for m in self.mounts.iter().filter(|m| m.builtin) {
             println!(
                 "  {} {} → {}",
                 check(&m.source),
@@ -193,6 +194,22 @@ impl Ramekin {
             );
         }
 
+        println!();
+        println!("Config volume mounts");
+        let config_mounts: Vec<_> = self.mounts.iter().filter(|m| !m.builtin).collect();
+        if config_mounts.is_empty() {
+            println!("  (none)");
+        } else {
+            for m in config_mounts {
+                println!(
+                    "  {} {} → {}",
+                    check(&m.source),
+                    m.source.display(),
+                    m.display_target()
+                );
+            }
+        }
+
         println!();
         println!("Dockerfile");
         match &self.custom_dockerfile {