Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] }

# Serialization
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_yaml = "0.9"

# Date/time for timestamps
Expand Down
10 changes: 10 additions & 0 deletions src/catalog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,16 @@ fn enumerate_entry_assets(entry: &Entry, manifest_dir: &Path) -> Result<Vec<Cata
});
}
}
AssetKind::ClaudeSettings => {
// Claude settings entries use composite sources (handled above for composites)
catalog_entries.push(CatalogEntry {
id: format!("{}:settings", entry.id),
name: "settings.json (composed)".to_string(),
kind: AssetKind::ClaudeSettings,
destination: format!("./{}", base_dest.display()),
short_description: None,
});
}
Comment on lines +268 to +277
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Unreachable code: ClaudeSettings entries are cataloged as CompositeAgentsMd.

This code block is unreachable because:

  1. validate_manifest requires sources to be non-empty for ClaudeSettings entries
  2. Entry::is_composite() returns true for ClaudeSettings when sources is non-empty (see src/manifest.rs lines 72-73)
  3. The early return at lines 135-144 catches all composite entries and returns with kind: AssetKind::CompositeAgentsMd

As a result, ClaudeSettings entries will be cataloged with incorrect metadata (kind=CompositeAgentsMd, name="AGENTS.md (composite)").

🐛 Proposed fix: Handle ClaudeSettings before the generic composite check
 fn enumerate_entry_assets(entry: &Entry, manifest_dir: &Path) -> Result<Vec<CatalogEntry>> {
     let base_dest = entry.destination();
     let mut catalog_entries = Vec::new();
 
+    // Handle ClaudeSettings entries (composite-like but distinct catalog representation)
+    if entry.kind == AssetKind::ClaudeSettings {
+        catalog_entries.push(CatalogEntry {
+            id: format!("{}:settings", entry.id),
+            name: "settings.json (composed)".to_string(),
+            kind: AssetKind::ClaudeSettings,
+            destination: format!("./{}", base_dest.display()),
+            short_description: Some(format!("Composed from {} sources", entry.sources.len())),
+        });
+        return Ok(catalog_entries);
+    }
+
     // Handle composite entries (no single source to resolve)
     if entry.is_composite() {

Then remove the unreachable AssetKind::ClaudeSettings match arm at lines 268-277.

🤖 Prompt for AI Agents
In `@src/catalog.rs` around lines 268 - 277, The cataloging path incorrectly
treats ClaudeSettings as CompositeAgentsMd because Entry::is_composite() (as
enforced by validate_manifest requiring non-empty sources) causes ClaudeSettings
to hit the early composite handling branch; to fix, move the
ClaudeSettings-specific handling ahead of the generic composite check so
ClaudeSettings entries are emitted with kind AssetKind::ClaudeSettings and the
correct name/destination, and then remove the now-unreachable match arm for
AssetKind::ClaudeSettings in the catalog entry match to avoid
duplicate/incorrect metadata.

}

Ok(catalog_entries)
Expand Down
Loading
Loading