prompt_objects 0.6.0 → 0.7.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/CHANGELOG.md +126 -0
- data/README.md +93 -22
- data/exe/poop +5 -0
- data/exe/prompt_objects +1 -1108
- data/exe/prompt_objects_mcp +5 -3
- data/lib/prompt_objects/capability.rb +33 -0
- data/lib/prompt_objects/cli/diagnostics_command.rb +69 -0
- data/lib/prompt_objects/cli/env_command.rb +435 -0
- data/lib/prompt_objects/cli/events_command.rb +145 -0
- data/lib/prompt_objects/cli/explore_command.rb +155 -0
- data/lib/prompt_objects/cli/helpers.rb +91 -0
- data/lib/prompt_objects/cli/message_command.rb +216 -0
- data/lib/prompt_objects/cli/repl_command.rb +366 -0
- data/lib/prompt_objects/cli/serve_command.rb +162 -0
- data/lib/prompt_objects/cli.rb +64 -422
- data/lib/prompt_objects/connectors/base.rb +16 -29
- data/lib/prompt_objects/connectors/mcp.rb +82 -98
- data/lib/prompt_objects/domain/records.rb +45 -0
- data/lib/prompt_objects/environment/exporter.rb +5 -4
- data/lib/prompt_objects/environment/git.rb +21 -1
- data/lib/prompt_objects/environment/importer.rb +5 -4
- data/lib/prompt_objects/environment/manager.rb +44 -6
- data/lib/prompt_objects/environment/manifest.rb +26 -4
- data/lib/prompt_objects/environment.rb +1337 -20
- data/lib/prompt_objects/execution/blocking_executor.rb +88 -0
- data/lib/prompt_objects/execution/context.rb +137 -0
- data/lib/prompt_objects/execution/contracts.rb +59 -0
- data/lib/prompt_objects/execution/permit_pool.rb +49 -0
- data/lib/prompt_objects/execution/policy.rb +47 -0
- data/lib/prompt_objects/execution/resource_lock_manager.rb +63 -0
- data/lib/prompt_objects/execution/runner.rb +498 -0
- data/lib/prompt_objects/execution/scheduler.rb +325 -0
- data/lib/prompt_objects/llm/factory.rb +4 -4
- data/lib/prompt_objects/llm/gemini_adapter.rb +25 -8
- data/lib/prompt_objects/llm/openai_adapter.rb +9 -1
- data/lib/prompt_objects/llm/pricing.rb +9 -2
- data/lib/prompt_objects/llm/response.rb +9 -4
- data/lib/prompt_objects/loader.rb +28 -1
- data/lib/prompt_objects/mcp/server.rb +6 -3
- data/lib/prompt_objects/mcp/tools/get_conversation.rb +15 -11
- data/lib/prompt_objects/mcp/tools/get_pending_requests.rb +2 -2
- data/lib/prompt_objects/mcp/tools/respond_to_request.rb +3 -3
- data/lib/prompt_objects/mcp/tools/send_message.rb +42 -32
- data/lib/prompt_objects/operations/diagnostics.rb +115 -0
- data/lib/prompt_objects/operations/retention.rb +75 -0
- data/lib/prompt_objects/operations/run_trace_builder.rb +152 -0
- data/lib/prompt_objects/primitives/http_get.rb +2 -0
- data/lib/prompt_objects/primitives/list_files.rb +2 -0
- data/lib/prompt_objects/primitives/read_file.rb +2 -0
- data/lib/prompt_objects/primitives/think.rb +36 -0
- data/lib/prompt_objects/primitives/write_file.rb +9 -0
- data/lib/prompt_objects/prompt_object.rb +171 -519
- data/lib/prompt_objects/repositories/artifact_repository.rb +109 -0
- data/lib/prompt_objects/repositories/base_repository.rb +37 -0
- data/lib/prompt_objects/repositories/definition_repository.rb +36 -0
- data/lib/prompt_objects/repositories/env_data_repository.rb +103 -0
- data/lib/prompt_objects/repositories/event_repository.rb +105 -0
- data/lib/prompt_objects/repositories/message_repository.rb +73 -0
- data/lib/prompt_objects/repositories/run_repository.rb +254 -0
- data/lib/prompt_objects/repositories/thread_repository.rb +87 -0
- data/lib/prompt_objects/repositories/tool_execution_repository.rb +88 -0
- data/lib/prompt_objects/repositories/workspace_session_repository.rb +61 -0
- data/lib/prompt_objects/server/api/routes.rb +549 -53
- data/lib/prompt_objects/server/app.rb +133 -14
- data/lib/prompt_objects/server/file_watcher.rb +9 -0
- data/lib/prompt_objects/server/public/assets/index-BjKlODDD.js +90 -0
- data/lib/prompt_objects/server/public/assets/index-w3fpIb5c.css +1 -0
- data/lib/prompt_objects/server/public/index.html +2 -2
- data/lib/prompt_objects/server/websocket_handler.rb +202 -227
- data/lib/prompt_objects/server.rb +170 -1
- data/lib/prompt_objects/service.rb +129 -0
- data/lib/prompt_objects/session/store.rb +600 -13
- data/lib/prompt_objects/universal/add_capability.rb +1 -1
- data/lib/prompt_objects/universal/create_capability.rb +4 -2
- data/lib/prompt_objects/universal/delete_env_data.rb +23 -15
- data/lib/prompt_objects/universal/delete_primitive.rb +1 -1
- data/lib/prompt_objects/universal/dispatch_po.rb +54 -0
- data/lib/prompt_objects/universal/get_env_data.rb +8 -14
- data/lib/prompt_objects/universal/get_run_status.rb +30 -0
- data/lib/prompt_objects/universal/join_runs.rb +35 -0
- data/lib/prompt_objects/universal/list_env_data.rb +10 -14
- data/lib/prompt_objects/universal/modify_primitive.rb +1 -1
- data/lib/prompt_objects/universal/render_artifact.rb +91 -0
- data/lib/prompt_objects/universal/request_primitive.rb +1 -1
- data/lib/prompt_objects/universal/{store_env_data.rb → set_env_data.rb} +34 -20
- data/lib/prompt_objects/version.rb +5 -0
- data/lib/prompt_objects.rb +33 -8
- data/objects/coordinator.md +8 -4
- data/templates/arc-agi-1/objects/data_manager.md +2 -2
- data/templates/arc-agi-1/objects/observer.md +2 -2
- data/templates/arc-agi-1/objects/solver.md +6 -5
- data/templates/arc-agi-1/objects/verifier.md +2 -2
- data/templates/arc-agi-3/manifest.yml +19 -0
- data/templates/arc-agi-3/objects/analyst.md +79 -0
- data/templates/arc-agi-3/objects/player.md +76 -0
- data/templates/arc-agi-3/objects/strategist.md +97 -0
- data/templates/arc-agi-3/primitives/action_log.rb +133 -0
- data/templates/arc-agi-3/primitives/arc3_api.rb +223 -0
- data/templates/arc-agi-3/primitives/arc3_scorecard.rb +131 -0
- data/templates/arc-agi-3/primitives/frame_diff.rb +143 -0
- data/templates/arc-agi-3/primitives/frame_info.rb +96 -0
- data/templates/arc-agi-3/primitives/render_frame.rb +140 -0
- data/templates/basic/objects/basic.md +11 -3
- data/templates/chiptune/extras/sonic_pi_boot.rb +220 -0
- data/templates/chiptune/manifest.yml +20 -0
- data/templates/chiptune/objects/conductor.md +184 -0
- data/templates/chiptune/objects/sonic_pi.md +65 -0
- data/templates/chiptune/objects/voice_bass.md +44 -0
- data/templates/chiptune/objects/voice_lead.md +44 -0
- data/templates/chiptune/objects/voice_pad.md +43 -0
- data/templates/chiptune/objects/voice_perc.md +45 -0
- data/templates/chiptune/primitives/play_note.rb +59 -0
- data/templates/chiptune/primitives/play_sequence.rb +55 -0
- data/templates/chiptune/primitives/query_sonic_pi.rb +141 -0
- data/templates/chiptune/primitives/set_synth.rb +57 -0
- data/templates/chiptune/primitives/set_tempo.rb +45 -0
- data/templates/chiptune/primitives/stop_voice.rb +46 -0
- data/templates/chiptune/primitives/support/osc_bridge.rb +33 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/LICENSE +19 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/address_pattern.rb +58 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/broadcast_client.rb +24 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/bundle.rb +46 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/client.rb +13 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/core_ext/time.rb +6 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/em_server.rb +63 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/message.rb +46 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/network_packet.rb +42 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_argument.rb +26 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_packet.rb +140 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_types.rb +53 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby/server.rb +91 -0
- data/templates/chiptune/vendor/osc-ruby-1.1.5/lib/osc-ruby.rb +18 -0
- data/templates/developer/objects/code_reviewer.md +1 -1
- data/templates/developer/objects/coordinator.md +16 -3
- data/templates/developer/objects/debugger.md +3 -3
- data/templates/empty/objects/assistant.md +10 -5
- data/templates/minimal/objects/assistant.md +10 -5
- data/templates/music/extras/sonic_pi_boot.rb +220 -0
- data/templates/music/manifest.yml +16 -0
- data/templates/music/objects/conductor.md +154 -0
- data/templates/music/objects/sonic_pi.md +65 -0
- data/templates/music/primitives/play_note.rb +55 -0
- data/templates/music/primitives/play_sequence.rb +51 -0
- data/templates/music/primitives/query_sonic_pi.rb +139 -0
- data/templates/music/primitives/set_synth.rb +53 -0
- data/templates/music/primitives/set_tempo.rb +43 -0
- data/templates/music/primitives/stop_voice.rb +44 -0
- data/templates/music/primitives/support/osc_bridge.rb +33 -0
- data/templates/music/vendor/osc-ruby-1.1.5/LICENSE +19 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/address_pattern.rb +58 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/broadcast_client.rb +24 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/bundle.rb +46 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/client.rb +13 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/core_ext/time.rb +6 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/em_server.rb +63 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/message.rb +46 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/network_packet.rb +42 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_argument.rb +26 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_packet.rb +140 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_types.rb +53 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby/server.rb +91 -0
- data/templates/music/vendor/osc-ruby-1.1.5/lib/osc-ruby.rb +18 -0
- data/templates/music-beginner/README.md +100 -0
- data/templates/music-beginner/extras/README.md +27 -0
- data/templates/music-beginner/extras/sonic_pi_boot.rb +297 -0
- data/templates/music-beginner/manifest.yml +25 -0
- data/templates/music-beginner/objects/conductor.md +222 -0
- data/templates/music-beginner/objects/engine_setup.md +54 -0
- data/templates/music-beginner/objects/voice_bass.md +43 -0
- data/templates/music-beginner/objects/voice_keys.md +48 -0
- data/templates/music-beginner/objects/voice_pad.md +46 -0
- data/templates/music-beginner/objects/voice_percussion.md +45 -0
- data/templates/music-beginner/objects/voice_texture.md +37 -0
- data/templates/music-beginner/primitives/play_pattern.rb +118 -0
- data/templates/music-beginner/primitives/query_music_engine.rb +94 -0
- data/templates/music-beginner/primitives/set_instrument.rb +47 -0
- data/templates/music-beginner/primitives/set_tempo.rb +43 -0
- data/templates/music-beginner/primitives/set_voice_level.rb +46 -0
- data/templates/music-beginner/primitives/stop_voice.rb +37 -0
- data/templates/music-beginner/primitives/support/osc_bridge.rb +25 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/LICENSE +19 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/address_pattern.rb +58 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/broadcast_client.rb +24 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/bundle.rb +46 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/client.rb +13 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/core_ext/time.rb +6 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/em_server.rb +63 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/message.rb +46 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/network_packet.rb +42 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_argument.rb +26 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_packet.rb +140 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_types.rb +53 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby/server.rb +91 -0
- data/templates/music-beginner/vendor/osc-ruby-1.1.5/lib/osc-ruby.rb +18 -0
- data/templates/music-pro/extras/AUDITION.md +100 -0
- data/templates/music-pro/extras/sonic_pi_boot.rb +546 -0
- data/templates/music-pro/manifest.yml +19 -0
- data/templates/music-pro/objects/conductor.md +126 -0
- data/templates/music-pro/objects/sonic_pi.md +35 -0
- data/templates/music-pro/objects/voice_harmony.md +48 -0
- data/templates/music-pro/objects/voice_rhythm.md +43 -0
- data/templates/music-pro/objects/voice_texture.md +42 -0
- data/templates/music-pro/primitives/define_patch.rb +46 -0
- data/templates/music-pro/primitives/query_music_engine.rb +69 -0
- data/templates/music-pro/primitives/set_live_pattern.rb +70 -0
- data/templates/music-pro/primitives/set_tempo.rb +31 -0
- data/templates/music-pro/primitives/stop_voice.rb +31 -0
- data/templates/music-pro/primitives/support/music_protocol.rb +136 -0
- data/templates/music-pro/primitives/support/osc_bridge.rb +33 -0
- data/templates/music-pro/primitives/trigger_event.rb +44 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/LICENSE +19 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/address_pattern.rb +58 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/broadcast_client.rb +24 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/bundle.rb +46 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/client.rb +13 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/core_ext/time.rb +6 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/em_server.rb +63 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/message.rb +46 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/network_packet.rb +42 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_argument.rb +26 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_packet.rb +140 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/osc_types.rb +53 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby/server.rb +91 -0
- data/templates/music-pro/vendor/osc-ruby-1.1.5/lib/osc-ruby.rb +18 -0
- data/templates/writer/objects/coordinator.md +14 -3
- data/templates/writer/objects/editor.md +1 -1
- data/templates/writer/objects/researcher.md +2 -2
- data/tools/thread-explorer.html +1 -1
- metadata +172 -65
- data/CLAUDE.md +0 -177
- data/Gemfile +0 -10
- data/Rakefile +0 -27
- data/frontend/.gitignore +0 -3
- data/frontend/index.html +0 -17
- data/frontend/package-lock.json +0 -4540
- data/frontend/package.json +0 -36
- data/frontend/postcss.config.js +0 -6
- data/frontend/src/App.tsx +0 -104
- data/frontend/src/canvas/CanvasView.tsx +0 -113
- data/frontend/src/canvas/ForceLayout.ts +0 -115
- data/frontend/src/canvas/SceneManager.ts +0 -587
- data/frontend/src/canvas/canvasStore.ts +0 -47
- data/frontend/src/canvas/constants.ts +0 -95
- data/frontend/src/canvas/controls/CameraControls.ts +0 -98
- data/frontend/src/canvas/edges/MessageArc.ts +0 -149
- data/frontend/src/canvas/inspector/InspectorPanel.tsx +0 -31
- data/frontend/src/canvas/inspector/POInspector.tsx +0 -262
- data/frontend/src/canvas/inspector/ToolCallInspector.tsx +0 -67
- data/frontend/src/canvas/nodes/PONode.ts +0 -249
- data/frontend/src/canvas/nodes/ToolCallNode.ts +0 -116
- data/frontend/src/canvas/types.ts +0 -24
- data/frontend/src/components/ContextMenu.tsx +0 -68
- data/frontend/src/components/EnvDataPane.tsx +0 -69
- data/frontend/src/components/Inspector.tsx +0 -263
- data/frontend/src/components/MarkdownMessage.tsx +0 -155
- data/frontend/src/components/MethodList.tsx +0 -90
- data/frontend/src/components/ModelSelector.tsx +0 -115
- data/frontend/src/components/NotificationPanel.tsx +0 -130
- data/frontend/src/components/ObjectList.tsx +0 -78
- data/frontend/src/components/PaneSlot.tsx +0 -30
- data/frontend/src/components/SourcePane.tsx +0 -202
- data/frontend/src/components/SystemBar.tsx +0 -74
- data/frontend/src/components/Transcript.tsx +0 -76
- data/frontend/src/components/UsagePanel.tsx +0 -105
- data/frontend/src/components/Workspace.tsx +0 -260
- data/frontend/src/components/index.ts +0 -12
- data/frontend/src/hooks/useResize.ts +0 -55
- data/frontend/src/hooks/useWebSocket.ts +0 -559
- data/frontend/src/index.css +0 -102
- data/frontend/src/main.tsx +0 -10
- data/frontend/src/store/index.ts +0 -311
- data/frontend/src/types/index.ts +0 -176
- data/frontend/tailwind.config.js +0 -44
- data/frontend/tsconfig.json +0 -30
- data/frontend/vite.config.ts +0 -29
- data/lib/prompt_objects/server/public/assets/index-DEPawnfZ.js +0 -4345
- data/lib/prompt_objects/server/public/assets/index-oMrRce1m.css +0 -1
- data/lib/prompt_objects/universal/add_primitive.rb +0 -118
- data/lib/prompt_objects/universal/ask_human.rb +0 -109
- data/lib/prompt_objects/universal/create_primitive.rb +0 -174
- data/lib/prompt_objects/universal/list_primitives.rb +0 -145
- data/lib/prompt_objects/universal/think.rb +0 -41
- data/lib/prompt_objects/universal/update_env_data.rb +0 -88
- data/prompt_objects.gemspec +0 -50
- data/templates/basic/.gitignore +0 -2
- data/templates/developer/.gitignore +0 -5
- data/templates/empty/.gitignore +0 -5
- data/templates/empty/objects/.gitkeep +0 -0
- data/templates/minimal/.gitignore +0 -5
- data/templates/writer/.gitignore +0 -5
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module OSC
|
|
2
|
+
class AddressPattern
|
|
3
|
+
def initialize(pattern)
|
|
4
|
+
@pattern = pattern
|
|
5
|
+
|
|
6
|
+
generate_regex_from_pattern
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def match?(address)
|
|
10
|
+
!!(@re.nil? || @re.match(address))
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def generate_regex_from_pattern
|
|
16
|
+
case @pattern
|
|
17
|
+
when nil
|
|
18
|
+
@re = @pattern
|
|
19
|
+
when Regexp
|
|
20
|
+
@re = @pattern
|
|
21
|
+
when String
|
|
22
|
+
# i'm unsure what this does
|
|
23
|
+
# @pattern.gsub!(/[.^(|)]/, '\\1')
|
|
24
|
+
|
|
25
|
+
# handles osc single char wildcard matching
|
|
26
|
+
@pattern.gsub!(/\?/, '[^/]')
|
|
27
|
+
|
|
28
|
+
# handles ** - used in creating osc routers
|
|
29
|
+
# TODO: turns out the OSC 1.1 spec says that we shoudl use "//"
|
|
30
|
+
# this will be implemented in the next major release of this gem
|
|
31
|
+
#@pattern.gsub!(/\*\*/, '.*' )
|
|
32
|
+
|
|
33
|
+
# handles osc * - 0 or more matching
|
|
34
|
+
@pattern.gsub!(/\*[^\*]/, '[^/]*')
|
|
35
|
+
|
|
36
|
+
# handles [!] matching
|
|
37
|
+
@pattern.gsub!(/\[!/, '[^')
|
|
38
|
+
|
|
39
|
+
# handles {} matching
|
|
40
|
+
@pattern.gsub!(/\{/, '(')
|
|
41
|
+
@pattern.gsub!(/,/, '|')
|
|
42
|
+
@pattern.gsub!(/\}/, ')')
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# keeps from matching before the begining of the pattern
|
|
46
|
+
@pattern.gsub!(/\A/, '\A')
|
|
47
|
+
|
|
48
|
+
# keeps from matching beyond the end,
|
|
49
|
+
# eg. pattern /hi does not match /hidden
|
|
50
|
+
@pattern.gsub!(/\z/, '\z')
|
|
51
|
+
|
|
52
|
+
@re = Regexp.new(@pattern)
|
|
53
|
+
else
|
|
54
|
+
raise(ArgumentError, 'invalid pattern')
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'ipaddr'
|
|
2
|
+
|
|
3
|
+
module OSC
|
|
4
|
+
class BroadcastClient
|
|
5
|
+
|
|
6
|
+
BROADCAST_ADDRESS = '<broadcast>'
|
|
7
|
+
|
|
8
|
+
attr_reader :port
|
|
9
|
+
|
|
10
|
+
def initialize(port, local_ip = nil)
|
|
11
|
+
@port = port
|
|
12
|
+
@so = UDPSocket.new
|
|
13
|
+
@so.setsockopt Socket::SOL_SOCKET, Socket::SO_BROADCAST, true
|
|
14
|
+
if local_ip
|
|
15
|
+
@so.setsockopt Socket::IPPROTO_IP, Socket::IP_MULTICAST_IF, IPAddr.new(local_ip).hton
|
|
16
|
+
@so.bind(local_ip, 0)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def send(mesg)
|
|
21
|
+
@so.send(mesg.encode, 0, BROADCAST_ADDRESS, @port)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module OSC
|
|
2
|
+
class Bundle
|
|
3
|
+
attr_accessor :timetag
|
|
4
|
+
|
|
5
|
+
def initialize(timetag=nil, *args)
|
|
6
|
+
@timetag = timetag
|
|
7
|
+
@args = args
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def encode()
|
|
11
|
+
s = OSCString.new('#bundle').encode
|
|
12
|
+
s << encode_timetag(@timetag)
|
|
13
|
+
s << @args.collect do |x|
|
|
14
|
+
x2 = x.encode; [x2.size].pack('N') + x2
|
|
15
|
+
end.join
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def to_a
|
|
19
|
+
@args.collect{|x| x.to_a}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def encode_timetag(t)
|
|
25
|
+
case t
|
|
26
|
+
when nil # immediately
|
|
27
|
+
t1 = 0
|
|
28
|
+
t2 = 1
|
|
29
|
+
when Numeric
|
|
30
|
+
t1, t2 = construct_timetag(t)
|
|
31
|
+
when Time
|
|
32
|
+
t1, t2 = construct_timetag(t.to_ntp)
|
|
33
|
+
else
|
|
34
|
+
raise(ArgumentError, 'invalid time')
|
|
35
|
+
end
|
|
36
|
+
[t1, t2].pack('N2')
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def construct_timetag(time)
|
|
40
|
+
t1, fr = time.divmod(1)
|
|
41
|
+
t2 = (fr * (2**32)).to_i
|
|
42
|
+
|
|
43
|
+
[t1, t2]
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require 'eventmachine'
|
|
2
|
+
|
|
3
|
+
module OSC
|
|
4
|
+
Channel = EM::Channel.new
|
|
5
|
+
|
|
6
|
+
class Connection < EventMachine::Connection
|
|
7
|
+
def receive_data(data)
|
|
8
|
+
ip_info = get_peername[2,6].unpack("nC4")
|
|
9
|
+
Channel << OSC::OSCPacket.messages_from_network(data, ip_info)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class EMServer
|
|
14
|
+
|
|
15
|
+
def initialize(port = 3333)
|
|
16
|
+
@port = port
|
|
17
|
+
setup_dispatcher
|
|
18
|
+
@tuples = []
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def run
|
|
22
|
+
EM.error_handler{ |e|
|
|
23
|
+
Thread.main.raise e
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
EM.run do
|
|
27
|
+
EM::open_datagram_socket "0.0.0.0", @port, Connection
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def add_method(address_pattern, &proc)
|
|
32
|
+
matcher = AddressPattern.new(address_pattern)
|
|
33
|
+
|
|
34
|
+
@tuples << [matcher, proc]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
def setup_dispatcher
|
|
39
|
+
Channel.subscribe do |messages|
|
|
40
|
+
messages.each do |message|
|
|
41
|
+
diff = (message.time || 0) - Time.now.to_ntp
|
|
42
|
+
|
|
43
|
+
if diff <= 0
|
|
44
|
+
sendmesg(message)
|
|
45
|
+
else
|
|
46
|
+
EM.defer do
|
|
47
|
+
sleep(diff)
|
|
48
|
+
sendmesg(message)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def sendmesg(mesg)
|
|
56
|
+
@tuples.each do |matcher, obj|
|
|
57
|
+
if matcher.match?(mesg.address)
|
|
58
|
+
obj.call(mesg)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module OSC
|
|
2
|
+
class Message
|
|
3
|
+
attr_accessor :address
|
|
4
|
+
attr_accessor :time
|
|
5
|
+
attr_accessor :ip_address
|
|
6
|
+
attr_accessor :ip_port
|
|
7
|
+
|
|
8
|
+
def self.new_with_time(address, time, tags=nil, *args)
|
|
9
|
+
message = new(address, tags, *args)
|
|
10
|
+
message.time = time
|
|
11
|
+
message
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def initialize(address, *args)
|
|
15
|
+
@address = address
|
|
16
|
+
@args = []
|
|
17
|
+
|
|
18
|
+
args.each do |arg|
|
|
19
|
+
case arg
|
|
20
|
+
when Integer; @args << OSCInt32.new(arg)
|
|
21
|
+
when Float; @args << OSCFloat32.new(arg)
|
|
22
|
+
when String; @args << OSCString.new(arg)
|
|
23
|
+
when OSCArgument; @args << arg
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def tags
|
|
29
|
+
@args.collect{|x| x.tag}.join
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def encode
|
|
33
|
+
s = OSCString.new(@address).encode
|
|
34
|
+
s << OSCString.new(',' + tags).encode
|
|
35
|
+
s << @args.collect{|x| x.encode}.join
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def to_a
|
|
39
|
+
@args.collect{|x| x.val}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def ==(other)
|
|
43
|
+
@address == other.address && to_a == other.to_a
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module OSC
|
|
2
|
+
class NetworkPacket
|
|
3
|
+
def initialize(str)
|
|
4
|
+
@str = str.force_encoding("BINARY")
|
|
5
|
+
@index = 0
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def to_s
|
|
9
|
+
@str
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def rem
|
|
13
|
+
@str.length - @index
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def eof?
|
|
17
|
+
rem <= 0
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def skip(n)
|
|
21
|
+
@index += n
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def skip_padding
|
|
25
|
+
skip((4 - (@index % 4)) % 4)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def getn(n)
|
|
29
|
+
raise(EOFError) if rem < n
|
|
30
|
+
s = @str[@index, n]
|
|
31
|
+
skip(n)
|
|
32
|
+
s
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def getc
|
|
36
|
+
raise(EOFError) if rem < 1
|
|
37
|
+
c = @str[@index]
|
|
38
|
+
skip(1)
|
|
39
|
+
c
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module OSC
|
|
2
|
+
class OSCArgument
|
|
3
|
+
def initialize(val)
|
|
4
|
+
@val = val
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
attr_accessor :val
|
|
8
|
+
|
|
9
|
+
def to_i()
|
|
10
|
+
@val.to_i
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def to_f()
|
|
14
|
+
@val.to_f
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def to_s()
|
|
18
|
+
@val.to_s
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
def padding(s)
|
|
23
|
+
s + ("\000" * ((4 - (s.size % 4)) % 4))
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
require File.join(File.dirname( __FILE__ ), 'network_packet')
|
|
2
|
+
require 'ostruct'
|
|
3
|
+
|
|
4
|
+
module OSC
|
|
5
|
+
class UnknownType < StandardError; end
|
|
6
|
+
|
|
7
|
+
class OSCPacket
|
|
8
|
+
def self.messages_from_network(string, ip_info=nil)
|
|
9
|
+
messages = []
|
|
10
|
+
osc = new(string)
|
|
11
|
+
|
|
12
|
+
if osc.bundle?
|
|
13
|
+
osc.get_string
|
|
14
|
+
time = osc.get_timestamp
|
|
15
|
+
|
|
16
|
+
osc.get_bundle_messages.each do |message|
|
|
17
|
+
msg = decode_simple_message(time, OSCPacket.new(message))
|
|
18
|
+
if ip_info
|
|
19
|
+
# Append info for the ip address
|
|
20
|
+
msg.ip_port = ip_info.shift
|
|
21
|
+
msg.ip_address = ip_info.join(".")
|
|
22
|
+
end
|
|
23
|
+
messages << msg
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
else
|
|
27
|
+
msg = decode_simple_message(time, osc)
|
|
28
|
+
if ip_info
|
|
29
|
+
# Append info for the ip address
|
|
30
|
+
msg.ip_port = ip_info.shift
|
|
31
|
+
msg.ip_address = ip_info.join(".")
|
|
32
|
+
end
|
|
33
|
+
messages << msg
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
return messages
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.decode_simple_message(time, osc_packet)
|
|
40
|
+
address = osc_packet.get_string
|
|
41
|
+
args = osc_packet.get_arguments
|
|
42
|
+
|
|
43
|
+
Message.new_with_time(address, time, nil, *args)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def initialize(string)
|
|
47
|
+
@packet = NetworkPacket.new(string)
|
|
48
|
+
|
|
49
|
+
@types = {
|
|
50
|
+
"i" => lambda{OSCInt32.new(get_int32)},
|
|
51
|
+
"f" => lambda{ OSCFloat32.new(get_float32)},
|
|
52
|
+
"d" => lambda{ OSCDouble64.new(get_double64)},
|
|
53
|
+
"s" => lambda{ OSCString.new(get_string)},
|
|
54
|
+
"b" => lambda{ OSCBlob.new(get_blob)}
|
|
55
|
+
}
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def get_bundle_messages
|
|
59
|
+
bundle_messages = []
|
|
60
|
+
|
|
61
|
+
until @packet.eof?
|
|
62
|
+
l = @packet.getn(4).unpack('N')[0]
|
|
63
|
+
bundle_messages << @packet.getn(l)
|
|
64
|
+
end
|
|
65
|
+
bundle_messages
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def get_string
|
|
69
|
+
result = ''
|
|
70
|
+
until ((c = @packet.getc) == string_delemeter)
|
|
71
|
+
result << c
|
|
72
|
+
end
|
|
73
|
+
@packet.skip_padding
|
|
74
|
+
result
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def get_timestamp
|
|
78
|
+
#TODO: refactor this so a mortal can figure it out
|
|
79
|
+
t1 = @packet.getn(4).unpack('N')[0]
|
|
80
|
+
t2 = @packet.getn(4).unpack('N')[0]
|
|
81
|
+
@packet.skip_padding
|
|
82
|
+
|
|
83
|
+
if t1 == 0 && t2 == 1
|
|
84
|
+
time = nil
|
|
85
|
+
else
|
|
86
|
+
time = t1 + t2.to_f / (2**32)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
time
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def get_arguments
|
|
93
|
+
if (@packet.getc == ?,)
|
|
94
|
+
tags = get_string
|
|
95
|
+
args = []
|
|
96
|
+
|
|
97
|
+
tags.scan(/./) do |tag|
|
|
98
|
+
type_handler = @types[tag]
|
|
99
|
+
raise(UnknownType, "Unknown OSC type: #{tag}") unless type_handler
|
|
100
|
+
args << type_handler.call
|
|
101
|
+
end
|
|
102
|
+
args
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def get_int32
|
|
107
|
+
i = @packet.getn(4).unpack('N')[0]
|
|
108
|
+
i -= 2**32 if i > (2**31-1)
|
|
109
|
+
@packet.skip_padding
|
|
110
|
+
i
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def get_float32
|
|
114
|
+
f = @packet.getn(4).unpack('g')[0]
|
|
115
|
+
@packet.skip_padding
|
|
116
|
+
f
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def get_double64
|
|
120
|
+
f = @packet.getn(8).unpack('G')[0]
|
|
121
|
+
@packet.skip_padding
|
|
122
|
+
f
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def get_blob
|
|
126
|
+
l = @packet.getn(4).unpack('N')[0]
|
|
127
|
+
b = @packet.getn(l)
|
|
128
|
+
@packet.skip_padding
|
|
129
|
+
b
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def bundle?
|
|
133
|
+
!(@packet.to_s =~ /\A\#bundle/).nil?
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def string_delemeter
|
|
137
|
+
"\x00"
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), "osc_argument")
|
|
2
|
+
|
|
3
|
+
module OSC
|
|
4
|
+
class OSCInt32 < OSCArgument
|
|
5
|
+
def tag
|
|
6
|
+
'i'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def encode
|
|
10
|
+
[@val].pack('N').force_encoding("BINARY")
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class OSCFloat32 < OSCArgument
|
|
15
|
+
def tag
|
|
16
|
+
'f'
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def encode
|
|
20
|
+
[@val].pack('g').force_encoding("BINARY")
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class OSCDouble64 < OSCArgument
|
|
25
|
+
def tag
|
|
26
|
+
'd'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def encode
|
|
30
|
+
[@val].pack('G').force_encoding("BINARY")
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class OSCString < OSCArgument
|
|
35
|
+
def tag
|
|
36
|
+
's'
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def encode
|
|
40
|
+
padding(@val.sub(/\000.*\z/, '') + "\000").force_encoding("BINARY")
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
class OSCBlob < OSCArgument
|
|
45
|
+
def tag
|
|
46
|
+
'b'
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def encode
|
|
50
|
+
padding([@val.size].pack('N') + @val).force_encoding("BINARY")
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
module OSC
|
|
2
|
+
class Server
|
|
3
|
+
def initialize(port)
|
|
4
|
+
@socket = UDPSocket.new
|
|
5
|
+
@socket.bind('', port)
|
|
6
|
+
@matchers = []
|
|
7
|
+
@queue = Queue.new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def run
|
|
11
|
+
start_dispatcher
|
|
12
|
+
|
|
13
|
+
start_detector
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def stop
|
|
17
|
+
@socket.close
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def add_method(address_pattern, &proc)
|
|
21
|
+
matcher = AddressPattern.new(address_pattern)
|
|
22
|
+
|
|
23
|
+
@matchers << [matcher, proc]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def start_detector
|
|
29
|
+
begin
|
|
30
|
+
detector
|
|
31
|
+
rescue
|
|
32
|
+
Thread.main.raise($!)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def start_dispatcher
|
|
37
|
+
Thread.fork do
|
|
38
|
+
begin
|
|
39
|
+
dispatcher
|
|
40
|
+
rescue
|
|
41
|
+
Thread.main.raise($!)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def dispatcher
|
|
47
|
+
loop do
|
|
48
|
+
mesg = @queue.pop
|
|
49
|
+
dispatch_message(mesg)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def dispatch_message(message)
|
|
54
|
+
diff = (message.time || 0) - Time.now.to_ntp
|
|
55
|
+
|
|
56
|
+
if diff <= 0
|
|
57
|
+
sendmesg(message)
|
|
58
|
+
else # spawn a thread to wait until it's time
|
|
59
|
+
Thread.fork do
|
|
60
|
+
sleep(diff)
|
|
61
|
+
sendmesg(message)
|
|
62
|
+
Thread.exit
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def sendmesg(mesg)
|
|
68
|
+
@matchers.each do |matcher, proc|
|
|
69
|
+
if matcher.match?(mesg.address)
|
|
70
|
+
proc.call(mesg)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def detector
|
|
76
|
+
loop do
|
|
77
|
+
osc_data, network = @socket.recvfrom(16384)
|
|
78
|
+
begin
|
|
79
|
+
ip_info = Array.new
|
|
80
|
+
ip_info << network[1]
|
|
81
|
+
ip_info.concat(network[2].split('.'))
|
|
82
|
+
OSCPacket.messages_from_network( osc_data, ip_info ).each do |message|
|
|
83
|
+
@queue.push(message)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
rescue(EOFError)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'socket'
|
|
2
|
+
require 'thread'
|
|
3
|
+
|
|
4
|
+
# core extensions
|
|
5
|
+
require 'osc-ruby/core_ext/time'
|
|
6
|
+
|
|
7
|
+
# jus the basics
|
|
8
|
+
require 'osc-ruby/osc_types'
|
|
9
|
+
require 'osc-ruby/osc_packet'
|
|
10
|
+
|
|
11
|
+
require 'osc-ruby/message'
|
|
12
|
+
require 'osc-ruby/bundle'
|
|
13
|
+
require 'osc-ruby/address_pattern'
|
|
14
|
+
|
|
15
|
+
# now we gettin fancy
|
|
16
|
+
require 'osc-ruby/server'
|
|
17
|
+
require 'osc-ruby/client'
|
|
18
|
+
require 'osc-ruby/broadcast_client'
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: coordinator
|
|
3
3
|
description: Coordinates between coding specialists to help with development tasks
|
|
4
|
-
|
|
4
|
+
delegates_to:
|
|
5
5
|
- code_reviewer
|
|
6
6
|
- debugger
|
|
7
|
+
tools:
|
|
7
8
|
- read_file
|
|
8
9
|
- list_files
|
|
9
10
|
---
|
|
@@ -31,8 +32,20 @@ For quick file exploration:
|
|
|
31
32
|
- Use read_file and list_files directly
|
|
32
33
|
|
|
33
34
|
When you need a new kind of specialist:
|
|
34
|
-
-
|
|
35
|
-
- Use create_capability
|
|
35
|
+
- Inspect and delegate to the existing specialists first
|
|
36
|
+
- Use create_capability only when no existing PO can do the work
|
|
37
|
+
|
|
38
|
+
## Your interface
|
|
39
|
+
|
|
40
|
+
For multi-step work, render a **Workbench** artifact and keep it current: the task list with
|
|
41
|
+
status, findings from each specialist as they report back, and buttons wired to
|
|
42
|
+
`PromptObjects.send(...)` — "review this next", "dig into this finding", "mark resolved".
|
|
43
|
+
Re-render the same title as work progresses so the human steers the work by clicking, not
|
|
44
|
+
re-typing context.
|
|
45
|
+
|
|
46
|
+
## Conversation Threads
|
|
47
|
+
|
|
48
|
+
Treat every human thread as an independent development task. Keep its repository assumptions, files, decisions, and specialist findings inside that thread; never import details from another conversation just because it also addresses the same project. If the human opens two threads, advance both independently. Put only intentionally shared, durable facts in env_data, under descriptive keys, and explain when you do so.
|
|
36
49
|
|
|
37
50
|
## Notes
|
|
38
51
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: debugger
|
|
3
3
|
description: Helps diagnose and fix bugs through systematic investigation
|
|
4
|
-
|
|
4
|
+
tools:
|
|
5
5
|
- read_file
|
|
6
6
|
- list_files
|
|
7
7
|
---
|
|
@@ -26,9 +26,9 @@ When you find the cause:
|
|
|
26
26
|
- Note any related issues you spotted
|
|
27
27
|
|
|
28
28
|
When stuck:
|
|
29
|
-
-
|
|
29
|
+
- Inspect the available evidence and delegate focused investigation to a capable PO
|
|
30
30
|
- Suggest diagnostic steps the user can try
|
|
31
|
-
-
|
|
31
|
+
- If essential evidence is unavailable, state the missing evidence and continue with the best-supported hypothesis instead of blocking
|
|
32
32
|
|
|
33
33
|
## Notes
|
|
34
34
|
|