aircana 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rspec_status +146 -101
- data/.rubocop.yml +29 -0
- data/CLAUDE.md +54 -9
- data/README.md +31 -19
- data/lib/aircana/cli/app.rb +93 -26
- data/lib/aircana/cli/commands/agents.rb +43 -0
- data/lib/aircana/cli/commands/files.rb +65 -0
- data/lib/aircana/cli/commands/generate.rb +19 -0
- data/lib/aircana/cli/commands/hooks.rb +276 -0
- data/lib/aircana/cli/commands/install.rb +113 -0
- data/lib/aircana/cli/commands/project.rb +156 -0
- data/lib/aircana/cli/help_formatter.rb +90 -0
- data/lib/aircana/cli/subcommand.rb +2 -1
- data/lib/aircana/configuration.rb +2 -1
- data/lib/aircana/generators/agents_generator.rb +1 -1
- data/lib/aircana/generators/hooks_generator.rb +82 -0
- data/lib/aircana/generators/project_config_generator.rb +54 -0
- data/lib/aircana/symlink_manager.rb +138 -0
- data/lib/aircana/system_checker.rb +10 -0
- data/lib/aircana/templates/hooks/bundle_install.erb +63 -0
- data/lib/aircana/templates/hooks/post_tool_use.erb +49 -0
- data/lib/aircana/templates/hooks/pre_tool_use.erb +43 -0
- data/lib/aircana/templates/hooks/rspec_test.erb +72 -0
- data/lib/aircana/templates/hooks/rubocop_pre_commit.erb +55 -0
- data/lib/aircana/templates/hooks/session_start.erb +127 -0
- data/lib/aircana/templates/hooks/user_prompt_submit.erb +46 -0
- data/lib/aircana/version.rb +1 -1
- metadata +18 -5
@@ -23,6 +23,16 @@ module Aircana
|
|
23
23
|
"Arch" => "pacman -S git",
|
24
24
|
"Other" => "https://git-scm.com/downloads"
|
25
25
|
}
|
26
|
+
},
|
27
|
+
"jq" => {
|
28
|
+
purpose: "JSON parsing for multi-root configuration",
|
29
|
+
install: {
|
30
|
+
"macOS" => "brew install jq",
|
31
|
+
"Ubuntu/Debian" => "apt install jq",
|
32
|
+
"Fedora/CentOS" => "dnf install jq",
|
33
|
+
"Arch" => "pacman -S jq",
|
34
|
+
"Other" => "https://jqlang.github.io/jq/download/"
|
35
|
+
}
|
26
36
|
}
|
27
37
|
}.freeze
|
28
38
|
|
@@ -0,0 +1,63 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
# Bundle install hook generated by Aircana
|
3
|
+
# This hook runs bundle install when Gemfile changes are detected
|
4
|
+
|
5
|
+
# Get the tool details
|
6
|
+
TOOL_NAME="$1"
|
7
|
+
TOOL_PARAMS="$2"
|
8
|
+
|
9
|
+
# Only act on file modification tools
|
10
|
+
case "$TOOL_NAME" in
|
11
|
+
"Edit"|"Write"|"MultiEdit")
|
12
|
+
;;
|
13
|
+
*)
|
14
|
+
exit 0
|
15
|
+
;;
|
16
|
+
esac
|
17
|
+
|
18
|
+
# Check if Gemfile was modified
|
19
|
+
if ! echo "$TOOL_PARAMS" | grep -q "Gemfile"; then
|
20
|
+
exit 0
|
21
|
+
fi
|
22
|
+
|
23
|
+
# Check if this is a Ruby project
|
24
|
+
if [ ! -f "Gemfile" ]; then
|
25
|
+
exit 0
|
26
|
+
fi
|
27
|
+
|
28
|
+
echo "Gemfile modified, running bundle install..."
|
29
|
+
|
30
|
+
# Run bundle install
|
31
|
+
if command -v bundle >/dev/null 2>&1; then
|
32
|
+
bundle install
|
33
|
+
BUNDLE_EXIT_CODE=$?
|
34
|
+
|
35
|
+
if [ $BUNDLE_EXIT_CODE -eq 0 ]; then
|
36
|
+
cat << EOF
|
37
|
+
{
|
38
|
+
"type": "advanced",
|
39
|
+
"decision": "allow",
|
40
|
+
"message": "Bundle install completed successfully after Gemfile modification."
|
41
|
+
}
|
42
|
+
EOF
|
43
|
+
else
|
44
|
+
cat << EOF
|
45
|
+
{
|
46
|
+
"type": "advanced",
|
47
|
+
"decision": "allow",
|
48
|
+
"message": "Bundle install failed. You may need to run 'bundle install' manually.\n\nError code: $BUNDLE_EXIT_CODE"
|
49
|
+
}
|
50
|
+
EOF
|
51
|
+
fi
|
52
|
+
else
|
53
|
+
cat << EOF
|
54
|
+
{
|
55
|
+
"type": "advanced",
|
56
|
+
"decision": "allow",
|
57
|
+
"message": "Bundler not found. Please install bundler and run 'bundle install' manually."
|
58
|
+
}
|
59
|
+
EOF
|
60
|
+
fi
|
61
|
+
|
62
|
+
# Always allow the modification to proceed
|
63
|
+
exit 0
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
# Post-tool-use hook generated by Aircana
|
3
|
+
# This hook runs after a tool has been executed
|
4
|
+
|
5
|
+
# Get tool execution details
|
6
|
+
TOOL_NAME="$1"
|
7
|
+
TOOL_PARAMS="$2"
|
8
|
+
TOOL_RESULT="$3"
|
9
|
+
EXIT_CODE="$4"
|
10
|
+
|
11
|
+
# Log the tool execution
|
12
|
+
echo "$(date): Tool '$TOOL_NAME' completed with exit code: $EXIT_CODE" >> ~/.aircana/hooks.log
|
13
|
+
|
14
|
+
# Initialize context for response
|
15
|
+
ADDITIONAL_CONTEXT=""
|
16
|
+
|
17
|
+
# Handle specific tools
|
18
|
+
case "$TOOL_NAME" in
|
19
|
+
"Edit"|"Write")
|
20
|
+
# Auto-update relevant files context if code files were modified
|
21
|
+
if echo "$TOOL_PARAMS" | grep -E "\.(rb|js|py|ts)$" && [ "$EXIT_CODE" -eq 0 ]; then
|
22
|
+
ADDITIONAL_CONTEXT="Code file modified - consider updating relevant files context."
|
23
|
+
fi
|
24
|
+
;;
|
25
|
+
"Bash")
|
26
|
+
# Handle bash command results
|
27
|
+
if [ "$EXIT_CODE" -ne 0 ]; then
|
28
|
+
echo "Bash command failed: $TOOL_PARAMS" >> ~/.aircana/hooks.log
|
29
|
+
ADDITIONAL_CONTEXT="Previous bash command failed with exit code $EXIT_CODE."
|
30
|
+
fi
|
31
|
+
;;
|
32
|
+
esac
|
33
|
+
|
34
|
+
# Output appropriate JSON response
|
35
|
+
if [ -n "$ADDITIONAL_CONTEXT" ]; then
|
36
|
+
# Escape context for JSON
|
37
|
+
ESCAPED_CONTEXT=$(echo -n "$ADDITIONAL_CONTEXT" | sed 's/"/\\"/g')
|
38
|
+
cat << EOF
|
39
|
+
{
|
40
|
+
"hookSpecificOutput": {
|
41
|
+
"hookEventName": "PostToolUse",
|
42
|
+
"additionalContext": "$ESCAPED_CONTEXT"
|
43
|
+
}
|
44
|
+
}
|
45
|
+
EOF
|
46
|
+
else
|
47
|
+
# No additional context needed
|
48
|
+
echo "{}"
|
49
|
+
fi
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
# Pre-tool-use hook generated by Aircana
|
3
|
+
# This hook runs before any tool is executed
|
4
|
+
|
5
|
+
# Get the tool name and parameters
|
6
|
+
TOOL_NAME="$1"
|
7
|
+
TOOL_PARAMS="$2"
|
8
|
+
|
9
|
+
# Log the tool usage (optional)
|
10
|
+
echo "$(date): About to use tool: $TOOL_NAME" >> ~/.aircana/hooks.log
|
11
|
+
|
12
|
+
# Basic validation example
|
13
|
+
case "$TOOL_NAME" in
|
14
|
+
"Bash")
|
15
|
+
# Add validation for bash commands
|
16
|
+
if echo "$TOOL_PARAMS" | grep -q "rm -rf /"; then
|
17
|
+
cat << EOF
|
18
|
+
{
|
19
|
+
"hookSpecificOutput": {
|
20
|
+
"hookEventName": "PreToolUse",
|
21
|
+
"permissionDecision": "deny",
|
22
|
+
"permissionDecisionReason": "Dangerous command detected: rm -rf /"
|
23
|
+
}
|
24
|
+
}
|
25
|
+
EOF
|
26
|
+
exit 0
|
27
|
+
fi
|
28
|
+
;;
|
29
|
+
"Edit"|"Write")
|
30
|
+
# Validate file operations
|
31
|
+
# Add custom validation logic here
|
32
|
+
;;
|
33
|
+
esac
|
34
|
+
|
35
|
+
# Allow the tool to proceed
|
36
|
+
cat << EOF
|
37
|
+
{
|
38
|
+
"hookSpecificOutput": {
|
39
|
+
"hookEventName": "PreToolUse",
|
40
|
+
"permissionDecision": "allow"
|
41
|
+
}
|
42
|
+
}
|
43
|
+
EOF
|
@@ -0,0 +1,72 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
# RSpec test hook generated by Aircana
|
3
|
+
# This hook runs relevant tests when Ruby files are modified
|
4
|
+
|
5
|
+
# Get the tool details
|
6
|
+
TOOL_NAME="$1"
|
7
|
+
TOOL_PARAMS="$2"
|
8
|
+
|
9
|
+
# Only act on file modification tools
|
10
|
+
case "$TOOL_NAME" in
|
11
|
+
"Edit"|"Write"|"MultiEdit")
|
12
|
+
;;
|
13
|
+
*)
|
14
|
+
exit 0
|
15
|
+
;;
|
16
|
+
esac
|
17
|
+
|
18
|
+
# Check if this is a Ruby project with RSpec
|
19
|
+
if [ ! -f "Gemfile" ] || ! grep -q "rspec" Gemfile 2>/dev/null; then
|
20
|
+
exit 0
|
21
|
+
fi
|
22
|
+
|
23
|
+
# Extract file path from tool parameters (basic extraction)
|
24
|
+
MODIFIED_FILE=$(echo "$TOOL_PARAMS" | grep -o '"[^"]*\.rb"' | head -1 | tr -d '"')
|
25
|
+
|
26
|
+
if [ -z "$MODIFIED_FILE" ]; then
|
27
|
+
exit 0
|
28
|
+
fi
|
29
|
+
|
30
|
+
# Determine which specs to run based on the modified file
|
31
|
+
SPEC_FILE=""
|
32
|
+
|
33
|
+
# Check for corresponding spec file
|
34
|
+
if echo "$MODIFIED_FILE" | grep -q "^lib/"; then
|
35
|
+
# For lib files, look for spec file
|
36
|
+
SPEC_FILE="spec/$(echo "$MODIFIED_FILE" | sed 's|^lib/||' | sed 's|\.rb$|_spec.rb|')"
|
37
|
+
elif echo "$MODIFIED_FILE" | grep -q "^app/"; then
|
38
|
+
# For Rails app files
|
39
|
+
SPEC_FILE="spec/$(echo "$MODIFIED_FILE" | sed 's|^app/||' | sed 's|\.rb$|_spec.rb|')"
|
40
|
+
elif echo "$MODIFIED_FILE" | grep -q "_spec\.rb$"; then
|
41
|
+
# If the modified file is already a spec file
|
42
|
+
SPEC_FILE="$MODIFIED_FILE"
|
43
|
+
fi
|
44
|
+
|
45
|
+
# Check if spec file exists
|
46
|
+
if [ -n "$SPEC_FILE" ] && [ -f "$SPEC_FILE" ]; then
|
47
|
+
echo "Running tests for modified file: $MODIFIED_FILE"
|
48
|
+
|
49
|
+
# Run the specific test
|
50
|
+
if command -v bundle >/dev/null 2>&1; then
|
51
|
+
bundle exec rspec "$SPEC_FILE" --format progress
|
52
|
+
else
|
53
|
+
rspec "$SPEC_FILE" --format progress
|
54
|
+
fi
|
55
|
+
|
56
|
+
RSPEC_EXIT_CODE=$?
|
57
|
+
|
58
|
+
if [ $RSPEC_EXIT_CODE -ne 0 ]; then
|
59
|
+
cat << EOF
|
60
|
+
{
|
61
|
+
"type": "advanced",
|
62
|
+
"decision": "allow",
|
63
|
+
"message": "Tests failed for $SPEC_FILE. Consider fixing the failing tests.\n\nYou can run: bundle exec rspec $SPEC_FILE"
|
64
|
+
}
|
65
|
+
EOF
|
66
|
+
else
|
67
|
+
echo "Tests passed for $SPEC_FILE"
|
68
|
+
fi
|
69
|
+
fi
|
70
|
+
|
71
|
+
# Always allow the modification to proceed
|
72
|
+
exit 0
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
# RuboCop pre-commit hook generated by Aircana
|
3
|
+
# This hook runs RuboCop before allowing commits
|
4
|
+
|
5
|
+
# Get the tool name and parameters
|
6
|
+
TOOL_NAME="$1"
|
7
|
+
TOOL_PARAMS="$2"
|
8
|
+
|
9
|
+
# Only act on Bash commands that look like git commits
|
10
|
+
if [ "$TOOL_NAME" != "Bash" ]; then
|
11
|
+
exit 0
|
12
|
+
fi
|
13
|
+
|
14
|
+
# Check if this is a git commit command
|
15
|
+
if ! echo "$TOOL_PARAMS" | grep -q "git commit"; then
|
16
|
+
exit 0
|
17
|
+
fi
|
18
|
+
|
19
|
+
# Check if we're in a Ruby project
|
20
|
+
if [ ! -f "Gemfile" ] && [ ! -f ".rubocop.yml" ]; then
|
21
|
+
exit 0
|
22
|
+
fi
|
23
|
+
|
24
|
+
# Get list of staged Ruby files
|
25
|
+
RUBY_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(rb)$' | tr '\n' ' ')
|
26
|
+
|
27
|
+
if [ -z "$RUBY_FILES" ]; then
|
28
|
+
# No Ruby files to check
|
29
|
+
exit 0
|
30
|
+
fi
|
31
|
+
|
32
|
+
echo "Running RuboCop on staged Ruby files..."
|
33
|
+
|
34
|
+
# Run RuboCop on staged files
|
35
|
+
if command -v bundle >/dev/null 2>&1 && [ -f "Gemfile" ]; then
|
36
|
+
bundle exec rubocop $RUBY_FILES
|
37
|
+
else
|
38
|
+
rubocop $RUBY_FILES
|
39
|
+
fi
|
40
|
+
|
41
|
+
RUBOCOP_EXIT_CODE=$?
|
42
|
+
|
43
|
+
if [ $RUBOCOP_EXIT_CODE -ne 0 ]; then
|
44
|
+
cat << EOF
|
45
|
+
{
|
46
|
+
"type": "advanced",
|
47
|
+
"decision": "deny",
|
48
|
+
"message": "RuboCop found style violations. Please fix them before committing.\n\nYou can run: bundle exec rubocop $RUBY_FILES --auto-correct\n\nOr fix them manually and try again."
|
49
|
+
}
|
50
|
+
EOF
|
51
|
+
exit 1
|
52
|
+
fi
|
53
|
+
|
54
|
+
# RuboCop passed, allow the commit
|
55
|
+
exit 0
|
@@ -0,0 +1,127 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
# Multi-root project support hook for Aircana
|
3
|
+
# This hook runs when a new Claude Code session starts
|
4
|
+
|
5
|
+
PROJECT_JSON=".aircana/project.json"
|
6
|
+
CLAUDE_AGENTS_DIR=".claude/agents"
|
7
|
+
AIRCANA_AGENTS_DIR=".aircana/agents"
|
8
|
+
|
9
|
+
# Create log directory if it doesn't exist
|
10
|
+
mkdir -p ~/.aircana
|
11
|
+
|
12
|
+
# Log session start
|
13
|
+
echo "$(date): New Claude Code session started in $(pwd)" >> ~/.aircana/hooks.log
|
14
|
+
|
15
|
+
# Check if jq is available
|
16
|
+
if ! command -v jq &> /dev/null; then
|
17
|
+
echo "$(date): Warning - jq not found. Multi-root support disabled." >> ~/.aircana/hooks.log
|
18
|
+
echo "{}"
|
19
|
+
exit 0
|
20
|
+
fi
|
21
|
+
|
22
|
+
# Check if project.json exists
|
23
|
+
if [ ! -f "$PROJECT_JSON" ]; then
|
24
|
+
echo "$(date): No project.json found, skipping multi-root setup" >> ~/.aircana/hooks.log
|
25
|
+
echo "{}"
|
26
|
+
exit 0
|
27
|
+
fi
|
28
|
+
|
29
|
+
echo "$(date): Processing multi-root configuration from $PROJECT_JSON" >> ~/.aircana/hooks.log
|
30
|
+
|
31
|
+
# Ensure directories exist
|
32
|
+
mkdir -p "$CLAUDE_AGENTS_DIR" 2>/dev/null
|
33
|
+
mkdir -p "$AIRCANA_AGENTS_DIR" 2>/dev/null
|
34
|
+
|
35
|
+
# Clean up existing symlinks (only remove symlinks, not real files)
|
36
|
+
find "$CLAUDE_AGENTS_DIR" -type l -delete 2>/dev/null
|
37
|
+
find "$AIRCANA_AGENTS_DIR" -type l -delete 2>/dev/null
|
38
|
+
|
39
|
+
# Parse folders from project.json
|
40
|
+
FOLDERS=$(jq -r '.folders[]?.path // empty' "$PROJECT_JSON" 2>/dev/null)
|
41
|
+
|
42
|
+
if [ -z "$FOLDERS" ]; then
|
43
|
+
echo "$(date): No folders configured in project.json" >> ~/.aircana/hooks.log
|
44
|
+
echo "{}"
|
45
|
+
exit 0
|
46
|
+
fi
|
47
|
+
|
48
|
+
# Track what we've linked for reporting
|
49
|
+
LINKED_AGENTS=0
|
50
|
+
LINKED_KNOWLEDGE=0
|
51
|
+
|
52
|
+
# Create symlinks for each configured folder
|
53
|
+
for folder in $FOLDERS; do
|
54
|
+
# Validate folder exists
|
55
|
+
if [ ! -d "$folder" ]; then
|
56
|
+
echo "$(date): Warning - folder '$folder' not found, skipping" >> ~/.aircana/hooks.log
|
57
|
+
continue
|
58
|
+
fi
|
59
|
+
|
60
|
+
echo "$(date): Processing folder: $folder" >> ~/.aircana/hooks.log
|
61
|
+
|
62
|
+
# Get folder name for prefix (replace slashes with underscores for nested paths)
|
63
|
+
PREFIX=$(echo "$folder" | tr '/' '_')
|
64
|
+
|
65
|
+
# Link agents from sub-folder .claude/agents
|
66
|
+
if [ -d "$folder/.claude/agents" ]; then
|
67
|
+
for agent_file in "$folder/.claude/agents"/*.md; do
|
68
|
+
if [ ! -f "$agent_file" ]; then
|
69
|
+
continue
|
70
|
+
fi
|
71
|
+
|
72
|
+
AGENT_NAME=$(basename "$agent_file" .md)
|
73
|
+
LINK_NAME="${PREFIX}_${AGENT_NAME}.md"
|
74
|
+
TARGET_PATH="$CLAUDE_AGENTS_DIR/$LINK_NAME"
|
75
|
+
|
76
|
+
# Create relative path from .claude/agents to the agent file
|
77
|
+
RELATIVE_PATH=$(realpath --relative-to="$CLAUDE_AGENTS_DIR" "$agent_file" 2>/dev/null)
|
78
|
+
|
79
|
+
if [ -n "$RELATIVE_PATH" ]; then
|
80
|
+
ln -sf "$RELATIVE_PATH" "$TARGET_PATH"
|
81
|
+
echo "$(date): Linked agent: $LINK_NAME -> $RELATIVE_PATH" >> ~/.aircana/hooks.log
|
82
|
+
((LINKED_AGENTS++))
|
83
|
+
fi
|
84
|
+
done
|
85
|
+
fi
|
86
|
+
|
87
|
+
# Link knowledge from sub-folder .aircana/agents
|
88
|
+
if [ -d "$folder/.aircana/agents" ]; then
|
89
|
+
for agent_dir in "$folder/.aircana/agents"/*; do
|
90
|
+
if [ ! -d "$agent_dir" ]; then
|
91
|
+
continue
|
92
|
+
fi
|
93
|
+
|
94
|
+
AGENT_NAME=$(basename "$agent_dir")
|
95
|
+
LINK_NAME="${PREFIX}_${AGENT_NAME}"
|
96
|
+
TARGET_PATH="$AIRCANA_AGENTS_DIR/$LINK_NAME"
|
97
|
+
|
98
|
+
# Create relative path from .aircana/agents to the knowledge directory
|
99
|
+
RELATIVE_PATH=$(realpath --relative-to="$AIRCANA_AGENTS_DIR" "$agent_dir" 2>/dev/null)
|
100
|
+
|
101
|
+
if [ -n "$RELATIVE_PATH" ]; then
|
102
|
+
ln -sf "$RELATIVE_PATH" "$TARGET_PATH"
|
103
|
+
echo "$(date): Linked knowledge: $LINK_NAME -> $RELATIVE_PATH" >> ~/.aircana/hooks.log
|
104
|
+
((LINKED_KNOWLEDGE++))
|
105
|
+
fi
|
106
|
+
done
|
107
|
+
fi
|
108
|
+
done
|
109
|
+
|
110
|
+
# Report results
|
111
|
+
echo "$(date): Multi-root setup complete - linked $LINKED_AGENTS agents and $LINKED_KNOWLEDGE knowledge bases" >> ~/.aircana/hooks.log
|
112
|
+
|
113
|
+
# Return success with optional context
|
114
|
+
if [ $LINKED_AGENTS -gt 0 ] || [ $LINKED_KNOWLEDGE -gt 0 ]; then
|
115
|
+
CONTEXT="Multi-root: Linked $LINKED_AGENTS agents and $LINKED_KNOWLEDGE knowledge bases from configured folders."
|
116
|
+
ESCAPED_CONTEXT=$(echo -n "$CONTEXT" | sed 's/"/\\"/g')
|
117
|
+
cat << EOF
|
118
|
+
{
|
119
|
+
"hookSpecificOutput": {
|
120
|
+
"hookEventName": "SessionStart",
|
121
|
+
"additionalContext": "$ESCAPED_CONTEXT"
|
122
|
+
}
|
123
|
+
}
|
124
|
+
EOF
|
125
|
+
else
|
126
|
+
echo "{}"
|
127
|
+
fi
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
# User prompt submit hook generated by Aircana
|
3
|
+
# This hook runs when the user submits a prompt
|
4
|
+
|
5
|
+
# Get the user prompt
|
6
|
+
USER_PROMPT="$1"
|
7
|
+
|
8
|
+
# Add context information based on project state
|
9
|
+
CONTEXT_ADDITIONS=""
|
10
|
+
|
11
|
+
# Check if this is a Ruby project and add relevant info
|
12
|
+
if [ -f "Gemfile" ]; then
|
13
|
+
CONTEXT_ADDITIONS="${CONTEXT_ADDITIONS}\n\nProject Context: This is a Ruby project with Gemfile present."
|
14
|
+
|
15
|
+
# Check for common Ruby frameworks
|
16
|
+
if grep -q "rails" Gemfile 2>/dev/null; then
|
17
|
+
CONTEXT_ADDITIONS="${CONTEXT_ADDITIONS} Rails framework detected."
|
18
|
+
fi
|
19
|
+
|
20
|
+
if grep -q "rspec" Gemfile 2>/dev/null; then
|
21
|
+
CONTEXT_ADDITIONS="${CONTEXT_ADDITIONS} RSpec testing framework in use."
|
22
|
+
fi
|
23
|
+
fi
|
24
|
+
|
25
|
+
# Check for relevant files context
|
26
|
+
if [ -d ".aircana/relevant_files" ] && [ "$(ls -A .aircana/relevant_files 2>/dev/null)" ]; then
|
27
|
+
RELEVANT_COUNT=$(ls .aircana/relevant_files | wc -l)
|
28
|
+
CONTEXT_ADDITIONS="${CONTEXT_ADDITIONS}\n\nRelevant Files: $RELEVANT_COUNT files currently in context."
|
29
|
+
fi
|
30
|
+
|
31
|
+
# Output JSON response with additional context
|
32
|
+
if [ -n "$CONTEXT_ADDITIONS" ]; then
|
33
|
+
# Escape context for JSON
|
34
|
+
ESCAPED_CONTEXT=$(echo -n "$CONTEXT_ADDITIONS" | sed 's/"/\\"/g' | tr '\n' ' ' | sed 's/ */ /g')
|
35
|
+
cat << EOF
|
36
|
+
{
|
37
|
+
"hookSpecificOutput": {
|
38
|
+
"hookEventName": "UserPromptSubmit",
|
39
|
+
"additionalContext": "$ESCAPED_CONTEXT"
|
40
|
+
}
|
41
|
+
}
|
42
|
+
EOF
|
43
|
+
else
|
44
|
+
# No additional context needed
|
45
|
+
echo "{}"
|
46
|
+
fi
|
data/lib/aircana/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aircana
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Weston Dransfield
|
@@ -93,9 +93,8 @@ dependencies:
|
|
93
93
|
- - "~>"
|
94
94
|
- !ruby/object:Gem::Version
|
95
95
|
version: '0.9'
|
96
|
-
description:
|
97
|
-
|
98
|
-
Claude Code agents, and optionally syncknowledge from Confluence.
|
96
|
+
description: Aircana provides context management and workflow utilities for software
|
97
|
+
engineering with AI agents, including file organization and template generation.
|
99
98
|
email:
|
100
99
|
- weston@dransfield.dev
|
101
100
|
executables:
|
@@ -127,10 +126,14 @@ files:
|
|
127
126
|
- lib/aircana/cli/commands/doctor_checks.rb
|
128
127
|
- lib/aircana/cli/commands/doctor_helpers.rb
|
129
128
|
- lib/aircana/cli/commands/dump_context.rb
|
129
|
+
- lib/aircana/cli/commands/files.rb
|
130
130
|
- lib/aircana/cli/commands/generate.rb
|
131
|
+
- lib/aircana/cli/commands/hooks.rb
|
131
132
|
- lib/aircana/cli/commands/install.rb
|
132
133
|
- lib/aircana/cli/commands/plan.rb
|
134
|
+
- lib/aircana/cli/commands/project.rb
|
133
135
|
- lib/aircana/cli/commands/work.rb
|
136
|
+
- lib/aircana/cli/help_formatter.rb
|
134
137
|
- lib/aircana/cli/shell_command.rb
|
135
138
|
- lib/aircana/cli/subcommand.rb
|
136
139
|
- lib/aircana/configuration.rb
|
@@ -146,17 +149,27 @@ files:
|
|
146
149
|
- lib/aircana/generators/agents_generator.rb
|
147
150
|
- lib/aircana/generators/base_generator.rb
|
148
151
|
- lib/aircana/generators/helpers.rb
|
152
|
+
- lib/aircana/generators/hooks_generator.rb
|
153
|
+
- lib/aircana/generators/project_config_generator.rb
|
149
154
|
- lib/aircana/generators/relevant_files_command_generator.rb
|
150
155
|
- lib/aircana/generators/relevant_files_verbose_results_generator.rb
|
151
156
|
- lib/aircana/human_logger.rb
|
152
157
|
- lib/aircana/initializers.rb
|
153
158
|
- lib/aircana/llm/claude_client.rb
|
154
159
|
- lib/aircana/progress_tracker.rb
|
160
|
+
- lib/aircana/symlink_manager.rb
|
155
161
|
- lib/aircana/system_checker.rb
|
156
162
|
- lib/aircana/templates/agents/base_agent.erb
|
157
163
|
- lib/aircana/templates/agents/defaults/planner.erb
|
158
164
|
- lib/aircana/templates/agents/defaults/worker.erb
|
159
165
|
- lib/aircana/templates/commands/add_relevant_files.erb
|
166
|
+
- lib/aircana/templates/hooks/bundle_install.erb
|
167
|
+
- lib/aircana/templates/hooks/post_tool_use.erb
|
168
|
+
- lib/aircana/templates/hooks/pre_tool_use.erb
|
169
|
+
- lib/aircana/templates/hooks/rspec_test.erb
|
170
|
+
- lib/aircana/templates/hooks/rubocop_pre_commit.erb
|
171
|
+
- lib/aircana/templates/hooks/session_start.erb
|
172
|
+
- lib/aircana/templates/hooks/user_prompt_submit.erb
|
160
173
|
- lib/aircana/templates/relevant_files_verbose_results.erb
|
161
174
|
- lib/aircana/version.rb
|
162
175
|
- sig/aircana.rbs
|
@@ -185,5 +198,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
185
198
|
requirements: []
|
186
199
|
rubygems_version: 3.6.9
|
187
200
|
specification_version: 4
|
188
|
-
summary:
|
201
|
+
summary: Humble workflow and context utilities for engineering with agents
|
189
202
|
test_files: []
|