aircana 1.2.0 → 1.4.0.rc1

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.
@@ -126,6 +126,54 @@ module Aircana
126
126
  end
127
127
  end
128
128
  end
129
+
130
+ module SQSIntegration
131
+ def check_sqs_integration
132
+ Aircana.human_logger.info "\nSQS Integration:"
133
+
134
+ check_sqs_dependencies
135
+ check_sqs_configuration
136
+ end
137
+
138
+ def check_sqs_dependencies
139
+ check_command("aws", "SQS operations", required: false)
140
+ check_command("jq", "JSON processing for notifications", required: false)
141
+ end
142
+
143
+ def check_sqs_configuration
144
+ sqs_queue_url = ENV.fetch("AIRCANA_SQS_QUEUE_URL", nil)
145
+ sqs_message_template = ENV.fetch("AIRCANA_SQS_MESSAGE_TEMPLATE", nil)
146
+ aws_region = ENV.fetch("AWS_REGION", "us-east-1")
147
+
148
+ if sqs_configured?(sqs_queue_url, sqs_message_template)
149
+ log_success("SQS Config", "Environment variables configured")
150
+ log_sqs_config_details(sqs_queue_url, sqs_message_template, aws_region) if @verbose
151
+ else
152
+ log_info("SQS Config", "Not configured")
153
+ log_sqs_configuration_remedy
154
+ end
155
+ end
156
+
157
+ def sqs_configured?(queue_url, message_template)
158
+ !queue_url.nil? && !queue_url.empty? &&
159
+ !message_template.nil? && !message_template.empty?
160
+ end
161
+
162
+ def log_sqs_config_details(queue_url, message_template, aws_region)
163
+ log_info(" AIRCANA_SQS_QUEUE_URL", queue_url.length > 50 ? "#{queue_url[0..47]}..." : queue_url)
164
+ log_info(" AIRCANA_SQS_MESSAGE_TEMPLATE",
165
+ message_template.length > 40 ? "#{message_template[0..37]}..." : message_template)
166
+ log_info(" AWS_REGION", aws_region)
167
+ end
168
+
169
+ def log_sqs_configuration_remedy
170
+ log_remedy("Set AIRCANA_SQS_QUEUE_URL and AIRCANA_SQS_MESSAGE_TEMPLATE for SQS notifications")
171
+ log_remedy("Example:")
172
+ log_remedy(' export AIRCANA_SQS_QUEUE_URL="https://sqs.us-east-1.amazonaws.com/account/queue"')
173
+ log_remedy(' export AIRCANA_SQS_MESSAGE_TEMPLATE=\'{"text":"{{message}}}\'')
174
+ log_remedy(' export AWS_REGION="us-east-1" # Optional, defaults to us-east-1')
175
+ end
176
+ end
129
177
  end
130
178
  end
131
179
  end
@@ -9,7 +9,7 @@ module Aircana
9
9
  module Install
10
10
  class << self
11
11
  def run
12
- ensure_output_exists
12
+ generate_files
13
13
  ensure_project_config_exists
14
14
  install_commands_to_claude
15
15
  install_hooks_to_claude
@@ -17,10 +17,8 @@ module Aircana
17
17
 
18
18
  private
19
19
 
20
- def ensure_output_exists
21
- return if Dir.exist?(Aircana.configuration.output_dir)
22
-
23
- Aircana.human_logger.warn("No generated output files-auto generating now...")
20
+ def generate_files
21
+ Aircana.human_logger.info("Generating files before installation...")
24
22
  Generate.run
25
23
  end
26
24
 
@@ -118,6 +116,7 @@ module Aircana
118
116
  "post_tool_use" => { event: "PostToolUse", matcher: nil },
119
117
  "user_prompt_submit" => { event: "UserPromptSubmit", matcher: nil },
120
118
  "session_start" => { event: "SessionStart", matcher: nil },
119
+ "notification_sqs" => { event: "Notification", matcher: nil },
121
120
  "rubocop_pre_commit" => { event: "PreToolUse", matcher: "Bash" },
122
121
  "rspec_test" => { event: "PostToolUse", matcher: "Bash" },
123
122
  "bundle_install" => { event: "PostToolUse", matcher: "Bash" }
@@ -7,7 +7,7 @@ module Aircana
7
7
  class AgentsGenerator < BaseGenerator
8
8
  attr_reader :agent_name, :short_description, :description, :model, :color, :default_agent
9
9
 
10
- AVAILABLE_DEFAULT_AGENTS = %w[planner worker].freeze
10
+ AVAILABLE_DEFAULT_AGENTS = ["planner"].freeze
11
11
 
12
12
  class << self
13
13
  def create_default_agent(agent_name)
@@ -6,8 +6,7 @@ module Aircana
6
6
  class << self
7
7
  def model_instructions(instructions, important: false)
8
8
  <<~INSTRUCTIONS
9
- INSTRUCTIONS #{"IMPORTANT" if important}:
10
- #{instructions}
9
+ INSTRUCTIONS #{"IMPORTANT" if important}: #{instructions}
11
10
  INSTRUCTIONS
12
11
  end
13
12
  end
@@ -11,6 +11,7 @@ module Aircana
11
11
  post_tool_use
12
12
  user_prompt_submit
13
13
  session_start
14
+ notification_sqs
14
15
  rubocop_pre_commit
15
16
  rspec_test
16
17
  bundle_install
@@ -19,6 +20,7 @@ module Aircana
19
20
  # Default hooks that are auto-installed
20
21
  DEFAULT_HOOK_TYPES = %w[
21
22
  session_start
23
+ notification_sqs
22
24
  ].freeze
23
25
 
24
26
  class << self
@@ -25,7 +25,7 @@ module Aircana
25
25
  end
26
26
 
27
27
  def default_output_path
28
- File.join(Aircana.configuration.output_dir, "commands", "ac-add-relevant-files.md")
28
+ File.join(Aircana.configuration.output_dir, "commands", "air-add-relevant-files.md")
29
29
  end
30
30
 
31
31
  def relevant_project_files_path
@@ -37,6 +37,17 @@ module Aircana
37
37
  }.freeze
38
38
 
39
39
  OPTIONAL_COMMANDS = {
40
+ "aws" => {
41
+ purpose: "SQS notifications via AWS CLI",
42
+ fallback: "SQS notifications will be disabled",
43
+ install: {
44
+ "macOS" => "brew install awscli",
45
+ "Ubuntu/Debian" => "apt install awscli",
46
+ "Fedora/CentOS" => "dnf install awscli",
47
+ "Arch" => "pacman -S aws-cli",
48
+ "Other" => "https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html"
49
+ }
50
+ },
40
51
  "bat" => {
41
52
  purpose: "enhanced file previews",
42
53
  fallback: "head/cat for basic previews",
@@ -4,12 +4,11 @@ description: <%= short_description %>
4
4
  model: <%= model %>
5
5
  color: <%= color %>
6
6
  ---
7
- <%= description %>
8
7
 
9
8
  <%= helpers.model_instructions("ALWAYS check your knowledge base FIRST for every query, task, or question you receive. Your knowledge is stored in: @#{knowledge_path}
10
9
 
11
10
  MANDATORY WORKFLOW:
12
- 1. BEFORE responding to ANY query - search and read relevant files in your knowledge base
11
+ 1. BEFORE responding to ANY request - search and read relevant files in your knowledge base
13
12
  2. Base your responses primarily on information found in your knowledge base
14
13
  3. If knowledge base contains relevant information, cite specific files/sections
15
14
  4. Only use general knowledge when your knowledge base lacks specific information
@@ -27,4 +26,6 @@ This knowledge base contains:
27
26
  - Team standards and best practices
28
27
  - Technical specifications and requirements
29
28
 
30
- Always consult this knowledge base before making recommendations or providing guidance.
29
+ Always consult this knowledge base before making recommendations or providing guidance.
30
+
31
+ <%= description %>
@@ -1,126 +1,55 @@
1
1
  ---
2
2
  name: planner
3
- description: Specialized agent for creating implementation plans for Jira tickets
3
+ description: Strategic project planning agent that integrates with Jira and collaborates with other sub-agents to create comprehensive implementation plans
4
4
  model: inherit
5
5
  color: blue
6
6
  ---
7
- # Planner Agent
8
7
 
9
- You are the Planner Agent, specialized in creating comprehensive implementation plans for Jira tickets through AI-powered collaboration with expert agents.
10
-
11
- <%= helpers.model_instructions("ALWAYS check your knowledge base FIRST for every query, task, or question you receive. Your knowledge is stored in: @#{knowledge_path}
12
-
13
- MANDATORY WORKFLOW FOR KNOWLEDGE:
14
- 1. BEFORE starting any planning - search and read relevant files in your knowledge base
15
- 2. Look for existing planning templates, processes, and methodologies
16
- 3. Check for similar ticket plans or implementation patterns
17
- 4. Review project-specific requirements and constraints
18
- 5. Base your planning approach on knowledge base guidance when available
19
- 6. Incorporate knowledge base standards into your execution plans
20
-
21
- Your knowledge base contains domain-specific information that takes priority over general planning knowledge.", important: true) %>
22
-
23
- ## Core Responsibilities
24
-
25
- You create detailed implementation plans by:
26
- 1. Gathering ticket requirements from Jira
27
- 2. Collecting relevant project files for context
28
- 3. Coordinating with expert agents for specialized analysis
29
- 4. Generating comprehensive execution plans
30
- 5. Creating actionable todo lists
31
- 6. Storing plans in structured format
32
-
33
- ## Planning Workflow
34
-
35
- Follow this exact sequence for every planning session:
36
-
37
- ### Step A: Ticket Identification
38
- - Prompt user for Jira ticket ID to plan for
39
- - If no ticket provided, ask if they want to create a new one.
40
- - Use MCP Jira tools to fetch ticket details
41
-
42
- **IMMEDIATELY: Check Knowledge Base**
43
- - Search your knowledge base (@<%= knowledge_path %>) for:
44
- - Similar tickets or implementations
45
- - Relevant planning methodologies
46
- - Project-specific planning templates
47
- - Domain-specific requirements and constraints
48
-
49
- ### Step B: Check Existing Plan
50
- - Examine ticket description for "# AGENT PLAN #" section
51
- - If found, present existing plan to user
52
- - Ask if adjustments are needed to current plan
53
-
54
- ### Step C: Gather Context (if no plan exists)
55
- - **FIRST: Ask user for relevant files**
56
- - Prompt: "What files are most relevant to this ticket? Please list file paths."
57
- - These files provide crucial context before expert consultation
58
- - Read and analyze provided relevant files
59
- - Extract key patterns, frameworks, and architectural decisions
60
-
61
- ### Step D: Expert Agent Coordination
62
- - Based on ticket requirements, relevant files, and knowledge base findings, identify expert agents
63
- - **BEFORE consulting experts**: Review knowledge base for existing expert guidance on similar topics
64
- - Use Claude Code's Task tool to consult expert agents in parallel
65
- - Ask each expert to provide key details for the plan in their domain of expertise
66
- - **Combine knowledge base findings with expert recommendations** for comprehensive planning
67
-
68
- ### Step E: Plan Generation
69
- - Consolidate expert recommendations into cohesive execution plan
70
- - Create detailed todo list including:
71
- - Implementation steps
72
- - Unit test writing requirements
73
- - Test execution and iteration cycles
74
- - Present plan to user for approval and adjustments
75
-
76
- ### Step F: Plan Storage
77
- - Format plan with required sections (see below)
78
- - If new ticket needed, ask for Jira project and create ticket
79
- - Update/create Jira ticket with complete plan in description. Do not search yourself
80
- for an appropriate Jira project. Always ask the user what Jira project the ticket
81
- should be created in.
82
-
83
- ## Plan Format
84
-
85
- Store plans in Jira ticket descriptions using this exact structure:
86
-
87
- ```markdown
88
- # AGENT PLAN #
89
-
90
- ## Relevant Files
91
- - path/to/file1.rb
92
- - path/to/file2.rb
93
- - directory/file3.rb
94
-
95
- ## Expert Agents
96
- - agent-name-1
97
- - agent-name-2
98
-
99
- ## Execution Plan
100
- [Detailed implementation steps from expert analysis]
101
-
102
- ## Todo List
103
- - [ ] Task 1
104
- - [ ] Task 2
105
- - [ ] Write unit tests for [specific functionality]
106
- - [ ] Run tests and iterate until all pass
107
- - [ ] Final integration testing
108
- ```
109
-
110
- ## Key Instructions
111
-
112
- 1. **Always ask for relevant files BEFORE consulting expert agents**
113
- 2. **Use the exact "# AGENT PLAN #" header for plan sections**
114
- 3. **Include test writing and execution in every todo list**
115
- 4. **Present plans to users for approval before saving**
116
- 5. **Use MCP Jira tools for all ticket operations**
117
- 6. **Coordinate expert agents using Claude Code's Task tool**
118
-
119
- ## Error Handling
120
-
121
- - If Jira access fails, guide user to check MCP Jira configuration
122
- - If no expert agents found, proceed with general analysis
123
- - If file access fails, note in plan and continue
124
- - Always provide fallback options when tools fail
125
-
126
- Start every planning session by confirming: "I'm ready to help you create an implementation plan. Do you have a Jira ticket ID to plan for, or would you like to create a new ticket?"
8
+ <%= helpers.model_instructions("You are a Strategic Project Planning Agent that creates comprehensive implementation plans by integrating with Jira tickets and leveraging other specialized sub-agents' knowledge.
9
+
10
+ MANDATORY WORKFLOW:
11
+ 1. JIRA TICKET VERIFICATION:
12
+ - If no Jira ticket was provided, ask if the user wants to create a new ticket or provide a ticket number
13
+ - If a Jira ticket is provided, use the built-in `jira` mcp tool to fetch the ticket details
14
+ - If user doesn't have the jira mcp tool installed, prompt them to run `aircana doctor` for setup details
15
+
16
+ 2. REQUIREMENTS GATHERING:
17
+ - If ticket details are available, read the description from Jira
18
+ - If no ticket or description, ask the user for a description of the issue
19
+ - Ask the user to provide references to any files they know might be part of the solution
20
+ - Read all referenced files to understand the codebase context
21
+
22
+ 3. SUB-AGENT CONSULTATION:
23
+ - Consider the ticket description and potentially relevant files
24
+ - Identify all available sub-agents installed in Claude Code that may be helpful for planning
25
+ - For each relevant agent, present the ticket description and ask specifically for input on the solution using their knowledge base
26
+ - Run these sub-agent consultation processes in parallel when possible
27
+ - Gather insights from specialized domains (testing, security, frontend, backend, etc.)
28
+
29
+ 4. PLANNING MODE EXECUTION:
30
+ - Enter Claude Code planning mode
31
+ - Synthesize information from ticket description, relevant files, and sub-agent consultations
32
+ - Create a comprehensive implementation plan
33
+ - Present the proposed plan to the user for input and iteration
34
+
35
+ 5. PLAN FINALIZATION:
36
+ - Iterate with the user to refine and finalize the plan
37
+ - Ensure all technical considerations and sub-agent recommendations are incorporated
38
+ - Validate the plan addresses all requirements from the Jira ticket
39
+
40
+ 6. JIRA INTEGRATION:
41
+ - Create or update the Jira ticket with a new markdown attachment describing the final plan
42
+ - The plan should be in markdown format with proper frontmatter including:
43
+ * List of consulted sub-agents (frontmatter)
44
+ * List of relevant files referenced (frontmatter)
45
+ - The markdown body should contain:
46
+ * Detailed implementation steps as a todo list using `[]` format for easy LLM consumption
47
+ * Technical considerations and dependencies
48
+
49
+ IMPORTANT INSTRUCTIONS:
50
+ - Always start by checking for Jira ticket information
51
+ - Leverage the expertise of available sub-agents rather than working in isolation
52
+ - Use proper markdown formatting for Jira attachments
53
+ - Focus on creating implementable, step-by-step plans", important: true) %>
54
+
55
+ Always identify available sub-agents and leverage their specialized knowledge to create more comprehensive and accurate plans.
@@ -0,0 +1,75 @@
1
+ #!/bin/bash
2
+ # Aircana SQS notification hook
3
+ # Sends Claude Code notifications to SQS
4
+
5
+ # Read JSON input from stdin
6
+ INPUT=$(cat)
7
+
8
+ # Set up logging
9
+ mkdir -p ~/.aircana
10
+ LOG_FILE="$HOME/.aircana/sqs_notifications.log"
11
+
12
+ # Log the notification input for debugging
13
+ echo "$(date): Notification Hook Input:" >> $LOG_FILE
14
+ echo "$INPUT" >> $LOG_FILE
15
+ echo "---" >> $LOG_FILE
16
+
17
+ # Check if jq is available
18
+ if ! command -v jq &> /dev/null; then
19
+ echo "$(date): Error - jq not found. Cannot parse notification." >> $LOG_FILE
20
+ exit 0
21
+ fi
22
+
23
+ # Check if aws CLI is available
24
+ if ! command -v aws &> /dev/null; then
25
+ echo "$(date): Error - aws CLI not found. Cannot send to SQS." >> $LOG_FILE
26
+ exit 0
27
+ fi
28
+
29
+ # Parse the notification message
30
+ MESSAGE=$(echo "$INPUT" | jq -r '.message // empty')
31
+
32
+ # Skip empty messages
33
+ if [ -z "$MESSAGE" ] || [ "$MESSAGE" = "null" ]; then
34
+ echo "$(date): No message found in notification" >> $LOG_FILE
35
+ exit 0
36
+ fi
37
+
38
+ # Check required environment variables
39
+ if [ -z "$AIRCANA_SQS_QUEUE_URL" ]; then
40
+ echo "$(date): AIRCANA_SQS_QUEUE_URL not set, skipping SQS notification" >> $LOG_FILE
41
+ exit 0
42
+ fi
43
+
44
+ if [ -z "$AIRCANA_SQS_MESSAGE_TEMPLATE" ]; then
45
+ echo "$(date): AIRCANA_SQS_MESSAGE_TEMPLATE not set, skipping SQS notification" >> $LOG_FILE
46
+ exit 0
47
+ fi
48
+
49
+ # Create the message body by substituting {{message}} in the template
50
+ MESSAGE_BODY=$(echo "$AIRCANA_SQS_MESSAGE_TEMPLATE" | sed "s|{{message}}|$MESSAGE|g")
51
+
52
+ # Log the message being sent
53
+ echo "$(date): Sending SQS message:" >> $LOG_FILE
54
+ echo "Queue URL: $AIRCANA_SQS_QUEUE_URL" >> $LOG_FILE
55
+ echo "Message Body: $MESSAGE_BODY" >> $LOG_FILE
56
+
57
+ # Send message to SQS using aws CLI
58
+ AWS_REGION=${AWS_REGION:-us-east-1}
59
+ SQS_RESULT=$(aws --region "$AWS_REGION" sqs send-message \
60
+ --queue-url "$AIRCANA_SQS_QUEUE_URL" \
61
+ --message-body "$MESSAGE_BODY" 2>&1)
62
+
63
+ # Log the result
64
+ if [ $? -eq 0 ]; then
65
+ echo "$(date): Successfully sent SQS message" >> $LOG_FILE
66
+ echo "Response: $SQS_RESULT" >> $LOG_FILE
67
+ else
68
+ echo "$(date): Failed to send SQS message" >> $LOG_FILE
69
+ echo "Error: $SQS_RESULT" >> $LOG_FILE
70
+ fi
71
+
72
+ echo "---" >> $LOG_FILE
73
+
74
+ # Return success - don't block Claude Code if SQS fails
75
+ exit 0
@@ -2,25 +2,33 @@
2
2
  # Pre-tool-use hook generated by Aircana
3
3
  # This hook runs before any tool is executed
4
4
 
5
- # Get the tool name and parameters
6
- TOOL_NAME="$1"
7
- TOOL_PARAMS="$2"
5
+ # Read JSON input from stdin
6
+ INPUT=$(cat)
7
+
8
+ # Parse JSON to extract tool information
9
+ TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // empty')
10
+ TOOL_INPUT=$(echo "$INPUT" | jq -r '.tool_input // empty')
11
+ SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // empty')
12
+ CWD=$(echo "$INPUT" | jq -r '.cwd // empty')
8
13
 
9
14
  # Log the tool usage (optional)
10
- echo "$(date): About to use tool: $TOOL_NAME" >> ~/.aircana/hooks.log
15
+ echo "$(date): Session $SESSION_ID - About to use tool: $TOOL_NAME in $CWD" >> ~/.aircana/hooks.log
11
16
 
12
17
  # Basic validation example
13
18
  case "$TOOL_NAME" in
14
19
  "Bash")
15
20
  # Add validation for bash commands
16
- if echo "$TOOL_PARAMS" | grep -q "rm -rf /"; then
21
+ COMMAND=$(echo "$TOOL_INPUT" | jq -r '.command // empty')
22
+ if echo "$COMMAND" | grep -q "rm -rf /"; then
17
23
  cat << EOF
18
24
  {
19
25
  "hookSpecificOutput": {
20
26
  "hookEventName": "PreToolUse",
21
27
  "permissionDecision": "deny",
22
28
  "permissionDecisionReason": "Dangerous command detected: rm -rf /"
23
- }
29
+ },
30
+ "continue": false,
31
+ "stopReason": "Blocked dangerous command"
24
32
  }
25
33
  EOF
26
34
  exit 0
@@ -28,7 +36,23 @@ EOF
28
36
  ;;
29
37
  "Edit"|"Write")
30
38
  # Validate file operations
39
+ FILE_PATH=$(echo "$TOOL_INPUT" | jq -r '.file_path // empty')
31
40
  # Add custom validation logic here
41
+ # Example: Check if trying to modify system files
42
+ if echo "$FILE_PATH" | grep -q "^/etc/\|^/usr/\|^/bin/\|^/sbin/"; then
43
+ cat << EOF
44
+ {
45
+ "hookSpecificOutput": {
46
+ "hookEventName": "PreToolUse",
47
+ "permissionDecision": "ask",
48
+ "permissionDecisionReason": "Attempting to modify system file: $FILE_PATH"
49
+ },
50
+ "continue": true,
51
+ "systemMessage": "Warning: About to modify a system file"
52
+ }
53
+ EOF
54
+ exit 0
55
+ fi
32
56
  ;;
33
57
  esac
34
58
 
@@ -38,6 +62,7 @@ cat << EOF
38
62
  "hookSpecificOutput": {
39
63
  "hookEventName": "PreToolUse",
40
64
  "permissionDecision": "allow"
41
- }
65
+ },
66
+ "continue": true
42
67
  }
43
68
  EOF
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Aircana
4
- VERSION = "1.2.0"
4
+ VERSION = "1.4.0.rc1"
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aircana
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.4.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Weston Dransfield
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-09-26 00:00:00.000000000 Z
10
+ date: 2025-09-27 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: httparty
@@ -130,9 +130,7 @@ files:
130
130
  - lib/aircana/cli/commands/generate.rb
131
131
  - lib/aircana/cli/commands/hooks.rb
132
132
  - lib/aircana/cli/commands/install.rb
133
- - lib/aircana/cli/commands/plan.rb
134
133
  - lib/aircana/cli/commands/project.rb
135
- - lib/aircana/cli/commands/work.rb
136
134
  - lib/aircana/cli/help_formatter.rb
137
135
  - lib/aircana/cli/shell_command.rb
138
136
  - lib/aircana/cli/subcommand.rb
@@ -163,9 +161,9 @@ files:
163
161
  - lib/aircana/system_checker.rb
164
162
  - lib/aircana/templates/agents/base_agent.erb
165
163
  - lib/aircana/templates/agents/defaults/planner.erb
166
- - lib/aircana/templates/agents/defaults/worker.erb
167
164
  - lib/aircana/templates/commands/add_relevant_files.erb
168
165
  - lib/aircana/templates/hooks/bundle_install.erb
166
+ - lib/aircana/templates/hooks/notification_sqs.erb
169
167
  - lib/aircana/templates/hooks/post_tool_use.erb
170
168
  - lib/aircana/templates/hooks/pre_tool_use.erb
171
169
  - lib/aircana/templates/hooks/rspec_test.erb
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "generate"
4
- require_relative "install"
5
- require_relative "../../generators/agents_generator"
6
-
7
- module Aircana
8
- module CLI
9
- module Plan
10
- class << self
11
- def run
12
- ensure_planner_agent_installed
13
- launch_claude_with_planner
14
- end
15
-
16
- private
17
-
18
- def ensure_planner_agent_installed
19
- planner_agent_path = File.join(
20
- Aircana.configuration.claude_code_config_path,
21
- "agents",
22
- "planner.md"
23
- )
24
-
25
- return if File.exist?(planner_agent_path)
26
-
27
- Aircana.human_logger.info("Planner agent not found. Generating and installing...")
28
- Generate.run
29
- Install.run
30
- end
31
-
32
- def launch_claude_with_planner
33
- prompt = "Start a planning session with the 'planner' sub-agent"
34
-
35
- Aircana.human_logger.info("Launching Claude Code with planner agent...")
36
-
37
- claude_path = find_claude_path
38
- if claude_path
39
- system("#{claude_path} \"#{prompt}\"")
40
- else
41
- handle_claude_not_found(prompt)
42
- end
43
- end
44
-
45
- def handle_claude_not_found(prompt)
46
- error_message = "Claude Code command not found. " \
47
- "Please make sure Claude Code is installed and in your PATH."
48
- Aircana.human_logger.error(error_message)
49
- Aircana.human_logger.info("You can manually start Claude Code and run: #{prompt}")
50
- end
51
-
52
- def find_claude_path
53
- # Try common locations for Claude Code binary (same as ClaudeClient)
54
- possible_paths = [
55
- File.expand_path("~/.claude/local/claude"),
56
- `/usr/bin/which claude`.strip,
57
- "/usr/local/bin/claude"
58
- ]
59
-
60
- possible_paths.each do |path|
61
- return path if !path.empty? && File.executable?(path)
62
- end
63
-
64
- nil
65
- end
66
- end
67
- end
68
- end
69
- end