claude_swarm 1.0.1 → 1.0.2
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/.claude/commands/release.md +1 -1
- data/.claude/hooks/lint-code-files.rb +65 -0
- data/.rubocop.yml +22 -2
- data/CHANGELOG.md +14 -1
- data/CLAUDE.md +1 -1
- data/CONTRIBUTING.md +69 -0
- data/README.md +27 -2
- data/Rakefile +71 -3
- data/analyze_coverage.rb +94 -0
- data/docs/v2/CHANGELOG.swarm_cli.md +43 -0
- data/docs/v2/CHANGELOG.swarm_memory.md +379 -0
- data/docs/v2/CHANGELOG.swarm_sdk.md +362 -0
- data/docs/v2/README.md +308 -0
- data/docs/v2/guides/claude-code-agents.md +262 -0
- data/docs/v2/guides/complete-tutorial.md +3088 -0
- data/docs/v2/guides/getting-started.md +1456 -0
- data/docs/v2/guides/memory-adapters.md +998 -0
- data/docs/v2/guides/plugins.md +816 -0
- data/docs/v2/guides/quick-start-cli.md +1745 -0
- data/docs/v2/guides/rails-integration.md +1902 -0
- data/docs/v2/guides/swarm-memory.md +599 -0
- data/docs/v2/reference/cli.md +729 -0
- data/docs/v2/reference/ruby-dsl.md +2154 -0
- data/docs/v2/reference/yaml.md +1835 -0
- data/docs-team-swarm.yml +2222 -0
- data/examples/learning-assistant/assistant.md +7 -0
- data/examples/learning-assistant/example-memories/concept-example.md +90 -0
- data/examples/learning-assistant/example-memories/experience-example.md +66 -0
- data/examples/learning-assistant/example-memories/fact-example.md +76 -0
- data/examples/learning-assistant/example-memories/memory-index.md +78 -0
- data/examples/learning-assistant/example-memories/skill-example.md +168 -0
- data/examples/learning-assistant/learning_assistant.rb +34 -0
- data/examples/learning-assistant/learning_assistant.yml +20 -0
- data/examples/v2/dsl/01_basic.rb +44 -0
- data/examples/v2/dsl/02_core_parameters.rb +59 -0
- data/examples/v2/dsl/03_capabilities.rb +71 -0
- data/examples/v2/dsl/04_llm_parameters.rb +56 -0
- data/examples/v2/dsl/05_advanced_flags.rb +73 -0
- data/examples/v2/dsl/06_permissions.rb +80 -0
- data/examples/v2/dsl/07_mcp_server.rb +62 -0
- data/examples/v2/dsl/08_swarm_hooks.rb +53 -0
- data/examples/v2/dsl/09_agent_hooks.rb +67 -0
- data/examples/v2/dsl/10_all_agents_hooks.rb +67 -0
- data/examples/v2/dsl/11_delegation.rb +60 -0
- data/examples/v2/dsl/12_complete_integration.rb +137 -0
- data/examples/v2/file_tools_swarm.yml +102 -0
- data/examples/v2/hooks/01_basic_hooks.rb +133 -0
- data/examples/v2/hooks/02_usage_tracking.rb +201 -0
- data/examples/v2/hooks/03_production_monitoring.rb +429 -0
- data/examples/v2/hooks/agent_stop_exit_0.yml +21 -0
- data/examples/v2/hooks/agent_stop_exit_1.yml +21 -0
- data/examples/v2/hooks/agent_stop_exit_2.yml +26 -0
- data/examples/v2/hooks/multiple_hooks_all_pass.yml +37 -0
- data/examples/v2/hooks/multiple_hooks_first_fails.yml +37 -0
- data/examples/v2/hooks/multiple_hooks_second_fails.yml +37 -0
- data/examples/v2/hooks/multiple_hooks_warnings.yml +37 -0
- data/examples/v2/hooks/post_tool_use_exit_0.yml +24 -0
- data/examples/v2/hooks/post_tool_use_exit_1.yml +24 -0
- data/examples/v2/hooks/post_tool_use_exit_2.yml +24 -0
- data/examples/v2/hooks/post_tool_use_multi_matcher_exit_0.yml +26 -0
- data/examples/v2/hooks/post_tool_use_multi_matcher_exit_1.yml +26 -0
- data/examples/v2/hooks/post_tool_use_multi_matcher_exit_2.yml +26 -0
- data/examples/v2/hooks/pre_tool_use_exit_0.yml +24 -0
- data/examples/v2/hooks/pre_tool_use_exit_1.yml +24 -0
- data/examples/v2/hooks/pre_tool_use_exit_2.yml +24 -0
- data/examples/v2/hooks/pre_tool_use_multi_matcher_exit_0.yml +26 -0
- data/examples/v2/hooks/pre_tool_use_multi_matcher_exit_1.yml +26 -0
- data/examples/v2/hooks/pre_tool_use_multi_matcher_exit_2.yml +27 -0
- data/examples/v2/hooks/swarm_summary.sh +44 -0
- data/examples/v2/hooks/user_prompt_exit_0.yml +21 -0
- data/examples/v2/hooks/user_prompt_exit_1.yml +21 -0
- data/examples/v2/hooks/user_prompt_exit_2.yml +21 -0
- data/examples/v2/hooks/validate_bash.rb +59 -0
- data/examples/v2/multi_directory_permissions.yml +221 -0
- data/examples/v2/node_context_demo.rb +127 -0
- data/examples/v2/node_workflow.rb +173 -0
- data/examples/v2/path_resolution_demo.rb +216 -0
- data/examples/v2/simple-swarm-v2.rb +90 -0
- data/examples/v2/simple-swarm-v2.yml +62 -0
- data/examples/v2/swarm.yml +71 -0
- data/examples/v2/swarm_with_hooks.yml +61 -0
- data/examples/v2/swarm_with_hooks_simple.yml +25 -0
- data/examples/v2/think_tool_demo.rb +62 -0
- data/exe/swarm +6 -0
- data/lib/claude_swarm/claude_mcp_server.rb +0 -6
- data/lib/claude_swarm/cli.rb +10 -3
- data/lib/claude_swarm/commands/ps.rb +19 -20
- data/lib/claude_swarm/commands/show.rb +1 -1
- data/lib/claude_swarm/configuration.rb +10 -12
- data/lib/claude_swarm/mcp_generator.rb +10 -1
- data/lib/claude_swarm/orchestrator.rb +73 -49
- data/lib/claude_swarm/system_utils.rb +37 -11
- data/lib/claude_swarm/version.rb +1 -1
- data/lib/claude_swarm/worktree_manager.rb +1 -0
- data/lib/claude_swarm/yaml_loader.rb +22 -0
- data/lib/claude_swarm.rb +6 -2
- data/lib/swarm_cli/cli.rb +201 -0
- data/lib/swarm_cli/command_registry.rb +61 -0
- data/lib/swarm_cli/commands/mcp_serve.rb +130 -0
- data/lib/swarm_cli/commands/mcp_tools.rb +148 -0
- data/lib/swarm_cli/commands/migrate.rb +55 -0
- data/lib/swarm_cli/commands/run.rb +173 -0
- data/lib/swarm_cli/config_loader.rb +97 -0
- data/lib/swarm_cli/formatters/human_formatter.rb +711 -0
- data/lib/swarm_cli/formatters/json_formatter.rb +51 -0
- data/lib/swarm_cli/interactive_repl.rb +918 -0
- data/lib/swarm_cli/mcp_serve_options.rb +44 -0
- data/lib/swarm_cli/mcp_tools_options.rb +59 -0
- data/lib/swarm_cli/migrate_options.rb +54 -0
- data/lib/swarm_cli/migrator.rb +132 -0
- data/lib/swarm_cli/options.rb +151 -0
- data/lib/swarm_cli/ui/components/agent_badge.rb +33 -0
- data/lib/swarm_cli/ui/components/content_block.rb +120 -0
- data/lib/swarm_cli/ui/components/divider.rb +57 -0
- data/lib/swarm_cli/ui/components/panel.rb +62 -0
- data/lib/swarm_cli/ui/components/usage_stats.rb +70 -0
- data/lib/swarm_cli/ui/formatters/cost.rb +49 -0
- data/lib/swarm_cli/ui/formatters/number.rb +58 -0
- data/lib/swarm_cli/ui/formatters/text.rb +77 -0
- data/lib/swarm_cli/ui/formatters/time.rb +73 -0
- data/lib/swarm_cli/ui/icons.rb +59 -0
- data/lib/swarm_cli/ui/renderers/event_renderer.rb +188 -0
- data/lib/swarm_cli/ui/state/agent_color_cache.rb +45 -0
- data/lib/swarm_cli/ui/state/depth_tracker.rb +40 -0
- data/lib/swarm_cli/ui/state/spinner_manager.rb +170 -0
- data/lib/swarm_cli/ui/state/usage_tracker.rb +62 -0
- data/lib/swarm_cli/version.rb +5 -0
- data/lib/swarm_cli.rb +44 -0
- data/lib/swarm_memory/adapters/base.rb +141 -0
- data/lib/swarm_memory/adapters/filesystem_adapter.rb +845 -0
- data/lib/swarm_memory/chat_extension.rb +34 -0
- data/lib/swarm_memory/cli/commands.rb +306 -0
- data/lib/swarm_memory/core/entry.rb +37 -0
- data/lib/swarm_memory/core/frontmatter_parser.rb +108 -0
- data/lib/swarm_memory/core/metadata_extractor.rb +68 -0
- data/lib/swarm_memory/core/path_normalizer.rb +75 -0
- data/lib/swarm_memory/core/semantic_index.rb +244 -0
- data/lib/swarm_memory/core/storage.rb +288 -0
- data/lib/swarm_memory/core/storage_read_tracker.rb +63 -0
- data/lib/swarm_memory/dsl/builder_extension.rb +40 -0
- data/lib/swarm_memory/dsl/memory_config.rb +113 -0
- data/lib/swarm_memory/embeddings/embedder.rb +36 -0
- data/lib/swarm_memory/embeddings/informers_embedder.rb +152 -0
- data/lib/swarm_memory/errors.rb +21 -0
- data/lib/swarm_memory/integration/cli_registration.rb +30 -0
- data/lib/swarm_memory/integration/configuration.rb +43 -0
- data/lib/swarm_memory/integration/registration.rb +31 -0
- data/lib/swarm_memory/integration/sdk_plugin.rb +531 -0
- data/lib/swarm_memory/optimization/analyzer.rb +244 -0
- data/lib/swarm_memory/optimization/defragmenter.rb +863 -0
- data/lib/swarm_memory/prompts/memory.md.erb +109 -0
- data/lib/swarm_memory/prompts/memory_assistant.md.erb +181 -0
- data/lib/swarm_memory/prompts/memory_researcher.md.erb +281 -0
- data/lib/swarm_memory/prompts/memory_retrieval.md.erb +78 -0
- data/lib/swarm_memory/search/semantic_search.rb +112 -0
- data/lib/swarm_memory/search/text_search.rb +42 -0
- data/lib/swarm_memory/search/text_similarity.rb +80 -0
- data/lib/swarm_memory/skills/meta/deep-learning.md +101 -0
- data/lib/swarm_memory/skills/meta/deep-learning.yml +14 -0
- data/lib/swarm_memory/tools/load_skill.rb +313 -0
- data/lib/swarm_memory/tools/memory_defrag.rb +382 -0
- data/lib/swarm_memory/tools/memory_delete.rb +99 -0
- data/lib/swarm_memory/tools/memory_edit.rb +185 -0
- data/lib/swarm_memory/tools/memory_glob.rb +160 -0
- data/lib/swarm_memory/tools/memory_grep.rb +247 -0
- data/lib/swarm_memory/tools/memory_multi_edit.rb +281 -0
- data/lib/swarm_memory/tools/memory_read.rb +123 -0
- data/lib/swarm_memory/tools/memory_write.rb +231 -0
- data/lib/swarm_memory/utils.rb +50 -0
- data/lib/swarm_memory/version.rb +5 -0
- data/lib/swarm_memory.rb +166 -0
- data/lib/swarm_sdk/agent/RETRY_LOGIC.md +127 -0
- data/lib/swarm_sdk/agent/builder.rb +461 -0
- data/lib/swarm_sdk/agent/chat/context_tracker.rb +314 -0
- data/lib/swarm_sdk/agent/chat/hook_integration.rb +372 -0
- data/lib/swarm_sdk/agent/chat/logging_helpers.rb +116 -0
- data/lib/swarm_sdk/agent/chat/system_reminder_injector.rb +152 -0
- data/lib/swarm_sdk/agent/chat.rb +1159 -0
- data/lib/swarm_sdk/agent/context.rb +112 -0
- data/lib/swarm_sdk/agent/context_manager.rb +309 -0
- data/lib/swarm_sdk/agent/definition.rb +556 -0
- data/lib/swarm_sdk/claude_code_agent_adapter.rb +205 -0
- data/lib/swarm_sdk/configuration.rb +296 -0
- data/lib/swarm_sdk/context_compactor/metrics.rb +147 -0
- data/lib/swarm_sdk/context_compactor/token_counter.rb +106 -0
- data/lib/swarm_sdk/context_compactor.rb +340 -0
- data/lib/swarm_sdk/hooks/adapter.rb +359 -0
- data/lib/swarm_sdk/hooks/context.rb +197 -0
- data/lib/swarm_sdk/hooks/definition.rb +80 -0
- data/lib/swarm_sdk/hooks/error.rb +29 -0
- data/lib/swarm_sdk/hooks/executor.rb +146 -0
- data/lib/swarm_sdk/hooks/registry.rb +147 -0
- data/lib/swarm_sdk/hooks/result.rb +150 -0
- data/lib/swarm_sdk/hooks/shell_executor.rb +254 -0
- data/lib/swarm_sdk/hooks/tool_call.rb +35 -0
- data/lib/swarm_sdk/hooks/tool_result.rb +62 -0
- data/lib/swarm_sdk/log_collector.rb +51 -0
- data/lib/swarm_sdk/log_stream.rb +69 -0
- data/lib/swarm_sdk/markdown_parser.rb +75 -0
- data/lib/swarm_sdk/model_aliases.json +5 -0
- data/lib/swarm_sdk/models.json +1 -0
- data/lib/swarm_sdk/models.rb +120 -0
- data/lib/swarm_sdk/node/agent_config.rb +49 -0
- data/lib/swarm_sdk/node/builder.rb +439 -0
- data/lib/swarm_sdk/node/transformer_executor.rb +248 -0
- data/lib/swarm_sdk/node_context.rb +170 -0
- data/lib/swarm_sdk/node_orchestrator.rb +384 -0
- data/lib/swarm_sdk/permissions/config.rb +239 -0
- data/lib/swarm_sdk/permissions/error_formatter.rb +121 -0
- data/lib/swarm_sdk/permissions/path_matcher.rb +35 -0
- data/lib/swarm_sdk/permissions/validator.rb +173 -0
- data/lib/swarm_sdk/permissions_builder.rb +122 -0
- data/lib/swarm_sdk/plugin.rb +147 -0
- data/lib/swarm_sdk/plugin_registry.rb +101 -0
- data/lib/swarm_sdk/prompts/base_system_prompt.md.erb +243 -0
- data/lib/swarm_sdk/providers/openai_with_responses.rb +582 -0
- data/lib/swarm_sdk/result.rb +97 -0
- data/lib/swarm_sdk/swarm/agent_initializer.rb +334 -0
- data/lib/swarm_sdk/swarm/all_agents_builder.rb +140 -0
- data/lib/swarm_sdk/swarm/builder.rb +586 -0
- data/lib/swarm_sdk/swarm/mcp_configurator.rb +151 -0
- data/lib/swarm_sdk/swarm/tool_configurator.rb +419 -0
- data/lib/swarm_sdk/swarm.rb +982 -0
- data/lib/swarm_sdk/tools/bash.rb +274 -0
- data/lib/swarm_sdk/tools/clock.rb +44 -0
- data/lib/swarm_sdk/tools/delegate.rb +164 -0
- data/lib/swarm_sdk/tools/document_converters/base_converter.rb +83 -0
- data/lib/swarm_sdk/tools/document_converters/docx_converter.rb +99 -0
- data/lib/swarm_sdk/tools/document_converters/html_converter.rb +101 -0
- data/lib/swarm_sdk/tools/document_converters/pdf_converter.rb +78 -0
- data/lib/swarm_sdk/tools/document_converters/xlsx_converter.rb +194 -0
- data/lib/swarm_sdk/tools/edit.rb +150 -0
- data/lib/swarm_sdk/tools/glob.rb +158 -0
- data/lib/swarm_sdk/tools/grep.rb +228 -0
- data/lib/swarm_sdk/tools/image_extractors/docx_image_extractor.rb +43 -0
- data/lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb +163 -0
- data/lib/swarm_sdk/tools/image_formats/tiff_builder.rb +65 -0
- data/lib/swarm_sdk/tools/multi_edit.rb +232 -0
- data/lib/swarm_sdk/tools/path_resolver.rb +43 -0
- data/lib/swarm_sdk/tools/read.rb +251 -0
- data/lib/swarm_sdk/tools/registry.rb +93 -0
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_list.rb +96 -0
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_read.rb +76 -0
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_write.rb +91 -0
- data/lib/swarm_sdk/tools/stores/read_tracker.rb +61 -0
- data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +224 -0
- data/lib/swarm_sdk/tools/stores/storage.rb +148 -0
- data/lib/swarm_sdk/tools/stores/todo_manager.rb +65 -0
- data/lib/swarm_sdk/tools/think.rb +95 -0
- data/lib/swarm_sdk/tools/todo_write.rb +216 -0
- data/lib/swarm_sdk/tools/web_fetch.rb +261 -0
- data/lib/swarm_sdk/tools/write.rb +117 -0
- data/lib/swarm_sdk/utils.rb +50 -0
- data/lib/swarm_sdk/version.rb +5 -0
- data/lib/swarm_sdk.rb +157 -0
- data/llm.v2.txt +13407 -0
- data/rubocop/cop/security/no_reflection_methods.rb +47 -0
- data/rubocop/cop/security/no_ruby_llm_logger.rb +32 -0
- data/swarm_cli.gemspec +57 -0
- data/swarm_memory.gemspec +28 -0
- data/swarm_sdk.gemspec +41 -0
- data/team.yml +1 -1
- data/team_full.yml +1875 -0
- data/{team_v2.yml → team_sdk.yml} +121 -52
- metadata +247 -4
- data/EXAMPLES.md +0 -164
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Test: post_tool_use with exit 1
|
|
2
|
+
# Expected: stderr added to log stream, execution continues (non-blocking error)
|
|
3
|
+
# Run: bundle exec exe/swarm run lib/swarm_sdk/examples/hooks/post_tool_use_exit_1.yml -p "Run 'ls' command"
|
|
4
|
+
|
|
5
|
+
version: 2
|
|
6
|
+
swarm:
|
|
7
|
+
name: "post_tool_use Exit 1 Test"
|
|
8
|
+
lead: agent
|
|
9
|
+
|
|
10
|
+
agents:
|
|
11
|
+
agent:
|
|
12
|
+
description: "Test agent"
|
|
13
|
+
model: gpt-5
|
|
14
|
+
provider: openai
|
|
15
|
+
system_prompt: "You are a test agent."
|
|
16
|
+
tools:
|
|
17
|
+
- Bash
|
|
18
|
+
|
|
19
|
+
hooks:
|
|
20
|
+
post_tool_use:
|
|
21
|
+
- matcher: "Bash"
|
|
22
|
+
type: command
|
|
23
|
+
command: "echo 'Warning: Bash tool execution metrics collection failed' >&2 && exit 1"
|
|
24
|
+
timeout: 5
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Test: post_tool_use with exit 2
|
|
2
|
+
# Expected: Tool already ran, stderr sent to agent to process
|
|
3
|
+
# Run: bundle exec exe/swarm run lib/swarm_sdk/examples/hooks/post_tool_use_exit_2.yml -p "Run 'ls' command"
|
|
4
|
+
|
|
5
|
+
version: 2
|
|
6
|
+
swarm:
|
|
7
|
+
name: "post_tool_use Exit 2 Test"
|
|
8
|
+
lead: agent
|
|
9
|
+
|
|
10
|
+
agents:
|
|
11
|
+
agent:
|
|
12
|
+
description: "Test agent"
|
|
13
|
+
model: gpt-5
|
|
14
|
+
provider: openai
|
|
15
|
+
system_prompt: "You are a test agent."
|
|
16
|
+
tools:
|
|
17
|
+
- Bash
|
|
18
|
+
|
|
19
|
+
hooks:
|
|
20
|
+
post_tool_use:
|
|
21
|
+
- matcher: "Bash"
|
|
22
|
+
type: command
|
|
23
|
+
command: "echo 'ERROR: Bash tool produced suspicious output. Review the command output carefully for security issues.' >&2 && exit 2"
|
|
24
|
+
timeout: 5
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Test: post_tool_use with multiple tool matcher (Read|Grep|Glob) and exit 0
|
|
2
|
+
# Expected: stdout logged, execution continues
|
|
3
|
+
# Run: bundle exec exe/swarm run lib/swarm_sdk/examples/hooks/post_tool_use_multi_matcher_exit_0.yml -p "Search README.md for 'swarm'"
|
|
4
|
+
|
|
5
|
+
version: 2
|
|
6
|
+
swarm:
|
|
7
|
+
name: "post_tool_use Multi-Matcher Exit 0"
|
|
8
|
+
lead: agent
|
|
9
|
+
|
|
10
|
+
agents:
|
|
11
|
+
agent:
|
|
12
|
+
description: "Test agent"
|
|
13
|
+
model: gpt-5
|
|
14
|
+
provider: openai
|
|
15
|
+
system_prompt: "You are a test agent."
|
|
16
|
+
tools:
|
|
17
|
+
- Read
|
|
18
|
+
- Grep
|
|
19
|
+
- Glob
|
|
20
|
+
|
|
21
|
+
hooks:
|
|
22
|
+
post_tool_use:
|
|
23
|
+
- matcher: "Read|Grep|Glob"
|
|
24
|
+
type: command
|
|
25
|
+
command: "echo 'File access logged successfully for audit' && exit 0"
|
|
26
|
+
timeout: 5
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Test: post_tool_use with multiple tool matcher (Read|Grep|Glob) and exit 1
|
|
2
|
+
# Expected: stderr logged as warning, execution continues
|
|
3
|
+
# Run: bundle exec exe/swarm run lib/swarm_sdk/examples/hooks/post_tool_use_multi_matcher_exit_1.yml -p "Search README.md for 'swarm'"
|
|
4
|
+
|
|
5
|
+
version: 2
|
|
6
|
+
swarm:
|
|
7
|
+
name: "post_tool_use Multi-Matcher Exit 1"
|
|
8
|
+
lead: agent
|
|
9
|
+
|
|
10
|
+
agents:
|
|
11
|
+
agent:
|
|
12
|
+
description: "Test agent"
|
|
13
|
+
model: gpt-5
|
|
14
|
+
provider: openai
|
|
15
|
+
system_prompt: "You are a test agent."
|
|
16
|
+
tools:
|
|
17
|
+
- Read
|
|
18
|
+
- Grep
|
|
19
|
+
- Glob
|
|
20
|
+
|
|
21
|
+
hooks:
|
|
22
|
+
post_tool_use:
|
|
23
|
+
- matcher: "Read|Grep|Glob"
|
|
24
|
+
type: command
|
|
25
|
+
command: "echo 'Warning: Could not update file access statistics' >&2 && exit 1"
|
|
26
|
+
timeout: 5
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Test: post_tool_use with multiple tool matcher (Read|Grep|Glob) and exit 2
|
|
2
|
+
# Expected: Tools already ran, stderr sent to agent to review output
|
|
3
|
+
# Run: bundle exec exe/swarm run lib/swarm_sdk/examples/hooks/post_tool_use_multi_matcher_exit_2.yml -p "Search README.md for 'swarm'"
|
|
4
|
+
|
|
5
|
+
version: 2
|
|
6
|
+
swarm:
|
|
7
|
+
name: "post_tool_use Multi-Matcher Exit 2"
|
|
8
|
+
lead: agent
|
|
9
|
+
|
|
10
|
+
agents:
|
|
11
|
+
agent:
|
|
12
|
+
description: "Test agent"
|
|
13
|
+
model: gpt-5
|
|
14
|
+
provider: openai
|
|
15
|
+
system_prompt: "You are a test agent."
|
|
16
|
+
tools:
|
|
17
|
+
- Read
|
|
18
|
+
- Grep
|
|
19
|
+
- Glob
|
|
20
|
+
|
|
21
|
+
hooks:
|
|
22
|
+
post_tool_use:
|
|
23
|
+
- matcher: "Read|Grep|Glob"
|
|
24
|
+
type: command
|
|
25
|
+
command: "echo 'SECURITY WARNING: File access tool detected potential sensitive data exposure. Review the output carefully before proceeding.' >&2 && exit 2"
|
|
26
|
+
timeout: 5
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Test: pre_tool_use with exit 0
|
|
2
|
+
# Expected: stdout added to log stream, execution continues
|
|
3
|
+
# Run: bundle exec exe/swarm run lib/swarm_sdk/examples/hooks/pre_tool_use_exit_0.yml -p "Run 'ls' command"
|
|
4
|
+
|
|
5
|
+
version: 2
|
|
6
|
+
swarm:
|
|
7
|
+
name: "pre_tool_use Exit 0 Test"
|
|
8
|
+
lead: agent
|
|
9
|
+
|
|
10
|
+
agents:
|
|
11
|
+
agent:
|
|
12
|
+
description: "Test agent"
|
|
13
|
+
model: gpt-5
|
|
14
|
+
provider: openai
|
|
15
|
+
system_prompt: "You are a test agent."
|
|
16
|
+
tools:
|
|
17
|
+
- Bash
|
|
18
|
+
|
|
19
|
+
hooks:
|
|
20
|
+
pre_tool_use:
|
|
21
|
+
- matcher: "Bash"
|
|
22
|
+
type: command
|
|
23
|
+
command: "echo 'Validation passed - allowing Bash tool' && exit 0"
|
|
24
|
+
timeout: 5
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Test: pre_tool_use with exit 1
|
|
2
|
+
# Expected: stderr added to log stream, execution continues (non-blocking error)
|
|
3
|
+
# Run: bundle exec exe/swarm run lib/swarm_sdk/examples/hooks/pre_tool_use_exit_1.yml -p "Run 'ls' command"
|
|
4
|
+
|
|
5
|
+
version: 2
|
|
6
|
+
swarm:
|
|
7
|
+
name: "pre_tool_use Exit 1 Test"
|
|
8
|
+
lead: agent
|
|
9
|
+
|
|
10
|
+
agents:
|
|
11
|
+
agent:
|
|
12
|
+
description: "Test agent"
|
|
13
|
+
model: gpt-5
|
|
14
|
+
provider: openai
|
|
15
|
+
system_prompt: "You are a test agent."
|
|
16
|
+
tools:
|
|
17
|
+
- Bash
|
|
18
|
+
|
|
19
|
+
hooks:
|
|
20
|
+
pre_tool_use:
|
|
21
|
+
- matcher: "Bash"
|
|
22
|
+
type: command
|
|
23
|
+
command: "echo 'Warning: unusual Bash usage detected' >&2 && exit 1"
|
|
24
|
+
timeout: 5
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Test: pre_tool_use with exit 2
|
|
2
|
+
# Expected: Blocks tool execution, stderr sent to agent
|
|
3
|
+
# Run: bundle exec exe/swarm run lib/swarm_sdk/examples/hooks/pre_tool_use_exit_2.yml -p "Run 'ls' command"
|
|
4
|
+
|
|
5
|
+
version: 2
|
|
6
|
+
swarm:
|
|
7
|
+
name: "pre_tool_use Exit 2 Test"
|
|
8
|
+
lead: agent
|
|
9
|
+
|
|
10
|
+
agents:
|
|
11
|
+
agent:
|
|
12
|
+
description: "Test agent"
|
|
13
|
+
model: gpt-5
|
|
14
|
+
provider: openai
|
|
15
|
+
system_prompt: "You are a test agent."
|
|
16
|
+
tools:
|
|
17
|
+
- Bash
|
|
18
|
+
|
|
19
|
+
hooks:
|
|
20
|
+
pre_tool_use:
|
|
21
|
+
- matcher: "Bash"
|
|
22
|
+
type: command
|
|
23
|
+
command: "echo 'Bash tool is disabled by policy. Please use alternative methods.' >&2 && exit 2"
|
|
24
|
+
timeout: 5
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Test: pre_tool_use with multiple tool matcher (Read|Grep|Glob) and exit 0
|
|
2
|
+
# Expected: stdout logged, tools execute normally
|
|
3
|
+
# Run: bundle exec exe/swarm run lib/swarm_sdk/examples/hooks/pre_tool_use_multi_matcher_exit_0.yml -p "Search README.md for 'swarm'"
|
|
4
|
+
|
|
5
|
+
version: 2
|
|
6
|
+
swarm:
|
|
7
|
+
name: "pre_tool_use Multi-Matcher Exit 0"
|
|
8
|
+
lead: agent
|
|
9
|
+
|
|
10
|
+
agents:
|
|
11
|
+
agent:
|
|
12
|
+
description: "Test agent"
|
|
13
|
+
model: gpt-5
|
|
14
|
+
provider: openai
|
|
15
|
+
system_prompt: "You are a test agent."
|
|
16
|
+
tools:
|
|
17
|
+
- Read
|
|
18
|
+
- Grep
|
|
19
|
+
- Glob
|
|
20
|
+
|
|
21
|
+
hooks:
|
|
22
|
+
pre_tool_use:
|
|
23
|
+
- matcher: "Read|Grep|Glob"
|
|
24
|
+
type: command
|
|
25
|
+
command: "echo 'Validating file access tool usage' && exit 0"
|
|
26
|
+
timeout: 5
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Test: pre_tool_use with multiple tool matcher (Read|Grep|Glob) and exit 1
|
|
2
|
+
# Expected: stderr logged as warning, tools execute normally
|
|
3
|
+
# Run: bundle exec exe/swarm run lib/swarm_sdk/examples/hooks/pre_tool_use_multi_matcher_exit_1.yml -p "Search README.md for 'swarm'"
|
|
4
|
+
|
|
5
|
+
version: 2
|
|
6
|
+
swarm:
|
|
7
|
+
name: "pre_tool_use Multi-Matcher Exit 1"
|
|
8
|
+
lead: agent
|
|
9
|
+
|
|
10
|
+
agents:
|
|
11
|
+
agent:
|
|
12
|
+
description: "Test agent"
|
|
13
|
+
model: gpt-5
|
|
14
|
+
provider: openai
|
|
15
|
+
system_prompt: "You are a test agent."
|
|
16
|
+
tools:
|
|
17
|
+
- Read
|
|
18
|
+
- Grep
|
|
19
|
+
- Glob
|
|
20
|
+
|
|
21
|
+
hooks:
|
|
22
|
+
pre_tool_use:
|
|
23
|
+
- matcher: "Read|Grep|Glob"
|
|
24
|
+
type: command
|
|
25
|
+
command: "echo 'Warning: File access monitoring service unavailable' >&2 && exit 1"
|
|
26
|
+
timeout: 5
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Test: pre_tool_use with multiple tool matcher (Read|Grep|Glob) and exit 2
|
|
2
|
+
# Expected: Tools blocked, stderr sent to agent
|
|
3
|
+
# Run: bundle exec exe/swarm run lib/swarm_sdk/examples/hooks/pre_tool_use_multi_matcher_exit_2.yml -p "Search README.md for 'swarm'"
|
|
4
|
+
|
|
5
|
+
version: 2
|
|
6
|
+
swarm:
|
|
7
|
+
name: "pre_tool_use Multi-Matcher Exit 2"
|
|
8
|
+
lead: agent
|
|
9
|
+
|
|
10
|
+
agents:
|
|
11
|
+
agent:
|
|
12
|
+
description: "Test agent"
|
|
13
|
+
model: gpt-5
|
|
14
|
+
provider: openai
|
|
15
|
+
system_prompt: "You are a test agent."
|
|
16
|
+
tools:
|
|
17
|
+
- Read
|
|
18
|
+
- Grep
|
|
19
|
+
- Glob
|
|
20
|
+
- Bash # Allow Bash as alternative
|
|
21
|
+
|
|
22
|
+
hooks:
|
|
23
|
+
pre_tool_use:
|
|
24
|
+
- matcher: "Read|Grep|Glob"
|
|
25
|
+
type: command
|
|
26
|
+
command: "echo 'File access tools are disabled. Use Bash with cat/grep commands instead.' >&2 && exit 2"
|
|
27
|
+
timeout: 5
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# Example swarm_stop hook: Generate execution summary
|
|
4
|
+
#
|
|
5
|
+
# This demonstrates:
|
|
6
|
+
# - Reading JSON from stdin
|
|
7
|
+
# - Accessing swarm metadata
|
|
8
|
+
# - Generating output
|
|
9
|
+
# - Exit 0 to continue (allow swarm to finish)
|
|
10
|
+
|
|
11
|
+
# Read JSON input from stdin
|
|
12
|
+
input=$(cat)
|
|
13
|
+
|
|
14
|
+
# Parse fields using jq (if available) or basic grep
|
|
15
|
+
if command -v jq &> /dev/null; then
|
|
16
|
+
swarm_name=$(echo "$input" | jq -r '.swarm // "Unknown"')
|
|
17
|
+
success=$(echo "$input" | jq -r '.success // false')
|
|
18
|
+
duration=$(echo "$input" | jq -r '.duration // 0')
|
|
19
|
+
cost=$(echo "$input" | jq -r '.total_cost // 0')
|
|
20
|
+
else
|
|
21
|
+
swarm_name="Unknown"
|
|
22
|
+
success="unknown"
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# Print summary to stderr (visible in logs)
|
|
26
|
+
echo "========================================" >&2
|
|
27
|
+
echo "Swarm Execution Summary" >&2
|
|
28
|
+
echo "========================================" >&2
|
|
29
|
+
echo "Swarm: $swarm_name" >&2
|
|
30
|
+
echo "Success: $success" >&2
|
|
31
|
+
echo "Duration: ${duration}s" >&2
|
|
32
|
+
echo "Cost: \$${cost}" >&2
|
|
33
|
+
echo "========================================" >&2
|
|
34
|
+
|
|
35
|
+
# Output success JSON
|
|
36
|
+
cat << EOF
|
|
37
|
+
{
|
|
38
|
+
"success": true,
|
|
39
|
+
"message": "Summary generated"
|
|
40
|
+
}
|
|
41
|
+
EOF
|
|
42
|
+
|
|
43
|
+
# Exit 0 to allow swarm to finish normally
|
|
44
|
+
exit 0
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Test: user_prompt with exit 0
|
|
2
|
+
# Expected: stdout appended to prompt and shown to agent
|
|
3
|
+
# Run: bundle exec exe/swarm run lib/swarm_sdk/examples/hooks/user_prompt_exit_0.yml -p "What is 2+2?"
|
|
4
|
+
|
|
5
|
+
version: 2
|
|
6
|
+
swarm:
|
|
7
|
+
name: "user_prompt Exit 0 Test"
|
|
8
|
+
lead: agent
|
|
9
|
+
|
|
10
|
+
agents:
|
|
11
|
+
agent:
|
|
12
|
+
description: "Test agent"
|
|
13
|
+
model: gpt-5
|
|
14
|
+
provider: openai
|
|
15
|
+
system_prompt: "You are a test agent."
|
|
16
|
+
|
|
17
|
+
hooks:
|
|
18
|
+
user_prompt:
|
|
19
|
+
- type: command
|
|
20
|
+
command: "echo 'Additional context from hook: Current timestamp is' $(date) && exit 0"
|
|
21
|
+
timeout: 5
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Test: user_prompt with exit 1
|
|
2
|
+
# Expected: stderr added to log stream, execution continues (non-blocking error)
|
|
3
|
+
# Run: bundle exec exe/swarm run lib/swarm_sdk/examples/hooks/user_prompt_exit_1.yml -p "What is 2+2?"
|
|
4
|
+
|
|
5
|
+
version: 2
|
|
6
|
+
swarm:
|
|
7
|
+
name: "user_prompt Exit 1 Test"
|
|
8
|
+
lead: agent
|
|
9
|
+
|
|
10
|
+
agents:
|
|
11
|
+
agent:
|
|
12
|
+
description: "Test agent"
|
|
13
|
+
model: gpt-5
|
|
14
|
+
provider: openai
|
|
15
|
+
system_prompt: "You are a test agent."
|
|
16
|
+
|
|
17
|
+
hooks:
|
|
18
|
+
user_prompt:
|
|
19
|
+
- type: command
|
|
20
|
+
command: "echo 'Warning: Unable to fetch additional context for this prompt' >&2 && exit 1"
|
|
21
|
+
timeout: 5
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Test: user_prompt with exit 2
|
|
2
|
+
# Expected: Blocks prompt processing, prompt erased, stderr to logs only (NOT to agent)
|
|
3
|
+
# Run: bundle exec exe/swarm run lib/swarm_sdk/examples/hooks/user_prompt_exit_2.yml -p "Any dangerous prompt"
|
|
4
|
+
|
|
5
|
+
version: 2
|
|
6
|
+
swarm:
|
|
7
|
+
name: "user_prompt Exit 2 Test"
|
|
8
|
+
lead: agent
|
|
9
|
+
|
|
10
|
+
agents:
|
|
11
|
+
agent:
|
|
12
|
+
description: "Test agent"
|
|
13
|
+
model: gpt-5
|
|
14
|
+
provider: openai
|
|
15
|
+
system_prompt: "You are a test agent."
|
|
16
|
+
|
|
17
|
+
hooks:
|
|
18
|
+
user_prompt:
|
|
19
|
+
- type: command
|
|
20
|
+
command: "echo 'This prompt violates content policy and has been blocked' >&2 && exit 2"
|
|
21
|
+
timeout: 5
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Example hook script: Validate Bash commands
|
|
5
|
+
#
|
|
6
|
+
# This demonstrates SwarmSDK hooks with JSON I/O and exit codes.
|
|
7
|
+
#
|
|
8
|
+
# Exit codes:
|
|
9
|
+
# 0 - Success (continue execution)
|
|
10
|
+
# 2 - Block execution with error feedback to LLM
|
|
11
|
+
# Other - Non-blocking error (log warning, continue)
|
|
12
|
+
#
|
|
13
|
+
# Input (stdin): JSON with event details
|
|
14
|
+
# Output (stdout): JSON with success/error info
|
|
15
|
+
|
|
16
|
+
require "json"
|
|
17
|
+
|
|
18
|
+
# Read input from stdin
|
|
19
|
+
begin
|
|
20
|
+
input_data = JSON.parse($stdin.read)
|
|
21
|
+
rescue JSON::ParserError => e
|
|
22
|
+
$stderr.puts JSON.generate(success: false, error: "Invalid JSON input: #{e.message}")
|
|
23
|
+
exit(1)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Extract command from parameters
|
|
27
|
+
parameters = input_data["parameters"] || {}
|
|
28
|
+
command = parameters["command"] || ""
|
|
29
|
+
|
|
30
|
+
# Define dangerous patterns
|
|
31
|
+
dangerous_patterns = [
|
|
32
|
+
[%r{rm\s+-rf\s+/}, "Recursive force removal from root"],
|
|
33
|
+
[/dd\s+if=/, "dd command (can overwrite data)"],
|
|
34
|
+
[/mkfs/, "Filesystem formatting"],
|
|
35
|
+
[/:\(\)\{.*\|.*&\};:/, "Fork bomb pattern"],
|
|
36
|
+
[%r{>\s*/dev/sd}, "Writing to disk devices"],
|
|
37
|
+
[/chmod\s+777/, "Insecure permissions"],
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
# Check for dangerous patterns
|
|
41
|
+
dangerous_patterns.each do |pattern, description|
|
|
42
|
+
next unless command.match?(pattern)
|
|
43
|
+
|
|
44
|
+
# Exit 2 to block with error
|
|
45
|
+
output = {
|
|
46
|
+
success: false,
|
|
47
|
+
error: "Dangerous command blocked: #{description}\nCommand: #{command}",
|
|
48
|
+
}
|
|
49
|
+
puts JSON.generate(output)
|
|
50
|
+
exit 2 # Exit 2 = block execution
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Validation passed - allow execution
|
|
54
|
+
output = {
|
|
55
|
+
success: true,
|
|
56
|
+
message: "Bash command validation passed",
|
|
57
|
+
}
|
|
58
|
+
puts JSON.generate(output)
|
|
59
|
+
exit 0 # Exit 0 = continue
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# Multi-Directory Access via Permissions
|
|
2
|
+
#
|
|
3
|
+
# This example demonstrates the new v1.0 approach to multi-directory access.
|
|
4
|
+
#
|
|
5
|
+
# BREAKING CHANGE (v0.x → v1.0):
|
|
6
|
+
# - OLD: directories: ['.', 'lib/', 'test/'] # Multiple directories
|
|
7
|
+
# - NEW: directory: 'lib/' # Single directory + permissions
|
|
8
|
+
#
|
|
9
|
+
# WHY THE CHANGE?
|
|
10
|
+
# 1. Correctness: Tools now operate where agents expect (not in Dir.pwd)
|
|
11
|
+
# 2. Fiber-safe: No reliance on process-global Dir.pwd
|
|
12
|
+
# 3. Security: Explicit permission model for cross-directory access
|
|
13
|
+
# 4. Simplicity: One directory = clear mental model
|
|
14
|
+
#
|
|
15
|
+
# MIGRATION GUIDE:
|
|
16
|
+
# If your agent needs access to multiple directories:
|
|
17
|
+
# 1. Choose ONE primary directory (where agent "lives")
|
|
18
|
+
# 2. Use permissions to grant access to other directories
|
|
19
|
+
# 3. Use relative paths like '../other_dir/file.txt'
|
|
20
|
+
#
|
|
21
|
+
# Run: swarm-cli run -f lib/swarm_sdk/examples/multi_directory_permissions.yml
|
|
22
|
+
|
|
23
|
+
version: 2
|
|
24
|
+
|
|
25
|
+
swarm:
|
|
26
|
+
name: "Multi-Directory Access Demo"
|
|
27
|
+
lead: backend_dev
|
|
28
|
+
|
|
29
|
+
# Global permissions example (optional)
|
|
30
|
+
# Uncomment to apply permissions to ALL agents
|
|
31
|
+
# all_agents:
|
|
32
|
+
# permissions:
|
|
33
|
+
# Read:
|
|
34
|
+
# denied_paths: [".env", "**/.env", "**/secrets/**"]
|
|
35
|
+
# Bash:
|
|
36
|
+
# denied_commands: ["^rm -rf /", "^sudo .*"]
|
|
37
|
+
|
|
38
|
+
agents:
|
|
39
|
+
# Backend developer works primarily in backend/ directory
|
|
40
|
+
# but needs access to shared configuration and utilities
|
|
41
|
+
backend_dev:
|
|
42
|
+
description: "Backend developer with cross-directory access"
|
|
43
|
+
model: gpt-5-nano
|
|
44
|
+
provider: openai
|
|
45
|
+
|
|
46
|
+
# Primary working directory (singular!)
|
|
47
|
+
directory: backend/
|
|
48
|
+
|
|
49
|
+
tools:
|
|
50
|
+
- Read
|
|
51
|
+
- Write
|
|
52
|
+
- Edit
|
|
53
|
+
- Grep
|
|
54
|
+
- Glob
|
|
55
|
+
- Bash
|
|
56
|
+
|
|
57
|
+
# Permissions grant access beyond the primary directory
|
|
58
|
+
permissions:
|
|
59
|
+
# File operations: allow access to shared utilities and config
|
|
60
|
+
Read:
|
|
61
|
+
# Relative paths are resolved against agent's directory (backend/)
|
|
62
|
+
# So '../shared/**' means 'shared/' from project root
|
|
63
|
+
allowed_paths:
|
|
64
|
+
- "**/*" # All files in backend/ (agent's directory)
|
|
65
|
+
- "../shared/**" # Shared utilities (project_root/shared/)
|
|
66
|
+
- "../config/**" # Configuration files (project_root/config/)
|
|
67
|
+
- "../README.md" # Project README at root
|
|
68
|
+
denied_paths:
|
|
69
|
+
- "../frontend/**" # Cannot read frontend code
|
|
70
|
+
- "**/.env" # Cannot read environment secrets
|
|
71
|
+
- "**/secrets/**" # Cannot read secrets directory
|
|
72
|
+
|
|
73
|
+
Write:
|
|
74
|
+
# More restrictive for writes
|
|
75
|
+
allowed_paths:
|
|
76
|
+
- "**/*" # Can write anywhere in backend/
|
|
77
|
+
- "../shared/utils/**" # Can write shared utilities
|
|
78
|
+
denied_paths:
|
|
79
|
+
- "../config/**" # Cannot modify config files
|
|
80
|
+
- "**/*.env" # Cannot write .env files
|
|
81
|
+
|
|
82
|
+
Edit:
|
|
83
|
+
# Same as Write (Edit is just a different operation)
|
|
84
|
+
allowed_paths:
|
|
85
|
+
- "**/*"
|
|
86
|
+
- "../shared/utils/**"
|
|
87
|
+
denied_paths:
|
|
88
|
+
- "../config/**"
|
|
89
|
+
|
|
90
|
+
# Bash commands: restrict dangerous operations
|
|
91
|
+
Bash:
|
|
92
|
+
allowed_commands:
|
|
93
|
+
- "^git .*" # All git commands
|
|
94
|
+
- "^npm (install|test|run).*" # Safe npm commands
|
|
95
|
+
- "^ruby .*" # Ruby scripts
|
|
96
|
+
- "^bundle .*" # Bundler commands
|
|
97
|
+
denied_commands:
|
|
98
|
+
- "^rm -rf /.*" # No recursive root deletion
|
|
99
|
+
- "^sudo .*" # No sudo
|
|
100
|
+
- "^curl.*\\|.*sh.*" # No piping curl to shell
|
|
101
|
+
|
|
102
|
+
system_prompt: |
|
|
103
|
+
You are a backend developer working in the backend/ directory.
|
|
104
|
+
|
|
105
|
+
Your working directory is: backend/
|
|
106
|
+
- Relative paths like "server.rb" resolve to: backend/server.rb
|
|
107
|
+
- Relative paths like "../shared/utils.rb" resolve to: shared/utils.rb (project root)
|
|
108
|
+
|
|
109
|
+
You have permission to:
|
|
110
|
+
✅ Read/write all files in backend/
|
|
111
|
+
✅ Read shared utilities (../shared/**)
|
|
112
|
+
✅ Read configuration (../config/**)
|
|
113
|
+
✅ Read project README (../README.md)
|
|
114
|
+
✅ Write to shared utilities (../shared/utils/**)
|
|
115
|
+
|
|
116
|
+
You do NOT have permission to:
|
|
117
|
+
❌ Access frontend code (../frontend/**)
|
|
118
|
+
❌ Modify configuration files (../config/**)
|
|
119
|
+
❌ Read/write .env or secrets files
|
|
120
|
+
❌ Run dangerous bash commands (rm -rf /, sudo, etc.)
|
|
121
|
+
|
|
122
|
+
When file operations fail with "Permission denied", check if:
|
|
123
|
+
1. The file is outside your allowed paths
|
|
124
|
+
2. The file is explicitly denied
|
|
125
|
+
3. You're trying to Write/Edit where you only have Read access
|
|
126
|
+
|
|
127
|
+
# Frontend developer: similar pattern, different directory
|
|
128
|
+
frontend_dev:
|
|
129
|
+
description: "Frontend developer with limited backend access"
|
|
130
|
+
model: gpt-5-nano
|
|
131
|
+
provider: openai
|
|
132
|
+
|
|
133
|
+
# Primary working directory
|
|
134
|
+
directory: frontend/
|
|
135
|
+
|
|
136
|
+
tools: [Read, Write, Edit, Grep, Glob, Bash]
|
|
137
|
+
|
|
138
|
+
permissions:
|
|
139
|
+
Read:
|
|
140
|
+
allowed_paths:
|
|
141
|
+
- "**/*" # All files in frontend/
|
|
142
|
+
- "../shared/**" # Shared utilities
|
|
143
|
+
- "../backend/api/**" # Can read API documentation
|
|
144
|
+
denied_paths:
|
|
145
|
+
- "../backend/secrets/**"
|
|
146
|
+
- "**/.env"
|
|
147
|
+
|
|
148
|
+
Write:
|
|
149
|
+
allowed_paths:
|
|
150
|
+
- "**/*" # Can write anywhere in frontend/
|
|
151
|
+
- "../shared/ui/**" # Can write shared UI components
|
|
152
|
+
|
|
153
|
+
Edit:
|
|
154
|
+
allowed_paths:
|
|
155
|
+
- "**/*"
|
|
156
|
+
- "../shared/ui/**"
|
|
157
|
+
|
|
158
|
+
Bash:
|
|
159
|
+
allowed_commands:
|
|
160
|
+
- "^git .*"
|
|
161
|
+
- "^npm .*"
|
|
162
|
+
- "^yarn .*"
|
|
163
|
+
- "^node .*"
|
|
164
|
+
|
|
165
|
+
system_prompt: |
|
|
166
|
+
You are a frontend developer working in the frontend/ directory.
|
|
167
|
+
|
|
168
|
+
Your working directory is: frontend/
|
|
169
|
+
- Relative paths like "index.html" resolve to: frontend/index.html
|
|
170
|
+
- Relative paths like "../shared/ui.css" resolve to: shared/ui.css
|
|
171
|
+
|
|
172
|
+
You have permission to:
|
|
173
|
+
✅ Read/write all files in frontend/
|
|
174
|
+
✅ Read shared utilities and UI components
|
|
175
|
+
✅ Read backend API documentation (../backend/api/**)
|
|
176
|
+
✅ Write to shared UI components (../shared/ui/**)
|
|
177
|
+
|
|
178
|
+
You do NOT have permission to:
|
|
179
|
+
❌ Modify backend code
|
|
180
|
+
❌ Read backend secrets
|
|
181
|
+
❌ Read/write .env files
|
|
182
|
+
|
|
183
|
+
# Coordinator: works in project root, can delegate to specialists
|
|
184
|
+
coordinator:
|
|
185
|
+
description: "Coordinator with read-only access to entire project"
|
|
186
|
+
model: gpt-5-nano
|
|
187
|
+
provider: openai
|
|
188
|
+
|
|
189
|
+
# Works in project root
|
|
190
|
+
directory: .
|
|
191
|
+
|
|
192
|
+
tools: [Read, Grep, Glob, TodoWrite]
|
|
193
|
+
delegates_to: [backend_dev, frontend_dev]
|
|
194
|
+
|
|
195
|
+
# Read-only access to everything except secrets
|
|
196
|
+
permissions:
|
|
197
|
+
Read:
|
|
198
|
+
allowed_paths: ["**/*"]
|
|
199
|
+
denied_paths: ["**/.env", "**/secrets/**"]
|
|
200
|
+
|
|
201
|
+
system_prompt: |
|
|
202
|
+
You are a project coordinator with read-only access to the entire codebase.
|
|
203
|
+
|
|
204
|
+
Your working directory is the project root.
|
|
205
|
+
- Relative path "README.md" → ./README.md (root)
|
|
206
|
+
- Relative path "backend/server.rb" → ./backend/server.rb
|
|
207
|
+
- Relative path "frontend/index.html" → ./frontend/index.html
|
|
208
|
+
|
|
209
|
+
You can:
|
|
210
|
+
✅ Read any file in the project (except secrets)
|
|
211
|
+
✅ Search across all directories
|
|
212
|
+
✅ Delegate work to backend_dev and frontend_dev
|
|
213
|
+
|
|
214
|
+
You cannot:
|
|
215
|
+
❌ Write or edit files (delegate to specialists)
|
|
216
|
+
❌ Read .env or secrets files
|
|
217
|
+
|
|
218
|
+
When delegating:
|
|
219
|
+
- Backend work → backend_dev
|
|
220
|
+
- Frontend work → frontend_dev
|
|
221
|
+
- Complex tasks → use TodoWrite to track progress
|