Skip to content

Commit 873f7f1

Browse files
authored
feat: add package installation instructions to AGENTS.md during brin init (#44)
* feat: add package installation instructions to brin init When agents_md is enabled during brin init, append a Package Installation section to AGENTS.md instructing agents to use brin instead of npm/pip. The section is only added if it does not already exist (idempotent). Closes #36 * bump versions
1 parent 5c24db5 commit 873f7f1

File tree

4 files changed

+90
-2
lines changed

4 files changed

+90
-2
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ members = [
1111
]
1212

1313
[workspace.package]
14-
version = "0.1.10"
14+
version = "0.1.11"
1515
edition = "2021"
1616
authors = ["brin contributors"]
1717
license = "MIT"

crates/cli/src/agents_md.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ const BRIN_DOCS_DIR: &str = ".brin-docs";
1414
const BRIN_MARKER_START: &str = "[brin Docs Index]";
1515
const BRIN_MARKER_END: &str = "[/brin Docs Index]";
1616

17+
/// Marker to detect package installation instructions in AGENTS.md
18+
const INSTALL_INSTRUCTIONS_MARKER: &str = "## Package Installation";
19+
1720
/// Convert a package name to a valid filename
1821
/// - Lowercase only
1922
/// - Alphanumeric and hyphens only
@@ -270,6 +273,41 @@ fn remove_brin_section(content: &str) -> String {
270273
}
271274
}
272275

276+
/// Add package installation instructions to AGENTS.md (idempotent)
277+
pub fn add_install_instructions() -> Result<()> {
278+
add_install_instructions_at_path(Path::new(AGENTS_MD_PATH))
279+
}
280+
281+
fn add_install_instructions_at_path(agents_path: &Path) -> Result<()> {
282+
let instructions = r#"
283+
## Package Installation
284+
285+
Use `brin` for all package operations:
286+
- `brin add <pkg>` -- install with security scan
287+
- `brin remove <pkg>` -- uninstall
288+
- `brin scan` -- audit all dependencies
289+
- `brin check <pkg>` -- look up without installing
290+
291+
Do not use npm install, yarn add, pnpm add, or pip install directly.
292+
"#;
293+
294+
if agents_path.exists() {
295+
let content = fs::read_to_string(agents_path)?;
296+
if content.contains(INSTALL_INSTRUCTIONS_MARKER) {
297+
// Already present, nothing to do
298+
return Ok(());
299+
}
300+
let new_content = format!("{}{}", content, instructions);
301+
fs::write(agents_path, new_content)?;
302+
} else {
303+
// Create new AGENTS.md with just the instructions
304+
let content = format!("# AGENTS.md\n{}", instructions);
305+
fs::write(agents_path, content)?;
306+
}
307+
308+
Ok(())
309+
}
310+
273311
/// Ensure .brin-docs directory exists
274312
pub fn ensure_docs_dir() -> Result<()> {
275313
fs::create_dir_all(BRIN_DOCS_DIR)?;
@@ -413,6 +451,49 @@ mod tests {
413451
assert!(!content.contains("old.md"));
414452
}
415453

454+
#[test]
455+
fn test_add_install_instructions_to_existing() {
456+
let temp_dir = TempDir::new().unwrap();
457+
let agents_path = temp_dir.path().join("AGENTS.md");
458+
459+
fs::write(&agents_path, "# AGENTS.md\n\nSome content\n").unwrap();
460+
461+
add_install_instructions_at_path(&agents_path).unwrap();
462+
463+
let content = fs::read_to_string(&agents_path).unwrap();
464+
assert!(content.contains("## Package Installation"));
465+
assert!(content.contains("brin add <pkg>"));
466+
assert!(content.contains("Do not use npm install"));
467+
}
468+
469+
#[test]
470+
fn test_add_install_instructions_idempotent() {
471+
let temp_dir = TempDir::new().unwrap();
472+
let agents_path = temp_dir.path().join("AGENTS.md");
473+
474+
fs::write(&agents_path, "# AGENTS.md\n\nSome content\n").unwrap();
475+
476+
add_install_instructions_at_path(&agents_path).unwrap();
477+
let content_after_first = fs::read_to_string(&agents_path).unwrap();
478+
479+
add_install_instructions_at_path(&agents_path).unwrap();
480+
let content_after_second = fs::read_to_string(&agents_path).unwrap();
481+
482+
assert_eq!(content_after_first, content_after_second);
483+
}
484+
485+
#[test]
486+
fn test_add_install_instructions_creates_new() {
487+
let temp_dir = TempDir::new().unwrap();
488+
let agents_path = temp_dir.path().join("AGENTS.md");
489+
490+
add_install_instructions_at_path(&agents_path).unwrap();
491+
492+
let content = fs::read_to_string(&agents_path).unwrap();
493+
assert!(content.contains("# AGENTS.md"));
494+
assert!(content.contains("## Package Installation"));
495+
}
496+
416497
#[test]
417498
fn test_remove_agents_md_index() {
418499
let temp_dir = TempDir::new().unwrap();

crates/cli/src/commands/init.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ pub async fn run(yes: bool) -> Result<()> {
5353
agents_md::update_agents_md_index()?;
5454
println!(" {} updated AGENTS.md with brin docs index", "✓".green());
5555

56+
// Add package installation instructions to AGENTS.md
57+
agents_md::add_install_instructions()?;
58+
println!(
59+
" {} added package installation instructions to AGENTS.md",
60+
"✓".green()
61+
);
62+
5663
println!();
5764
println!(
5865
" {} AGENTS.md docs index enabled. When you run {},",

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "brin",
3-
"version": "0.1.10",
3+
"version": "0.1.11",
44
"description": "Package gateway for AI agents - secure package installation with CVE scanning and threat detection",
55
"main": "index.js",
66
"bin": {

0 commit comments

Comments
 (0)