agentlink_domain/
layout.rs1use crate::model::{NodeKind, ResourceKind};
17use crate::path::RelPath;
18
19pub const STATE_DIR: &str = ".agentlink";
21
22pub const CONFIG_FILE: &str = ".agentlink/config.toml";
24
25pub const LOCK_FILE: &str = ".agentlink/lock.toml";
27
28pub const LOCAL_PROVIDERS_DIR: &str = ".agentlink/providers";
30
31#[derive(Debug, Clone, PartialEq, Eq)]
33pub struct Layout {
34 instructions: RelPath,
35 skills: RelPath,
36}
37
38impl Default for Layout {
39 fn default() -> Self {
40 Self {
41 instructions: RelPath::new("AGENTS.md").expect("valid default"),
42 skills: RelPath::new(".agents/skills").expect("valid default"),
43 }
44 }
45}
46
47impl Layout {
48 pub fn canonical(&self, kind: ResourceKind) -> &RelPath {
50 match kind {
51 ResourceKind::Instructions => &self.instructions,
52 ResourceKind::Skills => &self.skills,
53 }
54 }
55
56 pub fn node(&self, kind: ResourceKind) -> NodeKind {
58 kind.node()
59 }
60
61 pub fn seeds(&self) -> impl Iterator<Item = (ResourceKind, &RelPath)> {
63 ResourceKind::ALL
64 .iter()
65 .map(|&kind| (kind, self.canonical(kind)))
66 }
67}
68
69pub const AGENTS_MD_TEMPLATE: &str = "\
74# AGENTS.md
75
76Shared instructions for every AI coding agent working in this repository.
77Managed with [agentlink](https://github.com/fialhosoft/agentlink) — edit this
78file from any agent and the change is visible to all of them.
79
80## Project
81
82<!-- What this project is, in two or three sentences. -->
83
84## Commands
85
86<!-- Build, test and lint commands an agent should use. -->
87
88## Conventions
89
90<!-- Code style, patterns to follow, and anything that is off limits. -->
91";
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[test]
98 fn canonical_paths_match_the_ecosystem_standards() {
99 let layout = Layout::default();
100 assert_eq!(
101 layout.canonical(ResourceKind::Instructions).as_str(),
102 "AGENTS.md"
103 );
104 assert_eq!(
105 layout.canonical(ResourceKind::Skills).as_str(),
106 ".agents/skills"
107 );
108 }
109
110 #[test]
111 fn every_resource_kind_has_a_seed() {
112 let layout = Layout::default();
113 assert_eq!(layout.seeds().count(), ResourceKind::ALL.len());
114 }
115}