prompt_objects 0.3.0 → 0.4.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 +27 -0
- data/Gemfile.lock +31 -29
- data/exe/prompt_objects +161 -0
- data/frontend/package-lock.json +123 -0
- data/frontend/package.json +4 -0
- data/frontend/src/App.tsx +58 -51
- data/frontend/src/canvas/CanvasView.tsx +113 -0
- data/frontend/src/canvas/ForceLayout.ts +115 -0
- data/frontend/src/canvas/SceneManager.ts +587 -0
- data/frontend/src/canvas/canvasStore.ts +47 -0
- data/frontend/src/canvas/constants.ts +95 -0
- data/frontend/src/canvas/controls/CameraControls.ts +98 -0
- data/frontend/src/canvas/edges/MessageArc.ts +149 -0
- data/frontend/src/canvas/inspector/InspectorPanel.tsx +31 -0
- data/frontend/src/canvas/inspector/POInspector.tsx +262 -0
- data/frontend/src/canvas/inspector/ToolCallInspector.tsx +67 -0
- data/frontend/src/canvas/nodes/PONode.ts +249 -0
- data/frontend/src/canvas/nodes/ToolCallNode.ts +116 -0
- data/frontend/src/canvas/types.ts +24 -0
- data/frontend/src/components/ChatPanel.tsx +13 -5
- data/frontend/src/components/Header.tsx +13 -1
- data/frontend/src/hooks/useWebSocket.ts +246 -189
- data/frontend/src/index.css +48 -0
- data/frontend/src/store/index.ts +19 -0
- data/frontend/src/types/index.ts +3 -0
- data/lib/prompt_objects/connectors/mcp.rb +3 -6
- data/lib/prompt_objects/environment.rb +8 -0
- data/lib/prompt_objects/mcp/tools/get_pending_requests.rb +1 -2
- data/lib/prompt_objects/mcp/tools/list_prompt_objects.rb +1 -2
- data/lib/prompt_objects/primitives/list_files.rb +1 -2
- data/lib/prompt_objects/prompt_object.rb +25 -7
- data/lib/prompt_objects/server/app.rb +9 -0
- data/lib/prompt_objects/server/public/assets/index-6y64NXFy.css +1 -0
- data/lib/prompt_objects/server/public/assets/index-xvyeb-5Z.js +4345 -0
- data/lib/prompt_objects/server/public/index.html +2 -2
- data/prompt_objects.gemspec +1 -1
- data/tools/thread-explorer.html +1043 -0
- metadata +18 -4
- data/lib/prompt_objects/server/public/assets/index-Bkme6COu.css +0 -1
- data/lib/prompt_objects/server/public/assets/index-CQ7lVDF_.js +0 -77
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 92cf8b8492d42dee0adb37a4fb41692e6b228ab7a364f9176444c60cd81eb63d
|
|
4
|
+
data.tar.gz: 45e8828d53f7b9c4893fb6374535bbb099c77e92371a3e111bda07d9e35db93e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 123244bee715f744b7b377bbf4e2912ed28cbb966ce6b92bb7d43a5ea053bf2460e7bb10c35acf09ab5f4cfa8f0afeeb78198be62acfbde44b86f3c5f0559deb
|
|
7
|
+
data.tar.gz: 15ee859102e87e971df1e38b756d776a0f913148554974fc2fe9ae79b12853cf9028793aadfaabb92aa1d74961739c97a51c258c0e9e2a38cbf77fb5f931b46d
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to PromptObjects are documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.4.0] - 2026-02-11
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Spatial Canvas** — Three.js 2D visualization at `/canvas` showing POs as glowing hexagonal nodes with force-directed layout, tool call diamonds, animated message arcs with traveling particles, and click-to-inspect side panels. Real-time updates from the same WebSocket feed as the dashboard. Zoom, pan, and keyboard shortcuts (F to fit, Escape to deselect).
|
|
10
|
+
- **PO-to-PO delegation broadcasting** — Server now broadcasts `po_delegation_started` and `po_delegation_completed` WebSocket events when one PO calls another. Delegated POs show as active in both the canvas (cyan glow, "called by X" status) and dashboard views. Replaces client-side inference from message history scanning.
|
|
11
|
+
- **Ruby 4 support** — CI now tests against Ruby 4. Fixed empty required parameter handling for compatibility. Thanks to [@radanskoric](https://github.com/radanskoric) for the contribution! ([#2](https://github.com/works-on-your-machine/prompt_objects/pull/2))
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **WebSocket reconnection lifecycle** — Fixed duplicate connections on page refresh caused by zombie `onclose` handlers. Added socket identity guards, close-before-reconnect, and `handleMessageRef` pattern to prevent stale closures.
|
|
16
|
+
- **Stale state on disconnect** — PO statuses now reset to idle when WebSocket disconnects, preventing stuck "thinking" indicators and stale streaming content.
|
|
17
|
+
- **Chat input locked on disconnect** — Chat input is now only disabled when the PO is busy AND connected. Shows "Reconnecting..." indicator when disconnected instead of permanently locking.
|
|
18
|
+
- **Tool calls not appearing on canvas** — Tool call visualization now extracts from PO message history instead of looking for a format bus messages don't use.
|
|
19
|
+
|
|
20
|
+
## [0.3.1] - 2025-02-08
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- **Thread Explorer** — Standalone HTML visualizer for exploring conversation thread exports. Three views: sequence diagram (swim lanes showing PO communication), timeline (flat chronological event list), and detail panel (full conversation with tool calls). Includes token cost bar, search, per-PO filtering, breadcrumb navigation, and structural event highlighting.
|
|
25
|
+
- **`explore` CLI command** — Open Thread Explorer from the command line. `prompt_objects explore <env>` lists root threads and opens the most recent; `--session ID` targets a specific thread. Data is embedded directly so it opens ready to go.
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- Delegation messages now correctly show the calling PO's name instead of "human". Previously `context.current_capability` resolved to the target PO (matching its own name), causing a fallback to "human". Now uses `context.calling_po`.
|
|
30
|
+
- CLI integration tests skip gracefully in CI when no LLM API key is available, instead of failing.
|
|
31
|
+
|
|
5
32
|
## [0.3.0] - 2025-02-05
|
|
6
33
|
|
|
7
34
|
### Added
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
prompt_objects (0.
|
|
4
|
+
prompt_objects (0.4.0)
|
|
5
5
|
anthropic (~> 1.0)
|
|
6
6
|
async-websocket (~> 0.28)
|
|
7
7
|
falcon (~> 0.50)
|
|
@@ -17,24 +17,25 @@ GEM
|
|
|
17
17
|
specs:
|
|
18
18
|
addressable (2.8.8)
|
|
19
19
|
public_suffix (>= 2.0.2, < 8.0)
|
|
20
|
-
anthropic (1.
|
|
20
|
+
anthropic (1.19.0)
|
|
21
|
+
cgi
|
|
21
22
|
connection_pool
|
|
22
23
|
ast (2.4.3)
|
|
23
|
-
async (2.
|
|
24
|
+
async (2.36.0)
|
|
24
25
|
console (~> 1.29)
|
|
25
26
|
fiber-annotation
|
|
26
27
|
io-event (~> 1.11)
|
|
27
28
|
metrics (~> 0.12)
|
|
28
29
|
traces (~> 0.18)
|
|
29
|
-
async-container (0.
|
|
30
|
+
async-container (0.30.0)
|
|
30
31
|
async (~> 2.22)
|
|
31
|
-
async-container-supervisor (0.9.
|
|
32
|
+
async-container-supervisor (0.9.3)
|
|
32
33
|
async-service
|
|
33
34
|
io-endpoint
|
|
34
35
|
memory (~> 0.7)
|
|
35
36
|
memory-leak (~> 0.5)
|
|
36
37
|
process-metrics
|
|
37
|
-
async-http (0.94.
|
|
38
|
+
async-http (0.94.2)
|
|
38
39
|
async (>= 2.10.2)
|
|
39
40
|
async-pool (~> 0.11)
|
|
40
41
|
io-endpoint (~> 0.14)
|
|
@@ -49,9 +50,9 @@ GEM
|
|
|
49
50
|
async-http (~> 0.56)
|
|
50
51
|
async-pool (0.11.1)
|
|
51
52
|
async (>= 2.0)
|
|
52
|
-
async-service (0.
|
|
53
|
+
async-service (0.19.0)
|
|
53
54
|
async
|
|
54
|
-
async-container (~> 0.
|
|
55
|
+
async-container (~> 0.29)
|
|
55
56
|
string-format (~> 0.2)
|
|
56
57
|
async-websocket (0.30.0)
|
|
57
58
|
async-http (~> 0.76)
|
|
@@ -63,6 +64,7 @@ GEM
|
|
|
63
64
|
samovar (~> 2.1)
|
|
64
65
|
base64 (0.3.0)
|
|
65
66
|
bigdecimal (4.0.1)
|
|
67
|
+
cgi (0.5.1)
|
|
66
68
|
connection_pool (3.0.2)
|
|
67
69
|
console (1.34.2)
|
|
68
70
|
fiber-annotation
|
|
@@ -74,20 +76,20 @@ GEM
|
|
|
74
76
|
reline (>= 0.3.8)
|
|
75
77
|
erb (6.0.1)
|
|
76
78
|
event_stream_parser (1.0.0)
|
|
77
|
-
falcon (0.
|
|
79
|
+
falcon (0.54.2)
|
|
78
80
|
async
|
|
79
81
|
async-container (~> 0.20)
|
|
80
82
|
async-container-supervisor (~> 0.6)
|
|
81
83
|
async-http (~> 0.75)
|
|
82
84
|
async-http-cache (~> 0.4)
|
|
83
|
-
async-service (~> 0.
|
|
85
|
+
async-service (~> 0.19)
|
|
84
86
|
bundler
|
|
85
87
|
localhost (~> 1.1)
|
|
86
88
|
openssl (>= 3.0)
|
|
87
89
|
protocol-http (~> 0.31)
|
|
88
90
|
protocol-rack (~> 0.7)
|
|
89
91
|
samovar (~> 2.3)
|
|
90
|
-
faraday (2.14.
|
|
92
|
+
faraday (2.14.1)
|
|
91
93
|
faraday-net_http (>= 2.0, < 3.5)
|
|
92
94
|
json
|
|
93
95
|
logger
|
|
@@ -103,29 +105,29 @@ GEM
|
|
|
103
105
|
fiber-storage (1.0.1)
|
|
104
106
|
front_matter_parser (1.0.1)
|
|
105
107
|
io-console (0.8.2)
|
|
106
|
-
io-endpoint (0.
|
|
108
|
+
io-endpoint (0.17.2)
|
|
107
109
|
io-event (1.14.2)
|
|
108
110
|
io-stream (0.11.1)
|
|
109
|
-
irb (1.
|
|
111
|
+
irb (1.17.0)
|
|
110
112
|
pp (>= 0.6.0)
|
|
113
|
+
prism (>= 1.3.0)
|
|
111
114
|
rdoc (>= 4.0.0)
|
|
112
115
|
reline (>= 0.4.2)
|
|
113
|
-
json (2.18.
|
|
116
|
+
json (2.18.1)
|
|
114
117
|
json-schema (6.1.0)
|
|
115
118
|
addressable (~> 2.8)
|
|
116
119
|
bigdecimal (>= 3.1, < 5)
|
|
117
|
-
json_rpc_handler (0.1.1)
|
|
118
120
|
language_server-protocol (3.17.0.5)
|
|
119
121
|
lint_roller (1.1.0)
|
|
120
|
-
listen (3.
|
|
122
|
+
listen (3.10.0)
|
|
123
|
+
logger
|
|
121
124
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
|
122
125
|
rb-inotify (~> 0.9, >= 0.9.10)
|
|
123
|
-
localhost (1.
|
|
126
|
+
localhost (1.7.0)
|
|
124
127
|
logger (1.7.0)
|
|
125
128
|
mapping (1.1.3)
|
|
126
|
-
mcp (0.
|
|
129
|
+
mcp (0.6.0)
|
|
127
130
|
json-schema (>= 4.1)
|
|
128
|
-
json_rpc_handler (~> 0.1)
|
|
129
131
|
memory (0.12.0)
|
|
130
132
|
bake (~> 0.15)
|
|
131
133
|
console
|
|
@@ -139,25 +141,25 @@ GEM
|
|
|
139
141
|
uri (>= 0.11.1)
|
|
140
142
|
openssl (4.0.0)
|
|
141
143
|
parallel (1.27.0)
|
|
142
|
-
parser (3.3.10.
|
|
144
|
+
parser (3.3.10.1)
|
|
143
145
|
ast (~> 2.4.1)
|
|
144
146
|
racc
|
|
145
147
|
pp (0.6.3)
|
|
146
148
|
prettyprint
|
|
147
149
|
prettyprint (0.2.0)
|
|
148
|
-
prism (1.
|
|
150
|
+
prism (1.9.0)
|
|
149
151
|
process-metrics (0.8.0)
|
|
150
152
|
console (~> 1.8)
|
|
151
153
|
json (~> 2)
|
|
152
154
|
samovar (~> 2.1)
|
|
153
155
|
protocol-hpack (1.5.1)
|
|
154
|
-
protocol-http (0.
|
|
155
|
-
protocol-http1 (0.
|
|
156
|
+
protocol-http (0.59.0)
|
|
157
|
+
protocol-http1 (0.37.0)
|
|
156
158
|
protocol-http (~> 0.58)
|
|
157
|
-
protocol-http2 (0.
|
|
159
|
+
protocol-http2 (0.24.0)
|
|
158
160
|
protocol-hpack (~> 1.4)
|
|
159
161
|
protocol-http (~> 0.47)
|
|
160
|
-
protocol-rack (0.21.
|
|
162
|
+
protocol-rack (0.21.1)
|
|
161
163
|
io-stream (>= 0.10)
|
|
162
164
|
protocol-http (~> 0.58)
|
|
163
165
|
rack (>= 1.0)
|
|
@@ -167,7 +169,7 @@ GEM
|
|
|
167
169
|
psych (5.3.1)
|
|
168
170
|
date
|
|
169
171
|
stringio
|
|
170
|
-
public_suffix (7.0.
|
|
172
|
+
public_suffix (7.0.2)
|
|
171
173
|
racc (1.8.1)
|
|
172
174
|
rack (3.2.4)
|
|
173
175
|
rainbow (3.1.1)
|
|
@@ -175,14 +177,14 @@ GEM
|
|
|
175
177
|
rb-fsevent (0.11.2)
|
|
176
178
|
rb-inotify (0.11.1)
|
|
177
179
|
ffi (~> 1.0)
|
|
178
|
-
rdoc (7.0
|
|
180
|
+
rdoc (7.2.0)
|
|
179
181
|
erb
|
|
180
182
|
psych (>= 4.0.0)
|
|
181
183
|
tsort
|
|
182
184
|
regexp_parser (2.11.3)
|
|
183
185
|
reline (0.6.3)
|
|
184
186
|
io-console (~> 0.5)
|
|
185
|
-
rubocop (1.
|
|
187
|
+
rubocop (1.84.1)
|
|
186
188
|
json (~> 2.3)
|
|
187
189
|
language_server-protocol (~> 3.17.0.2)
|
|
188
190
|
lint_roller (~> 1.1.0)
|
|
@@ -190,7 +192,7 @@ GEM
|
|
|
190
192
|
parser (>= 3.3.0.2)
|
|
191
193
|
rainbow (>= 2.2.2, < 4.0)
|
|
192
194
|
regexp_parser (>= 2.9.3, < 3.0)
|
|
193
|
-
rubocop-ast (>= 1.
|
|
195
|
+
rubocop-ast (>= 1.49.0, < 2.0)
|
|
194
196
|
ruby-progressbar (~> 1.7)
|
|
195
197
|
unicode-display_width (>= 2.4.0, < 4.0)
|
|
196
198
|
rubocop-ast (1.49.0)
|
data/exe/prompt_objects
CHANGED
|
@@ -285,6 +285,7 @@ def print_main_help
|
|
|
285
285
|
serve <env> Run environment as a web server
|
|
286
286
|
message <env> <po> "text" Send a message to a PO and print the response
|
|
287
287
|
events <env> [--session ID] Show recent events from the message bus
|
|
288
|
+
explore [env] [--session ID] Open Thread Explorer to visualize conversations
|
|
288
289
|
repl [name] [objects_dir] Start interactive REPL with a prompt object
|
|
289
290
|
help Show this help message
|
|
290
291
|
|
|
@@ -297,6 +298,7 @@ def print_main_help
|
|
|
297
298
|
prompt_objects serve my-env --open # Start and open browser
|
|
298
299
|
prompt_objects message my-env solver "Hello" # Send a message
|
|
299
300
|
prompt_objects message my-env solver "Hello" --json # JSON output
|
|
301
|
+
prompt_objects explore my-env # Visualize conversations
|
|
300
302
|
HELP
|
|
301
303
|
end
|
|
302
304
|
|
|
@@ -920,6 +922,163 @@ def print_events(events)
|
|
|
920
922
|
end
|
|
921
923
|
end
|
|
922
924
|
|
|
925
|
+
# === Explore Command ===
|
|
926
|
+
|
|
927
|
+
def run_explore(args)
|
|
928
|
+
options = { session_id: nil }
|
|
929
|
+
positional = []
|
|
930
|
+
skip_next = false
|
|
931
|
+
|
|
932
|
+
args.each_with_index do |arg, i|
|
|
933
|
+
if skip_next
|
|
934
|
+
skip_next = false
|
|
935
|
+
next
|
|
936
|
+
end
|
|
937
|
+
|
|
938
|
+
case arg
|
|
939
|
+
when "--session"
|
|
940
|
+
options[:session_id] = args[i + 1]
|
|
941
|
+
skip_next = true
|
|
942
|
+
when "--help", "-h"
|
|
943
|
+
print_explore_help
|
|
944
|
+
exit 0
|
|
945
|
+
else
|
|
946
|
+
positional << arg
|
|
947
|
+
end
|
|
948
|
+
end
|
|
949
|
+
|
|
950
|
+
explorer_html = File.expand_path("../tools/thread-explorer.html", __dir__)
|
|
951
|
+
|
|
952
|
+
# No args: just open the empty visualizer
|
|
953
|
+
unless positional[0]
|
|
954
|
+
open_in_browser("file://#{explorer_html}")
|
|
955
|
+
puts "Opened Thread Explorer in browser"
|
|
956
|
+
exit 0
|
|
957
|
+
end
|
|
958
|
+
|
|
959
|
+
env_path = resolve_environment(positional[0])
|
|
960
|
+
unless env_path
|
|
961
|
+
$stderr.puts "Error: environment '#{positional[0]}' not found"
|
|
962
|
+
exit 1
|
|
963
|
+
end
|
|
964
|
+
|
|
965
|
+
db_path = File.join(env_path, "sessions.db")
|
|
966
|
+
unless File.exist?(db_path)
|
|
967
|
+
$stderr.puts "No session data found (sessions.db not found)"
|
|
968
|
+
$stderr.puts "Opening empty Thread Explorer..."
|
|
969
|
+
open_in_browser("file://#{explorer_html}")
|
|
970
|
+
exit 0
|
|
971
|
+
end
|
|
972
|
+
|
|
973
|
+
store = PromptObjects::Session::Store.new(db_path)
|
|
974
|
+
|
|
975
|
+
if options[:session_id]
|
|
976
|
+
# Export a specific thread
|
|
977
|
+
export_and_open(store, options[:session_id], explorer_html)
|
|
978
|
+
else
|
|
979
|
+
# List sessions and let user choose, or export the most recent root thread
|
|
980
|
+
# Query root sessions directly (list_sessions requires po_name)
|
|
981
|
+
rows = store.instance_variable_get(:@db).execute(<<~SQL)
|
|
982
|
+
SELECT * FROM sessions
|
|
983
|
+
WHERE thread_type IS NULL OR thread_type = 'root'
|
|
984
|
+
ORDER BY created_at ASC
|
|
985
|
+
SQL
|
|
986
|
+
root_sessions = rows.map { |r| { id: r["id"], po_name: r["po_name"], name: r["name"], thread_type: r["thread_type"], created_at: r["created_at"] } }
|
|
987
|
+
|
|
988
|
+
if root_sessions.empty?
|
|
989
|
+
$stderr.puts "No root sessions found"
|
|
990
|
+
open_in_browser("file://#{explorer_html}")
|
|
991
|
+
exit 0
|
|
992
|
+
end
|
|
993
|
+
|
|
994
|
+
# Show available sessions
|
|
995
|
+
puts "Root threads:"
|
|
996
|
+
root_sessions.last(10).each_with_index do |s, i|
|
|
997
|
+
name = s[:name] || "(unnamed)"
|
|
998
|
+
po = s[:po_name] || "?"
|
|
999
|
+
time = s[:created_at]
|
|
1000
|
+
time_str = time.is_a?(Time) ? time.strftime("%Y-%m-%d %H:%M") : time.to_s[0, 16]
|
|
1001
|
+
puts " #{i + 1}. [#{po}] #{name} (#{time_str}) #{s[:id]}"
|
|
1002
|
+
end
|
|
1003
|
+
|
|
1004
|
+
puts
|
|
1005
|
+
puts "Opening most recent thread..."
|
|
1006
|
+
export_and_open(store, root_sessions.last[:id], explorer_html)
|
|
1007
|
+
end
|
|
1008
|
+
|
|
1009
|
+
store.close
|
|
1010
|
+
end
|
|
1011
|
+
|
|
1012
|
+
def export_and_open(store, session_id, explorer_html)
|
|
1013
|
+
data = store.export_thread_tree_json(session_id)
|
|
1014
|
+
unless data
|
|
1015
|
+
$stderr.puts "Error: session '#{session_id}' not found"
|
|
1016
|
+
exit 1
|
|
1017
|
+
end
|
|
1018
|
+
|
|
1019
|
+
json_str = JSON.generate(data)
|
|
1020
|
+
|
|
1021
|
+
# Read the explorer HTML and inject the data as auto-load
|
|
1022
|
+
html_content = File.read(explorer_html)
|
|
1023
|
+
inject_script = <<~JS
|
|
1024
|
+
<script>
|
|
1025
|
+
// Auto-load embedded data
|
|
1026
|
+
window.addEventListener('DOMContentLoaded', function() {
|
|
1027
|
+
var data = #{json_str};
|
|
1028
|
+
if (typeof loadData === 'function') loadData(data);
|
|
1029
|
+
});
|
|
1030
|
+
</script>
|
|
1031
|
+
JS
|
|
1032
|
+
|
|
1033
|
+
# Insert before </body>
|
|
1034
|
+
html_content = html_content.sub("</body>", "#{inject_script}</body>")
|
|
1035
|
+
|
|
1036
|
+
# Write to temp file
|
|
1037
|
+
require "tempfile"
|
|
1038
|
+
tmp = Tempfile.new(["thread-explorer-", ".html"])
|
|
1039
|
+
tmp.write(html_content)
|
|
1040
|
+
tmp.close
|
|
1041
|
+
|
|
1042
|
+
open_in_browser("file://#{tmp.path}")
|
|
1043
|
+
puts "Opened Thread Explorer for session #{session_id}"
|
|
1044
|
+
|
|
1045
|
+
# Keep temp file around briefly so the browser can load it
|
|
1046
|
+
sleep 2
|
|
1047
|
+
end
|
|
1048
|
+
|
|
1049
|
+
def open_in_browser(url)
|
|
1050
|
+
case RUBY_PLATFORM
|
|
1051
|
+
when /darwin/
|
|
1052
|
+
system("open", url)
|
|
1053
|
+
when /linux/
|
|
1054
|
+
system("xdg-open", url)
|
|
1055
|
+
when /mswin|mingw|cygwin/
|
|
1056
|
+
system("start", url)
|
|
1057
|
+
else
|
|
1058
|
+
$stderr.puts "Open this URL in your browser: #{url}"
|
|
1059
|
+
end
|
|
1060
|
+
end
|
|
1061
|
+
|
|
1062
|
+
def print_explore_help
|
|
1063
|
+
puts <<~HELP
|
|
1064
|
+
Usage: prompt_objects explore [env] [options]
|
|
1065
|
+
|
|
1066
|
+
Open the Thread Explorer to visualize conversation threads.
|
|
1067
|
+
|
|
1068
|
+
Arguments:
|
|
1069
|
+
env Environment name or path (optional)
|
|
1070
|
+
|
|
1071
|
+
Options:
|
|
1072
|
+
--session ID Open a specific thread by session ID
|
|
1073
|
+
--help, -h Show this help message
|
|
1074
|
+
|
|
1075
|
+
Examples:
|
|
1076
|
+
prompt_objects explore # Open empty explorer
|
|
1077
|
+
prompt_objects explore my-env # Open most recent thread
|
|
1078
|
+
prompt_objects explore my-env --session abc123 # Open specific thread
|
|
1079
|
+
HELP
|
|
1080
|
+
end
|
|
1081
|
+
|
|
923
1082
|
# === Main Entry Point ===
|
|
924
1083
|
|
|
925
1084
|
def run_env(args)
|
|
@@ -947,6 +1106,8 @@ def main
|
|
|
947
1106
|
run_message(args)
|
|
948
1107
|
when "events"
|
|
949
1108
|
run_events(args)
|
|
1109
|
+
when "explore"
|
|
1110
|
+
run_explore(args)
|
|
950
1111
|
when "help", "--help", "-h"
|
|
951
1112
|
print_main_help
|
|
952
1113
|
else
|
data/frontend/package-lock.json
CHANGED
|
@@ -10,16 +10,20 @@
|
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@types/react-syntax-highlighter": "^15.5.13",
|
|
12
12
|
"clsx": "^2.1.1",
|
|
13
|
+
"d3-force": "^3.0.0",
|
|
13
14
|
"react": "^18.3.1",
|
|
14
15
|
"react-dom": "^18.3.1",
|
|
15
16
|
"react-markdown": "^10.1.0",
|
|
16
17
|
"react-syntax-highlighter": "^16.1.0",
|
|
17
18
|
"remark-gfm": "^4.0.1",
|
|
19
|
+
"three": "^0.182.0",
|
|
18
20
|
"zustand": "^5.0.0"
|
|
19
21
|
},
|
|
20
22
|
"devDependencies": {
|
|
23
|
+
"@types/d3-force": "^3.0.10",
|
|
21
24
|
"@types/react": "^18.3.12",
|
|
22
25
|
"@types/react-dom": "^18.3.1",
|
|
26
|
+
"@types/three": "^0.182.0",
|
|
23
27
|
"@vitejs/plugin-react": "^4.3.4",
|
|
24
28
|
"autoprefixer": "^10.4.20",
|
|
25
29
|
"postcss": "^8.4.49",
|
|
@@ -332,6 +336,13 @@
|
|
|
332
336
|
"node": ">=6.9.0"
|
|
333
337
|
}
|
|
334
338
|
},
|
|
339
|
+
"node_modules/@dimforge/rapier3d-compat": {
|
|
340
|
+
"version": "0.12.0",
|
|
341
|
+
"resolved": "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz",
|
|
342
|
+
"integrity": "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==",
|
|
343
|
+
"dev": true,
|
|
344
|
+
"license": "Apache-2.0"
|
|
345
|
+
},
|
|
335
346
|
"node_modules/@esbuild/aix-ppc64": {
|
|
336
347
|
"version": "0.25.12",
|
|
337
348
|
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz",
|
|
@@ -1219,6 +1230,13 @@
|
|
|
1219
1230
|
"win32"
|
|
1220
1231
|
]
|
|
1221
1232
|
},
|
|
1233
|
+
"node_modules/@tweenjs/tween.js": {
|
|
1234
|
+
"version": "23.1.3",
|
|
1235
|
+
"resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz",
|
|
1236
|
+
"integrity": "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==",
|
|
1237
|
+
"dev": true,
|
|
1238
|
+
"license": "MIT"
|
|
1239
|
+
},
|
|
1222
1240
|
"node_modules/@types/babel__core": {
|
|
1223
1241
|
"version": "7.20.5",
|
|
1224
1242
|
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
|
|
@@ -1264,6 +1282,13 @@
|
|
|
1264
1282
|
"@babel/types": "^7.28.2"
|
|
1265
1283
|
}
|
|
1266
1284
|
},
|
|
1285
|
+
"node_modules/@types/d3-force": {
|
|
1286
|
+
"version": "3.0.10",
|
|
1287
|
+
"resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz",
|
|
1288
|
+
"integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==",
|
|
1289
|
+
"dev": true,
|
|
1290
|
+
"license": "MIT"
|
|
1291
|
+
},
|
|
1267
1292
|
"node_modules/@types/debug": {
|
|
1268
1293
|
"version": "4.1.12",
|
|
1269
1294
|
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
|
|
@@ -1353,12 +1378,42 @@
|
|
|
1353
1378
|
"@types/react": "*"
|
|
1354
1379
|
}
|
|
1355
1380
|
},
|
|
1381
|
+
"node_modules/@types/stats.js": {
|
|
1382
|
+
"version": "0.17.4",
|
|
1383
|
+
"resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.4.tgz",
|
|
1384
|
+
"integrity": "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==",
|
|
1385
|
+
"dev": true,
|
|
1386
|
+
"license": "MIT"
|
|
1387
|
+
},
|
|
1388
|
+
"node_modules/@types/three": {
|
|
1389
|
+
"version": "0.182.0",
|
|
1390
|
+
"resolved": "https://registry.npmjs.org/@types/three/-/three-0.182.0.tgz",
|
|
1391
|
+
"integrity": "sha512-WByN9V3Sbwbe2OkWuSGyoqQO8Du6yhYaXtXLoA5FkKTUJorZ+yOHBZ35zUUPQXlAKABZmbYp5oAqpA4RBjtJ/Q==",
|
|
1392
|
+
"dev": true,
|
|
1393
|
+
"license": "MIT",
|
|
1394
|
+
"dependencies": {
|
|
1395
|
+
"@dimforge/rapier3d-compat": "~0.12.0",
|
|
1396
|
+
"@tweenjs/tween.js": "~23.1.3",
|
|
1397
|
+
"@types/stats.js": "*",
|
|
1398
|
+
"@types/webxr": ">=0.5.17",
|
|
1399
|
+
"@webgpu/types": "*",
|
|
1400
|
+
"fflate": "~0.8.2",
|
|
1401
|
+
"meshoptimizer": "~0.22.0"
|
|
1402
|
+
}
|
|
1403
|
+
},
|
|
1356
1404
|
"node_modules/@types/unist": {
|
|
1357
1405
|
"version": "3.0.3",
|
|
1358
1406
|
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
|
|
1359
1407
|
"integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
|
|
1360
1408
|
"license": "MIT"
|
|
1361
1409
|
},
|
|
1410
|
+
"node_modules/@types/webxr": {
|
|
1411
|
+
"version": "0.5.24",
|
|
1412
|
+
"resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.24.tgz",
|
|
1413
|
+
"integrity": "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==",
|
|
1414
|
+
"dev": true,
|
|
1415
|
+
"license": "MIT"
|
|
1416
|
+
},
|
|
1362
1417
|
"node_modules/@ungap/structured-clone": {
|
|
1363
1418
|
"version": "1.3.0",
|
|
1364
1419
|
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
|
|
@@ -1386,6 +1441,13 @@
|
|
|
1386
1441
|
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
|
|
1387
1442
|
}
|
|
1388
1443
|
},
|
|
1444
|
+
"node_modules/@webgpu/types": {
|
|
1445
|
+
"version": "0.1.69",
|
|
1446
|
+
"resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.69.tgz",
|
|
1447
|
+
"integrity": "sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ==",
|
|
1448
|
+
"dev": true,
|
|
1449
|
+
"license": "BSD-3-Clause"
|
|
1450
|
+
},
|
|
1389
1451
|
"node_modules/any-promise": {
|
|
1390
1452
|
"version": "1.3.0",
|
|
1391
1453
|
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
|
|
@@ -1705,6 +1767,47 @@
|
|
|
1705
1767
|
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
|
|
1706
1768
|
"license": "MIT"
|
|
1707
1769
|
},
|
|
1770
|
+
"node_modules/d3-dispatch": {
|
|
1771
|
+
"version": "3.0.1",
|
|
1772
|
+
"resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz",
|
|
1773
|
+
"integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==",
|
|
1774
|
+
"license": "ISC",
|
|
1775
|
+
"engines": {
|
|
1776
|
+
"node": ">=12"
|
|
1777
|
+
}
|
|
1778
|
+
},
|
|
1779
|
+
"node_modules/d3-force": {
|
|
1780
|
+
"version": "3.0.0",
|
|
1781
|
+
"resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz",
|
|
1782
|
+
"integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==",
|
|
1783
|
+
"license": "ISC",
|
|
1784
|
+
"dependencies": {
|
|
1785
|
+
"d3-dispatch": "1 - 3",
|
|
1786
|
+
"d3-quadtree": "1 - 3",
|
|
1787
|
+
"d3-timer": "1 - 3"
|
|
1788
|
+
},
|
|
1789
|
+
"engines": {
|
|
1790
|
+
"node": ">=12"
|
|
1791
|
+
}
|
|
1792
|
+
},
|
|
1793
|
+
"node_modules/d3-quadtree": {
|
|
1794
|
+
"version": "3.0.1",
|
|
1795
|
+
"resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz",
|
|
1796
|
+
"integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==",
|
|
1797
|
+
"license": "ISC",
|
|
1798
|
+
"engines": {
|
|
1799
|
+
"node": ">=12"
|
|
1800
|
+
}
|
|
1801
|
+
},
|
|
1802
|
+
"node_modules/d3-timer": {
|
|
1803
|
+
"version": "3.0.1",
|
|
1804
|
+
"resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
|
|
1805
|
+
"integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
|
|
1806
|
+
"license": "ISC",
|
|
1807
|
+
"engines": {
|
|
1808
|
+
"node": ">=12"
|
|
1809
|
+
}
|
|
1810
|
+
},
|
|
1708
1811
|
"node_modules/debug": {
|
|
1709
1812
|
"version": "4.4.3",
|
|
1710
1813
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
|
@@ -1911,6 +2014,13 @@
|
|
|
1911
2014
|
"url": "https://github.com/sponsors/wooorm"
|
|
1912
2015
|
}
|
|
1913
2016
|
},
|
|
2017
|
+
"node_modules/fflate": {
|
|
2018
|
+
"version": "0.8.2",
|
|
2019
|
+
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
|
|
2020
|
+
"integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==",
|
|
2021
|
+
"dev": true,
|
|
2022
|
+
"license": "MIT"
|
|
2023
|
+
},
|
|
1914
2024
|
"node_modules/fill-range": {
|
|
1915
2025
|
"version": "7.1.1",
|
|
1916
2026
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
|
@@ -2624,6 +2734,13 @@
|
|
|
2624
2734
|
"node": ">= 8"
|
|
2625
2735
|
}
|
|
2626
2736
|
},
|
|
2737
|
+
"node_modules/meshoptimizer": {
|
|
2738
|
+
"version": "0.22.0",
|
|
2739
|
+
"resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.22.0.tgz",
|
|
2740
|
+
"integrity": "sha512-IebiK79sqIy+E4EgOr+CAw+Ke8hAspXKzBd0JdgEmPHiAwmvEj2S4h1rfvo+o/BnfEYd/jAOg5IeeIjzlzSnDg==",
|
|
2741
|
+
"dev": true,
|
|
2742
|
+
"license": "MIT"
|
|
2743
|
+
},
|
|
2627
2744
|
"node_modules/micromark": {
|
|
2628
2745
|
"version": "4.0.2",
|
|
2629
2746
|
"resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz",
|
|
@@ -4006,6 +4123,12 @@
|
|
|
4006
4123
|
"node": ">=0.8"
|
|
4007
4124
|
}
|
|
4008
4125
|
},
|
|
4126
|
+
"node_modules/three": {
|
|
4127
|
+
"version": "0.182.0",
|
|
4128
|
+
"resolved": "https://registry.npmjs.org/three/-/three-0.182.0.tgz",
|
|
4129
|
+
"integrity": "sha512-GbHabT+Irv+ihI1/f5kIIsZ+Ef9Sl5A1Y7imvS5RQjWgtTPfPnZ43JmlYI7NtCRDK9zir20lQpfg8/9Yd02OvQ==",
|
|
4130
|
+
"license": "MIT"
|
|
4131
|
+
},
|
|
4009
4132
|
"node_modules/tinyglobby": {
|
|
4010
4133
|
"version": "0.2.15",
|
|
4011
4134
|
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
|
data/frontend/package.json
CHANGED
|
@@ -12,16 +12,20 @@
|
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@types/react-syntax-highlighter": "^15.5.13",
|
|
14
14
|
"clsx": "^2.1.1",
|
|
15
|
+
"d3-force": "^3.0.0",
|
|
15
16
|
"react": "^18.3.1",
|
|
16
17
|
"react-dom": "^18.3.1",
|
|
17
18
|
"react-markdown": "^10.1.0",
|
|
18
19
|
"react-syntax-highlighter": "^16.1.0",
|
|
19
20
|
"remark-gfm": "^4.0.1",
|
|
21
|
+
"three": "^0.182.0",
|
|
20
22
|
"zustand": "^5.0.0"
|
|
21
23
|
},
|
|
22
24
|
"devDependencies": {
|
|
25
|
+
"@types/d3-force": "^3.0.10",
|
|
23
26
|
"@types/react": "^18.3.12",
|
|
24
27
|
"@types/react-dom": "^18.3.1",
|
|
28
|
+
"@types/three": "^0.182.0",
|
|
25
29
|
"@vitejs/plugin-react": "^4.3.4",
|
|
26
30
|
"autoprefixer": "^10.4.20",
|
|
27
31
|
"postcss": "^8.4.49",
|