@mohammadhprp/system-prompt 0.12.1 → 0.12.3

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 (173) hide show
  1. package/framework/agents/README.md +0 -1
  2. package/framework/commands/README.md +1 -1
  3. package/framework/commands/mr.md +8 -9
  4. package/framework/commands/review.md +1 -1
  5. package/framework/mcps/README.md +0 -4
  6. package/framework/plugins/ponytail/README.md +0 -1
  7. package/framework/plugins/ponytail/capabilities.md +1 -1
  8. package/framework/references/standards/api.md +0 -1
  9. package/framework/references/standards/architecture.md +0 -1
  10. package/framework/references/standards/database.md +0 -1
  11. package/framework/references/standards/debugging.md +0 -1
  12. package/framework/references/standards/documentation.md +0 -1
  13. package/framework/references/standards/logging.md +0 -1
  14. package/framework/references/standards/naming.md +0 -1
  15. package/framework/references/standards/observability.md +0 -1
  16. package/framework/references/standards/performance.md +0 -1
  17. package/framework/references/standards/pull-requests.md +0 -1
  18. package/framework/references/standards/security.md +0 -1
  19. package/framework/references/standards/testing.md +0 -1
  20. package/framework/skills/README.md +4 -14
  21. package/framework/skills/glab/SKILL.md +222 -0
  22. package/framework/skills/glab/references/commands-detailed.md +616 -0
  23. package/framework/skills/glab/references/quick-reference.md +145 -0
  24. package/framework/skills/glab/references/troubleshooting.md +669 -0
  25. package/framework/skills/improve/SKILL.md +135 -0
  26. package/framework/skills/improve/examples.md +19 -0
  27. package/framework/skills/improve/references/audit-playbook.md +130 -0
  28. package/framework/skills/improve/references/closing-the-loop.md +96 -0
  29. package/framework/skills/improve/references/plan-template.md +197 -0
  30. package/framework/skills/jira-cli/SKILL.md +260 -0
  31. package/framework/skills/jira-cli/references/commands-detailed.md +268 -0
  32. package/framework/skills/jira-cli/references/quick-reference.md +111 -0
  33. package/framework/skills/jira-cli/references/troubleshooting.md +114 -0
  34. package/framework/skills/laravel-best-practices/SKILL.md +56 -216
  35. package/framework/skills/laravel-best-practices/references/architecture.md +1 -1
  36. package/framework/skills/laravel-best-practices/references/checklist.md +139 -0
  37. package/framework/skills/laravel-best-practices/references/eloquent.md +4 -2
  38. package/framework/skills/laravel-best-practices/references/infer-conventions.md +97 -0
  39. package/framework/skills/laravel-best-practices/references/pest-testing.md +47 -18
  40. package/framework/skills/laravel-best-practices/references/security.md +1 -1
  41. package/framework/skills/laravel-best-practices/references/style.md +1 -1
  42. package/framework/skills/laravel-best-practices/references/tailwindcss.md +0 -1
  43. package/framework/styles/README.md +9 -4
  44. package/framework/styles/factory/DESIGN.md +360 -0
  45. package/framework/styles/factory/README.md +32 -0
  46. package/framework/styles/factory/assets/preview.jpg +0 -0
  47. package/framework/styles/huly/DESIGN.md +449 -0
  48. package/framework/styles/huly/README.md +32 -0
  49. package/framework/styles/huly/assets/preview.jpg +0 -0
  50. package/framework/styles/notion/DESIGN.md +423 -0
  51. package/framework/styles/notion/README.md +32 -0
  52. package/framework/styles/notion/assets/preview.jpg +0 -0
  53. package/package.json +1 -1
  54. package/src/catalog.js +7 -19
  55. package/framework/agents/backend-architect.md +0 -146
  56. package/framework/mcps/github-mcp/README.md +0 -51
  57. package/framework/mcps/github-mcp/capabilities.md +0 -83
  58. package/framework/mcps/github-mcp/configs/.env.example +0 -1
  59. package/framework/mcps/github-mcp/configs/opencode.json +0 -13
  60. package/framework/mcps/github-mcp/install.md +0 -60
  61. package/framework/mcps/github-mcp/troubleshooting.md +0 -79
  62. package/framework/mcps/gitlab-mcp/README.md +0 -53
  63. package/framework/mcps/gitlab-mcp/capabilities.md +0 -216
  64. package/framework/mcps/gitlab-mcp/configs/.env.example +0 -2
  65. package/framework/mcps/gitlab-mcp/configs/opencode.json +0 -13
  66. package/framework/mcps/gitlab-mcp/install.md +0 -99
  67. package/framework/mcps/gitlab-mcp/troubleshooting.md +0 -116
  68. package/framework/mcps/jira-mcp/README.md +0 -52
  69. package/framework/mcps/jira-mcp/capabilities.md +0 -79
  70. package/framework/mcps/jira-mcp/configs/.env.example +0 -2
  71. package/framework/mcps/jira-mcp/configs/opencode.json +0 -13
  72. package/framework/mcps/jira-mcp/install.md +0 -94
  73. package/framework/mcps/jira-mcp/troubleshooting.md +0 -113
  74. package/framework/mcps/notion-mcp/README.md +0 -57
  75. package/framework/mcps/notion-mcp/capabilities.md +0 -118
  76. package/framework/mcps/notion-mcp/configs/opencode.json +0 -9
  77. package/framework/mcps/notion-mcp/install.md +0 -70
  78. package/framework/mcps/notion-mcp/troubleshooting.md +0 -95
  79. package/framework/skills/brainstorming/SKILL.md +0 -159
  80. package/framework/skills/brainstorming/examples.md +0 -49
  81. package/framework/skills/brainstorming/scripts/frame-template.html +0 -213
  82. package/framework/skills/brainstorming/scripts/helper.js +0 -167
  83. package/framework/skills/brainstorming/scripts/server.cjs +0 -723
  84. package/framework/skills/brainstorming/scripts/start-server.sh +0 -209
  85. package/framework/skills/brainstorming/scripts/stop-server.sh +0 -120
  86. package/framework/skills/brainstorming/visual-companion.md +0 -291
  87. package/framework/skills/code-review/SKILL.md +0 -72
  88. package/framework/skills/code-review/examples.md +0 -31
  89. package/framework/skills/codenavi/SKILL.md +0 -306
  90. package/framework/skills/codenavi/examples.md +0 -33
  91. package/framework/skills/codenavi/references/coding-principles.md +0 -143
  92. package/framework/skills/codenavi/references/notebook-spec.md +0 -171
  93. package/framework/skills/create-adr/SKILL.md +0 -429
  94. package/framework/skills/create-adr/examples.md +0 -35
  95. package/framework/skills/design/SKILL.md +0 -399
  96. package/framework/skills/design/examples.md +0 -34
  97. package/framework/skills/gitlab-mcp/SKILL.md +0 -83
  98. package/framework/skills/gitlab-mcp/examples.md +0 -31
  99. package/framework/skills/gitlab-mcp/references/code-review.md +0 -110
  100. package/framework/skills/gitlab-mcp/references/issues.md +0 -141
  101. package/framework/skills/gitlab-mcp/references/merge-requests.md +0 -120
  102. package/framework/skills/gitlab-mcp/references/pipelines.md +0 -67
  103. package/framework/skills/gitlab-mcp/references/search.md +0 -17
  104. package/framework/skills/gitlab-mcp/references/webhooks.md +0 -32
  105. package/framework/skills/gitlab-mcp/references/work-items.md +0 -50
  106. package/framework/skills/great-interface/SKILL.md +0 -43
  107. package/framework/skills/great-interface/references/animations.md +0 -205
  108. package/framework/skills/great-interface/references/better-accessibility.md +0 -106
  109. package/framework/skills/great-interface/references/better-colors.md +0 -100
  110. package/framework/skills/great-interface/references/better-interface.md +0 -132
  111. package/framework/skills/great-interface/references/better-layout.md +0 -76
  112. package/framework/skills/great-interface/references/better-typography.md +0 -157
  113. package/framework/skills/great-interface/references/better-ui.md +0 -107
  114. package/framework/skills/great-interface/references/better-writing.md +0 -109
  115. package/framework/skills/great-interface/references/choosing-fonts.md +0 -64
  116. package/framework/skills/great-interface/references/color-formats.md +0 -90
  117. package/framework/skills/great-interface/references/color-usage.md +0 -118
  118. package/framework/skills/great-interface/references/contrast.md +0 -79
  119. package/framework/skills/great-interface/references/css-cheat-sheet.md +0 -65
  120. package/framework/skills/great-interface/references/details-and-accessibility.md +0 -119
  121. package/framework/skills/great-interface/references/enter-exit.md +0 -147
  122. package/framework/skills/great-interface/references/explain-interface.md +0 -126
  123. package/framework/skills/great-interface/references/find-the-effect.md +0 -94
  124. package/framework/skills/great-interface/references/focus-and-keyboard.md +0 -131
  125. package/framework/skills/great-interface/references/forms.md +0 -84
  126. package/framework/skills/great-interface/references/from-an-image.md +0 -55
  127. package/framework/skills/great-interface/references/grouping-and-alignment.md +0 -123
  128. package/framework/skills/great-interface/references/hit-areas.md +0 -94
  129. package/framework/skills/great-interface/references/icon-transitions.md +0 -102
  130. package/framework/skills/great-interface/references/icons.md +0 -110
  131. package/framework/skills/great-interface/references/interface-review.md +0 -148
  132. package/framework/skills/great-interface/references/motion-and-zoom.md +0 -79
  133. package/framework/skills/great-interface/references/no-browser.md +0 -73
  134. package/framework/skills/great-interface/references/palette-generation.md +0 -104
  135. package/framework/skills/great-interface/references/palette-structure.md +0 -76
  136. package/framework/skills/great-interface/references/performance.md +0 -88
  137. package/framework/skills/great-interface/references/picker.md +0 -76
  138. package/framework/skills/great-interface/references/read-the-system.md +0 -178
  139. package/framework/skills/great-interface/references/removed-signals.md +0 -38
  140. package/framework/skills/great-interface/references/review-format.md +0 -46
  141. package/framework/skills/great-interface/references/scope-resolution.md +0 -88
  142. package/framework/skills/great-interface/references/screen-readers.md +0 -101
  143. package/framework/skills/great-interface/references/semantics-and-aria.md +0 -84
  144. package/framework/skills/great-interface/references/spacing-and-adaptivity.md +0 -159
  145. package/framework/skills/great-interface/references/spacing-and-sizing.md +0 -121
  146. package/framework/skills/great-interface/references/surfaces.md +0 -219
  147. package/framework/skills/great-interface/references/token-naming.md +0 -97
  148. package/framework/skills/great-interface/references/variable-fonts-and-opentype.md +0 -105
  149. package/framework/skills/great-interface/references/variant.md +0 -104
  150. package/framework/skills/great-interface/references/wrapping-and-punctuation.md +0 -55
  151. package/framework/skills/jira-mcp/SKILL.md +0 -57
  152. package/framework/skills/jira-mcp/examples.md +0 -31
  153. package/framework/skills/jira-mcp/references/comments.md +0 -27
  154. package/framework/skills/jira-mcp/references/issues.md +0 -97
  155. package/framework/skills/jira-mcp/references/projects.md +0 -39
  156. package/framework/skills/learning-opportunities/SKILL.md +0 -140
  157. package/framework/skills/learning-opportunities/examples.md +0 -34
  158. package/framework/skills/learning-opportunities/references/PRINCIPLES.md +0 -42
  159. package/framework/skills/notion-mcp/SKILL.md +0 -57
  160. package/framework/skills/notion-mcp/examples.md +0 -31
  161. package/framework/skills/notion-mcp/references/comments.md +0 -112
  162. package/framework/skills/notion-mcp/references/databases.md +0 -193
  163. package/framework/skills/notion-mcp/references/pages.md +0 -235
  164. package/framework/skills/spec-driven-eval/SKILL.md +0 -341
  165. package/framework/skills/spec-driven-eval/examples.md +0 -35
  166. package/framework/skills/spec-driven-eval/references/quickstart.md +0 -118
  167. package/framework/skills/spec-driven-eval/references/reference.md +0 -295
  168. package/framework/skills/technical-design-doc-creator/README.md +0 -411
  169. package/framework/skills/technical-design-doc-creator/SKILL.md +0 -1484
  170. package/framework/skills/technical-design-doc-creator/examples.md +0 -35
  171. package/framework/skills/web-design-guidelines/SKILL.md +0 -65
  172. package/framework/skills/web-design-guidelines/examples.md +0 -32
  173. package/framework/skills/web-design-guidelines/references/guideline.md +0 -174
@@ -1,213 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8">
5
- <title>Brainstorming</title>
6
- <style>
7
- /*
8
- * BRAINSTORM COMPANION FRAME TEMPLATE
9
- *
10
- * This template provides a consistent frame with:
11
- * - OS-aware light/dark theming
12
- * - Header branding and connection status
13
- * - Scrollable main content area
14
- * - CSS helpers for common UI patterns
15
- *
16
- * Content is injected via placeholder comment in #frame-content.
17
- */
18
-
19
- * { box-sizing: border-box; margin: 0; padding: 0; }
20
- html, body { height: 100%; overflow: hidden; }
21
-
22
- /* ===== THEME VARIABLES ===== */
23
- :root {
24
- --bg-primary: #f5f5f7;
25
- --bg-secondary: #ffffff;
26
- --bg-tertiary: #e5e5e7;
27
- --border: #d1d1d6;
28
- --text-primary: #1d1d1f;
29
- --text-secondary: #86868b;
30
- --text-tertiary: #aeaeb2;
31
- --accent: #0071e3;
32
- --accent-hover: #0077ed;
33
- --success: #34c759;
34
- --warning: #ff9f0a;
35
- --error: #ff3b30;
36
- --selected-bg: #e8f4fd;
37
- --selected-border: #0071e3;
38
- }
39
-
40
- @media (prefers-color-scheme: dark) {
41
- :root {
42
- --bg-primary: #1d1d1f;
43
- --bg-secondary: #2d2d2f;
44
- --bg-tertiary: #3d3d3f;
45
- --border: #424245;
46
- --text-primary: #f5f5f7;
47
- --text-secondary: #86868b;
48
- --text-tertiary: #636366;
49
- --accent: #0a84ff;
50
- --accent-hover: #409cff;
51
- --selected-bg: rgba(10, 132, 255, 0.15);
52
- --selected-border: #0a84ff;
53
- }
54
- }
55
-
56
- body {
57
- font-family: system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
58
- background: var(--bg-primary);
59
- color: var(--text-primary);
60
- display: flex;
61
- flex-direction: column;
62
- line-height: 1.5;
63
- }
64
-
65
- /* ===== FRAME STRUCTURE ===== */
66
- .brand { display: flex; align-items: center; min-width: 0; overflow: hidden; color: var(--text-secondary); line-height: 1; }
67
- .brand a { color: inherit; text-decoration: none; display: flex; align-items: center; gap: 0.5rem; min-width: 0; max-width: 100%; line-height: 1; }
68
- .brand-copy { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 1; transform: translateY(-1px); }
69
- .brand-logo { display: block; height: 1em; width: auto; max-width: 180px; flex-shrink: 0; filter: invert(1); }
70
- @media (prefers-color-scheme: dark) {
71
- .brand-logo { filter: none; }
72
- }
73
- .status { font-size: 0.7rem; color: var(--status-color, var(--success)); display: flex; align-items: center; gap: 0.4rem; justify-self: end; white-space: nowrap; line-height: 1; }
74
- .status::before { content: ''; width: 6px; height: 6px; background: var(--status-color, var(--success)); border-radius: 50%; }
75
-
76
- .main { flex: 1; overflow-y: auto; }
77
- #frame-content { padding: 2rem; min-height: 100%; }
78
-
79
- .header {
80
- background: var(--bg-secondary);
81
- border-bottom: 1px solid var(--border);
82
- padding: 0.5rem 1.5rem;
83
- flex-shrink: 0;
84
- display: grid;
85
- grid-template-columns: minmax(0, 1fr) auto;
86
- align-items: center;
87
- gap: 1rem;
88
- min-height: 42px;
89
- }
90
- .header .brand { justify-self: start; width: 100%; font-size: 0.75rem; line-height: 1; }
91
- .header .status { grid-column: 2; line-height: 1; }
92
- .header span {
93
- font-size: 0.75rem;
94
- color: var(--text-secondary);
95
- }
96
- .header .selected-text {
97
- color: var(--accent);
98
- font-weight: 500;
99
- }
100
-
101
- /* ===== TYPOGRAPHY ===== */
102
- h2 { font-size: 1.5rem; font-weight: 600; margin-bottom: 0.5rem; }
103
- h3 { font-size: 1.1rem; font-weight: 600; margin-bottom: 0.25rem; }
104
- .subtitle { color: var(--text-secondary); margin-bottom: 1.5rem; }
105
- .section { margin-bottom: 2rem; }
106
- .label { font-size: 0.7rem; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.5rem; }
107
-
108
- /* ===== OPTIONS (for A/B/C choices) ===== */
109
- .options { display: flex; flex-direction: column; gap: 0.75rem; }
110
- .option {
111
- background: var(--bg-secondary);
112
- border: 2px solid var(--border);
113
- border-radius: 12px;
114
- padding: 1rem 1.25rem;
115
- cursor: pointer;
116
- transition: all 0.15s ease;
117
- display: flex;
118
- align-items: flex-start;
119
- gap: 1rem;
120
- }
121
- .option:hover { border-color: var(--accent); }
122
- .option.selected { background: var(--selected-bg); border-color: var(--selected-border); }
123
- .option .letter {
124
- background: var(--bg-tertiary);
125
- color: var(--text-secondary);
126
- width: 1.75rem; height: 1.75rem;
127
- border-radius: 6px;
128
- display: flex; align-items: center; justify-content: center;
129
- font-weight: 600; font-size: 0.85rem; flex-shrink: 0;
130
- }
131
- .option.selected .letter { background: var(--accent); color: white; }
132
- .option .content { flex: 1; }
133
- .option .content h3 { font-size: 0.95rem; margin-bottom: 0.15rem; }
134
- .option .content p { color: var(--text-secondary); font-size: 0.85rem; margin: 0; }
135
-
136
- /* ===== CARDS (for showing designs/mockups) ===== */
137
- .cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1rem; }
138
- .card {
139
- background: var(--bg-secondary);
140
- border: 1px solid var(--border);
141
- border-radius: 12px;
142
- overflow: hidden;
143
- cursor: pointer;
144
- transition: all 0.15s ease;
145
- }
146
- .card:hover { border-color: var(--accent); transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
147
- .card.selected { border-color: var(--selected-border); border-width: 2px; }
148
- .card-image { background: var(--bg-tertiary); aspect-ratio: 16/10; display: flex; align-items: center; justify-content: center; }
149
- .card-body { padding: 1rem; }
150
- .card-body h3 { margin-bottom: 0.25rem; }
151
- .card-body p { color: var(--text-secondary); font-size: 0.85rem; }
152
-
153
- /* ===== MOCKUP CONTAINER ===== */
154
- .mockup {
155
- background: var(--bg-secondary);
156
- border: 1px solid var(--border);
157
- border-radius: 12px;
158
- overflow: hidden;
159
- margin-bottom: 1.5rem;
160
- }
161
- .mockup-header {
162
- background: var(--bg-tertiary);
163
- padding: 0.5rem 1rem;
164
- font-size: 0.75rem;
165
- color: var(--text-secondary);
166
- border-bottom: 1px solid var(--border);
167
- }
168
- .mockup-body { padding: 1.5rem; }
169
-
170
- /* ===== SPLIT VIEW (side-by-side comparison) ===== */
171
- .split { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; }
172
- @media (max-width: 700px) { .split { grid-template-columns: 1fr; } }
173
-
174
- /* ===== PROS/CONS ===== */
175
- .pros-cons { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin: 1rem 0; }
176
- .pros, .cons { background: var(--bg-secondary); border-radius: 8px; padding: 1rem; }
177
- .pros h4 { color: var(--success); font-size: 0.85rem; margin-bottom: 0.5rem; }
178
- .cons h4 { color: var(--error); font-size: 0.85rem; margin-bottom: 0.5rem; }
179
- .pros ul, .cons ul { margin-left: 1.25rem; font-size: 0.85rem; color: var(--text-secondary); }
180
- .pros li, .cons li { margin-bottom: 0.25rem; }
181
-
182
- /* ===== PLACEHOLDER (for mockup areas) ===== */
183
- .placeholder {
184
- background: var(--bg-tertiary);
185
- border: 2px dashed var(--border);
186
- border-radius: 8px;
187
- padding: 2rem;
188
- text-align: center;
189
- color: var(--text-tertiary);
190
- }
191
-
192
- /* ===== INLINE MOCKUP ELEMENTS ===== */
193
- .mock-nav { background: var(--accent); color: white; padding: 0.75rem 1rem; display: flex; gap: 1.5rem; font-size: 0.9rem; }
194
- .mock-sidebar { background: var(--bg-tertiary); padding: 1rem; min-width: 180px; }
195
- .mock-content { padding: 1.5rem; flex: 1; }
196
- .mock-button { background: var(--accent); color: white; border: none; padding: 0.5rem 1rem; border-radius: 6px; font-size: 0.85rem; }
197
- .mock-input { background: var(--bg-primary); border: 1px solid var(--border); border-radius: 6px; padding: 0.5rem; width: 100%; }
198
- </style>
199
- </head>
200
- <body>
201
- <div class="header">
202
- <!-- BRANDING -->
203
- <div class="status">Connecting…</div>
204
- </div>
205
-
206
- <div class="main">
207
- <div id="frame-content">
208
- <!-- CONTENT -->
209
- </div>
210
- </div>
211
-
212
- </body>
213
- </html>
@@ -1,167 +0,0 @@
1
- (function() {
2
- const MIN_RECONNECT_MS = 500;
3
- const MAX_RECONNECT_MS = 30000;
4
- const TOMBSTONE_AFTER_MS = 15000; // show the "paused" overlay after this long disconnected
5
-
6
- // Pure: next backoff delay (doubles, capped). Exported for unit tests.
7
- function nextReconnectDelay(current, max) {
8
- return Math.min(current * 2, max);
9
- }
10
- if (typeof module !== 'undefined' && module.exports) {
11
- module.exports = { nextReconnectDelay, MIN_RECONNECT_MS, MAX_RECONNECT_MS, TOMBSTONE_AFTER_MS };
12
- }
13
-
14
- // Everything below is browser-only; bail out when loaded in Node (tests).
15
- if (typeof window === 'undefined') return;
16
-
17
- let ws = null;
18
- let eventQueue = [];
19
- let reconnectDelay = MIN_RECONNECT_MS;
20
- let reconnectTimer = null;
21
- let disconnectedSince = null;
22
- let everConnected = false;
23
- let tombstoneShown = false;
24
-
25
- function sessionKey() {
26
- try {
27
- return window.sessionStorage && window.sessionStorage.getItem('brainstorm-session-key');
28
- } catch (e) {}
29
- return null;
30
- }
31
-
32
- function websocketUrl() {
33
- const key = sessionKey();
34
- return 'ws://' + window.location.host + (key ? '/?key=' + encodeURIComponent(key) : '');
35
- }
36
-
37
- function reloadAfterRecovery() {
38
- const key = sessionKey();
39
- if (key) {
40
- window.location.replace('/?key=' + encodeURIComponent(key));
41
- } else {
42
- window.location.reload();
43
- }
44
- }
45
-
46
- // Reflect connection state in the frame's status pill (absent on full-doc screens).
47
- function setStatus(state) {
48
- const el = document.querySelector('.status');
49
- if (!el) return;
50
- const map = {
51
- connecting: ['Connecting…', 'var(--text-tertiary)'],
52
- connected: ['Connected', 'var(--success)'],
53
- reconnecting: ['Reconnecting…', 'var(--warning)'],
54
- disconnected: ['Disconnected', 'var(--error)']
55
- };
56
- const [text, color] = map[state] || map.disconnected;
57
- el.textContent = text;
58
- el.style.setProperty('--status-color', color);
59
- }
60
-
61
- // Self-styled so it works on framed and full-document screens alike.
62
- function showTombstone() {
63
- if (tombstoneShown) return;
64
- tombstoneShown = true;
65
- const el = document.createElement('div');
66
- el.id = 'bs-tombstone';
67
- el.style.cssText = 'position:fixed;inset:0;z-index:99999;display:flex;' +
68
- 'align-items:center;justify-content:center;padding:2rem;text-align:center;' +
69
- 'background:rgba(20,20,22,0.92);color:#f5f5f7;font-family:system-ui,sans-serif';
70
- el.innerHTML = '<div style="max-width:480px">' +
71
- '<h2 style="margin:0 0 .5rem;font-weight:600">Companion paused</h2>' +
72
- '<p style="margin:0;opacity:.85">This brainstorm companion has stopped. ' +
73
- 'Ask your coding agent to bring it back — this page reconnects automatically.</p></div>';
74
- if (document.body) document.body.appendChild(el);
75
- }
76
-
77
- function connect() {
78
- if (reconnectTimer) { clearTimeout(reconnectTimer); reconnectTimer = null; }
79
- setStatus(everConnected ? 'reconnecting' : 'connecting');
80
- ws = new WebSocket(websocketUrl());
81
-
82
- ws.onopen = () => {
83
- const recovered = tombstoneShown;
84
- everConnected = true;
85
- disconnectedSince = null;
86
- reconnectDelay = MIN_RECONNECT_MS;
87
- tombstoneShown = false;
88
- setStatus('connected');
89
- eventQueue.forEach(e => ws.send(JSON.stringify(e)));
90
- eventQueue = [];
91
- // Recovered from a tombstoned outage (e.g. the server restarted on the same
92
- // port) — reload through the keyed bootstrap when possible so the cookie is
93
- // refreshed before the visible URL returns to bare /.
94
- if (recovered) reloadAfterRecovery();
95
- };
96
-
97
- ws.onmessage = (msg) => {
98
- let data;
99
- try { data = JSON.parse(msg.data); } catch (e) { return; }
100
- if (data.type === 'reload') window.location.reload();
101
- };
102
-
103
- ws.onclose = () => {
104
- ws = null;
105
- if (disconnectedSince === null) disconnectedSince = Date.now();
106
- if (Date.now() - disconnectedSince >= TOMBSTONE_AFTER_MS) {
107
- setStatus('disconnected');
108
- showTombstone();
109
- } else {
110
- setStatus('reconnecting');
111
- }
112
- reconnectTimer = setTimeout(connect, reconnectDelay);
113
- reconnectDelay = nextReconnectDelay(reconnectDelay, MAX_RECONNECT_MS);
114
- };
115
-
116
- // Let onclose own reconnection so we don't schedule it twice.
117
- ws.onerror = () => { try { ws.close(); } catch (e) {} };
118
- }
119
-
120
- function sendEvent(event) {
121
- event.timestamp = Date.now();
122
- if (ws && ws.readyState === WebSocket.OPEN) {
123
- ws.send(JSON.stringify(event));
124
- } else {
125
- eventQueue.push(event);
126
- }
127
- }
128
-
129
- // Capture clicks on choice elements
130
- document.addEventListener('click', (e) => {
131
- const target = e.target.closest('[data-choice]');
132
- if (!target) return;
133
-
134
- sendEvent({
135
- type: 'click',
136
- text: target.textContent.trim(),
137
- choice: target.dataset.choice,
138
- id: target.id || null
139
- });
140
-
141
- });
142
-
143
- // Frame UI: selection tracking
144
- window.selectedChoice = null;
145
-
146
- window.toggleSelect = function(el) {
147
- const container = el.closest('.options') || el.closest('.cards');
148
- const multi = container && container.dataset.multiselect !== undefined;
149
- if (container && !multi) {
150
- container.querySelectorAll('.option, .card').forEach(o => o.classList.remove('selected'));
151
- }
152
- if (multi) {
153
- el.classList.toggle('selected');
154
- } else {
155
- el.classList.add('selected');
156
- }
157
- window.selectedChoice = el.dataset.choice;
158
- };
159
-
160
- // Expose API for explicit use
161
- window.brainstorm = {
162
- send: sendEvent,
163
- choice: (value, metadata = {}) => sendEvent({ type: 'choice', value, ...metadata })
164
- };
165
-
166
- connect();
167
- })();