Skip to content
Merged
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
31 changes: 14 additions & 17 deletions .kiro/generators/aws-test.kdl
Original file line number Diff line number Diff line change
@@ -1,35 +1,32 @@
description "all the AWS tools you want"
prompt "you are an AWS expert"
allowed-tools "@awsdocs"

allowed-tools "@awsdocs"
resource "file://AGENTS.md"
resource "file://README.md"
resource "file://.amazonq/rules/**/*.md"

hook {
agent-spawn "whoami" {
command "aws sts get-caller-identity"
timeout-ms 4000
cache-ttl-seconds 300
}
}

native-tool {
aws {
allow "ec2" "s3"
deny "iam"
}
aws {
allows "ec2" "s3"
denies "iam"
}
}

mcp "awsbilling" {
command "uvx"
args "awslabs.billing-cost-management-mcp-server@latest"
env "FASTMCP_LOG_LEVEL" "ERROR"
command "uvx"
args """
awslabs.billing-cost-management-mcp-server@latest
"""
env "FASTMCP_LOG_LEVEL" "ERROR"
}

mcp "awsdocs" {
command "uvx"
args "awslabs.aws-documentation-mcp-server@latest"
env "FASTMCP_LOG_LEVEL" "ERROR"
env "AWS_DOCUMENTATION_PARTITION" "aws"
command "uvx"
args "awslabs.aws-documentation-mcp-server@latest"
env "FASTMCP_LOG_LEVEL" "ERROR"
env "AWS_DOCUMENTATION_PARTITION" "aws"
}
3 changes: 2 additions & 1 deletion .kiro/generators/bad.kdl
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
foo "bar"
agent "bad" include-mcp-json="bar" {
}
64 changes: 38 additions & 26 deletions .kiro/generators/base.kdl
Original file line number Diff line number Diff line change
@@ -1,39 +1,51 @@
description "Default agent for Kiro"
tools "*"
allowed-tools "read" "knowledge" "@fetch"
allowed-tools "read" "knowledge" "fetch"
resource "file://README.md"
resource "file://.amazonq/rules/**/*.md"
alias "execute_shell" "bash"

hook {
agent-spawn "echo" {
command "echo My name is Bob"
timeout-ms 4000
cache-ttl-seconds 300
}
agent-spawn echo {
command "echo My name is Bob"
timeout-ms 4000
cache-ttl-seconds 300
}
}

native-tool {
read { deny ".*Cargo.toml.*" ".*yarn.lock.*"; }
write { deny ".*Cargo.toml.*"; }
shell {
allow "git status" "git fetch" "git diff .*" \
"git pull .*" "yarn .*" "pulumi preview .*" \
"kubectl .*" "pdf2.*" "ps .*" "timeout.*" "pgrep.*"

deny "git commit .*" "git push .*" "kubectl .*delete*" \
".*delete.*" "pulumi up.*" "^rm .*" \
".*destroy.*" ".*rollout.*" ".*kill.*"
}
read {
denies ".*Cargo.toml.*" ".*yarn.lock.*"
}
write {
denies ".*Cargo.toml.*"
}
shell {
allows "git status" \
"git fetch" \
"git diff .*" \
"git pull.*" \
"yarn.*" \
"pulumi preview .*" \
"pdf2.*" \
"ps .*" \
"timeout.*" \
"pgrep.*"
denies "git commit .*" \
"git push .*" \
"kubectl .*delete*" \
".*delete.*" \
"pulumi up.*" \
"^rm .*" \
".*destroy.*" \
".*rollout.*" \
".*kill.*"
}
}

mcp "rustdocs" {
mcp rustdocs {
command "mcp-docsrs"
timeout 1200
}

mcp "cargo" {
command "cargo-mcp"
args "--debug"
timeout 120000
mcp cargo {
command "cargo-mcp"
args "--debug"
timeout 120000
}
16 changes: 10 additions & 6 deletions .kiro/generators/dependabot.kdl
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
description "I make life painful for developers"

native-tool {
shell { override "git commit .*"; override "git push .*"; }
read { override ".*Cargo.toml.*"; }
write { override ".*Cargo.toml.*"; }
aws disable-auto-readonly=true
native-tool disable-auto-readonly=#true {
shell {
overrides "git commit .*" "git push .*"
}
read {
overrides ".*Cargo.toml.*"
}
write {
overrides ".*Cargo.toml.*"
}
}
2 changes: 1 addition & 1 deletion .kiro/generators/kg.kdl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
agent "base" template=true {}
agent "base" template=#true {}
agent "aws-test" {
inherits "base"
hook {
Expand Down
16 changes: 8 additions & 8 deletions .kiro/global/aws-test.kdl
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
prompt "you are NOT an AWS expert"
allowed-tools "@awsdocs"
allowed-tools "@awsdocs"
resource "file://AGENTS.md"
resource "file://README.md"
native-tool {
aws {
allow "ec2" "s3"
}
aws {
allows "ec2" "s3"
}
}
mcp "awsdocs" {
command "blah"
args "awslabs.aws-documentation-mcp-server@latest"
env "FASTMCP_LOG_LEVEL" "INFO"
env "AWS_DOCUMENTATION_PARTITION" "ec2"
command "blah"
args "awslabs.aws-documentation-mcp-server@latest"
env "FASTMCP_LOG_LEVEL" "INFO"
env "AWS_DOCUMENTATION_PARTITION" "ec2"
}
2 changes: 1 addition & 1 deletion .kiro/global/kg.kdl
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
agent "base" template=true {}
agent "base" template=#true {}
agent "aws-test" { inherits "base"; }
agent "dependabot" { }
176 changes: 3 additions & 173 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,188 +86,18 @@ When analyzing the code, explicitly check:
- Explanation of *why* each change aligns with Unix conventions
- Prioritize changes: critical issues first, nice-to-haves last

## Error Handling with color_eyre

This project uses [color_eyre](https://docs.rs/color-eyre/latest/color_eyre/) for enhanced error reporting and diagnostics.
## Error Handling with miette

### Setup & Integration

**Initialization:**
- Call `color_eyre::install()?` early in `main()` before any fallible operations
- Consider using `color_eyre::config::HookBuilder` for custom configuration
- Disable colors in non-TTY environments or when `NO_COLOR` is set

**Example:**
```rust
fn main() -> color_eyre::Result<()> {
color_eyre::config::HookBuilder::default()
.display_env_section(false) // Hide environment vars in production
.install()?;

// Your CLI logic here
}
```

### Error Context Best Practices

**Use `.wrap_err()` and `.wrap_err_with()` liberally:**
- Add context at each layer where it's meaningful
- Focus on *what* the code was trying to do, not *why* it failed (eyre handles that)
- Provide user-actionable information when possible

**Good context:**
```rust
fs::read_to_string(&config_path)
.wrap_err_with(|| format!("Failed to read config file at {}", config_path.display()))
.wrap_err("Unable to load application configuration")?;
```

**Poor context:**
```rust
fs::read_to_string(&config_path)
.wrap_err("Error reading file")?; // Too vague
```

### Context Patterns

**File operations:**
```rust
.wrap_err_with(|| format!("Failed to read '{}'", path.display()))
.wrap_err_with(|| format!("Failed to write to '{}'", path.display()))
.wrap_err_with(|| format!("Failed to create directory '{}'", path.display()))
```

**Network/external operations:**
```rust
.wrap_err_with(|| format!("Failed to fetch data from {}", url))
.wrap_err("Unable to connect to remote service")
```

**Parsing/validation:**
```rust
.wrap_err_with(|| format!("Invalid configuration in '{}'", config_path.display()))
.wrap_err_with(|| format!("Failed to parse {} as JSON", file_name))
```

**User input:**
```rust
.wrap_err("Invalid argument provided")
.wrap_err_with(|| format!("Unknown format '{}'. Valid formats: json, yaml, csv", format))
```

### Error Reporting Guidelines

**For production CLIs:**
- Set `RUST_BACKTRACE=0` behavior as default
- Only show full backtraces in debug builds or with `--verbose`
- Consider using `HookBuilder` to customize what's displayed:
```rust
color_eyre::config::HookBuilder::default()
.display_env_section(cfg!(debug_assertions))
.issue_url(concat!(env!("CARGO_PKG_REPOSITORY"), "/issues/new"))
.install()?;
```

**Error message structure:**
- Top-level context should explain the high-level operation that failed
- Each `.wrap_err()` adds a layer showing the call stack conceptually
- The root cause (from the original error) appears at the bottom
- Suggestions and help text should go in the outermost context

**User-facing vs. developer errors:**
- Configuration errors, invalid input → Detailed, actionable messages
- Unexpected errors, bugs → Include issue tracker URL via `HookBuilder::issue_url()`
- Network timeouts, connection failures → Suggest retry, check connectivity

### Common Pitfalls to Avoid

❌ **Don't add redundant context:**
```rust
// The error already says "No such file or directory"
.wrap_err("File not found")?
```

❌ **Don't expose internal implementation details:**
```rust
// User doesn't care about your HashMap
.wrap_err("Failed to insert into cache HashMap")?
```

❌ **Don't use context for control flow:**
```rust
// Use proper error types for expected failures
match x {
Some(v) => v,
None => return Err(eyre!("Value missing"))?, // ❌ Not an exceptional error
}
```

✅ **Do create custom error types for domain errors:**
```rust
#[derive(Debug, thiserror::Error)]
enum ConfigError {
#[error("Missing required field: {0}")]
MissingField(String),
#[error("Invalid port number: {0}")]
InvalidPort(u16),
}

// Then wrap with color_eyre for context
validate_config(&config)
.wrap_err("Configuration validation failed")?;
```

### Integration with Clap

**Handling clap errors:**
```rust
use clap::Parser;

#[derive(Parser)]
struct Cli { /* ... */ }

fn main() -> color_eyre::Result<()> {
color_eyre::install()?;

// Clap handles its own error formatting, which is good
let cli = Cli::parse();

run(cli)?;
Ok(())
}
```

**Adding suggestions to errors:**
```rust
use color_eyre::{eyre::eyre, Help, SectionExt};

if !config_path.exists() {
return Err(eyre!("Config file not found"))
.with_suggestion(|| format!("Create a config file at: {}", config_path.display()))
.suggestion("Run with --init to create a default configuration");
}
```

### Review Checklist

When reviewing error handling:

1. Is `color_eyre::install()` called early in `main()`?
2. Does each `.wrap_err()` add meaningful context?
3. Are error messages actionable for the user?
4. Are internal implementation details hidden from user-facing errors?
5. Do errors include suggestions where appropriate?
6. Is backtrace/env output appropriate for the audience (debug vs. production)?
7. Are file paths, URLs, and identifiers included in error context?
8. Do network/IO errors guide users toward resolution?
Refer to [miette](https://docs.rs/miette/latest/miette/) for error handles and reporting. Suggest utilizing [Diagnostic](https://docs.rs/miette/latest/miette/trait.Diagnostic.html) trait or enchanced error reporting


## Performance

Runtime Performance is **NOT** critical or important. This CLI will rarely be executed, it is far **MORE** important that the code is clean, maintainable and **SIMPLE** at the cost of performance.


## Further Documentation
## Further Documentation

The directory `docs` contains mdbook formatted documentation for the project. Some notiable files:

Expand Down
Loading
Loading