mdboard 1.3.0 → 2.1.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.
Files changed (53) hide show
  1. package/bin.js +117 -59
  2. package/index.html +2161 -1579
  3. package/package.json +7 -5
  4. package/presets/kanban/api.json +91 -0
  5. package/presets/kanban/cli.json +69 -0
  6. package/presets/kanban/docs.json +29 -0
  7. package/presets/kanban/entities.json +128 -0
  8. package/presets/kanban/structure.json +15 -0
  9. package/presets/kanban/ui.json +86 -0
  10. package/presets/scrum/api.json +98 -0
  11. package/presets/scrum/cli.json +120 -0
  12. package/presets/scrum/docs.json +43 -0
  13. package/presets/scrum/entities.json +268 -0
  14. package/presets/scrum/structure.json +32 -0
  15. package/presets/scrum/ui.json +201 -0
  16. package/presets/shape-up/api.json +40 -0
  17. package/presets/shape-up/cli.json +44 -0
  18. package/presets/shape-up/docs.json +32 -0
  19. package/presets/shape-up/entities.json +140 -0
  20. package/presets/shape-up/structure.json +28 -0
  21. package/presets/shape-up/ui.json +114 -0
  22. package/src/cli/cli.js +186 -210
  23. package/src/cli/config.js +234 -0
  24. package/src/cli/init.js +128 -76
  25. package/src/cli/preset.js +849 -0
  26. package/src/cli/skill.js +417 -0
  27. package/src/cli/status.js +126 -96
  28. package/src/core/config.js +491 -38
  29. package/src/core/history.js +17 -1
  30. package/src/core/scanner.js +373 -463
  31. package/src/core/workspace.js +0 -15
  32. package/src/server/api.js +464 -741
  33. package/src/server/server.js +105 -130
  34. package/build.js +0 -44
  35. package/defaults.json +0 -43
  36. package/src/cli/sync.js +0 -194
  37. package/src/cli/theme.js +0 -142
  38. package/src/client/app.js +0 -266
  39. package/src/client/board.js +0 -157
  40. package/src/client/core.js +0 -331
  41. package/src/client/editor.js +0 -318
  42. package/src/client/history.js +0 -137
  43. package/src/client/metrics.js +0 -38
  44. package/src/client/milestones.js +0 -77
  45. package/src/client/notes.js +0 -183
  46. package/src/client/overview.js +0 -104
  47. package/src/client/panel.js +0 -637
  48. package/src/client/styles.css +0 -471
  49. package/src/client/table.js +0 -111
  50. package/src/client/template.html +0 -144
  51. package/src/client/themes.js +0 -261
  52. package/src/client/workspace.js +0 -164
  53. package/src/core/agent-scanner.js +0 -260
@@ -1,144 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>mdboard</title>
7
- <style>
8
- <!-- STYLES -->
9
- </style>
10
- <style id="dynamic-styles"></style>
11
- <style id="theme-styles"></style>
12
- <link id="custom-theme" rel="stylesheet" href="/mdboard.css">
13
- </head>
14
- <body>
15
- <div class="app">
16
- <!-- Source Rail (Discord/Slack style) -->
17
- <nav class="source-rail" id="source-rail"></nav>
18
-
19
- <!-- Sidebar -->
20
- <aside class="sidebar">
21
- <div class="sidebar-logo" id="sidebar-logo">
22
- <span class="sidebar-logo-icon" id="sidebar-logo-icon">&#9632;</span>
23
- <span class="sidebar-logo-text" id="sidebar-logo-text">mdboard</span>
24
- </div>
25
- <nav id="sidebar-nav">
26
- <a href="#board" data-view="board" class="active">
27
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg>
28
- <span>Board</span>
29
- </a>
30
- <a href="#table" data-view="table">
31
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
32
- <span>Table</span>
33
- </a>
34
- <a href="#milestones" data-view="milestones">
35
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"/><line x1="4" y1="22" x2="4" y2="15"/></svg>
36
- <span>Milestones</span>
37
- </a>
38
- <a href="#metrics" data-view="metrics">
39
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M18 20V10M12 20V4M6 20v-6"/></svg>
40
- <span>Metrics</span>
41
- </a>
42
- <a href="#notes" data-view="notes">
43
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/></svg>
44
- <span>Notes</span>
45
- </a>
46
- </nav>
47
- <div class="sidebar-settings" id="sidebar-settings">
48
- <a href="#" id="settings-toggle">
49
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 01-2.83 2.83l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83-2.83l.06-.06A1.65 1.65 0 004.68 15a1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 012.83-2.83l.06.06A1.65 1.65 0 009 4.68a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 2.83l-.06.06A1.65 1.65 0 0019.4 9a1.65 1.65 0 001.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z"/></svg>
50
- <span>Settings</span>
51
- </a>
52
- </div>
53
- <div class="sidebar-footer">mdboard</div>
54
- </aside>
55
-
56
- <div class="main">
57
- <!-- Header -->
58
- <header class="header">
59
- <div class="header-section" id="h-milestone-wrap" style="display:none">
60
- <span class="header-section-label">Milestone</span>
61
- <span class="header-section-value" id="h-milestone-name"></span>
62
- <div class="progress progress-accent"><div class="progress-fill" id="h-milestone-progress" style="width:0%"></div></div>
63
- </div>
64
- <div class="header-section" id="h-sprint-wrap" style="display:none">
65
- <span class="header-section-label">Sprint</span>
66
- <span class="header-section-value" id="h-sprint-name"></span>
67
- <span style="font-size:11px;color:var(--text2)" id="h-sprint-days"></span>
68
- </div>
69
- <div id="h-stats"></div>
70
- </header>
71
-
72
- <!-- Content -->
73
- <div class="content">
74
- <div id="view-board" class="view active">
75
- <div id="sprint-bar" style="display:none"></div>
76
- <div id="board-filters" class="filter-bar"></div>
77
- <div id="board"></div>
78
- </div>
79
- <div id="view-table" class="view">
80
- <div id="table-controls" class="filter-bar"></div>
81
- <div id="table-wrapper"></div>
82
- </div>
83
- <div id="view-milestones" class="view">
84
- <div id="ms-filters" class="filter-bar"></div>
85
- <div id="milestones-container"></div>
86
- </div>
87
- <div id="view-metrics" class="view">
88
- <div id="metrics-container"></div>
89
- </div>
90
- <div id="view-overview" class="view">
91
- <div id="overview-container"></div>
92
- </div>
93
- <div id="view-notes" class="view">
94
- <div id="notes-container"></div>
95
- </div>
96
- </div>
97
- </div>
98
- </div>
99
-
100
- <!-- Detail Panel -->
101
- <div id="panel-overlay" class="panel-overlay"></div>
102
- <div id="detail-panel" class="detail-panel"></div>
103
-
104
- <!-- Settings Panel -->
105
- <div id="settings-overlay" class="settings-overlay"></div>
106
- <div id="settings-panel" class="settings-panel">
107
- <div class="settings-header">
108
- <h2>Settings</h2>
109
- <button class="panel-close" id="settings-close">&times;</button>
110
- </div>
111
- <div class="settings-content">
112
- <div class="settings-section">
113
- <h3>Theme</h3>
114
- <p id="settings-theme-info" class="settings-theme-info"></p>
115
- <div id="theme-grid" class="theme-grid"></div>
116
- </div>
117
- </div>
118
- <div class="settings-footer">
119
- <label class="toggle-label">
120
- <input type="checkbox" id="theme-default-toggle">
121
- <span class="toggle-switch"></span>
122
- <span>Set as default for all projects</span>
123
- </label>
124
- <button class="btn btn-primary" id="settings-save">Save</button>
125
- </div>
126
- </div>
127
-
128
- <!-- History Modal -->
129
- <div id="history-overlay" class="history-overlay"></div>
130
- <div id="history-modal" class="history-modal"></div>
131
-
132
- <script src="https://cdn.jsdelivr.net/npm/@editorjs/editorjs@2/dist/editorjs.umd.js"></script>
133
- <script src="https://cdn.jsdelivr.net/npm/@editorjs/header@latest/dist/header.umd.js"></script>
134
- <script src="https://cdn.jsdelivr.net/npm/@editorjs/list@latest/dist/editorjs-list.umd.js"></script>
135
- <script src="https://cdn.jsdelivr.net/npm/@editorjs/code@latest/dist/code.umd.js"></script>
136
- <script src="https://cdn.jsdelivr.net/npm/@editorjs/quote@latest/dist/quote.umd.js"></script>
137
- <script src="https://cdn.jsdelivr.net/npm/@editorjs/delimiter@latest/dist/delimiter.umd.js"></script>
138
- <script src="https://cdn.jsdelivr.net/npm/@editorjs/marker@latest/dist/marker.umd.js"></script>
139
- <script src="https://cdn.jsdelivr.net/npm/@editorjs/inline-code@latest/dist/inline-code.umd.js"></script>
140
- <script>
141
- <!-- SCRIPTS -->
142
- </script>
143
- </body>
144
- </html>
@@ -1,261 +0,0 @@
1
- /* ══════════════════════════════════════════════════════════════
2
- THEMES — Predefined color themes for mdboard
3
- ══════════════════════════════════════════════════════════════ */
4
- var THEMES = {
5
- 'default-dark': {
6
- name: 'Default Dark', type: 'dark',
7
- vars: {
8
- bg:'#0A0A0B',surface:'#141415',surface2:'#1A1A1C',border:'#232326',border2:'#2E2E33',
9
- text:'#E8E8ED',text2:'#8B8B93',text3:'#5A5A63',
10
- accent:'#5B6EF5','accent-dim':'rgba(91,110,245,.15)',
11
- success:'#2EA043','success-dim':'rgba(46,160,67,.15)',
12
- warning:'#D4A72C','warning-dim':'rgba(212,167,44,.15)',
13
- danger:'#DA3633','danger-dim':'rgba(218,54,51,.15)',
14
- purple:'#8B5CF6','purple-dim':'rgba(139,92,246,.15)'
15
- }
16
- },
17
- 'linear-dark': {
18
- name: 'Linear Dark', type: 'dark',
19
- vars: {
20
- bg:'#101012',surface:'#1A1A1F',surface2:'#222228',border:'#2C2C35',border2:'#38384A',
21
- text:'#E2E2E9',text2:'#8E8E9E',text3:'#5C5C6E',
22
- accent:'#5E6AD2','accent-dim':'rgba(94,106,210,.15)',
23
- success:'#4DA771','success-dim':'rgba(77,167,113,.15)',
24
- warning:'#F2C94C','warning-dim':'rgba(242,201,76,.15)',
25
- danger:'#EB5757','danger-dim':'rgba(235,87,87,.15)',
26
- purple:'#BB87FC','purple-dim':'rgba(187,135,252,.15)'
27
- }
28
- },
29
- 'linear-light': {
30
- name: 'Linear Light', type: 'light',
31
- vars: {
32
- bg:'#F9F9FB',surface:'#FFFFFF',surface2:'#F0F0F4',border:'#E0E0E6',border2:'#D0D0D8',
33
- text:'#1A1A2E',text2:'#6B6B80',text3:'#9090A0',
34
- accent:'#5E6AD2','accent-dim':'rgba(94,106,210,.1)',
35
- success:'#4DA771','success-dim':'rgba(77,167,113,.1)',
36
- warning:'#D4A017','warning-dim':'rgba(212,160,23,.1)',
37
- danger:'#EB5757','danger-dim':'rgba(235,87,87,.1)',
38
- purple:'#9B6DD7','purple-dim':'rgba(155,109,215,.1)'
39
- }
40
- },
41
- 'jira-dark': {
42
- name: 'Jira Dark', type: 'dark',
43
- vars: {
44
- bg:'#0D1117',surface:'#161B22',surface2:'#1C2333',border:'#293040',border2:'#344050',
45
- text:'#DEE4EC',text2:'#8C96A5',text3:'#5A6577',
46
- accent:'#2684FF','accent-dim':'rgba(38,132,255,.15)',
47
- success:'#36B37E','success-dim':'rgba(54,179,126,.15)',
48
- warning:'#FFAB00','warning-dim':'rgba(255,171,0,.15)',
49
- danger:'#FF5630','danger-dim':'rgba(255,86,48,.15)',
50
- purple:'#6554C0','purple-dim':'rgba(101,84,192,.15)'
51
- }
52
- },
53
- 'jira-light': {
54
- name: 'Jira Light', type: 'light',
55
- vars: {
56
- bg:'#F4F5F7',surface:'#FFFFFF',surface2:'#EBECF0',border:'#DFE1E6',border2:'#C1C7D0',
57
- text:'#172B4D',text2:'#6B778C',text3:'#97A0AF',
58
- accent:'#0052CC','accent-dim':'rgba(0,82,204,.1)',
59
- success:'#36B37E','success-dim':'rgba(54,179,126,.1)',
60
- warning:'#FF991F','warning-dim':'rgba(255,153,31,.1)',
61
- danger:'#FF5630','danger-dim':'rgba(255,86,48,.1)',
62
- purple:'#6554C0','purple-dim':'rgba(101,84,192,.1)'
63
- }
64
- },
65
- 'catppuccin-mocha': {
66
- name: 'Catppuccin Mocha', type: 'dark',
67
- vars: {
68
- bg:'#1E1E2E',surface:'#262637',surface2:'#313244',border:'#3B3B52',border2:'#45475A',
69
- text:'#CDD6F4',text2:'#A6ADC8',text3:'#6C7086',
70
- accent:'#89B4FA','accent-dim':'rgba(137,180,250,.15)',
71
- success:'#A6E3A1','success-dim':'rgba(166,227,161,.15)',
72
- warning:'#F9E2AF','warning-dim':'rgba(249,226,175,.15)',
73
- danger:'#F38BA8','danger-dim':'rgba(243,139,168,.15)',
74
- purple:'#CBA6F7','purple-dim':'rgba(203,166,247,.15)'
75
- }
76
- },
77
- 'catppuccin-latte': {
78
- name: 'Catppuccin Latte', type: 'light',
79
- vars: {
80
- bg:'#EFF1F5',surface:'#FFFFFF',surface2:'#E6E9EF',border:'#CCD0DA',border2:'#BCC0CC',
81
- text:'#4C4F69',text2:'#6C6F85',text3:'#9CA0B0',
82
- accent:'#1E66F5','accent-dim':'rgba(30,102,245,.1)',
83
- success:'#40A02B','success-dim':'rgba(64,160,43,.1)',
84
- warning:'#DF8E1D','warning-dim':'rgba(223,142,29,.1)',
85
- danger:'#D20F39','danger-dim':'rgba(210,15,57,.1)',
86
- purple:'#8839EF','purple-dim':'rgba(136,57,239,.1)'
87
- }
88
- },
89
- 'ayu-dark': {
90
- name: 'Ayu Dark', type: 'dark',
91
- vars: {
92
- bg:'#0B0E14',surface:'#0F1219',surface2:'#151920',border:'#1E222A',border2:'#272D38',
93
- text:'#BFBDB6',text2:'#6C7380',text3:'#4A5060',
94
- accent:'#E6B450','accent-dim':'rgba(230,180,80,.15)',
95
- success:'#7FD962','success-dim':'rgba(127,217,98,.15)',
96
- warning:'#FFB454','warning-dim':'rgba(255,180,84,.15)',
97
- danger:'#F07178','danger-dim':'rgba(240,113,120,.15)',
98
- purple:'#D2A6FF','purple-dim':'rgba(210,166,255,.15)'
99
- }
100
- },
101
- 'ayu-light': {
102
- name: 'Ayu Light', type: 'light',
103
- vars: {
104
- bg:'#F8F9FA',surface:'#FFFFFF',surface2:'#F0F1F2',border:'#E0E1E2',border2:'#D4D5D6',
105
- text:'#5C6166',text2:'#787B80',text3:'#ACB0B5',
106
- accent:'#FF9940','accent-dim':'rgba(255,153,64,.1)',
107
- success:'#6CBF43','success-dim':'rgba(108,191,67,.1)',
108
- warning:'#F2AE49','warning-dim':'rgba(242,174,73,.1)',
109
- danger:'#F07171','danger-dim':'rgba(240,113,113,.1)',
110
- purple:'#A37ACC','purple-dim':'rgba(163,122,204,.1)'
111
- }
112
- },
113
- 'tokyo-night': {
114
- name: 'Tokyo Night', type: 'dark',
115
- vars: {
116
- bg:'#1A1B26',surface:'#1F2335',surface2:'#24283B',border:'#2F3449',border2:'#3B4261',
117
- text:'#C0CAF5',text2:'#7982A9',text3:'#565F89',
118
- accent:'#7AA2F7','accent-dim':'rgba(122,162,247,.15)',
119
- success:'#9ECE6A','success-dim':'rgba(158,206,106,.15)',
120
- warning:'#E0AF68','warning-dim':'rgba(224,175,104,.15)',
121
- danger:'#F7768E','danger-dim':'rgba(247,118,142,.15)',
122
- purple:'#BB9AF7','purple-dim':'rgba(187,154,247,.15)'
123
- }
124
- },
125
- 'tokyo-night-storm': {
126
- name: 'Tokyo Night Storm', type: 'dark',
127
- vars: {
128
- bg:'#24283B',surface:'#292E42',surface2:'#2F3549',border:'#3B4261',border2:'#464F78',
129
- text:'#C0CAF5',text2:'#7982A9',text3:'#565F89',
130
- accent:'#7AA2F7','accent-dim':'rgba(122,162,247,.15)',
131
- success:'#9ECE6A','success-dim':'rgba(158,206,106,.15)',
132
- warning:'#E0AF68','warning-dim':'rgba(224,175,104,.15)',
133
- danger:'#F7768E','danger-dim':'rgba(247,118,142,.15)',
134
- purple:'#BB9AF7','purple-dim':'rgba(187,154,247,.15)'
135
- }
136
- },
137
- 'notion-light': {
138
- name: 'Notion Light', type: 'light',
139
- vars: {
140
- bg:'#F7F6F3',surface:'#FFFFFF',surface2:'#EEEEEC',border:'#E3E2DE',border2:'#D4D3CF',
141
- text:'#37352F',text2:'#6B6B6B',text3:'#9B9A97',
142
- accent:'#2383E2','accent-dim':'rgba(35,131,226,.1)',
143
- success:'#0F7B0F','success-dim':'rgba(15,123,15,.1)',
144
- warning:'#CB7B00','warning-dim':'rgba(203,123,0,.1)',
145
- danger:'#E03E3E','danger-dim':'rgba(224,62,62,.1)',
146
- purple:'#6940A5','purple-dim':'rgba(105,64,165,.1)'
147
- }
148
- },
149
- 'notion-dark': {
150
- name: 'Notion Dark', type: 'dark',
151
- vars: {
152
- bg:'#191919',surface:'#202020',surface2:'#2B2B2B',border:'#363636',border2:'#444444',
153
- text:'#E3E2DE',text2:'#9B9B9B',text3:'#6B6B6B',
154
- accent:'#529CCA','accent-dim':'rgba(82,156,202,.15)',
155
- success:'#4DAB9A','success-dim':'rgba(77,171,154,.15)',
156
- warning:'#CB7B00','warning-dim':'rgba(203,123,0,.15)',
157
- danger:'#E03E3E','danger-dim':'rgba(224,62,62,.15)',
158
- purple:'#9A6DD7','purple-dim':'rgba(154,109,215,.15)'
159
- }
160
- },
161
- 'github-dark': {
162
- name: 'GitHub Dark', type: 'dark',
163
- vars: {
164
- bg:'#0D1117',surface:'#161B22',surface2:'#1C2128',border:'#30363D',border2:'#3D444D',
165
- text:'#E6EDF3',text2:'#8B949E',text3:'#6E7681',
166
- accent:'#58A6FF','accent-dim':'rgba(88,166,255,.15)',
167
- success:'#3FB950','success-dim':'rgba(63,185,80,.15)',
168
- warning:'#D29922','warning-dim':'rgba(210,153,34,.15)',
169
- danger:'#F85149','danger-dim':'rgba(248,81,73,.15)',
170
- purple:'#BC8CFF','purple-dim':'rgba(188,140,255,.15)'
171
- }
172
- },
173
- 'github-light': {
174
- name: 'GitHub Light', type: 'light',
175
- vars: {
176
- bg:'#F6F8FA',surface:'#FFFFFF',surface2:'#EAEEF2',border:'#D0D7DE',border2:'#BCC3CB',
177
- text:'#1F2328',text2:'#656D76',text3:'#8C959F',
178
- accent:'#0969DA','accent-dim':'rgba(9,105,218,.1)',
179
- success:'#1A7F37','success-dim':'rgba(26,127,55,.1)',
180
- warning:'#9A6700','warning-dim':'rgba(154,103,0,.1)',
181
- danger:'#CF222E','danger-dim':'rgba(207,34,46,.1)',
182
- purple:'#8250DF','purple-dim':'rgba(130,80,223,.1)'
183
- }
184
- },
185
- 'dracula': {
186
- name: 'Dracula', type: 'dark',
187
- vars: {
188
- bg:'#1E1F29',surface:'#282A36',surface2:'#2E303E',border:'#3A3C4E',border2:'#44475A',
189
- text:'#F8F8F2',text2:'#ADB0C0',text3:'#6272A4',
190
- accent:'#BD93F9','accent-dim':'rgba(189,147,249,.15)',
191
- success:'#50FA7B','success-dim':'rgba(80,250,123,.15)',
192
- warning:'#F1FA8C','warning-dim':'rgba(241,250,140,.15)',
193
- danger:'#FF5555','danger-dim':'rgba(255,85,85,.15)',
194
- purple:'#FF79C6','purple-dim':'rgba(255,121,198,.15)'
195
- }
196
- },
197
- 'nord': {
198
- name: 'Nord', type: 'dark',
199
- vars: {
200
- bg:'#242933',surface:'#2E3440',surface2:'#353C4A',border:'#3B4252',border2:'#434C5E',
201
- text:'#ECEFF4',text2:'#A5B1C2',text3:'#697688',
202
- accent:'#88C0D0','accent-dim':'rgba(136,192,208,.15)',
203
- success:'#A3BE8C','success-dim':'rgba(163,190,140,.15)',
204
- warning:'#EBCB8B','warning-dim':'rgba(235,203,139,.15)',
205
- danger:'#BF616A','danger-dim':'rgba(191,97,106,.15)',
206
- purple:'#B48EAD','purple-dim':'rgba(180,142,173,.15)'
207
- }
208
- },
209
- 'solarized-dark': {
210
- name: 'Solarized Dark', type: 'dark',
211
- vars: {
212
- bg:'#002129',surface:'#002B36',surface2:'#073642',border:'#0A4050',border2:'#1A5060',
213
- text:'#93A1A1',text2:'#839496',text3:'#586E75',
214
- accent:'#268BD2','accent-dim':'rgba(38,139,210,.15)',
215
- success:'#859900','success-dim':'rgba(133,153,0,.15)',
216
- warning:'#B58900','warning-dim':'rgba(181,137,0,.15)',
217
- danger:'#DC322F','danger-dim':'rgba(220,50,47,.15)',
218
- purple:'#6C71C4','purple-dim':'rgba(108,113,196,.15)'
219
- }
220
- },
221
- 'solarized-light': {
222
- name: 'Solarized Light', type: 'light',
223
- vars: {
224
- bg:'#FDF6E3',surface:'#FFFFFF',surface2:'#EEE8D5',border:'#DDD6C1',border2:'#C9C2AD',
225
- text:'#586E75',text2:'#657B83',text3:'#93A1A1',
226
- accent:'#268BD2','accent-dim':'rgba(38,139,210,.1)',
227
- success:'#859900','success-dim':'rgba(133,153,0,.1)',
228
- warning:'#B58900','warning-dim':'rgba(181,137,0,.1)',
229
- danger:'#DC322F','danger-dim':'rgba(220,50,47,.1)',
230
- purple:'#6C71C4','purple-dim':'rgba(108,113,196,.1)'
231
- }
232
- },
233
- 'one-dark': {
234
- name: 'One Dark', type: 'dark',
235
- vars: {
236
- bg:'#1E2127',surface:'#282C34',surface2:'#2C313C',border:'#3A3F4B',border2:'#4B5263',
237
- text:'#ABB2BF',text2:'#7F848E',text3:'#5C6370',
238
- accent:'#61AFEF','accent-dim':'rgba(97,175,239,.15)',
239
- success:'#98C379','success-dim':'rgba(152,195,121,.15)',
240
- warning:'#E5C07B','warning-dim':'rgba(229,192,123,.15)',
241
- danger:'#E06C75','danger-dim':'rgba(224,108,117,.15)',
242
- purple:'#C678DD','purple-dim':'rgba(198,120,221,.15)'
243
- }
244
- },
245
- 'gruvbox-dark': {
246
- name: 'Gruvbox Dark', type: 'dark',
247
- vars: {
248
- bg:'#1D2021',surface:'#282828',surface2:'#32302F',border:'#3C3836',border2:'#504945',
249
- text:'#EBDBB2',text2:'#A89984',text3:'#7C6F64',
250
- accent:'#FE8019','accent-dim':'rgba(254,128,25,.15)',
251
- success:'#B8BB26','success-dim':'rgba(184,187,38,.15)',
252
- warning:'#FABD2F','warning-dim':'rgba(250,189,47,.15)',
253
- danger:'#FB4934','danger-dim':'rgba(251,73,52,.15)',
254
- purple:'#D3869B','purple-dim':'rgba(211,134,155,.15)'
255
- }
256
- }
257
- };
258
-
259
- var THEME_LIST = Object.keys(THEMES).map(function(id) {
260
- return { id: id, name: THEMES[id].name, type: THEMES[id].type };
261
- });
@@ -1,164 +0,0 @@
1
- /* ══════════════════════════════════════════════════════════════
2
- WORKSPACE — Source switching & sidebar
3
- ══════════════════════════════════════════════════════════════ */
4
- function renderSidebarLogo() {
5
- var p = D.project || {};
6
- var logoEl = document.getElementById('sidebar-logo');
7
- var iconEl = document.getElementById('sidebar-logo-icon');
8
- var textEl = document.getElementById('sidebar-logo-text');
9
-
10
- textEl.textContent = p.name || 'Project';
11
-
12
- if (D.config && D.config.logo) {
13
- var logoSrc = D.config.logo.startsWith('http') ? D.config.logo : '/logo';
14
- iconEl.innerHTML = '<img src="' + escHtml(logoSrc) + '" alt="">';
15
- } else {
16
- var initial = (p.name || 'P').charAt(0).toUpperCase();
17
- iconEl.textContent = initial;
18
- }
19
-
20
- logoEl.onclick = function() {
21
- if (hasWorkspace()) {
22
- switchSource('overview');
23
- }
24
- };
25
- }
26
-
27
- function buildSourceRail() {
28
- var rail = document.getElementById('source-rail');
29
- if (!rail) return;
30
- rail.innerHTML = '';
31
-
32
- if (!hasWorkspace()) return;
33
-
34
- // Home icon (overview)
35
- var home = document.createElement('div');
36
- home.className = 'rail-icon' + (D.activeSource === 'overview' ? ' active' : '');
37
- home.dataset.source = 'overview';
38
- home.setAttribute('data-tooltip', 'Overview');
39
- home.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>';
40
- home.onclick = function() { switchSource('overview'); };
41
- rail.appendChild(home);
42
-
43
- // Divider
44
- var divider = document.createElement('div');
45
- divider.className = 'rail-divider';
46
- rail.appendChild(divider);
47
-
48
- // Source icons
49
- var wsSources = D.config.workspace.sources;
50
- for (var i = 0; i < wsSources.length; i++) {
51
- var s = wsSources[i];
52
- if (s.name === 'overview') continue;
53
-
54
- var color = s.color || 'var(--accent)';
55
- var icon = document.createElement('div');
56
- icon.className = 'rail-icon' + (D.activeSource === s.name ? ' active' : '');
57
- icon.dataset.source = s.name;
58
- icon.setAttribute('data-tooltip', s.label || s.name);
59
- icon.style.background = color + '20';
60
- icon.style.color = color;
61
- icon.innerHTML = escHtml(s.icon || s.name.charAt(0).toUpperCase());
62
- icon.onclick = (function(name) {
63
- return function() { switchSource(name); };
64
- })(s.name);
65
- rail.appendChild(icon);
66
- }
67
-
68
- // Switch project icon (bottom of rail)
69
- var switchDivider = document.createElement('div');
70
- switchDivider.className = 'rail-divider';
71
- switchDivider.style.marginTop = 'auto';
72
- rail.appendChild(switchDivider);
73
-
74
- var switchIcon = document.createElement('div');
75
- switchIcon.className = 'rail-icon rail-switch';
76
- switchIcon.setAttribute('data-tooltip', 'Switch workspace');
77
- switchIcon.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 3h5v5"/><path d="M21 3l-7 7"/><path d="M8 21H3v-5"/><path d="M3 21l7-7"/></svg>';
78
- switchIcon.onclick = function() { openHistoryModal(); };
79
- rail.appendChild(switchIcon);
80
- }
81
-
82
- function switchSource(sourceName) {
83
- if (sourceName === D.activeSource) return;
84
-
85
- // Update active source marker
86
- D.activeSource = sourceName;
87
- D.loaded = false;
88
-
89
- // Persist selection
90
- try { localStorage.setItem('mdboard-source', sourceName); } catch(e) {}
91
-
92
- // Update source rail active state
93
- document.querySelectorAll('.rail-icon').forEach(function(el) {
94
- el.classList.toggle('active', el.dataset.source === sourceName);
95
- });
96
-
97
- // If switching to overview, show overview tabs; otherwise show normal tabs
98
- var isOverview = sourceName === 'overview';
99
- var viewTabs = document.querySelectorAll('#sidebar-nav a[data-view]');
100
- viewTabs.forEach(function(tab) {
101
- var view = tab.dataset.view;
102
- if (isOverview) {
103
- tab.style.display = (view === 'overview' || view === 'metrics') ? '' : 'none';
104
- } else {
105
- tab.style.display = (view === 'overview') ? 'none' : '';
106
- }
107
- });
108
-
109
- // Switch to appropriate view
110
- if (isOverview) {
111
- switchView('overview');
112
- } else {
113
- var currentView = document.querySelector('.view.active');
114
- if (currentView && currentView.id === 'view-overview') {
115
- switchView('board');
116
- }
117
- }
118
-
119
- // Reload data for this source
120
- loadAll().then(function() {
121
- initFromConfig();
122
- renderAll();
123
- buildSourceRail();
124
- });
125
- }
126
-
127
- /* ── SSE — Hot Reload ────────────────────────────────────── */
128
- function connectSSE() {
129
- try {
130
- var src = new EventSource('/api/events');
131
- src.onmessage = function(e) {
132
- var data;
133
- try { data = JSON.parse(e.data); } catch { data = {}; }
134
-
135
- if (data.type === 'project-changed') {
136
- // Full reload on project switch (from another tab or API call)
137
- D.activeSource = null;
138
- D.loaded = false;
139
- loadAll().then(function() {
140
- initFromConfig();
141
- if (hasWorkspace()) {
142
- buildSourceRail();
143
- D.activeSource = null;
144
- switchSource('overview');
145
- } else {
146
- // Hide source rail if no workspace
147
- var rail = document.getElementById('source-rail');
148
- if (rail) rail.innerHTML = '';
149
- renderAll();
150
- }
151
- renderSidebarLogo();
152
- });
153
- return;
154
- }
155
-
156
- if (data.cssReload) {
157
- var link = document.getElementById('custom-theme');
158
- if (link) link.href = '/mdboard.css?' + Date.now();
159
- }
160
- refreshData();
161
- };
162
- src.onerror = function() { setTimeout(connectSSE, 5000); src.close(); };
163
- } catch { /* no SSE support */ }
164
- }