Skip to main content

code_system_graph_hooks/
templates.rs

1//! Visible, versioned templates shared by Agent Plugin generation and native host adapters.
2
3/// Portable Agent Plugins 1.0 manifest template.
4pub const AGENT_PLUGIN_MANIFEST: &str =
5    include_str!("../agent-integration-template/agent-plugin/plugin.json");
6/// Portable Agent Plugins 1.0 MCP template.
7pub const AGENT_PLUGIN_MCP: &str =
8    include_str!("../agent-integration-template/agent-plugin/mcp.json");
9/// Canonical cross-client Code System Graph skill.
10pub const AGENT_PLUGIN_SKILL: &str =
11    include_str!("../agent-integration-template/agent-plugin/skills/code-system-graph/SKILL.md");
12/// Optional Codex UI metadata for the canonical skill.
13pub const AGENT_PLUGIN_OPENAI_METADATA: &str = include_str!(
14    "../agent-integration-template/agent-plugin/skills/code-system-graph/agents/openai.yaml"
15);
16/// Extended operating guide referenced by the canonical skill.
17pub const AGENT_PLUGIN_OPERATING_GUIDE: &str = include_str!(
18    "../agent-integration-template/agent-plugin/skills/code-system-graph/references/operating-guide.md"
19);
20/// License emitted in a complete portable plugin.
21pub const AGENT_PLUGIN_LICENSE: &str =
22    include_str!("../agent-integration-template/agent-plugin/LICENSE");
23/// Ignore rule emitted for developer-local plugin bindings.
24pub const AGENT_PLUGIN_GITIGNORE: &str =
25    include_str!("../agent-integration-template/agent-plugin/generated.gitignore");
26/// Skill discovery description rendered into the portable frontmatter.
27pub const AGENT_PLUGIN_SKILL_DESCRIPTION: &str =
28    include_str!("../agent-integration-template/agent-plugin/metadata/skill-description.txt");
29/// Optional Codex display name for the canonical skill.
30pub const AGENT_PLUGIN_OPENAI_DISPLAY_NAME: &str =
31    include_str!("../agent-integration-template/agent-plugin/metadata/openai-display-name.txt");
32/// Optional Codex starter prompt for the canonical skill.
33pub const AGENT_PLUGIN_OPENAI_DEFAULT_PROMPT: &str =
34    include_str!("../agent-integration-template/agent-plugin/metadata/openai-default-prompt.txt");
35
36/// Dynamic prompt-hook guidance for federated work with `CodeGraph` enrichment.
37pub const FEDERATED_CODEGRAPH_GUIDANCE: &str =
38    include_str!("../agent-integration-template/native-hooks/guidance/federated-codegraph.txt");
39/// Dynamic prompt-hook guidance for repository-local work with `CodeGraph` enrichment.
40pub const LOCAL_CODEGRAPH_GUIDANCE: &str =
41    include_str!("../agent-integration-template/native-hooks/guidance/local-codegraph.txt");
42/// Dynamic prompt-hook guidance for federated work without `CodeGraph` enrichment.
43pub const FEDERATED_NATIVE_GUIDANCE: &str =
44    include_str!("../agent-integration-template/native-hooks/guidance/federated-native.txt");
45/// Dynamic prompt-hook guidance for repository-local work without `CodeGraph` enrichment.
46pub const LOCAL_NATIVE_GUIDANCE: &str =
47    include_str!("../agent-integration-template/native-hooks/guidance/local-native.txt");
48/// Newline-separated prompt signals for federated intent.
49pub const FEDERATED_SIGNALS: &str =
50    include_str!("../agent-integration-template/native-hooks/signals/federated.txt");
51/// Newline-separated prompt signals for repository-local intent.
52pub const LOCAL_SIGNALS: &str =
53    include_str!("../agent-integration-template/native-hooks/signals/local.txt");
54/// Marker-scoped static-rule template used only as a compatibility fallback.
55pub const STATIC_RULE: &str =
56    include_str!("../agent-integration-template/native-hooks/static-rule.md");
57/// Static routing policy when `CodeGraph` enrichment is enabled.
58pub const STATIC_ROUTING_CODEGRAPH: &str =
59    include_str!("../agent-integration-template/native-hooks/static-routing-codegraph.md");
60/// Static routing policy when `CodeGraph` enrichment is unavailable.
61pub const STATIC_ROUTING_NATIVE: &str =
62    include_str!("../agent-integration-template/native-hooks/static-routing-native.md");
63/// Cursor wrapper for the static compatibility rule.
64pub const CURSOR_RULE: &str =
65    include_str!("../agent-integration-template/native-hooks/cursor-rule.mdc");
66/// Strict pre-commit gate shell template.
67pub const STRICT_GATE: &str =
68    include_str!("../agent-integration-template/native-hooks/strict-gate.sh");
69/// Cursor limitation reported by hook installation.
70pub const CURSOR_LIMITATION: &str =
71    include_str!("../agent-integration-template/native-hooks/limitations/cursor.txt");
72/// Antigravity limitation reported by hook installation.
73pub const ANTIGRAVITY_LIMITATION: &str =
74    include_str!("../agent-integration-template/native-hooks/limitations/antigravity.txt");
75/// Claude/Codex hook status text.
76pub const HOOK_STATUS_MESSAGE: &str =
77    include_str!("../agent-integration-template/native-hooks/metadata/status-message.txt");
78/// Gemini hook description.
79pub 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}