aircana 4.0.0.rc2 → 4.0.0.rc4

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.
data/README.md CHANGED
@@ -549,15 +549,15 @@ export AWS_REGION="us-east-1"
549
549
 
550
550
  The message template supports `{{message}}` placeholder which gets replaced with the Claude Code notification text.
551
551
 
552
- #### 3. Install and Enable Hook
552
+ #### 3. Initialize Plugin
553
+
554
+ The notification_sqs hook is automatically generated when you initialize your plugin:
553
555
 
554
556
  ```bash
555
- aircana generate
556
557
  aircana init
557
- aircana hooks enable notification_sqs
558
558
  ```
559
559
 
560
- Reload your shell or run `source ~/.zshrc` (or your shell config file).
560
+ The hook will be automatically enabled and ready to use.
561
561
 
562
562
  ### Verify Configuration
563
563
 
@@ -590,15 +590,6 @@ aircana kb add-url [KB-NAME] [URL] # Add a web URL to a knowledge base
590
590
  aircana kb list # List all configured knowledge bases
591
591
  ```
592
592
 
593
- ### Hook Management
594
- ```bash
595
- aircana hooks list # List all available and installed hooks
596
- aircana hooks enable [HOOK] # Enable a specific hook
597
- aircana hooks disable [HOOK] # Disable a specific hook
598
- aircana hooks create # Create custom hook
599
- aircana hooks status # Show hook configuration status
600
- ```
601
-
602
593
  ### System
603
594
  ```bash
604
595
  aircana generate # Generate plugin components from templates
@@ -10,7 +10,6 @@ require_relative "commands/init"
10
10
  require_relative "subcommand"
11
11
  require_relative "help_formatter"
12
12
  require_relative "commands/kb"
13
- require_relative "commands/hooks"
14
13
  require_relative "commands/plugin"
15
14
 
16
15
  module Aircana
@@ -74,39 +73,9 @@ module Aircana
74
73
  end
75
74
  end
76
75
 
77
- class HooksSubcommand < Subcommand
78
- desc "list", "List all available and installed hooks"
79
- def list
80
- Hooks.list
81
- end
82
-
83
- desc "enable HOOK_NAME", "Enable a specific hook"
84
- def enable(hook_name)
85
- Hooks.enable(hook_name)
86
- end
87
-
88
- desc "disable HOOK_NAME", "Disable a specific hook"
89
- def disable(hook_name)
90
- Hooks.disable(hook_name)
91
- end
92
-
93
- desc "create", "Create a new custom hook"
94
- def create
95
- Hooks.create
96
- end
97
-
98
- desc "status", "Show current hook configuration status"
99
- def status
100
- Hooks.status
101
- end
102
- end
103
-
104
76
  desc "kb", "Create and manage knowledge bases for Claude Code skills"
105
77
  subcommand "kb", KBSubcommand
106
78
 
107
- desc "hooks", "Manage Claude Code hooks"
108
- subcommand "hooks", HooksSubcommand
109
-
110
79
  class PluginSubcommand < Subcommand
111
80
  desc "info", "Display plugin information"
112
81
  def info
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../../generators/plan_command_generator"
4
- require_relative "../../generators/record_command_generator"
5
- require_relative "../../generators/execute_command_generator"
6
- require_relative "../../generators/review_command_generator"
7
- require_relative "../../generators/apply_feedback_command_generator"
8
- require_relative "../../generators/ask_expert_command_generator"
3
+ # Commands that reference old agent system - commented out for now
4
+ # require_relative "../../generators/plan_command_generator"
5
+ # require_relative "../../generators/record_command_generator"
6
+ # require_relative "../../generators/execute_command_generator"
7
+ # require_relative "../../generators/review_command_generator"
8
+ # require_relative "../../generators/apply_feedback_command_generator"
9
+ # require_relative "../../generators/ask_expert_command_generator"
9
10
  require_relative "../../generators/hooks_generator"
10
11
 
11
12
  module Aircana
@@ -13,14 +14,18 @@ module Aircana
13
14
  module Generate
14
15
  class << self
15
16
  def generators
16
- @generators ||= [
17
- Aircana::Generators::PlanCommandGenerator.new,
18
- Aircana::Generators::RecordCommandGenerator.new,
19
- Aircana::Generators::ExecuteCommandGenerator.new,
20
- Aircana::Generators::ReviewCommandGenerator.new,
21
- Aircana::Generators::ApplyFeedbackCommandGenerator.new,
22
- Aircana::Generators::AskExpertCommandGenerator.new
23
- ]
17
+ # No default commands for now - they referenced the old agent system
18
+ @generators ||= []
19
+
20
+ # TODO: Re-enable these when we have a new command system
21
+ # @generators ||= [
22
+ # Aircana::Generators::PlanCommandGenerator.new,
23
+ # Aircana::Generators::RecordCommandGenerator.new,
24
+ # Aircana::Generators::ExecuteCommandGenerator.new,
25
+ # Aircana::Generators::ReviewCommandGenerator.new,
26
+ # Aircana::Generators::ApplyFeedbackCommandGenerator.new,
27
+ # Aircana::Generators::AskExpertCommandGenerator.new
28
+ # ]
24
29
  end
25
30
 
26
31
  def run
@@ -57,10 +57,10 @@ module Aircana
57
57
  Aircana.configuration.instance_variable_set(:@plugin_manifest_dir,
58
58
  File.join(target_dir, ".claude-plugin"))
59
59
  Aircana.configuration.instance_variable_set(:@commands_dir, File.join(target_dir, "commands"))
60
- Aircana.configuration.instance_variable_set(:@agents_dir, File.join(target_dir, "agents"))
60
+ Aircana.configuration.instance_variable_set(:@skills_dir, File.join(target_dir, "skills"))
61
+ Aircana.configuration.instance_variable_set(:@kb_knowledge_dir, File.join(target_dir, "skills"))
61
62
  Aircana.configuration.instance_variable_set(:@hooks_dir, File.join(target_dir, "hooks"))
62
63
  Aircana.configuration.instance_variable_set(:@scripts_dir, File.join(target_dir, "scripts"))
63
- Aircana.configuration.instance_variable_set(:@agent_knowledge_dir, File.join(target_dir, "agents"))
64
64
 
65
65
  yield
66
66
  ensure
@@ -71,11 +71,17 @@ module Aircana
71
71
  File.join(original_plugin_root, ".claude-plugin"))
72
72
  Aircana.configuration.instance_variable_set(:@commands_dir,
73
73
  File.join(original_plugin_root, "commands"))
74
- Aircana.configuration.instance_variable_set(:@agents_dir, File.join(original_plugin_root, "agents"))
74
+ # Restore skills_dir based on whether original_plugin_root is a plugin
75
+ original_plugin_mode = File.exist?(File.join(original_plugin_root, ".claude-plugin", "plugin.json"))
76
+ original_skills_dir = if original_plugin_mode
77
+ File.join(original_plugin_root, "skills")
78
+ else
79
+ File.join(original_plugin_root, ".claude", "skills")
80
+ end
81
+ Aircana.configuration.instance_variable_set(:@skills_dir, original_skills_dir)
82
+ Aircana.configuration.instance_variable_set(:@kb_knowledge_dir, original_skills_dir)
75
83
  Aircana.configuration.instance_variable_set(:@hooks_dir, File.join(original_plugin_root, "hooks"))
76
84
  Aircana.configuration.instance_variable_set(:@scripts_dir, File.join(original_plugin_root, "scripts"))
77
- Aircana.configuration.instance_variable_set(:@agent_knowledge_dir,
78
- File.join(original_plugin_root, "agents"))
79
85
  end
80
86
  end
81
87
 
@@ -109,7 +115,7 @@ module Aircana
109
115
 
110
116
  def create_plugin_structure(target_dir)
111
117
  # Create plugin directories
112
- [".claude-plugin", "commands", "agents", "hooks", "scripts"].each do |dir|
118
+ [".claude-plugin", "commands", "agents", "skills", "hooks", "scripts"].each do |dir|
113
119
  dir_path = File.join(target_dir, dir)
114
120
  Aircana.create_dir_if_needed(dir_path)
115
121
  Aircana.human_logger.info("Created directory: #{dir}/")
@@ -132,7 +138,6 @@ module Aircana
132
138
  Aircana.create_dir_if_needed(commands_dir)
133
139
 
134
140
  copy_command_files(commands_dir)
135
- install_default_agents
136
141
  end
137
142
 
138
143
  def copy_command_files(destination_dir)
@@ -142,33 +147,6 @@ module Aircana
142
147
  end
143
148
  end
144
149
 
145
- def install_default_agents
146
- agents_dir = Aircana.configuration.agents_dir
147
- Aircana.create_dir_if_needed(agents_dir)
148
-
149
- copy_agent_files(agents_dir)
150
- end
151
-
152
- def copy_agent_files(destination_dir)
153
- agent_files_pattern = File.join(Aircana.configuration.output_dir, "agents", "*.md")
154
- Dir.glob(agent_files_pattern).each do |file|
155
- agent_name = File.basename(file, ".md")
156
- next unless default_agent?(agent_name)
157
-
158
- destination_file = File.join(destination_dir, File.basename(file))
159
- # Skip copying if source and destination are the same
160
- next if File.expand_path(file) == File.expand_path(destination_file)
161
-
162
- Aircana.human_logger.success("Installing default agent: #{agent_name}")
163
- FileUtils.cp(file, destination_dir)
164
- end
165
- end
166
-
167
- def default_agent?(agent_name)
168
- require_relative "../../generators/agents_generator"
169
- Aircana::Generators::AgentsGenerator.available_default_agents.include?(agent_name)
170
- end
171
-
172
150
  def install_hooks
173
151
  scripts_dir = Aircana.configuration.scripts_dir
174
152
  return unless Dir.exist?(scripts_dir)
@@ -201,7 +179,7 @@ module Aircana
201
179
  "post_tool_use" => { event: "PostToolUse", matcher: nil },
202
180
  "user_prompt_submit" => { event: "UserPromptSubmit", matcher: nil },
203
181
  "session_start" => { event: "SessionStart", matcher: nil },
204
- "refresh_agents" => { event: "SessionStart", matcher: nil },
182
+ "refresh_skills" => { event: "SessionStart", matcher: nil },
205
183
  "notification_sqs" => { event: "Notification", matcher: nil },
206
184
  "rubocop_pre_commit" => { event: "PreToolUse", matcher: "Bash" },
207
185
  "rspec_test" => { event: "PostToolUse", matcher: "Bash" },
@@ -265,11 +243,12 @@ module Aircana
265
243
  Aircana.human_logger.info("\nPlugin structure:")
266
244
  Aircana.human_logger.info(" .claude-plugin/plugin.json - Plugin metadata")
267
245
  Aircana.human_logger.info(" commands/ - Slash commands")
268
- Aircana.human_logger.info(" agents/ - Specialized agents")
246
+ Aircana.human_logger.info(" agents/ - Knowledge base manifests")
247
+ Aircana.human_logger.info(" skills/ - Knowledge base SKILL.md files")
269
248
  Aircana.human_logger.info(" hooks/ - Event hook configurations")
270
249
  Aircana.human_logger.info(" scripts/ - Hook scripts and utilities")
271
250
  Aircana.human_logger.info("\nNext steps:")
272
- Aircana.human_logger.info(" - Create agents: aircana agents create")
251
+ Aircana.human_logger.info(" - Create knowledge bases: aircana kb create")
273
252
  Aircana.human_logger.info(" - Install plugin in Claude Code")
274
253
  Aircana.human_logger.info(" - Run: aircana plugin info")
275
254
  end
@@ -284,11 +284,21 @@ module Aircana
284
284
  end
285
285
 
286
286
  def remote_knowledge_pattern
287
- ".claude/skills/*/*.md"
287
+ # Pattern depends on whether we're in a plugin
288
+ if Aircana.configuration.plugin_mode?
289
+ "skills/*/*.md"
290
+ else
291
+ ".claude/skills/*/*.md"
292
+ end
288
293
  end
289
294
 
290
295
  def local_knowledge_negation_pattern
291
- "!.claude/skills/*/*.md"
296
+ # Negation pattern depends on whether we're in a plugin
297
+ if Aircana.configuration.plugin_mode?
298
+ "!skills/*/*.md"
299
+ else
300
+ "!.claude/skills/*/*.md"
301
+ end
292
302
  end
293
303
 
294
304
  def gitignore_has_pattern?(gitignore_path, pattern)
@@ -24,8 +24,7 @@ module Aircana
24
24
  def command_groups
25
25
  {
26
26
  "Knowledge Base Management" => %w[kb],
27
- "Hook Management" => %w[hooks],
28
- "System" => %w[generate init doctor dump-context]
27
+ "System" => %w[init doctor]
29
28
  }
30
29
  end
31
30
 
@@ -69,17 +69,28 @@ module Aircana
69
69
  @output_dir = File.join(@global_dir, "aircana.out")
70
70
  end
71
71
 
72
+ # rubocop:disable Metrics/MethodLength
72
73
  def setup_plugin_paths
73
74
  # Plugin root can be set via AIRCANA_PLUGIN_ROOT (for hooks) or CLAUDE_PLUGIN_ROOT,
74
75
  # otherwise defaults to the current project directory
75
76
  @plugin_root = ENV.fetch("AIRCANA_PLUGIN_ROOT", ENV.fetch("CLAUDE_PLUGIN_ROOT", @project_dir))
76
77
  @plugin_manifest_dir = File.join(@plugin_root, ".claude-plugin")
77
78
  @commands_dir = File.join(@plugin_root, "commands")
78
- @skills_dir = File.join(@plugin_root, ".claude", "skills")
79
+
80
+ # Skills directory location depends on whether we're in a plugin
81
+ # Plugin mode: skills/ (Claude Code standard location)
82
+ # Non-plugin mode: .claude/skills/ (local development/one-off usage)
83
+ @skills_dir = if plugin_mode?
84
+ File.join(@plugin_root, "skills")
85
+ else
86
+ File.join(@plugin_root, ".claude", "skills")
87
+ end
88
+
79
89
  @hooks_dir = File.join(@plugin_root, "hooks")
80
90
  @scripts_dir = File.join(@plugin_root, "scripts")
81
91
  @kb_knowledge_dir = @skills_dir
82
92
  end
93
+ # rubocop:enable Metrics/MethodLength
83
94
 
84
95
  def setup_claude_code_paths
85
96
  @claude_code_config_path = File.join(Dir.home, ".claude")
@@ -11,7 +11,7 @@ module Aircana
11
11
  post_tool_use
12
12
  user_prompt_submit
13
13
  session_start
14
- refresh_agents
14
+ refresh_skills
15
15
  notification_sqs
16
16
  rubocop_pre_commit
17
17
  rspec_test
@@ -21,7 +21,7 @@ module Aircana
21
21
  # Default hooks that are auto-installed
22
22
  DEFAULT_HOOK_TYPES = %w[
23
23
  session_start
24
- refresh_agents
24
+ refresh_skills
25
25
  notification_sqs
26
26
  ].freeze
27
27
 
@@ -0,0 +1,121 @@
1
+ #!/bin/bash
2
+ # Auto-refresh remote knowledge bases on session start
3
+ # Runs at most once per 24 hours to avoid API rate limits
4
+ # Only refreshes remote KBs, skips local KBs
5
+
6
+ set -e
7
+
8
+ # Create log directory if it doesn't exist
9
+ mkdir -p ~/.aircana
10
+ LOG_FILE="$HOME/.aircana/hooks.log"
11
+
12
+ # Claude Code provides this environment variable
13
+ PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"
14
+
15
+ if [ -z "$PLUGIN_ROOT" ]; then
16
+ echo "$(date): Warning - CLAUDE_PLUGIN_ROOT not set, skipping KB refresh" >> "$LOG_FILE"
17
+ echo "{}"
18
+ exit 0
19
+ fi
20
+
21
+ TIMESTAMP_FILE="${PLUGIN_ROOT}/.last_refresh"
22
+ REFRESH_INTERVAL_SECONDS=86400 # 24 hours
23
+
24
+ # Check if we've refreshed recently
25
+ if [ -f "$TIMESTAMP_FILE" ]; then
26
+ LAST_REFRESH=$(cat "$TIMESTAMP_FILE")
27
+ CURRENT_TIME=$(date +%s)
28
+ TIME_DIFF=$((CURRENT_TIME - LAST_REFRESH))
29
+
30
+ if [ $TIME_DIFF -lt $REFRESH_INTERVAL_SECONDS ]; then
31
+ HOURS_SINCE=$((TIME_DIFF / 3600))
32
+ echo "$(date): Knowledge bases refreshed ${HOURS_SINCE}h ago, skipping refresh" >> "$LOG_FILE"
33
+ echo "{}"
34
+ exit 0
35
+ fi
36
+ fi
37
+
38
+ # Tell aircana where the plugin lives
39
+ export AIRCANA_PLUGIN_ROOT="$PLUGIN_ROOT"
40
+
41
+ echo "$(date): Starting knowledge base refresh from plugin root: $PLUGIN_ROOT" >> "$LOG_FILE"
42
+
43
+ # Find all knowledge bases in agents directory
44
+ AGENTS_DIR="${PLUGIN_ROOT}/agents"
45
+
46
+ if [ ! -d "$AGENTS_DIR" ]; then
47
+ echo "$(date): No agents directory found, skipping refresh" >> "$LOG_FILE"
48
+ echo "{}"
49
+ exit 0
50
+ fi
51
+
52
+ # Track if we refreshed any KBs
53
+ REFRESHED_COUNT=0
54
+ SKIPPED_COUNT=0
55
+
56
+ # Iterate through each KB directory
57
+ for kb_dir in "${AGENTS_DIR}"/*/ ; do
58
+ # Skip if no directories found
59
+ [ -d "$kb_dir" ] || continue
60
+
61
+ kb_name=$(basename "$kb_dir")
62
+ manifest_file="${kb_dir}manifest.json"
63
+
64
+ # Skip if no manifest exists
65
+ if [ ! -f "$manifest_file" ]; then
66
+ echo "$(date): No manifest found for KB '$kb_name', skipping" >> "$LOG_FILE"
67
+ continue
68
+ fi
69
+
70
+ # Determine KB type from manifest (default to remote if not specified)
71
+ kb_type="remote"
72
+
73
+ # Try to parse with jq if available, otherwise use grep
74
+ if command -v jq >/dev/null 2>&1; then
75
+ kb_type=$(jq -r '.kb_type // "remote"' "$manifest_file" 2>/dev/null || echo "remote")
76
+ else
77
+ # Fallback: grep for kb_type field
78
+ if grep -q '"kb_type"[[:space:]]*:[[:space:]]*"local"' "$manifest_file" 2>/dev/null; then
79
+ kb_type="local"
80
+ fi
81
+ fi
82
+
83
+ # Only refresh remote KBs
84
+ if [ "$kb_type" = "local" ]; then
85
+ echo "$(date): Skipping local KB '$kb_name'" >> "$LOG_FILE"
86
+ SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
87
+ continue
88
+ fi
89
+
90
+ # Refresh remote KB
91
+ echo "$(date): Refreshing remote KB '$kb_name'" >> "$LOG_FILE"
92
+ if aircana kb refresh "$kb_name" >> "$LOG_FILE" 2>&1; then
93
+ echo "$(date): Successfully refreshed KB '$kb_name'" >> "$LOG_FILE"
94
+ REFRESHED_COUNT=$((REFRESHED_COUNT + 1))
95
+ else
96
+ echo "$(date): Warning - Failed to refresh KB '$kb_name'" >> "$LOG_FILE"
97
+ fi
98
+ done
99
+
100
+ # Update timestamp on completion (even if some refreshes failed)
101
+ date +%s > "$TIMESTAMP_FILE"
102
+
103
+ # Log summary
104
+ echo "$(date): KB refresh completed - refreshed: $REFRESHED_COUNT, skipped (local): $SKIPPED_COUNT" >> "$LOG_FILE"
105
+
106
+ # Return success with context
107
+ if [ $REFRESHED_COUNT -gt 0 ]; then
108
+ CONTEXT="Refreshed $REFRESHED_COUNT remote knowledge base(s)"
109
+ else
110
+ CONTEXT="No remote knowledge bases to refresh"
111
+ fi
112
+
113
+ ESCAPED_CONTEXT=$(echo -n "$CONTEXT" | sed 's/"/\\"/g')
114
+ cat << EOF
115
+ {
116
+ "hookSpecificOutput": {
117
+ "hookEventName": "SessionStart",
118
+ "additionalContext": "$ESCAPED_CONTEXT"
119
+ }
120
+ }
121
+ EOF
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Aircana
4
- VERSION = "4.0.0.rc2"
4
+ VERSION = "4.0.0.rc4"
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: 4.0.0.rc2
4
+ version: 4.0.0.rc4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Weston Dransfield
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-10-17 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: httparty
@@ -115,15 +115,8 @@ files:
115
115
  - README.md
116
116
  - Rakefile
117
117
  - SECURITY.md
118
- - commands/apply-feedback.md
119
- - commands/ask-expert.md
120
- - commands/execute.md
121
- - commands/plan.md
122
- - commands/record.md
123
- - commands/review.md
124
118
  - compose.yml
125
119
  - exe/aircana
126
- - hooks/hooks.json
127
120
  - lib/aircana.rb
128
121
  - lib/aircana/cli.rb
129
122
  - lib/aircana/cli/app.rb
@@ -132,7 +125,6 @@ files:
132
125
  - lib/aircana/cli/commands/doctor_helpers.rb
133
126
  - lib/aircana/cli/commands/dump_context.rb
134
127
  - lib/aircana/cli/commands/generate.rb
135
- - lib/aircana/cli/commands/hooks.rb
136
128
  - lib/aircana/cli/commands/init.rb
137
129
  - lib/aircana/cli/commands/kb.rb
138
130
  - lib/aircana/cli/commands/plugin.rb
@@ -177,6 +169,7 @@ files:
177
169
  - lib/aircana/templates/hooks/notification_sqs.erb
178
170
  - lib/aircana/templates/hooks/post_tool_use.erb
179
171
  - lib/aircana/templates/hooks/pre_tool_use.erb
172
+ - lib/aircana/templates/hooks/refresh_skills.erb
180
173
  - lib/aircana/templates/hooks/rspec_test.erb
181
174
  - lib/aircana/templates/hooks/rubocop_pre_commit.erb
182
175
  - lib/aircana/templates/hooks/session_start.erb
@@ -207,7 +200,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
207
200
  - !ruby/object:Gem::Version
208
201
  version: '0'
209
202
  requirements: []
210
- rubygems_version: 3.6.2
203
+ rubygems_version: 3.6.9
211
204
  specification_version: 4
212
205
  summary: CLI for creating and managing Claude Code plugins with per-agent knowledge
213
206
  bases
@@ -1,15 +0,0 @@
1
- INSTRUCTIONS : Use the Task tool with subagent_type 'apply-feedback' to apply code review feedback from the previous /air-review command.
2
-
3
- Pass the review feedback from the conversation context to the apply-feedback agent.
4
-
5
- The apply-feedback agent will:
6
- 1. Parse review feedback from the previous review
7
- 2. Create todo list of changes prioritized by severity
8
- 3. Present plan to user for approval
9
- 4. Apply approved changes
10
- 5. Re-run unit tests to verify changes
11
- 6. Fix any test failures
12
- 7. Amend the HEAD commit with improvements using 'git commit --amend --no-edit'
13
- 8. Summarize changes made
14
-
15
- IMPORTANT: This command reads the review output from the conversation context, so it must be run in the same conversation as /air-review.
@@ -1,42 +0,0 @@
1
- INSTRUCTIONS : You are coordinating expert consultation to answer a question by leveraging multiple specialized sub-agents. Follow this precise workflow:
2
-
3
- STEP 1: QUESTION VALIDATION
4
- Ask the user: \"What is your question?\" and wait for their response before proceeding.
5
-
6
- STEP 2: COORDINATION PHASE
7
- Use the Task tool with subagent_type 'sub-agent-coordinator' to analyze the question and identify relevant sub-agents. Provide the coordinator with the complete question context.
8
-
9
- STEP 3: PARALLEL EXPERT CONSULTATION
10
- Based on the coordinator's recommendations, use the Task tool to consult each identified relevant sub-agent in parallel. For each agent:
11
- - Use the appropriate subagent_type for each recommended agent
12
- - Provide the original question plus any agent-specific context the coordinator suggested
13
- - Execute multiple Task tool calls in a single message for parallel processing
14
-
15
- STEP 4: SYNTHESIS AND RESPONSE
16
- After receiving responses from all consulted agents:
17
- - Analyze and synthesize the expert feedback
18
- - Identify common themes, conflicting viewpoints, and complementary insights
19
- - Provide a comprehensive answer that leverages the collective expertise
20
- - Cite which agents contributed specific insights where relevant
21
- - Note any areas where experts disagreed and provide your assessment
22
-
23
- STEP 5: FOLLOW-UP GUIDANCE
24
- If the question requires further clarification or the expert responses suggest additional considerations:
25
- - Suggest specific follow-up questions
26
- - Recommend additional agents to consult if needed
27
- - Provide guidance on next steps based on the expert consensus
28
-
29
- IMPORTANT EXECUTION NOTES:
30
- - Always start with the sub-agent-coordinator for proper agent selection
31
- - Use parallel Task tool execution when consulting multiple agents (single message with multiple tool calls)
32
- - Ensure each agent receives context appropriate to their expertise domain
33
- - Synthesize responses rather than simply concatenating them
34
- - Maintain focus on providing actionable, comprehensive answers
35
-
36
- EXAMPLE PARALLEL EXECUTION:
37
- If coordinator recommends agents A, B, and C, send one message with three Task tool calls:
38
- 1. Task(subagent_type='agent-A', prompt='[question + A-specific context]')
39
- 2. Task(subagent_type='agent-B', prompt='[question + B-specific context]')
40
- 3. Task(subagent_type='agent-C', prompt='[question + C-specific context]')
41
-
42
- This approach ensures you leverage the full expertise available while maintaining efficient coordination.
data/commands/execute.md DELETED
@@ -1,13 +0,0 @@
1
- INSTRUCTIONS : Use the Task tool with subagent_type 'executor' to execute the implementation plan from a Jira ticket.
2
-
3
- INSTRUCTIONS FOR EXECUTOR AGENT:
4
- Ask the user to provide a Jira ticket key/ID to execute.
5
-
6
- The executor agent will:
7
- 1. Read the plan from the Jira ticket via the 'jira' sub-agent
8
- 2. Review and validate the plan structure
9
- 3. Create a detailed execution todo list in Claude Code planning mode
10
- 4. Present the plan for your approval
11
- 5. Execute the approved implementation tasks
12
-
13
- IMPORTANT: All Jira operations are delegated to the 'jira' sub-agent using Task tool with subagent_type 'jira'.
data/commands/plan.md DELETED
@@ -1,33 +0,0 @@
1
- INSTRUCTIONS : First, ask the user to specify relevant files, directories, or areas of the codebase to examine for this planning task.
2
-
3
- Then use the Task tool with subagent_type 'planner' to invoke the planner agent with the following explicit instructions:
4
-
5
- STEP 1: CREATE TODO LIST FILE
6
- First, create a todo list file with the following tasks enumerated in order:
7
-
8
- 1. Ask user for relevant files and context (if not already provided)
9
- 2. Use Task tool with subagent_type 'jira' to verify Jira ticket information (or ask user to create/provide ticket)
10
- 3. Perform targeted initial research on user-specified files
11
- 4. Consult relevant sub-agents with research context (run in parallel when possible)
12
- 5. Create high-level strategic implementation plan
13
- 6. Iterate with user feedback
14
- 7. Suggest user runs '/air-record' command to save the plan to Jira ticket
15
-
16
- STEP 2: EXECUTE EACH TASK IN ORDER
17
- Work through each task in the todo list sequentially:
18
- - Mark each task as 'in_progress' when you start it
19
- - Mark each task as 'completed' when finished
20
- - Continue until all tasks are done
21
-
22
- IMPORTANT CONTEXT-SHARING PROTOCOL:
23
- - When consulting sub-agents, explicitly provide: files already searched, files already read, key findings, and specific focus area
24
- - This prevents sub-agents from duplicating research work
25
-
26
- IMPORTANT PLAN CONSTRAINTS:
27
- - Focus on strategic, high-level implementation guidance
28
- - NO rollout plans, effort estimates, or exhaustive code implementations
29
- - Small code examples (5-10 lines) are OK to illustrate concepts
30
-
31
- User specified relevant files/areas: [User will specify]
32
-
33
- Ask the user to provide a Jira ticket or task description.
data/commands/record.md DELETED
@@ -1,17 +0,0 @@
1
- INSTRUCTIONS : Use the Task tool with subagent_type 'jira' to append the implementation plan to the Jira ticket description using Jira MCP tools.
2
-
3
- INSTRUCTIONS FOR JIRA AGENT:
4
- 1. Read the implementation plan from the current context (look for recent planning output)
5
- 2. Get the current ticket description using mcp__jira__getJiraIssue with fields=["description"]
6
- 3. Append the plan to the existing description under a new "## Implementation Plan" heading
7
- 4. Update the ticket using mcp__jira__editJiraIssue with the combined description
8
- 5. Format the appended plan section with:
9
- - Consulted sub-agents
10
- - Relevant files analyzed
11
- - Planning timestamp
12
- - Implementation steps as todo list using `[ ]` format
13
- 6. Provide the ticket URL for easy access
14
-
15
- CRITICAL: The jira sub-agent must append to the ticket description using mcp__jira__editJiraIssue (NOT create files or comments).
16
-
17
- IMPORTANT: Delegate all Jira operations to the 'jira' sub-agent using Task tool with subagent_type 'jira'. The Jira ticket key/ID is already in context.
data/commands/review.md DELETED
@@ -1,12 +0,0 @@
1
- INSTRUCTIONS : Use the Task tool with subagent_type 'reviewer' to conduct an adversarial code review of the HEAD commit.
2
-
3
- The reviewer agent will:
4
- 1. Get HEAD commit details and changes
5
- 2. Analyze changed files to identify technical domains
6
- 3. Use the sub-agent-coordinator to select relevant expert agents
7
- 4. Present changes to experts in parallel for review
8
- 5. Synthesize feedback organized by severity
9
- 6. Store review output for the apply-feedback command
10
- 7. Suggest running '/air-apply-feedback' to apply recommended changes
11
-
12
- IMPORTANT: The review agent will automatically review the HEAD commit. No arguments needed.