code_system_graph_hooks/
templates.rs1pub const AGENT_PLUGIN_MANIFEST: &str =
5 include_str!("../agent-integration-template/agent-plugin/plugin.json");
6pub const AGENT_PLUGIN_MCP: &str =
8 include_str!("../agent-integration-template/agent-plugin/mcp.json");
9pub const AGENT_PLUGIN_SKILL: &str =
11 include_str!("../agent-integration-template/agent-plugin/skills/code-system-graph/SKILL.md");
12pub const AGENT_PLUGIN_OPENAI_METADATA: &str = include_str!(
14 "../agent-integration-template/agent-plugin/skills/code-system-graph/agents/openai.yaml"
15);
16pub const AGENT_PLUGIN_OPERATING_GUIDE: &str = include_str!(
18 "../agent-integration-template/agent-plugin/skills/code-system-graph/references/operating-guide.md"
19);
20pub const AGENT_PLUGIN_LICENSE: &str =
22 include_str!("../agent-integration-template/agent-plugin/LICENSE");
23pub const AGENT_PLUGIN_GITIGNORE: &str =
25 include_str!("../agent-integration-template/agent-plugin/generated.gitignore");
26pub const AGENT_PLUGIN_SKILL_DESCRIPTION: &str =
28 include_str!("../agent-integration-template/agent-plugin/metadata/skill-description.txt");
29pub const AGENT_PLUGIN_OPENAI_DISPLAY_NAME: &str =
31 include_str!("../agent-integration-template/agent-plugin/metadata/openai-display-name.txt");
32pub const AGENT_PLUGIN_OPENAI_DEFAULT_PROMPT: &str =
34 include_str!("../agent-integration-template/agent-plugin/metadata/openai-default-prompt.txt");
35
36pub const FEDERATED_CODEGRAPH_GUIDANCE: &str =
38 include_str!("../agent-integration-template/native-hooks/guidance/federated-codegraph.txt");
39pub const LOCAL_CODEGRAPH_GUIDANCE: &str =
41 include_str!("../agent-integration-template/native-hooks/guidance/local-codegraph.txt");
42pub const FEDERATED_NATIVE_GUIDANCE: &str =
44 include_str!("../agent-integration-template/native-hooks/guidance/federated-native.txt");
45pub const LOCAL_NATIVE_GUIDANCE: &str =
47 include_str!("../agent-integration-template/native-hooks/guidance/local-native.txt");
48pub const FEDERATED_SIGNALS: &str =
50 include_str!("../agent-integration-template/native-hooks/signals/federated.txt");
51pub const LOCAL_SIGNALS: &str =
53 include_str!("../agent-integration-template/native-hooks/signals/local.txt");
54pub const STATIC_RULE: &str =
56 include_str!("../agent-integration-template/native-hooks/static-rule.md");
57pub const STATIC_ROUTING_CODEGRAPH: &str =
59 include_str!("../agent-integration-template/native-hooks/static-routing-codegraph.md");
60pub const STATIC_ROUTING_NATIVE: &str =
62 include_str!("../agent-integration-template/native-hooks/static-routing-native.md");
63pub const CURSOR_RULE: &str =
65 include_str!("../agent-integration-template/native-hooks/cursor-rule.mdc");
66pub const STRICT_GATE: &str =
68 include_str!("../agent-integration-template/native-hooks/strict-gate.sh");
69pub const CURSOR_LIMITATION: &str =
71 include_str!("../agent-integration-template/native-hooks/limitations/cursor.txt");
72pub const ANTIGRAVITY_LIMITATION: &str =
74 include_str!("../agent-integration-template/native-hooks/limitations/antigravity.txt");
75pub const HOOK_STATUS_MESSAGE: &str =
77 include_str!("../agent-integration-template/native-hooks/metadata/status-message.txt");
78pub const GEMINI_HOOK_DESCRIPTION: &str =
80 include_str!("../agent-integration-template/native-hooks/metadata/gemini-description.txt");
81
82#[cfg(test)]
83mod tests {
84 use std::collections::BTreeSet;
85
86 use super::{
87 AGENT_PLUGIN_MANIFEST, AGENT_PLUGIN_MCP, AGENT_PLUGIN_OPENAI_DEFAULT_PROMPT, AGENT_PLUGIN_OPENAI_DISPLAY_NAME, AGENT_PLUGIN_OPENAI_METADATA, AGENT_PLUGIN_SKILL, AGENT_PLUGIN_SKILL_DESCRIPTION, CURSOR_RULE, FEDERATED_CODEGRAPH_GUIDANCE, FEDERATED_NATIVE_GUIDANCE, FEDERATED_SIGNALS, GEMINI_HOOK_DESCRIPTION, HOOK_STATUS_MESSAGE, LOCAL_CODEGRAPH_GUIDANCE, LOCAL_NATIVE_GUIDANCE, LOCAL_SIGNALS, STATIC_RULE, STRICT_GATE
88 };
89
90 #[test]
91 fn template_placeholder_contracts_should_be_explicit() {
92 assert_eq!(
93 placeholders(AGENT_PLUGIN_MANIFEST),
94 set(&["PLUGIN_NAME", "PLUGIN_VERSION", "WORKSPACE_JSON_STRING"])
95 );
96 assert_eq!(placeholders(AGENT_PLUGIN_MCP), set(&["MCP_SERVER_NAME"]));
97 assert_eq!(
98 placeholders(AGENT_PLUGIN_SKILL),
99 set(&["SKILL_DESCRIPTION_YAML", "SKILL_NAME", "WORKSPACE"])
100 );
101 assert_eq!(
102 placeholders(AGENT_PLUGIN_OPENAI_METADATA),
103 set(&["SKILL_DEFAULT_PROMPT_YAML", "SKILL_DISPLAY_NAME_YAML"])
104 );
105 assert_eq!(
106 placeholders(STATIC_RULE),
107 set(&["BEGIN_MARKER", "END_MARKER", "ROUTING"])
108 );
109 assert_eq!(placeholders(CURSOR_RULE), set(&["BLOCK", "PRODUCT_MARKER"]));
110 assert_eq!(
111 placeholders(AGENT_PLUGIN_SKILL_DESCRIPTION),
112 set(&["WORKSPACE"])
113 );
114 assert_eq!(
115 placeholders(AGENT_PLUGIN_OPENAI_DISPLAY_NAME),
116 set(&["WORKSPACE"])
117 );
118 assert_eq!(
119 placeholders(AGENT_PLUGIN_OPENAI_DEFAULT_PROMPT),
120 set(&["SKILL_NAME"])
121 );
122 assert_eq!(
123 placeholders(STRICT_GATE),
124 set(&[
125 "BEGIN_MARKER",
126 "BINARY",
127 "DATABASE",
128 "END_MARKER",
129 "REPOSITORY",
130 "WORKSPACE",
131 ])
132 );
133 for template in [
134 FEDERATED_CODEGRAPH_GUIDANCE,
135 FEDERATED_NATIVE_GUIDANCE,
136 LOCAL_CODEGRAPH_GUIDANCE,
137 LOCAL_NATIVE_GUIDANCE,
138 HOOK_STATUS_MESSAGE,
139 GEMINI_HOOK_DESCRIPTION,
140 ] {
141 assert_ne!(template.trim(), "");
142 assert!(placeholders(template).is_empty());
143 }
144 }
145
146 #[test]
147 fn routing_signals_should_be_lowercase_specific_and_unique() {
148 let forbidden = set(&[
149 "architecture",
150 "code",
151 "diff",
152 "donde",
153 "dónde",
154 "impact",
155 "pull request",
156 "repo",
157 "repository",
158 "test",
159 "where does",
160 "where is",
161 ]);
162 for signals in [FEDERATED_SIGNALS, LOCAL_SIGNALS] {
163 let mut observed = BTreeSet::new();
164 for signal in signals.lines().map(str::trim) {
165 assert_ne!(signal, "");
166 assert_eq!(signal, signal.to_lowercase());
167 assert!(
168 observed.insert(signal),
169 "duplicate routing signal `{signal}`"
170 );
171 assert!(
172 !forbidden.contains(signal),
173 "routing signal `{signal}` is too broad"
174 );
175 }
176 }
177 }
178
179 fn placeholders(template: &str) -> BTreeSet<&str> {
180 template
181 .split("{{")
182 .skip(1)
183 .map(|remainder| {
184 remainder
185 .split_once("}}")
186 .map(|(name, _)| name)
187 .expect("every template placeholder must close")
188 })
189 .collect()
190 }
191
192 fn set<'a>(values: &[&'a str]) -> BTreeSet<&'a str> {
193 values.iter().copied().collect()
194 }
195}