@ash-qw/dsh-theme-prts 0.1.91

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.
Files changed (50) hide show
  1. package/LICENSE +24 -0
  2. package/README.en.md +103 -0
  3. package/README.md +107 -0
  4. package/THIRD_PARTY_NOTICES.md +48 -0
  5. package/cordis.patch.yml +4 -0
  6. package/lib/client.js +7466 -0
  7. package/lib/index.js +3 -0
  8. package/package.json +64 -0
  9. package/src/assets/faction-emblems/lungmen.png +0 -0
  10. package/src/assets/faction-emblems/penguin-logistics.png +0 -0
  11. package/src/assets/faction-emblems/reunion.png +0 -0
  12. package/src/assets/faction-emblems/rhine-lab.png +0 -0
  13. package/src/assets/faction-emblems/rhodes-island.png +0 -0
  14. package/src/assets/prts-original-avatar.png +0 -0
  15. package/src/assets/rhodes-dsh.svg +6 -0
  16. package/src/assets/topographic-map.svg +72 -0
  17. package/src/assets/topographic-tech.svg +19 -0
  18. package/src/client/assistant-glass-adapter.js +231 -0
  19. package/src/client/composer-glass-adapter.js +210 -0
  20. package/src/client/conversation-control-adapter.js +109 -0
  21. package/src/client/conversation-scale-adapter.js +2243 -0
  22. package/src/client/facility-geometry.js +60 -0
  23. package/src/client/facility-vector.js +230 -0
  24. package/src/client/floating-glass-adapter.js +177 -0
  25. package/src/client/host-geometry-adapter.js +123 -0
  26. package/src/client/index.js +359 -0
  27. package/src/client/layout-stability-diagnostics.js +162 -0
  28. package/src/client/operations-shell-v2.js +248 -0
  29. package/src/client/particle-field-adapter.js +1840 -0
  30. package/src/client/preferences.js +239 -0
  31. package/src/client/rc7-adapter.js +83 -0
  32. package/src/client/resize-shield-adapter.js +64 -0
  33. package/src/client/settings-page.js +62 -0
  34. package/src/client/sidebar-control-adapter.js +317 -0
  35. package/src/client/startup-sequence.js +366 -0
  36. package/src/client/status-projection.js +79 -0
  37. package/src/client/terrain-motion-adapter.js +188 -0
  38. package/src/client/theme-controller-v2.js +134 -0
  39. package/src/client/theme-controller.js +119 -0
  40. package/src/client/theme-settings-workbench.js +583 -0
  41. package/src/client/to-bottom-adapter.js +85 -0
  42. package/src/client/ui-store.js +23 -0
  43. package/src/index.js +4 -0
  44. package/src/styles/conversation-scale.css +471 -0
  45. package/src/styles/facility-vector.css +292 -0
  46. package/src/styles/prts.css +1223 -0
  47. package/src/styles/refinement.css +429 -0
  48. package/src/styles/stabilization.css +161 -0
  49. package/src/styles/startup-sequence.css +496 -0
  50. package/src/styles/theme-settings-workbench.css +803 -0
@@ -0,0 +1,210 @@
1
+ const CONTROL_ATTRIBUTE = 'data-prts-glass-control'
2
+ const MENU_ATTRIBUTE = 'data-prts-glass-menu'
3
+ const FALLBACK_COMPOSER_ATTRIBUTE = 'data-prts-composer-fallback'
4
+ const COMPOSER_SIGNAL_ATTRIBUTE = 'data-prts-composer-signal'
5
+ const COMPOSER_RELEVANCE_SELECTOR = [
6
+ '[data-composer-card]',
7
+ 'form textarea',
8
+ 'button[aria-haspopup="menu"]',
9
+ 'button[aria-haspopup="listbox"]',
10
+ '[role="menu"]',
11
+ '[role="listbox"]',
12
+ '[data-slot="conversation.input.overlay"]',
13
+ ].join(', ')
14
+ const PRESET_TRIGGER_SELECTOR = [
15
+ '[data-slot="conversation.hero.agentPreset"] button[aria-haspopup="menu"]',
16
+ 'button[class*="cubgiG_seat"][aria-haspopup="menu"]',
17
+ ].join(', ')
18
+
19
+ function mark(node, attribute, value) {
20
+ if (node?.nodeType === 1) node.setAttribute(attribute, value)
21
+ }
22
+
23
+ function controlledPopup(document, trigger) {
24
+ const id = trigger.getAttribute('aria-controls')
25
+ if (!id) return null
26
+ return document.getElementById(id)
27
+ }
28
+
29
+ function localPopup(trigger) {
30
+ const selector = '[role="menu"], [role="listbox"], [class*="mufS8W_card"]'
31
+ const sibling = trigger.nextElementSibling
32
+ if (sibling?.matches(selector)) return sibling
33
+ return trigger.parentElement?.querySelector(`:scope > ${selector}`) ?? null
34
+ }
35
+
36
+ function overlayPopup(document) {
37
+ const overlay = document.querySelector('[data-slot="conversation.input.overlay"]')
38
+ if (!overlay) return null
39
+ return overlay.querySelector('[role="listbox"], [role="menu"], [class*="mufS8W_card"]')
40
+ }
41
+
42
+ function linkedMenu(document, trigger) {
43
+ return controlledPopup(document, trigger)
44
+ ?? localPopup(trigger)
45
+ ?? overlayPopup(document)
46
+ }
47
+
48
+ function markPopup(popup, kind) {
49
+ if (!popup) return
50
+ mark(popup, MENU_ATTRIBUTE, kind)
51
+ const card = popup.closest?.('[class*="mufS8W_card"]')
52
+ mark(card, MENU_ATTRIBUTE, kind)
53
+ for (const nested of popup.querySelectorAll?.('[role="menu"], [role="listbox"], [class*="mufS8W_card"]') ?? []) {
54
+ mark(nested, MENU_ATTRIBUTE, kind)
55
+ }
56
+ }
57
+
58
+ export function createComposerGlassAdapter({ document, window }) {
59
+ let observer
60
+ let scanFrame
61
+ const ownedFallbacks = new Set()
62
+ const ownedSignals = new Set()
63
+
64
+ function ensureSignal(composer) {
65
+ let signal = composer.querySelector?.(`:scope > [${COMPOSER_SIGNAL_ATTRIBUTE}]`)
66
+ if (signal) return signal
67
+ signal = document.createElement('span')
68
+ signal.setAttribute(COMPOSER_SIGNAL_ATTRIBUTE, '')
69
+ signal.setAttribute('aria-hidden', 'true')
70
+ composer.append(signal)
71
+ ownedSignals.add(signal)
72
+ return signal
73
+ }
74
+
75
+ function mutationTouchesComposer(mutation) {
76
+ if (mutation.target?.closest?.('[data-composer-card], [data-prts-composer-fallback], [data-slot="conversation.input.overlay"]')) return true
77
+ for (const node of [...(mutation.addedNodes ?? []), ...(mutation.removedNodes ?? [])]) {
78
+ if (node?.nodeType !== 1) continue
79
+ if (node.matches?.(COMPOSER_RELEVANCE_SELECTOR) || node.querySelector?.(COMPOSER_RELEVANCE_SELECTOR)) return true
80
+ }
81
+ return mutation.type === 'attributes' && (
82
+ mutation.target?.matches?.(COMPOSER_RELEVANCE_SELECTOR)
83
+ || mutation.target?.closest?.(PRESET_TRIGGER_SELECTOR)
84
+ )
85
+ }
86
+
87
+ function onMutations(mutations) {
88
+ if (mutations.some(mutationTouchesComposer)) queueScan()
89
+ }
90
+
91
+ function queueScan() {
92
+ if (scanFrame !== undefined) return
93
+ const requestFrame = window?.requestAnimationFrame?.bind(window) ?? (callback => window?.setTimeout?.(callback, 0))
94
+ scanFrame = requestFrame(() => {
95
+ scanFrame = undefined
96
+ scan()
97
+ })
98
+ }
99
+
100
+ function scan() {
101
+ for (const signal of [...ownedSignals]) {
102
+ if (signal.isConnected) continue
103
+ signal.remove?.()
104
+ ownedSignals.delete(signal)
105
+ }
106
+ for (const form of [...ownedFallbacks]) {
107
+ if (!form.isConnected || form.hasAttribute('data-composer-card')) {
108
+ form.removeAttribute?.(FALLBACK_COMPOSER_ATTRIBUTE)
109
+ ownedFallbacks.delete(form)
110
+ }
111
+ }
112
+ const fallbackForms = new Set(
113
+ [...(document?.querySelectorAll?.('form textarea') ?? [])]
114
+ .map(textarea => textarea.closest('form'))
115
+ .filter(form => form && !form.querySelector('[data-composer-card]')),
116
+ )
117
+ for (const form of fallbackForms) {
118
+ form.setAttribute(FALLBACK_COMPOSER_ATTRIBUTE, '')
119
+ ownedFallbacks.add(form)
120
+ }
121
+ const composers = [
122
+ ...(document?.querySelectorAll?.('[data-composer-card]') ?? []),
123
+ ...fallbackForms,
124
+ ]
125
+ for (const composer of composers) {
126
+ ensureSignal(composer)
127
+ for (const menu of composer.querySelectorAll('[role="menu"], [role="listbox"]')) markPopup(menu, 'action')
128
+
129
+ for (const trigger of composer.querySelectorAll('button[aria-haspopup="menu"], button[aria-haspopup="listbox"]')) {
130
+ const menu = linkedMenu(document, trigger)
131
+ ?? trigger.parentElement?.querySelector('[role="menu"][aria-busy], [role="listbox"][aria-busy]')
132
+ const isModel = trigger.matches('[class*="_7KE1Ra_"]')
133
+ || menu?.hasAttribute('aria-busy')
134
+ const isCommands = trigger.getAttribute('aria-haspopup') === 'listbox'
135
+ || trigger.getAttribute('aria-label') === 'Commands'
136
+ || trigger.matches('[class*="uV2eYG_add"]')
137
+ const kind = isModel ? 'model' : isCommands ? 'action' : 'action'
138
+ mark(trigger, CONTROL_ATTRIBUTE, kind)
139
+ markPopup(menu, kind)
140
+ }
141
+
142
+ const permissionCandidates = [
143
+ ...composer.querySelectorAll('button.Sh0Q9G_trigger'),
144
+ ...composer.querySelectorAll('button[class*="Sh0Q9G_"]'),
145
+ ]
146
+ for (const trigger of new Set(permissionCandidates)) {
147
+ mark(trigger, CONTROL_ATTRIBUTE, 'permission')
148
+ markPopup(linkedMenu(document, trigger), 'permission')
149
+ }
150
+ }
151
+
152
+ for (const popup of document?.querySelectorAll?.(`[${MENU_ATTRIBUTE}="preset"]`) ?? []) {
153
+ popup.removeAttribute(MENU_ATTRIBUTE)
154
+ }
155
+ for (const trigger of document?.querySelectorAll?.(PRESET_TRIGGER_SELECTOR) ?? []) {
156
+ mark(trigger, CONTROL_ATTRIBUTE, 'preset')
157
+ if (trigger.getAttribute('aria-expanded') !== 'true') continue
158
+ const popup = controlledPopup(document, trigger)
159
+ ?? localPopup(trigger)
160
+ markPopup(popup, 'preset')
161
+ }
162
+
163
+ const overlay = document?.querySelector?.('[data-slot="conversation.input.overlay"]')
164
+ if (overlay) {
165
+ for (const popup of overlay.querySelectorAll('[role="menu"], [role="listbox"], [class*="mufS8W_card"]')) {
166
+ markPopup(popup, popup.hasAttribute('aria-busy') ? 'model' : 'action')
167
+ }
168
+ }
169
+ }
170
+
171
+ function removeMarkers() {
172
+ for (const node of document?.querySelectorAll?.(`[${CONTROL_ATTRIBUTE}], [${MENU_ATTRIBUTE}]`) ?? []) {
173
+ node.removeAttribute(CONTROL_ATTRIBUTE)
174
+ node.removeAttribute(MENU_ATTRIBUTE)
175
+ }
176
+ for (const form of ownedFallbacks) form.removeAttribute?.(FALLBACK_COMPOSER_ATTRIBUTE)
177
+ ownedFallbacks.clear()
178
+ for (const signal of ownedSignals) signal.remove?.()
179
+ ownedSignals.clear()
180
+ }
181
+
182
+ return {
183
+ start() {
184
+ if (!document || observer) return
185
+ scan()
186
+ const Observer = window?.MutationObserver
187
+ if (!Observer) return
188
+ const observationRoot = document.querySelector('[data-prts-region="operation"]')
189
+ ?? document.querySelector('[data-slot="conversation"]')
190
+ if (!observationRoot) return
191
+ observer = new Observer(onMutations)
192
+ observer.observe(observationRoot, {
193
+ subtree: true,
194
+ childList: true,
195
+ attributes: true,
196
+ attributeFilter: ['aria-controls', 'aria-expanded', 'aria-busy', 'class', 'role'],
197
+ })
198
+ },
199
+ dispose() {
200
+ observer?.disconnect()
201
+ observer = undefined
202
+ if (scanFrame !== undefined) {
203
+ if (window?.cancelAnimationFrame) window.cancelAnimationFrame(scanFrame)
204
+ else window?.clearTimeout?.(scanFrame)
205
+ }
206
+ scanFrame = undefined
207
+ removeMarkers()
208
+ },
209
+ }
210
+ }
@@ -0,0 +1,109 @@
1
+ export const CONVERSATION_CONTROL_ATTRIBUTE = 'data-prts-conversation-control'
2
+
3
+ function hasClassSuffix(node, suffix) {
4
+ return [...(node?.classList ?? [])].some(token => token.endsWith(suffix))
5
+ }
6
+
7
+ function closestWithClassSuffix(node, suffix) {
8
+ for (let current = node; current?.nodeType === 1; current = current.parentElement) {
9
+ if (hasClassSuffix(current, suffix)) return current
10
+ }
11
+ return null
12
+ }
13
+
14
+ function classify(button, operation) {
15
+ if (button.tagName !== 'BUTTON' || !operation.contains(button)) return null
16
+ if (hasClassSuffix(button, '_sessionLogButton')) return 'header'
17
+ if (button.closest('[data-produced-files-row]') || hasClassSuffix(button, '_showFolder')) return 'utility'
18
+ if (closestWithClassSuffix(button, '_older')) return 'utility'
19
+ if (hasClassSuffix(button, '_inspectButton')) return 'inspect'
20
+
21
+ const approval = button.closest('[data-approval-key]')
22
+ if (approval) return hasClassSuffix(button, '_reject') ? 'danger' : 'cta'
23
+ if (hasClassSuffix(button, '_modalAction') || button.closest('[role="dialog"]')) return 'cta'
24
+
25
+ if (button.closest('[data-chat-flow-kind], [data-message-role]')) return 'micro'
26
+ return null
27
+ }
28
+
29
+ export function createConversationControlAdapter({ document, window }) {
30
+ let observer
31
+ let operation
32
+ const owned = new Set()
33
+ const pending = new Set()
34
+
35
+ function collectButtons(node) {
36
+ if (node?.nodeType !== 1) return
37
+ if (node.tagName === 'BUTTON') pending.add(node)
38
+ for (const button of node.querySelectorAll?.('button') ?? []) pending.add(button)
39
+ const closest = node.closest?.('button')
40
+ if (closest) pending.add(closest)
41
+ }
42
+
43
+ function process(button) {
44
+ const kind = button?.isConnected ? classify(button, operation) : null
45
+ if (!kind) {
46
+ button?.removeAttribute?.(CONVERSATION_CONTROL_ATTRIBUTE)
47
+ owned.delete(button)
48
+ return
49
+ }
50
+ button.setAttribute(CONVERSATION_CONTROL_ATTRIBUTE, kind)
51
+ owned.add(button)
52
+ }
53
+
54
+ function scan() {
55
+ for (const button of pending) process(button)
56
+ pending.clear()
57
+ for (const button of [...owned]) {
58
+ if (!button.isConnected) process(button)
59
+ }
60
+ }
61
+
62
+ function queueScan() {
63
+ scan()
64
+ }
65
+
66
+ function onMutations(mutations) {
67
+ for (const mutation of mutations) {
68
+ if (mutation.type === 'attributes') collectButtons(mutation.target)
69
+ for (const node of mutation.addedNodes ?? []) collectButtons(node)
70
+ for (const node of mutation.removedNodes ?? []) {
71
+ if (node?.nodeType !== 1) continue
72
+ for (const button of owned) {
73
+ if (button === node || node.contains?.(button)) pending.add(button)
74
+ }
75
+ }
76
+ }
77
+ if (pending.size) queueScan()
78
+ }
79
+
80
+ function clear() {
81
+ for (const button of owned) button.removeAttribute?.(CONVERSATION_CONTROL_ATTRIBUTE)
82
+ owned.clear()
83
+ pending.clear()
84
+ }
85
+
86
+ return {
87
+ start() {
88
+ if (!document) return
89
+ operation = document.querySelector('[data-prts-region="operation"]')
90
+ if (!operation) return
91
+ collectButtons(operation)
92
+ scan()
93
+ if (observer || !window?.MutationObserver) return
94
+ observer = new window.MutationObserver(onMutations)
95
+ observer.observe(operation, {
96
+ subtree: true,
97
+ childList: true,
98
+ attributes: true,
99
+ attributeFilter: ['class', 'data-approval-key'],
100
+ })
101
+ },
102
+ dispose() {
103
+ observer?.disconnect()
104
+ observer = undefined
105
+ clear()
106
+ operation = undefined
107
+ },
108
+ }
109
+ }