@gxp-dev/tools 2.0.62 → 2.0.64
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.
- package/README.md +32 -31
- package/bin/gx-devtools.js +74 -54
- package/bin/lib/cli.js +23 -21
- package/bin/lib/commands/add-dependency.js +366 -325
- package/bin/lib/commands/assets.js +137 -139
- package/bin/lib/commands/build.js +169 -174
- package/bin/lib/commands/datastore.js +181 -183
- package/bin/lib/commands/dev.js +127 -131
- package/bin/lib/commands/extensions.js +147 -149
- package/bin/lib/commands/extract-config.js +73 -67
- package/bin/lib/commands/index.js +12 -12
- package/bin/lib/commands/init.js +342 -240
- package/bin/lib/commands/publish.js +69 -75
- package/bin/lib/commands/socket.js +69 -69
- package/bin/lib/commands/ssl.js +14 -14
- package/bin/lib/constants.js +10 -24
- package/bin/lib/tui/App.tsx +761 -705
- package/bin/lib/tui/components/AIPanel.tsx +191 -171
- package/bin/lib/tui/components/CommandInput.tsx +394 -343
- package/bin/lib/tui/components/GeminiPanel.tsx +175 -151
- package/bin/lib/tui/components/Header.tsx +23 -21
- package/bin/lib/tui/components/LogPanel.tsx +244 -220
- package/bin/lib/tui/components/TabBar.tsx +50 -48
- package/bin/lib/tui/components/WelcomeScreen.tsx +126 -71
- package/bin/lib/tui/index.tsx +37 -39
- package/bin/lib/tui/services/AIService.ts +518 -462
- package/bin/lib/tui/services/ExtensionService.ts +140 -129
- package/bin/lib/tui/services/GeminiService.ts +367 -337
- package/bin/lib/tui/services/ServiceManager.ts +344 -322
- package/bin/lib/tui/services/SocketService.ts +168 -168
- package/bin/lib/tui/services/ViteService.ts +88 -88
- package/bin/lib/tui/services/index.ts +47 -22
- package/bin/lib/utils/ai-scaffold.js +291 -280
- package/bin/lib/utils/extract-config.js +157 -140
- package/bin/lib/utils/files.js +82 -86
- package/bin/lib/utils/index.js +7 -7
- package/bin/lib/utils/paths.js +34 -34
- package/bin/lib/utils/prompts.js +194 -169
- package/bin/lib/utils/ssl.js +79 -81
- package/browser-extensions/README.md +0 -1
- package/browser-extensions/chrome/background.js +244 -237
- package/browser-extensions/chrome/content.js +32 -29
- package/browser-extensions/chrome/devtools.html +7 -7
- package/browser-extensions/chrome/devtools.js +19 -19
- package/browser-extensions/chrome/inspector.js +802 -767
- package/browser-extensions/chrome/manifest.json +71 -63
- package/browser-extensions/chrome/panel.html +674 -636
- package/browser-extensions/chrome/panel.js +722 -712
- package/browser-extensions/chrome/popup.html +586 -543
- package/browser-extensions/chrome/popup.js +282 -244
- package/browser-extensions/chrome/rules.json +1 -1
- package/browser-extensions/chrome/test-chrome.html +216 -136
- package/browser-extensions/chrome/test-mixed-content.html +284 -189
- package/browser-extensions/chrome/test-uri-pattern.html +221 -198
- package/browser-extensions/firefox/README.md +9 -6
- package/browser-extensions/firefox/background.js +221 -218
- package/browser-extensions/firefox/content.js +55 -52
- package/browser-extensions/firefox/debug-errors.html +386 -228
- package/browser-extensions/firefox/debug-https.html +153 -105
- package/browser-extensions/firefox/devtools.html +7 -7
- package/browser-extensions/firefox/devtools.js +23 -20
- package/browser-extensions/firefox/inspector.js +802 -767
- package/browser-extensions/firefox/manifest.json +68 -68
- package/browser-extensions/firefox/panel.html +674 -636
- package/browser-extensions/firefox/panel.js +722 -712
- package/browser-extensions/firefox/popup.html +572 -535
- package/browser-extensions/firefox/popup.js +281 -236
- package/browser-extensions/firefox/test-gramercy.html +170 -125
- package/browser-extensions/firefox/test-imports.html +59 -55
- package/browser-extensions/firefox/test-masking.html +231 -140
- package/browser-extensions/firefox/test-uri-pattern.html +221 -198
- package/dist/tui/App.d.ts +1 -1
- package/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/App.js +154 -150
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/components/AIPanel.d.ts.map +1 -1
- package/dist/tui/components/AIPanel.js +42 -35
- package/dist/tui/components/AIPanel.js.map +1 -1
- package/dist/tui/components/CommandInput.d.ts +1 -1
- package/dist/tui/components/CommandInput.d.ts.map +1 -1
- package/dist/tui/components/CommandInput.js +92 -62
- package/dist/tui/components/CommandInput.js.map +1 -1
- package/dist/tui/components/GeminiPanel.d.ts.map +1 -1
- package/dist/tui/components/GeminiPanel.js +37 -30
- package/dist/tui/components/GeminiPanel.js.map +1 -1
- package/dist/tui/components/Header.d.ts.map +1 -1
- package/dist/tui/components/Header.js +1 -1
- package/dist/tui/components/Header.js.map +1 -1
- package/dist/tui/components/LogPanel.d.ts +1 -1
- package/dist/tui/components/LogPanel.d.ts.map +1 -1
- package/dist/tui/components/LogPanel.js +26 -24
- package/dist/tui/components/LogPanel.js.map +1 -1
- package/dist/tui/components/TabBar.d.ts +2 -2
- package/dist/tui/components/TabBar.d.ts.map +1 -1
- package/dist/tui/components/TabBar.js +11 -11
- package/dist/tui/components/TabBar.js.map +1 -1
- package/dist/tui/components/WelcomeScreen.d.ts.map +1 -1
- package/dist/tui/components/WelcomeScreen.js +6 -6
- package/dist/tui/components/WelcomeScreen.js.map +1 -1
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/index.js +8 -8
- package/dist/tui/index.js.map +1 -1
- package/dist/tui/services/AIService.d.ts +2 -2
- package/dist/tui/services/AIService.d.ts.map +1 -1
- package/dist/tui/services/AIService.js +165 -125
- package/dist/tui/services/AIService.js.map +1 -1
- package/dist/tui/services/ExtensionService.d.ts +1 -1
- package/dist/tui/services/ExtensionService.d.ts.map +1 -1
- package/dist/tui/services/ExtensionService.js +33 -26
- package/dist/tui/services/ExtensionService.js.map +1 -1
- package/dist/tui/services/GeminiService.d.ts +1 -1
- package/dist/tui/services/GeminiService.d.ts.map +1 -1
- package/dist/tui/services/GeminiService.js +87 -76
- package/dist/tui/services/GeminiService.js.map +1 -1
- package/dist/tui/services/ServiceManager.d.ts +3 -3
- package/dist/tui/services/ServiceManager.d.ts.map +1 -1
- package/dist/tui/services/ServiceManager.js +72 -58
- package/dist/tui/services/ServiceManager.js.map +1 -1
- package/dist/tui/services/SocketService.d.ts.map +1 -1
- package/dist/tui/services/SocketService.js +32 -32
- package/dist/tui/services/SocketService.js.map +1 -1
- package/dist/tui/services/ViteService.d.ts.map +1 -1
- package/dist/tui/services/ViteService.js +26 -28
- package/dist/tui/services/ViteService.js.map +1 -1
- package/dist/tui/services/index.d.ts +6 -6
- package/dist/tui/services/index.d.ts.map +1 -1
- package/dist/tui/services/index.js +6 -6
- package/dist/tui/services/index.js.map +1 -1
- package/mcp/gxp-api-server.js +83 -81
- package/package.json +109 -93
- package/runtime/PortalContainer.vue +258 -234
- package/runtime/dev-tools/DevToolsModal.vue +153 -155
- package/runtime/dev-tools/LayoutSwitcher.vue +144 -140
- package/runtime/dev-tools/MockDataEditor.vue +456 -433
- package/runtime/dev-tools/SocketSimulator.vue +379 -371
- package/runtime/dev-tools/StoreInspector.vue +517 -455
- package/runtime/dev-tools/index.js +5 -5
- package/runtime/fallback-layouts/PrivateLayout.vue +2 -2
- package/runtime/fallback-layouts/PublicLayout.vue +2 -2
- package/runtime/fallback-layouts/SystemLayout.vue +2 -2
- package/runtime/gxpStringsPlugin.js +159 -134
- package/runtime/index.html +17 -19
- package/runtime/main.js +24 -22
- package/runtime/mock-api/auth-middleware.js +15 -15
- package/runtime/mock-api/image-generator.js +46 -46
- package/runtime/mock-api/index.js +55 -55
- package/runtime/mock-api/response-generator.js +116 -105
- package/runtime/mock-api/route-generator.js +107 -84
- package/runtime/mock-api/socket-triggers.js +94 -93
- package/runtime/mock-api/spec-loader.js +79 -80
- package/runtime/package.json +3 -0
- package/runtime/server.js +68 -68
- package/runtime/stores/gxpPortalConfigStore.js +204 -186
- package/runtime/stores/index.js +2 -2
- package/runtime/vite-inspector-plugin.js +858 -707
- package/runtime/vite-source-tracker-plugin.js +132 -113
- package/runtime/vite.config.js +207 -132
- package/scripts/launch-chrome.js +41 -41
- package/scripts/pack-chrome.js +38 -39
- package/socket-events/AiSessionMessageCreated.json +17 -17
- package/socket-events/SocialStreamPostCreated.json +23 -23
- package/socket-events/SocialStreamPostVariantCompleted.json +22 -22
- package/template/.claude/agents/gxp-developer.md +100 -99
- package/template/.claude/settings.json +7 -7
- package/template/AGENTS.md +30 -23
- package/template/GEMINI.md +20 -20
- package/template/README.md +70 -53
- package/template/app-manifest.json +2 -4
- package/template/configuration.json +10 -10
- package/template/default-styling.css +1 -1
- package/template/index.html +18 -20
- package/template/main.js +24 -22
- package/template/src/DemoPage.vue +415 -362
- package/template/src/Plugin.vue +76 -85
- package/template/src/stores/index.js +3 -3
- package/template/src/stores/test-data.json +164 -172
- package/template/theme-layouts/AdditionalStyling.css +50 -50
- package/template/theme-layouts/PrivateLayout.vue +8 -12
- package/template/theme-layouts/PublicLayout.vue +8 -12
- package/template/theme-layouts/SystemLayout.vue +8 -12
- package/template/vite.extend.js +45 -0
- package/template/vite.config.js +0 -409
|
@@ -1,562 +1,570 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
2
|
+
<div class="socket-simulator">
|
|
3
|
+
<div class="simulator-header">
|
|
4
|
+
<div class="connection-status" :class="{ connected: isConnected }">
|
|
5
|
+
<span class="status-dot"></span>
|
|
6
|
+
{{ isConnected ? "Connected" : "Disconnected" }}
|
|
7
|
+
</div>
|
|
8
|
+
<span class="socket-port">Port: {{ socketPort }}</span>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<div class="event-list">
|
|
12
|
+
<h4>Available Events</h4>
|
|
13
|
+
<p class="helper-text">
|
|
14
|
+
Click an event to send it. Events are loaded from
|
|
15
|
+
<code>socket-events/</code> directory.
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
<div v-if="events.length === 0" class="empty-state">
|
|
19
|
+
<p>No socket events found.</p>
|
|
20
|
+
<p class="hint">
|
|
21
|
+
Create JSON files in <code>socket-events/</code> to add events.
|
|
22
|
+
</p>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div v-else class="events-grid">
|
|
26
|
+
<div
|
|
27
|
+
v-for="event in events"
|
|
28
|
+
:key="event.name"
|
|
29
|
+
class="event-card"
|
|
30
|
+
@click="selectEvent(event)"
|
|
31
|
+
:class="{ selected: selectedEvent?.name === event.name }"
|
|
32
|
+
>
|
|
33
|
+
<div class="event-name">{{ event.name }}</div>
|
|
34
|
+
<div class="event-type">{{ event.event }}</div>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<div v-if="selectedEvent" class="event-editor">
|
|
40
|
+
<h4>Event Details: {{ selectedEvent.name }}</h4>
|
|
41
|
+
|
|
42
|
+
<div class="editor-field">
|
|
43
|
+
<label>Event Type:</label>
|
|
44
|
+
<input v-model="editableEvent.event" class="field-input" />
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<div class="editor-field">
|
|
48
|
+
<label>Channel:</label>
|
|
49
|
+
<input v-model="editableEvent.channel" class="field-input" />
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<div class="editor-field">
|
|
53
|
+
<label>Data (JSON):</label>
|
|
54
|
+
<textarea
|
|
55
|
+
v-model="editableEventData"
|
|
56
|
+
class="field-textarea"
|
|
57
|
+
rows="8"
|
|
58
|
+
@input="validateJson"
|
|
59
|
+
></textarea>
|
|
60
|
+
<span v-if="jsonError" class="json-error">{{ jsonError }}</span>
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
<div class="editor-actions">
|
|
64
|
+
<button
|
|
65
|
+
class="btn btn-primary"
|
|
66
|
+
@click="sendEvent"
|
|
67
|
+
:disabled="!!jsonError"
|
|
68
|
+
>
|
|
69
|
+
Send Event
|
|
70
|
+
</button>
|
|
71
|
+
<button class="btn btn-secondary" @click="resetEvent">Reset</button>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
|
|
75
|
+
<div class="event-log">
|
|
76
|
+
<div class="log-header">
|
|
77
|
+
<h4>Event Log</h4>
|
|
78
|
+
<button class="btn-clear" @click="clearLog">Clear</button>
|
|
79
|
+
</div>
|
|
80
|
+
<div class="log-entries">
|
|
81
|
+
<div v-if="eventLog.length === 0" class="empty-log">
|
|
82
|
+
No events sent yet
|
|
83
|
+
</div>
|
|
84
|
+
<div
|
|
85
|
+
v-for="(entry, index) in eventLog"
|
|
86
|
+
:key="index"
|
|
87
|
+
class="log-entry"
|
|
88
|
+
:class="entry.type"
|
|
89
|
+
>
|
|
90
|
+
<span class="log-time">{{ entry.time }}</span>
|
|
91
|
+
<span class="log-direction">{{ entry.direction }}</span>
|
|
92
|
+
<span class="log-event">{{ entry.event }}</span>
|
|
93
|
+
<span class="log-status">{{ entry.status }}</span>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
93
98
|
</template>
|
|
94
99
|
|
|
95
100
|
<script setup>
|
|
96
|
-
import { ref, reactive, computed, onMounted } from
|
|
101
|
+
import { ref, reactive, computed, onMounted } from "vue"
|
|
97
102
|
|
|
98
103
|
const props = defineProps({
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
const socketPort = ref(3069)
|
|
106
|
-
const isConnected = ref(false)
|
|
107
|
-
const events = ref([])
|
|
108
|
-
const selectedEvent = ref(null)
|
|
104
|
+
store: {
|
|
105
|
+
type: Object,
|
|
106
|
+
required: true,
|
|
107
|
+
},
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
const socketPort = ref(3069)
|
|
111
|
+
const isConnected = ref(false)
|
|
112
|
+
const events = ref([])
|
|
113
|
+
const selectedEvent = ref(null)
|
|
109
114
|
const editableEvent = reactive({
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
})
|
|
114
|
-
const editableEventData = ref(
|
|
115
|
-
const jsonError = ref(
|
|
116
|
-
const eventLog = ref([])
|
|
115
|
+
event: "",
|
|
116
|
+
channel: "",
|
|
117
|
+
data: {},
|
|
118
|
+
})
|
|
119
|
+
const editableEventData = ref("")
|
|
120
|
+
const jsonError = ref("")
|
|
121
|
+
const eventLog = ref([])
|
|
117
122
|
|
|
118
123
|
// Default events if none are loaded
|
|
119
124
|
const defaultEvents = [
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
]
|
|
125
|
+
{
|
|
126
|
+
name: "AiSessionMessageCreated",
|
|
127
|
+
event: "AiSessionMessageCreated",
|
|
128
|
+
channel: "private.ai_session.1",
|
|
129
|
+
data: {
|
|
130
|
+
id: 1,
|
|
131
|
+
message: "Test AI response",
|
|
132
|
+
session_id: 1,
|
|
133
|
+
created_at: new Date().toISOString(),
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: "SocialStreamPostCreated",
|
|
138
|
+
event: "SocialStreamPostCreated",
|
|
139
|
+
channel: "private.social_stream.1",
|
|
140
|
+
data: {
|
|
141
|
+
id: 1,
|
|
142
|
+
content: "Test social post",
|
|
143
|
+
author: "Test User",
|
|
144
|
+
created_at: new Date().toISOString(),
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
name: "StateChange",
|
|
149
|
+
event: "state-change",
|
|
150
|
+
channel: "broadcast",
|
|
151
|
+
data: {
|
|
152
|
+
key: "test_key",
|
|
153
|
+
value: "test_value",
|
|
154
|
+
timestamp: new Date().toISOString(),
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
]
|
|
153
158
|
|
|
154
159
|
onMounted(() => {
|
|
155
|
-
|
|
156
|
-
|
|
160
|
+
// Load events - in a real implementation, this would load from socket-events directory
|
|
161
|
+
events.value = defaultEvents
|
|
157
162
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
})
|
|
163
|
+
// Check socket connection
|
|
164
|
+
checkConnection()
|
|
165
|
+
})
|
|
161
166
|
|
|
162
167
|
function checkConnection() {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
168
|
+
// Try to connect to socket server
|
|
169
|
+
const socket = props.store?.sockets?.primary
|
|
170
|
+
isConnected.value = !!socket
|
|
166
171
|
}
|
|
167
172
|
|
|
168
173
|
function selectEvent(event) {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
174
|
+
selectedEvent.value = event
|
|
175
|
+
editableEvent.event = event.event
|
|
176
|
+
editableEvent.channel = event.channel
|
|
177
|
+
editableEvent.data = { ...event.data }
|
|
178
|
+
editableEventData.value = JSON.stringify(event.data, null, 2)
|
|
179
|
+
jsonError.value = ""
|
|
175
180
|
}
|
|
176
181
|
|
|
177
182
|
function validateJson() {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
183
|
+
try {
|
|
184
|
+
JSON.parse(editableEventData.value)
|
|
185
|
+
jsonError.value = ""
|
|
186
|
+
} catch (e) {
|
|
187
|
+
jsonError.value = "Invalid JSON: " + e.message
|
|
188
|
+
}
|
|
184
189
|
}
|
|
185
190
|
|
|
186
191
|
function resetEvent() {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
192
|
+
if (selectedEvent.value) {
|
|
193
|
+
selectEvent(selectedEvent.value)
|
|
194
|
+
}
|
|
190
195
|
}
|
|
191
196
|
|
|
192
197
|
async function sendEvent() {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
198
|
+
if (jsonError.value) return
|
|
199
|
+
|
|
200
|
+
let data
|
|
201
|
+
try {
|
|
202
|
+
data = JSON.parse(editableEventData.value)
|
|
203
|
+
} catch {
|
|
204
|
+
return
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const eventPayload = {
|
|
208
|
+
event: editableEvent.event,
|
|
209
|
+
channel: editableEvent.channel,
|
|
210
|
+
data: data,
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Log the send attempt
|
|
214
|
+
addLogEntry("send", editableEvent.event, "pending")
|
|
215
|
+
|
|
216
|
+
try {
|
|
217
|
+
// Try to send via the store's socket
|
|
218
|
+
const socket = props.store?.sockets?.primary
|
|
219
|
+
if (socket && socket.broadcast) {
|
|
220
|
+
socket.broadcast(editableEvent.event, data)
|
|
221
|
+
updateLastLogEntry("success")
|
|
222
|
+
console.log("[DevTools] Socket event sent:", eventPayload)
|
|
223
|
+
} else {
|
|
224
|
+
// Fallback: try to send via HTTP to the socket server
|
|
225
|
+
const response = await fetch(
|
|
226
|
+
`https://localhost:${socketPort.value}/emit`,
|
|
227
|
+
{
|
|
228
|
+
method: "POST",
|
|
229
|
+
headers: {
|
|
230
|
+
"Content-Type": "application/json",
|
|
231
|
+
},
|
|
232
|
+
body: JSON.stringify(eventPayload),
|
|
233
|
+
},
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
if (response.ok) {
|
|
237
|
+
updateLastLogEntry("success")
|
|
238
|
+
console.log("[DevTools] Socket event sent via HTTP:", eventPayload)
|
|
239
|
+
} else {
|
|
240
|
+
throw new Error("HTTP request failed")
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
} catch (err) {
|
|
244
|
+
updateLastLogEntry("error")
|
|
245
|
+
console.error("[DevTools] Failed to send event:", err)
|
|
246
|
+
}
|
|
239
247
|
}
|
|
240
248
|
|
|
241
249
|
function addLogEntry(direction, event, status) {
|
|
242
|
-
|
|
243
|
-
|
|
250
|
+
const now = new Date()
|
|
251
|
+
const time = now.toLocaleTimeString("en-US", { hour12: false })
|
|
244
252
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
253
|
+
eventLog.value.unshift({
|
|
254
|
+
time,
|
|
255
|
+
direction: direction === "send" ? "→" : "←",
|
|
256
|
+
event,
|
|
257
|
+
status,
|
|
258
|
+
type: status,
|
|
259
|
+
})
|
|
252
260
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
261
|
+
// Keep only last 50 entries
|
|
262
|
+
if (eventLog.value.length > 50) {
|
|
263
|
+
eventLog.value.pop()
|
|
264
|
+
}
|
|
257
265
|
}
|
|
258
266
|
|
|
259
267
|
function updateLastLogEntry(status) {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
268
|
+
if (eventLog.value.length > 0) {
|
|
269
|
+
eventLog.value[0].status = status
|
|
270
|
+
eventLog.value[0].type = status
|
|
271
|
+
}
|
|
264
272
|
}
|
|
265
273
|
|
|
266
274
|
function clearLog() {
|
|
267
|
-
|
|
275
|
+
eventLog.value = []
|
|
268
276
|
}
|
|
269
277
|
</script>
|
|
270
278
|
|
|
271
279
|
<style scoped>
|
|
272
280
|
.socket-simulator {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
281
|
+
display: flex;
|
|
282
|
+
flex-direction: column;
|
|
283
|
+
gap: 20px;
|
|
276
284
|
}
|
|
277
285
|
|
|
278
286
|
.simulator-header {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
287
|
+
display: flex;
|
|
288
|
+
justify-content: space-between;
|
|
289
|
+
align-items: center;
|
|
290
|
+
padding: 12px 16px;
|
|
291
|
+
background: #2d2d2d;
|
|
292
|
+
border-radius: 8px;
|
|
285
293
|
}
|
|
286
294
|
|
|
287
295
|
.connection-status {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
296
|
+
display: flex;
|
|
297
|
+
align-items: center;
|
|
298
|
+
gap: 8px;
|
|
299
|
+
font-size: 13px;
|
|
300
|
+
color: #ff6b6b;
|
|
293
301
|
}
|
|
294
302
|
|
|
295
303
|
.connection-status.connected {
|
|
296
|
-
|
|
304
|
+
color: #51cf66;
|
|
297
305
|
}
|
|
298
306
|
|
|
299
307
|
.status-dot {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
308
|
+
width: 8px;
|
|
309
|
+
height: 8px;
|
|
310
|
+
border-radius: 50%;
|
|
311
|
+
background: currentColor;
|
|
304
312
|
}
|
|
305
313
|
|
|
306
314
|
.socket-port {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
315
|
+
font-size: 12px;
|
|
316
|
+
color: #888;
|
|
317
|
+
font-family: "SF Mono", Monaco, monospace;
|
|
310
318
|
}
|
|
311
319
|
|
|
312
320
|
.event-list h4,
|
|
313
321
|
.event-editor h4,
|
|
314
322
|
.event-log h4 {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
323
|
+
margin: 0 0 8px 0;
|
|
324
|
+
font-size: 13px;
|
|
325
|
+
color: #e0e0e0;
|
|
318
326
|
}
|
|
319
327
|
|
|
320
328
|
.helper-text {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
329
|
+
font-size: 12px;
|
|
330
|
+
color: #888;
|
|
331
|
+
margin: 0 0 12px 0;
|
|
324
332
|
}
|
|
325
333
|
|
|
326
334
|
.helper-text code,
|
|
327
335
|
.hint code {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
336
|
+
background: #3d3d3d;
|
|
337
|
+
padding: 2px 6px;
|
|
338
|
+
border-radius: 3px;
|
|
339
|
+
font-family: "SF Mono", Monaco, monospace;
|
|
340
|
+
font-size: 11px;
|
|
333
341
|
}
|
|
334
342
|
|
|
335
343
|
.empty-state {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
344
|
+
padding: 20px;
|
|
345
|
+
text-align: center;
|
|
346
|
+
color: #666;
|
|
347
|
+
background: #2d2d2d;
|
|
348
|
+
border-radius: 8px;
|
|
341
349
|
}
|
|
342
350
|
|
|
343
351
|
.empty-state p {
|
|
344
|
-
|
|
352
|
+
margin: 0;
|
|
345
353
|
}
|
|
346
354
|
|
|
347
355
|
.hint {
|
|
348
|
-
|
|
349
|
-
|
|
356
|
+
font-size: 11px;
|
|
357
|
+
margin-top: 8px !important;
|
|
350
358
|
}
|
|
351
359
|
|
|
352
360
|
.events-grid {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
361
|
+
display: grid;
|
|
362
|
+
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
|
363
|
+
gap: 12px;
|
|
356
364
|
}
|
|
357
365
|
|
|
358
366
|
.event-card {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
367
|
+
background: #2d2d2d;
|
|
368
|
+
border-radius: 8px;
|
|
369
|
+
padding: 12px;
|
|
370
|
+
cursor: pointer;
|
|
371
|
+
border: 2px solid transparent;
|
|
372
|
+
transition: all 0.2s;
|
|
365
373
|
}
|
|
366
374
|
|
|
367
375
|
.event-card:hover {
|
|
368
|
-
|
|
369
|
-
|
|
376
|
+
border-color: #3d3d3d;
|
|
377
|
+
background: #333;
|
|
370
378
|
}
|
|
371
379
|
|
|
372
380
|
.event-card.selected {
|
|
373
|
-
|
|
374
|
-
|
|
381
|
+
border-color: #61dafb;
|
|
382
|
+
background: #2a3a4a;
|
|
375
383
|
}
|
|
376
384
|
|
|
377
385
|
.event-name {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
386
|
+
font-size: 13px;
|
|
387
|
+
font-weight: 500;
|
|
388
|
+
color: #e0e0e0;
|
|
389
|
+
margin-bottom: 4px;
|
|
382
390
|
}
|
|
383
391
|
|
|
384
392
|
.event-type {
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
393
|
+
font-size: 11px;
|
|
394
|
+
color: #888;
|
|
395
|
+
font-family: "SF Mono", Monaco, monospace;
|
|
388
396
|
}
|
|
389
397
|
|
|
390
398
|
.event-editor {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
399
|
+
background: #2d2d2d;
|
|
400
|
+
border-radius: 8px;
|
|
401
|
+
padding: 16px;
|
|
394
402
|
}
|
|
395
403
|
|
|
396
404
|
.editor-field {
|
|
397
|
-
|
|
405
|
+
margin-bottom: 12px;
|
|
398
406
|
}
|
|
399
407
|
|
|
400
408
|
.editor-field label {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
409
|
+
display: block;
|
|
410
|
+
font-size: 12px;
|
|
411
|
+
color: #888;
|
|
412
|
+
margin-bottom: 4px;
|
|
405
413
|
}
|
|
406
414
|
|
|
407
415
|
.field-input,
|
|
408
416
|
.field-textarea {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
417
|
+
width: 100%;
|
|
418
|
+
background: #1e1e1e;
|
|
419
|
+
border: 1px solid #3d3d3d;
|
|
420
|
+
color: #e0e0e0;
|
|
421
|
+
padding: 8px 12px;
|
|
422
|
+
border-radius: 4px;
|
|
423
|
+
font-family: "SF Mono", Monaco, monospace;
|
|
424
|
+
font-size: 12px;
|
|
425
|
+
box-sizing: border-box;
|
|
418
426
|
}
|
|
419
427
|
|
|
420
428
|
.field-input:focus,
|
|
421
429
|
.field-textarea:focus {
|
|
422
|
-
|
|
423
|
-
|
|
430
|
+
outline: none;
|
|
431
|
+
border-color: #61dafb;
|
|
424
432
|
}
|
|
425
433
|
|
|
426
434
|
.field-textarea {
|
|
427
|
-
|
|
428
|
-
|
|
435
|
+
resize: vertical;
|
|
436
|
+
min-height: 100px;
|
|
429
437
|
}
|
|
430
438
|
|
|
431
439
|
.json-error {
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
440
|
+
display: block;
|
|
441
|
+
color: #ff6b6b;
|
|
442
|
+
font-size: 11px;
|
|
443
|
+
margin-top: 4px;
|
|
436
444
|
}
|
|
437
445
|
|
|
438
446
|
.editor-actions {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
447
|
+
display: flex;
|
|
448
|
+
gap: 8px;
|
|
449
|
+
margin-top: 16px;
|
|
442
450
|
}
|
|
443
451
|
|
|
444
452
|
.btn {
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
453
|
+
padding: 8px 16px;
|
|
454
|
+
border: none;
|
|
455
|
+
border-radius: 4px;
|
|
456
|
+
cursor: pointer;
|
|
457
|
+
font-size: 12px;
|
|
458
|
+
transition: all 0.2s;
|
|
451
459
|
}
|
|
452
460
|
|
|
453
461
|
.btn-primary {
|
|
454
|
-
|
|
455
|
-
|
|
462
|
+
background: #61dafb;
|
|
463
|
+
color: #1e1e1e;
|
|
456
464
|
}
|
|
457
465
|
|
|
458
466
|
.btn-primary:hover {
|
|
459
|
-
|
|
467
|
+
background: #4fc3f7;
|
|
460
468
|
}
|
|
461
469
|
|
|
462
470
|
.btn-primary:disabled {
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
471
|
+
background: #3d3d3d;
|
|
472
|
+
color: #666;
|
|
473
|
+
cursor: not-allowed;
|
|
466
474
|
}
|
|
467
475
|
|
|
468
476
|
.btn-secondary {
|
|
469
|
-
|
|
470
|
-
|
|
477
|
+
background: #3d3d3d;
|
|
478
|
+
color: #e0e0e0;
|
|
471
479
|
}
|
|
472
480
|
|
|
473
481
|
.btn-secondary:hover {
|
|
474
|
-
|
|
482
|
+
background: #4d4d4d;
|
|
475
483
|
}
|
|
476
484
|
|
|
477
485
|
.event-log {
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
486
|
+
background: #2d2d2d;
|
|
487
|
+
border-radius: 8px;
|
|
488
|
+
overflow: hidden;
|
|
481
489
|
}
|
|
482
490
|
|
|
483
491
|
.log-header {
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
492
|
+
display: flex;
|
|
493
|
+
justify-content: space-between;
|
|
494
|
+
align-items: center;
|
|
495
|
+
padding: 12px 16px;
|
|
496
|
+
border-bottom: 1px solid #3d3d3d;
|
|
489
497
|
}
|
|
490
498
|
|
|
491
499
|
.log-header h4 {
|
|
492
|
-
|
|
500
|
+
margin: 0;
|
|
493
501
|
}
|
|
494
502
|
|
|
495
503
|
.btn-clear {
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
504
|
+
background: transparent;
|
|
505
|
+
border: none;
|
|
506
|
+
color: #888;
|
|
507
|
+
cursor: pointer;
|
|
508
|
+
font-size: 11px;
|
|
501
509
|
}
|
|
502
510
|
|
|
503
511
|
.btn-clear:hover {
|
|
504
|
-
|
|
512
|
+
color: #e0e0e0;
|
|
505
513
|
}
|
|
506
514
|
|
|
507
515
|
.log-entries {
|
|
508
|
-
|
|
509
|
-
|
|
516
|
+
max-height: 200px;
|
|
517
|
+
overflow-y: auto;
|
|
510
518
|
}
|
|
511
519
|
|
|
512
520
|
.empty-log {
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
521
|
+
padding: 20px;
|
|
522
|
+
text-align: center;
|
|
523
|
+
color: #666;
|
|
524
|
+
font-size: 12px;
|
|
517
525
|
}
|
|
518
526
|
|
|
519
527
|
.log-entry {
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
528
|
+
display: flex;
|
|
529
|
+
gap: 12px;
|
|
530
|
+
padding: 8px 16px;
|
|
531
|
+
font-size: 11px;
|
|
532
|
+
font-family: "SF Mono", Monaco, monospace;
|
|
533
|
+
border-bottom: 1px solid #252525;
|
|
526
534
|
}
|
|
527
535
|
|
|
528
536
|
.log-entry:last-child {
|
|
529
|
-
|
|
537
|
+
border-bottom: none;
|
|
530
538
|
}
|
|
531
539
|
|
|
532
540
|
.log-time {
|
|
533
|
-
|
|
534
|
-
|
|
541
|
+
color: #666;
|
|
542
|
+
min-width: 70px;
|
|
535
543
|
}
|
|
536
544
|
|
|
537
545
|
.log-direction {
|
|
538
|
-
|
|
546
|
+
color: #61dafb;
|
|
539
547
|
}
|
|
540
548
|
|
|
541
549
|
.log-event {
|
|
542
|
-
|
|
543
|
-
|
|
550
|
+
color: #e0e0e0;
|
|
551
|
+
flex: 1;
|
|
544
552
|
}
|
|
545
553
|
|
|
546
554
|
.log-status {
|
|
547
|
-
|
|
548
|
-
|
|
555
|
+
min-width: 60px;
|
|
556
|
+
text-align: right;
|
|
549
557
|
}
|
|
550
558
|
|
|
551
559
|
.log-entry.success .log-status {
|
|
552
|
-
|
|
560
|
+
color: #51cf66;
|
|
553
561
|
}
|
|
554
562
|
|
|
555
563
|
.log-entry.error .log-status {
|
|
556
|
-
|
|
564
|
+
color: #ff6b6b;
|
|
557
565
|
}
|
|
558
566
|
|
|
559
567
|
.log-entry.pending .log-status {
|
|
560
|
-
|
|
568
|
+
color: #ffd43b;
|
|
561
569
|
}
|
|
562
570
|
</style>
|