@autocode-cli/autocode 0.1.32 → 0.1.34

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 (51) hide show
  1. package/README.md +3 -3
  2. package/dist/cli/commands/init.js +1 -1
  3. package/dist/server/api.js +2 -2
  4. package/dist/server/api.js.map +1 -1
  5. package/dist/server/dashboard/pages/changelog.js +2 -2
  6. package/dist/server/dashboard/pages/changelog.js.map +1 -1
  7. package/dist/server/dashboard/pages/index.d.ts +3 -0
  8. package/dist/server/dashboard/pages/index.d.ts.map +1 -1
  9. package/dist/server/dashboard/pages/index.js +3 -0
  10. package/dist/server/dashboard/pages/index.js.map +1 -1
  11. package/dist/server/dashboard/pages/issue-comments.d.ts +8 -0
  12. package/dist/server/dashboard/pages/issue-comments.d.ts.map +1 -0
  13. package/dist/server/dashboard/pages/issue-comments.js +283 -0
  14. package/dist/server/dashboard/pages/issue-comments.js.map +1 -0
  15. package/dist/server/dashboard/pages/issue-history.d.ts +8 -0
  16. package/dist/server/dashboard/pages/issue-history.d.ts.map +1 -0
  17. package/dist/server/dashboard/pages/issue-history.js +149 -0
  18. package/dist/server/dashboard/pages/issue-history.js.map +1 -0
  19. package/dist/server/dashboard/pages/issue-shared.d.ts +27 -0
  20. package/dist/server/dashboard/pages/issue-shared.d.ts.map +1 -0
  21. package/dist/server/dashboard/pages/issue-shared.js +365 -0
  22. package/dist/server/dashboard/pages/issue-shared.js.map +1 -0
  23. package/dist/server/dashboard/pages/issue-terminal.d.ts +8 -0
  24. package/dist/server/dashboard/pages/issue-terminal.d.ts.map +1 -0
  25. package/dist/server/dashboard/pages/issue-terminal.js +363 -0
  26. package/dist/server/dashboard/pages/issue-terminal.js.map +1 -0
  27. package/dist/server/dashboard/pages/issue-view.d.ts +2 -2
  28. package/dist/server/dashboard/pages/issue-view.d.ts.map +1 -1
  29. package/dist/server/dashboard/pages/issue-view.js +49 -1027
  30. package/dist/server/dashboard/pages/issue-view.js.map +1 -1
  31. package/dist/server/dashboard/pages/main-dashboard.js +1 -1
  32. package/dist/server/dashboard/pages/main-dashboard.js.map +1 -1
  33. package/dist/server/dashboard/pages/new-issue.d.ts.map +1 -1
  34. package/dist/server/dashboard/pages/new-issue.js +66 -2
  35. package/dist/server/dashboard/pages/new-issue.js.map +1 -1
  36. package/dist/server/dashboard/pages/new-issue.test.js +208 -3
  37. package/dist/server/dashboard/pages/new-issue.test.js.map +1 -1
  38. package/dist/server/dashboard.d.ts +1 -1
  39. package/dist/server/dashboard.d.ts.map +1 -1
  40. package/dist/server/dashboard.js +1 -1
  41. package/dist/server/dashboard.js.map +1 -1
  42. package/dist/server/index.d.ts.map +1 -1
  43. package/dist/server/index.js +35 -5
  44. package/dist/server/index.js.map +1 -1
  45. package/dist/server/watcher.d.ts +1 -1
  46. package/dist/server/watcher.js +1 -1
  47. package/dist/services/issue-io.d.ts +1 -1
  48. package/dist/services/issue-io.js +1 -1
  49. package/dist/utils/config.js +2 -2
  50. package/dist/utils/config.js.map +1 -1
  51. package/package.json +4 -1
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Issue history page generator
3
+ */
4
+ import { getConfig } from '../../../utils/config.js';
5
+ import { getIssue } from '../../../core/issue.js';
6
+ import { escapeHtml } from '../utils.js';
7
+ import { generate404Page } from './shared.js';
8
+ import { generateIssueBaseStyles, generateIssueHeader, generateTabsNav, generateIssueBaseScript, } from './issue-shared.js';
9
+ /**
10
+ * Generate the issue history page
11
+ */
12
+ export function generateIssueHistoryPage(issueKey, lang) {
13
+ const config = getConfig();
14
+ const issue = getIssue(config.root, issueKey);
15
+ if (!issue) {
16
+ return generate404Page(issueKey, lang);
17
+ }
18
+ const pageData = {
19
+ issueKey,
20
+ title: issue.title,
21
+ commentsCount: issue.comments?.length || 0,
22
+ historyCount: issue.history?.length || 0,
23
+ lang,
24
+ };
25
+ const historyHtml = issue.history && issue.history.length > 0
26
+ ? issue.history.map((h) => {
27
+ const date = new Date(h.at);
28
+ const dateStr = date.toLocaleDateString('en-US', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' });
29
+ const showPromptBtn = h.to && h.action !== 'created' ? `<a href="/issue/${issueKey}/${escapeHtml(h.to)}/prompt" class="btn-action" title="View prompt">View Prompt</a>` : '';
30
+ const showLogBtn = h.to && h.action !== 'created' ? `<a href="/issue/${issueKey}/${escapeHtml(h.to)}/terminal" class="btn-action" title="View terminal log">View Terminal</a>` : '';
31
+ return `<li class="history-item">
32
+ <div class="history-main">
33
+ <span class="history-action history-action-${h.action}">${h.action}</span>
34
+ ${h.from ? `<span class="history-from">${escapeHtml(h.from)}</span> <span class="history-arrow">→</span>` : ''}
35
+ <span class="history-to">${escapeHtml(h.to)}</span>
36
+ </div>
37
+ <div class="history-actions">
38
+ ${showPromptBtn}
39
+ ${showLogBtn}
40
+ </div>
41
+ <span class="history-date">${dateStr}</span>
42
+ </li>`;
43
+ }).join('')
44
+ : '<li class="no-history">No history yet</li>';
45
+ return `<!DOCTYPE html>
46
+ <html lang="${lang}">
47
+ <head>
48
+ <meta charset="UTF-8">
49
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
50
+ <title>History - ${escapeHtml(issue.title)} - ${issueKey} - AutoCode</title>
51
+ <style>
52
+ ${generateIssueBaseStyles()}
53
+
54
+ .history-list {
55
+ list-style: none;
56
+ }
57
+ .history-item {
58
+ padding: 16px;
59
+ background: var(--bg-tertiary);
60
+ border-radius: 8px;
61
+ margin-bottom: 12px;
62
+ display: flex;
63
+ align-items: center;
64
+ gap: 16px;
65
+ flex-wrap: wrap;
66
+ }
67
+ .history-main {
68
+ display: flex;
69
+ align-items: center;
70
+ gap: 8px;
71
+ flex: 1;
72
+ }
73
+ .history-action {
74
+ font-weight: 600;
75
+ text-transform: capitalize;
76
+ font-size: 13px;
77
+ padding: 4px 10px;
78
+ border-radius: 4px;
79
+ }
80
+ .history-action-created { background: rgba(74, 222, 128, 0.2); color: var(--green); }
81
+ .history-action-moved { background: rgba(77, 171, 247, 0.2); color: var(--blue); }
82
+ .history-action-started { background: rgba(250, 204, 21, 0.2); color: var(--yellow); }
83
+ .history-action-forced { background: rgba(251, 146, 60, 0.2); color: var(--orange); }
84
+ .history-from, .history-to {
85
+ padding: 4px 10px;
86
+ background: var(--bg-secondary);
87
+ border-radius: 4px;
88
+ font-size: 12px;
89
+ font-family: 'SF Mono', Monaco, monospace;
90
+ }
91
+ .history-arrow {
92
+ color: var(--muted);
93
+ }
94
+ .history-actions {
95
+ display: flex;
96
+ gap: 8px;
97
+ }
98
+ .btn-action {
99
+ font-size: 12px;
100
+ padding: 6px 12px;
101
+ background: var(--bg-secondary);
102
+ color: var(--accent);
103
+ border: 1px solid var(--border);
104
+ border-radius: 4px;
105
+ text-decoration: none;
106
+ transition: all 0.2s;
107
+ }
108
+ .btn-action:hover {
109
+ border-color: var(--accent);
110
+ background: rgba(99, 102, 241, 0.1);
111
+ }
112
+ .history-date {
113
+ color: var(--muted);
114
+ font-size: 12px;
115
+ white-space: nowrap;
116
+ }
117
+ .no-history {
118
+ text-align: center;
119
+ color: var(--muted);
120
+ padding: 40px;
121
+ font-size: 14px;
122
+ }
123
+ </style>
124
+ </head>
125
+ <body>
126
+ ${generateIssueHeader(issueKey, issue.title)}
127
+ ${generateTabsNav(issueKey, 'history', pageData)}
128
+
129
+ <main class="main-content">
130
+ <div class="section">
131
+ <div class="section-title">
132
+ <span data-i18n="issueView.history">History</span>
133
+ <span>(${issue.history?.length || 0})</span>
134
+ </div>
135
+ <ul class="history-list">
136
+ ${historyHtml}
137
+ </ul>
138
+ </div>
139
+ </main>
140
+
141
+ <div class="notification" id="notification"></div>
142
+
143
+ <script>
144
+ ${generateIssueBaseScript(issueKey)}
145
+ </script>
146
+ </body>
147
+ </html>`;
148
+ }
149
+ //# sourceMappingURL=issue-history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue-history.js","sourceRoot":"","sources":["../../../../src/server/dashboard/pages/issue-history.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Shared components for issue pages
3
+ */
4
+ export interface IssuePageData {
5
+ issueKey: string;
6
+ title: string;
7
+ commentsCount: number;
8
+ historyCount: number;
9
+ lang: string;
10
+ }
11
+ /**
12
+ * Generate the base CSS styles shared across all issue pages
13
+ */
14
+ export declare function generateIssueBaseStyles(): string;
15
+ /**
16
+ * Generate the tabs navigation HTML
17
+ */
18
+ export declare function generateTabsNav(issueKey: string, activeTab: 'details' | 'comments' | 'history' | 'terminal', data: IssuePageData): string;
19
+ /**
20
+ * Generate the header HTML
21
+ */
22
+ export declare function generateIssueHeader(issueKey: string, title: string): string;
23
+ /**
24
+ * Generate the shared JavaScript for i18n and notifications
25
+ */
26
+ export declare function generateIssueBaseScript(issueKey: string): string;
27
+ //# sourceMappingURL=issue-shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue-shared.d.ts","sourceRoot":"","sources":["../../../../src/server/dashboard/pages/issue-shared.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAiKhD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,EAAE,IAAI,EAAE,aAAa,GAAG,MAAM,CAiBzI;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAc3E;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAyJhE"}
@@ -0,0 +1,365 @@
1
+ /**
2
+ * Shared components for issue pages
3
+ */
4
+ import { escapeHtml } from '../utils.js';
5
+ /**
6
+ * Generate the base CSS styles shared across all issue pages
7
+ */
8
+ export function generateIssueBaseStyles() {
9
+ return `
10
+ :root {
11
+ --bg: #0a0a0f;
12
+ --bg-secondary: #12121a;
13
+ --bg-tertiary: #1a1a24;
14
+ --text: #f1f5f9;
15
+ --muted: #94a3b8;
16
+ --border: #2a2a3a;
17
+ --accent: #6366f1;
18
+ --blue: #4dabf7;
19
+ --green: #4ade80;
20
+ --yellow: #facc15;
21
+ --orange: #fb923c;
22
+ --red: #f87171;
23
+ --purple: #a78bfa;
24
+ }
25
+ * { margin: 0; padding: 0; box-sizing: border-box; }
26
+ body {
27
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
28
+ background: var(--bg);
29
+ color: var(--text);
30
+ min-height: 100vh;
31
+ }
32
+ .header {
33
+ display: flex;
34
+ align-items: center;
35
+ gap: 24px;
36
+ padding: 16px 24px;
37
+ background: var(--bg-secondary);
38
+ border-bottom: 1px solid var(--border);
39
+ position: sticky;
40
+ top: 0;
41
+ z-index: 100;
42
+ }
43
+ .back-btn {
44
+ color: var(--muted);
45
+ text-decoration: none;
46
+ font-size: 14px;
47
+ display: flex;
48
+ align-items: center;
49
+ gap: 8px;
50
+ }
51
+ .back-btn:hover { color: var(--text); }
52
+ .issue-header-info {
53
+ flex: 1;
54
+ display: flex;
55
+ align-items: center;
56
+ gap: 16px;
57
+ }
58
+ .issue-key {
59
+ font-family: 'SF Mono', Monaco, monospace;
60
+ font-size: 12px;
61
+ color: var(--accent);
62
+ background: rgba(99, 102, 241, 0.15);
63
+ padding: 4px 10px;
64
+ border-radius: 4px;
65
+ font-weight: 600;
66
+ }
67
+ .issue-title {
68
+ font-size: 18px;
69
+ font-weight: 600;
70
+ color: var(--text);
71
+ overflow: hidden;
72
+ text-overflow: ellipsis;
73
+ white-space: nowrap;
74
+ }
75
+ .lang-selector {
76
+ display: flex;
77
+ gap: 4px;
78
+ }
79
+ .lang-btn {
80
+ background: transparent;
81
+ border: 1px solid var(--border);
82
+ color: var(--muted);
83
+ padding: 6px 12px;
84
+ border-radius: 4px;
85
+ cursor: pointer;
86
+ font-size: 12px;
87
+ font-weight: 500;
88
+ }
89
+ .lang-btn:hover { border-color: var(--accent); color: var(--text); }
90
+ .lang-btn.active { background: var(--accent); border-color: var(--accent); color: white; }
91
+
92
+ /* Tabs navigation */
93
+ .tabs-nav {
94
+ display: flex;
95
+ gap: 0;
96
+ padding: 0 24px;
97
+ background: var(--bg-secondary);
98
+ border-bottom: 1px solid var(--border);
99
+ }
100
+ .tab-link {
101
+ padding: 12px 20px;
102
+ color: var(--muted);
103
+ text-decoration: none;
104
+ font-size: 14px;
105
+ font-weight: 500;
106
+ border-bottom: 2px solid transparent;
107
+ transition: all 0.2s;
108
+ display: flex;
109
+ align-items: center;
110
+ gap: 8px;
111
+ }
112
+ .tab-link:hover {
113
+ color: var(--text);
114
+ background: var(--bg-tertiary);
115
+ }
116
+ .tab-link.active {
117
+ color: var(--accent);
118
+ border-bottom-color: var(--accent);
119
+ }
120
+ .tab-badge {
121
+ font-size: 11px;
122
+ padding: 2px 8px;
123
+ border-radius: 10px;
124
+ background: var(--bg-tertiary);
125
+ color: var(--muted);
126
+ }
127
+ .tab-link.active .tab-badge {
128
+ background: rgba(99, 102, 241, 0.2);
129
+ color: var(--accent);
130
+ }
131
+
132
+ .main-content {
133
+ padding: 24px 48px;
134
+ }
135
+ .section {
136
+ background: var(--bg-secondary);
137
+ border: 1px solid var(--border);
138
+ border-radius: 12px;
139
+ padding: 20px;
140
+ }
141
+ .section-title {
142
+ font-size: 12px;
143
+ font-weight: 600;
144
+ text-transform: uppercase;
145
+ letter-spacing: 0.5px;
146
+ color: var(--muted);
147
+ margin-bottom: 16px;
148
+ display: flex;
149
+ align-items: center;
150
+ justify-content: space-between;
151
+ }
152
+ .notification {
153
+ position: fixed;
154
+ bottom: 24px;
155
+ right: 24px;
156
+ padding: 12px 20px;
157
+ background: var(--green);
158
+ color: #000;
159
+ border-radius: 8px;
160
+ font-weight: 500;
161
+ transform: translateY(100px);
162
+ opacity: 0;
163
+ transition: all 0.3s ease;
164
+ z-index: 1000;
165
+ }
166
+ .notification.show { transform: translateY(0); opacity: 1; }
167
+ .notification.error { background: var(--red); color: white; }
168
+ `;
169
+ }
170
+ /**
171
+ * Generate the tabs navigation HTML
172
+ */
173
+ export function generateTabsNav(issueKey, activeTab, data) {
174
+ const tabs = [
175
+ { id: 'details', path: `/issue/${issueKey}`, labelKey: 'tabs.details' },
176
+ { id: 'comments', path: `/issue/${issueKey}/comments`, labelKey: 'tabs.comments', badge: data.commentsCount },
177
+ { id: 'history', path: `/issue/${issueKey}/history`, labelKey: 'tabs.history', badge: data.historyCount },
178
+ { id: 'terminal', path: `/issue/${issueKey}/terminal`, labelKey: 'tabs.terminal' },
179
+ ];
180
+ return `
181
+ <nav class="tabs-nav">
182
+ ${tabs.map(tab => {
183
+ const isActive = tab.id === activeTab;
184
+ const badgeHtml = tab.badge !== undefined ? `<span class="tab-badge">${tab.badge}</span>` : '';
185
+ return `<a href="${tab.path}" class="tab-link${isActive ? ' active' : ''}" data-i18n="${tab.labelKey}">${badgeHtml}</a>`;
186
+ }).join('')}
187
+ </nav>
188
+ `;
189
+ }
190
+ /**
191
+ * Generate the header HTML
192
+ */
193
+ export function generateIssueHeader(issueKey, title) {
194
+ return `
195
+ <header class="header">
196
+ <a href="/" class="back-btn">← Dashboard</a>
197
+ <div class="issue-header-info">
198
+ <span class="issue-key">${escapeHtml(issueKey)}</span>
199
+ <span class="issue-title">${escapeHtml(title)}</span>
200
+ </div>
201
+ <div class="lang-selector" id="lang-selector">
202
+ <button class="lang-btn" data-lang="en">EN</button>
203
+ <button class="lang-btn" data-lang="fr">FR</button>
204
+ </div>
205
+ </header>
206
+ `;
207
+ }
208
+ /**
209
+ * Generate the shared JavaScript for i18n and notifications
210
+ */
211
+ export function generateIssueBaseScript(issueKey) {
212
+ return `
213
+ const ISSUE_KEY = '${issueKey}';
214
+ const STORAGE_KEY = 'autocode-lang';
215
+ let currentLang = localStorage.getItem(STORAGE_KEY) || 'fr';
216
+
217
+ const translations = {
218
+ en: {
219
+ 'tabs.details': 'Details',
220
+ 'tabs.comments': 'Comments',
221
+ 'tabs.history': 'History',
222
+ 'tabs.terminal': 'Terminal',
223
+ 'issueView.meta': 'Meta',
224
+ 'issueView.labels': 'Labels',
225
+ 'issueView.description': 'Description',
226
+ 'issueView.criteria': 'Acceptance Criteria',
227
+ 'issueView.history': 'History',
228
+ 'issueView.actions': 'Actions',
229
+ 'issueView.save': 'Save',
230
+ 'issueView.moveNext': 'Move to next column',
231
+ 'issueView.archive': 'Archive',
232
+ 'issueView.confirmMove': 'Move this issue to the next column?',
233
+ 'issueView.confirmArchive': 'Archive this issue?',
234
+ 'issueView.comments': 'Comments',
235
+ 'issueView.addComment': 'Add a comment...',
236
+ 'issueView.noComments': 'No comments yet',
237
+ 'issueView.claudeTerminal': 'Claude Terminal',
238
+ 'issueView.noDescription': 'No description',
239
+ 'issueView.noLog': 'No log yet. Waiting for Claude processing...',
240
+ 'issueView.loadingPrompt': 'Loading prompt...',
241
+ 'issueView.promptError': 'Error',
242
+ 'btn.add': 'Add',
243
+ 'btn.sending': 'Sending...',
244
+ 'btn.saving': 'Saving...',
245
+ 'status.waiting': 'Waiting',
246
+ 'status.processing': 'Processing...',
247
+ 'status.completed': 'Completed',
248
+ 'status.failed': 'Failed',
249
+ 'notify.commentAdded': 'Comment added',
250
+ 'notify.issueAdvanced': 'Issue advanced',
251
+ 'notify.issueArchived': 'Issue archived',
252
+ 'notify.issueSaved': 'Issue saved',
253
+ 'notify.error': 'Error'
254
+ },
255
+ fr: {
256
+ 'tabs.details': 'Détails',
257
+ 'tabs.comments': 'Commentaires',
258
+ 'tabs.history': 'Historique',
259
+ 'tabs.terminal': 'Terminal',
260
+ 'issueView.meta': 'Méta',
261
+ 'issueView.labels': 'Labels',
262
+ 'issueView.description': 'Description',
263
+ 'issueView.criteria': 'Critères d\\'acceptation',
264
+ 'issueView.history': 'Historique',
265
+ 'issueView.actions': 'Actions',
266
+ 'issueView.save': 'Sauvegarder',
267
+ 'issueView.moveNext': 'Déplacer vers la colonne suivante',
268
+ 'issueView.archive': 'Archiver',
269
+ 'issueView.confirmMove': 'Déplacer ce ticket vers la colonne suivante ?',
270
+ 'issueView.confirmArchive': 'Archiver ce ticket ?',
271
+ 'issueView.comments': 'Commentaires',
272
+ 'issueView.addComment': 'Ajouter un commentaire...',
273
+ 'issueView.noComments': 'Aucun commentaire',
274
+ 'issueView.claudeTerminal': 'Terminal Claude',
275
+ 'issueView.noDescription': 'Aucune description',
276
+ 'issueView.noLog': 'Aucun log. En attente du traitement Claude...',
277
+ 'issueView.loadingPrompt': 'Chargement du prompt...',
278
+ 'issueView.promptError': 'Erreur',
279
+ 'btn.add': 'Ajouter',
280
+ 'btn.sending': 'Envoi...',
281
+ 'btn.saving': 'Sauvegarde...',
282
+ 'status.waiting': 'En attente',
283
+ 'status.processing': 'En cours...',
284
+ 'status.completed': 'Terminé',
285
+ 'status.failed': 'Échec',
286
+ 'notify.commentAdded': 'Commentaire ajouté',
287
+ 'notify.issueAdvanced': 'Ticket avancé',
288
+ 'notify.issueArchived': 'Ticket archivé',
289
+ 'notify.issueSaved': 'Ticket sauvegardé',
290
+ 'notify.error': 'Erreur'
291
+ }
292
+ };
293
+
294
+ function t(key) {
295
+ return translations[currentLang]?.[key] || translations['en'][key] || key;
296
+ }
297
+
298
+ function escapeHtml(text) {
299
+ if (!text) return '';
300
+ const div = document.createElement('div');
301
+ div.textContent = text;
302
+ return div.innerHTML;
303
+ }
304
+
305
+ function renderMarkdown(text) {
306
+ if (!text) return '';
307
+ let html = escapeHtml(text);
308
+ html = html.replace(/^### (.+)$/gm, '<h4>$1</h4>');
309
+ html = html.replace(/^## (.+)$/gm, '<h3>$1</h3>');
310
+ html = html.replace(/^# (.+)$/gm, '<h2>$1</h2>');
311
+ html = html.replace(/\\*\\*(.+?)\\*\\*/g, '<strong>$1</strong>');
312
+ html = html.replace(/\\*(.+?)\\*/g, '<em>$1</em>');
313
+ html = html.replace(/\`([^\`]+)\`/g, '<code>$1</code>');
314
+ html = html.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '<a href="$2" target="_blank">$1</a>');
315
+ html = html.replace(/^- (.+)$/gm, '<li>$1</li>');
316
+ html = html.replace(/(<li>.*<\\/li>\\n?)+/g, '<ul>$&</ul>');
317
+ html = html.replace(/\\n/g, '<br>');
318
+ return html;
319
+ }
320
+
321
+ function updateLangUI() {
322
+ document.querySelectorAll('.lang-btn').forEach(btn => {
323
+ btn.classList.toggle('active', btn.dataset.lang === currentLang);
324
+ });
325
+ document.querySelectorAll('[data-i18n]').forEach(el => {
326
+ const key = el.dataset.i18n;
327
+ const translated = t(key);
328
+ // Keep badge if present
329
+ const badge = el.querySelector('.tab-badge');
330
+ if (badge) {
331
+ el.innerHTML = translated + ' ' + badge.outerHTML;
332
+ } else {
333
+ el.textContent = translated;
334
+ }
335
+ });
336
+ document.querySelectorAll('[data-i18n-placeholder]').forEach(el => {
337
+ el.placeholder = t(el.dataset.i18nPlaceholder);
338
+ });
339
+ }
340
+
341
+ function showNotification(msg, isError) {
342
+ const notification = document.getElementById('notification');
343
+ notification.textContent = msg;
344
+ notification.className = 'notification show' + (isError ? ' error' : '');
345
+ setTimeout(() => notification.className = 'notification', 3000);
346
+ }
347
+
348
+ // Language switcher
349
+ document.querySelectorAll('.lang-btn').forEach(btn => {
350
+ btn.addEventListener('click', () => {
351
+ const newLang = btn.dataset.lang;
352
+ if (newLang !== currentLang) {
353
+ currentLang = newLang;
354
+ localStorage.setItem(STORAGE_KEY, newLang);
355
+ updateLangUI();
356
+ if (typeof onLangChange === 'function') onLangChange();
357
+ }
358
+ });
359
+ });
360
+
361
+ // Init lang
362
+ updateLangUI();
363
+ `;
364
+ }
365
+ //# sourceMappingURL=issue-shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue-shared.js","sourceRoot":"","sources":["../../../../src/server/dashboard/pages/issue-shared.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAUzC;;GAEG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+JN,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB,EAAE,SAA0D,EAAE,IAAmB;IAC/H,MAAM,IAAI,GAAG;QACX,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,QAAQ,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE;QACvE,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,QAAQ,WAAW,EAAE,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE;QAC7G,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,QAAQ,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE;QACzG,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,QAAQ,WAAW,EAAE,QAAQ,EAAE,eAAe,EAAE;KACnF,CAAC;IAEF,OAAO;;QAED,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QACf,MAAM,QAAQ,GAAG,GAAG,CAAC,EAAE,KAAK,SAAS,CAAC;QACtC,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,2BAA2B,GAAG,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/F,OAAO,YAAY,GAAG,CAAC,IAAI,oBAAoB,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,gBAAgB,GAAG,CAAC,QAAQ,KAAK,SAAS,MAAM,CAAC;IAC3H,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;;GAEd,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAgB,EAAE,KAAa;IACjE,OAAO;;;;gCAIuB,UAAU,CAAC,QAAQ,CAAC;kCAClB,UAAU,CAAC,KAAK,CAAC;;;;;;;GAOhD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,QAAgB;IACtD,OAAO;yBACgB,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsJ9B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Issue terminal page generator
3
+ */
4
+ /**
5
+ * Generate the issue terminal page
6
+ */
7
+ export declare function generateIssueTerminalPage(issueKey: string, lang: string): string;
8
+ //# sourceMappingURL=issue-terminal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue-terminal.d.ts","sourceRoot":"","sources":["../../../../src/server/dashboard/pages/issue-terminal.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAiWhF"}