@autocode-cli/autocode 0.1.15 → 0.1.17

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 (211) hide show
  1. package/README.md +38 -38
  2. package/dist/cli/commands/comment.d.ts +1 -1
  3. package/dist/cli/commands/comment.js +11 -11
  4. package/dist/cli/commands/comment.js.map +1 -1
  5. package/dist/cli/commands/init.js +1 -1
  6. package/dist/cli/commands/init.js.map +1 -1
  7. package/dist/cli/commands/list.d.ts +1 -1
  8. package/dist/cli/commands/list.d.ts.map +1 -1
  9. package/dist/cli/commands/list.js +65 -22
  10. package/dist/cli/commands/list.js.map +1 -1
  11. package/dist/cli/commands/move.d.ts +1 -1
  12. package/dist/cli/commands/move.js +12 -12
  13. package/dist/cli/commands/move.js.map +1 -1
  14. package/dist/cli/commands/new.d.ts +1 -1
  15. package/dist/cli/commands/new.d.ts.map +1 -1
  16. package/dist/cli/commands/new.js +26 -13
  17. package/dist/cli/commands/new.js.map +1 -1
  18. package/dist/cli/commands/next.d.ts +1 -1
  19. package/dist/cli/commands/next.js +15 -15
  20. package/dist/cli/commands/next.js.map +1 -1
  21. package/dist/cli/commands/parent.d.ts +9 -0
  22. package/dist/cli/commands/parent.d.ts.map +1 -0
  23. package/dist/cli/commands/parent.js +94 -0
  24. package/dist/cli/commands/parent.js.map +1 -0
  25. package/dist/cli/commands/serve.js +8 -8
  26. package/dist/cli/commands/serve.js.map +1 -1
  27. package/dist/cli/commands/show.d.ts +1 -1
  28. package/dist/cli/commands/show.d.ts.map +1 -1
  29. package/dist/cli/commands/show.js +51 -31
  30. package/dist/cli/commands/show.js.map +1 -1
  31. package/dist/cli/commands/stats.js +2 -2
  32. package/dist/cli/commands/stats.js.map +1 -1
  33. package/dist/cli/commands/sync.js +3 -3
  34. package/dist/cli/commands/sync.js.map +1 -1
  35. package/dist/cli/parser.d.ts.map +1 -1
  36. package/dist/cli/parser.js +5 -3
  37. package/dist/cli/parser.js.map +1 -1
  38. package/dist/core/column.js +2 -2
  39. package/dist/core/column.js.map +1 -1
  40. package/dist/core/hierarchy.d.ts +97 -0
  41. package/dist/core/hierarchy.d.ts.map +1 -0
  42. package/dist/core/hierarchy.js +274 -0
  43. package/dist/core/hierarchy.js.map +1 -0
  44. package/dist/core/issue.d.ts +62 -0
  45. package/dist/core/issue.d.ts.map +1 -0
  46. package/dist/core/issue.js +247 -0
  47. package/dist/core/issue.js.map +1 -0
  48. package/dist/core/sync.d.ts +9 -9
  49. package/dist/core/sync.d.ts.map +1 -1
  50. package/dist/core/sync.js +61 -58
  51. package/dist/core/sync.js.map +1 -1
  52. package/dist/core/workflow.d.ts +22 -20
  53. package/dist/core/workflow.d.ts.map +1 -1
  54. package/dist/core/workflow.js +68 -51
  55. package/dist/core/workflow.js.map +1 -1
  56. package/dist/index.d.ts +1 -1
  57. package/dist/index.js +1 -1
  58. package/dist/server/api-autocomplete.test.d.ts +6 -0
  59. package/dist/server/api-autocomplete.test.d.ts.map +1 -0
  60. package/dist/server/api-autocomplete.test.js +249 -0
  61. package/dist/server/api-autocomplete.test.js.map +1 -0
  62. package/dist/server/api.d.ts.map +1 -1
  63. package/dist/server/api.js +216 -106
  64. package/dist/server/api.js.map +1 -1
  65. package/dist/server/dashboard/pages/column-prompt.d.ts +1 -1
  66. package/dist/server/dashboard/pages/column-prompt.d.ts.map +1 -1
  67. package/dist/server/dashboard/pages/column-prompt.js +11 -11
  68. package/dist/server/dashboard/pages/column-prompt.js.map +1 -1
  69. package/dist/server/dashboard/pages/column-terminal.d.ts +1 -1
  70. package/dist/server/dashboard/pages/column-terminal.d.ts.map +1 -1
  71. package/dist/server/dashboard/pages/column-terminal.js +14 -14
  72. package/dist/server/dashboard/pages/column-terminal.js.map +1 -1
  73. package/dist/server/dashboard/pages/index.d.ts +3 -1
  74. package/dist/server/dashboard/pages/index.d.ts.map +1 -1
  75. package/dist/server/dashboard/pages/index.js +3 -1
  76. package/dist/server/dashboard/pages/index.js.map +1 -1
  77. package/dist/server/dashboard/pages/issue-graph.d.ts +9 -0
  78. package/dist/server/dashboard/pages/issue-graph.d.ts.map +1 -0
  79. package/dist/server/dashboard/pages/issue-graph.js +581 -0
  80. package/dist/server/dashboard/pages/issue-graph.js.map +1 -0
  81. package/dist/server/dashboard/pages/issue-view.d.ts +8 -0
  82. package/dist/server/dashboard/pages/issue-view.d.ts.map +1 -0
  83. package/dist/server/dashboard/pages/{ticket-view.js → issue-view.js} +128 -128
  84. package/dist/server/dashboard/pages/issue-view.js.map +1 -0
  85. package/dist/server/dashboard/pages/main-dashboard.js +21 -21
  86. package/dist/server/dashboard/pages/main-dashboard.js.map +1 -1
  87. package/dist/server/dashboard/pages/new-issue.d.ts +8 -0
  88. package/dist/server/dashboard/pages/new-issue.d.ts.map +1 -0
  89. package/dist/server/dashboard/pages/new-issue.js +648 -0
  90. package/dist/server/dashboard/pages/new-issue.js.map +1 -0
  91. package/dist/server/dashboard/pages/new-issue.test.d.ts +6 -0
  92. package/dist/server/dashboard/pages/new-issue.test.d.ts.map +1 -0
  93. package/dist/server/dashboard/pages/new-issue.test.js +349 -0
  94. package/dist/server/dashboard/pages/new-issue.test.js.map +1 -0
  95. package/dist/server/dashboard/pages/pipeline-configurator.js +1 -1
  96. package/dist/server/dashboard/pages/shared.d.ts +2 -2
  97. package/dist/server/dashboard/pages/shared.d.ts.map +1 -1
  98. package/dist/server/dashboard/pages/shared.js +5 -5
  99. package/dist/server/dashboard/pages/shared.js.map +1 -1
  100. package/dist/server/dashboard/pages/stats-page.js +11 -11
  101. package/dist/server/dashboard/scripts/index.js +134 -134
  102. package/dist/server/dashboard/styles/board.d.ts +1 -1
  103. package/dist/server/dashboard/styles/board.js +10 -10
  104. package/dist/server/dashboard.d.ts +1 -1
  105. package/dist/server/dashboard.d.ts.map +1 -1
  106. package/dist/server/dashboard.js +1 -1
  107. package/dist/server/dashboard.js.map +1 -1
  108. package/dist/server/index.d.ts.map +1 -1
  109. package/dist/server/index.js +40 -24
  110. package/dist/server/index.js.map +1 -1
  111. package/dist/server/websocket.d.ts +6 -6
  112. package/dist/server/websocket.d.ts.map +1 -1
  113. package/dist/server/websocket.js +10 -10
  114. package/dist/server/websocket.js.map +1 -1
  115. package/dist/services/claude.d.ts +13 -13
  116. package/dist/services/claude.d.ts.map +1 -1
  117. package/dist/services/claude.js +98 -98
  118. package/dist/services/claude.js.map +1 -1
  119. package/dist/services/issue-io.d.ts +81 -0
  120. package/dist/services/issue-io.d.ts.map +1 -0
  121. package/dist/services/{ticket-io.js → issue-io.js} +54 -53
  122. package/dist/services/issue-io.js.map +1 -0
  123. package/dist/services/stats.d.ts +2 -0
  124. package/dist/services/stats.d.ts.map +1 -1
  125. package/dist/services/stats.js.map +1 -1
  126. package/dist/types/index.d.ts +6 -4
  127. package/dist/types/index.d.ts.map +1 -1
  128. package/dist/utils/fs.d.ts +2 -2
  129. package/dist/utils/fs.d.ts.map +1 -1
  130. package/dist/utils/fs.js +2 -2
  131. package/dist/utils/fs.js.map +1 -1
  132. package/package.json +3 -3
  133. package/templates/catalog.yaml +2 -2
  134. package/templates/prompts/api-endpoints-test.en.md +2 -2
  135. package/templates/prompts/api-endpoints-test.fr.md +2 -2
  136. package/templates/prompts/backlog.en.md +6 -6
  137. package/templates/prompts/backlog.fr.md +1 -1
  138. package/templates/prompts/changelog.en.md +6 -6
  139. package/templates/prompts/changelog.fr.md +3 -3
  140. package/templates/prompts/dashboard-responsive.en.md +1 -1
  141. package/templates/prompts/deploy-prod.en.md +3 -3
  142. package/templates/prompts/deploy-prod.fr.md +3 -3
  143. package/templates/prompts/deploy-staging.en.md +3 -3
  144. package/templates/prompts/deploy-staging.fr.md +3 -3
  145. package/templates/prompts/design.en.md +5 -5
  146. package/templates/prompts/design.fr.md +3 -3
  147. package/templates/prompts/dev.en.md +4 -4
  148. package/templates/prompts/dev.fr.md +3 -3
  149. package/templates/prompts/done.en.md +5 -5
  150. package/templates/prompts/done.fr.md +2 -2
  151. package/templates/prompts/error-handling-review.en.md +1 -1
  152. package/templates/prompts/error-handling-review.fr.md +1 -1
  153. package/templates/prompts/file-watcher-test.en.md +4 -4
  154. package/templates/prompts/file-watcher-test.fr.md +1 -1
  155. package/templates/prompts/git-commit.en.md +5 -5
  156. package/templates/prompts/git-commit.fr.md +3 -3
  157. package/templates/prompts/git-push.en.md +3 -3
  158. package/templates/prompts/git-push.fr.md +3 -3
  159. package/templates/prompts/git-tag.en.md +3 -3
  160. package/templates/prompts/git-tag.fr.md +3 -3
  161. package/templates/prompts/in-progress.en.md +6 -6
  162. package/templates/prompts/in-progress.fr.md +3 -3
  163. package/templates/prompts/qualification.en.md +8 -8
  164. package/templates/prompts/qualification.fr.md +3 -3
  165. package/templates/prompts/retest-cypress.en.md +3 -3
  166. package/templates/prompts/retest-cypress.fr.md +3 -3
  167. package/templates/prompts/retest-playwright.en.md +4 -4
  168. package/templates/prompts/retest-playwright.fr.md +3 -3
  169. package/templates/prompts/retest.en.md +4 -4
  170. package/templates/prompts/retest.fr.md +3 -3
  171. package/templates/prompts/review-best-practices.en.md +3 -3
  172. package/templates/prompts/review-best-practices.fr.md +3 -3
  173. package/templates/prompts/review-code.en.md +4 -4
  174. package/templates/prompts/review-code.fr.md +3 -3
  175. package/templates/prompts/review-consistency.en.md +3 -3
  176. package/templates/prompts/review-consistency.fr.md +3 -3
  177. package/templates/prompts/review-no-duplication.en.md +3 -3
  178. package/templates/prompts/review-no-duplication.fr.md +3 -3
  179. package/templates/prompts/review-security.en.md +4 -4
  180. package/templates/prompts/review-security.fr.md +3 -3
  181. package/templates/prompts/specification.en.md +5 -5
  182. package/templates/prompts/specification.fr.md +3 -3
  183. package/templates/prompts/splitter.en.md +13 -13
  184. package/templates/prompts/splitter.fr.md +3 -3
  185. package/templates/prompts/template-validation.en.md +1 -1
  186. package/templates/prompts/template-validation.fr.md +1 -1
  187. package/templates/prompts/testing-coverage.en.md +1 -1
  188. package/templates/prompts/testing-coverage.fr.md +1 -1
  189. package/templates/prompts/testing-cypress.en.md +4 -4
  190. package/templates/prompts/testing-cypress.fr.md +3 -3
  191. package/templates/prompts/testing-integration.en.md +4 -4
  192. package/templates/prompts/testing-integration.fr.md +3 -3
  193. package/templates/prompts/testing-playwright.en.md +4 -4
  194. package/templates/prompts/testing-playwright.fr.md +3 -3
  195. package/templates/prompts/testing-unit.en.md +4 -4
  196. package/templates/prompts/testing-unit.fr.md +3 -3
  197. package/templates/prompts/update-docs.en.md +3 -3
  198. package/templates/prompts/update-docs.fr.md +3 -3
  199. package/templates/prompts/validate-staging.en.md +3 -3
  200. package/templates/prompts/validate-staging.fr.md +3 -3
  201. package/templates/prompts/websocket-test.en.md +1 -1
  202. package/dist/core/ticket.d.ts +0 -50
  203. package/dist/core/ticket.d.ts.map +0 -1
  204. package/dist/core/ticket.js +0 -224
  205. package/dist/core/ticket.js.map +0 -1
  206. package/dist/server/dashboard/pages/ticket-view.d.ts +0 -8
  207. package/dist/server/dashboard/pages/ticket-view.d.ts.map +0 -1
  208. package/dist/server/dashboard/pages/ticket-view.js.map +0 -1
  209. package/dist/services/ticket-io.d.ts +0 -80
  210. package/dist/services/ticket-io.d.ts.map +0 -1
  211. package/dist/services/ticket-io.js.map +0 -1
@@ -0,0 +1,349 @@
1
+ /**
2
+ * Unit tests for new-issue.ts
3
+ * Tests for the /issue/new page generation
4
+ */
5
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
6
+ import { generateNewIssuePage } from './new-issue.js';
7
+ // Mock getColumns from column.js
8
+ vi.mock('../../../core/column.js', () => ({
9
+ getColumns: vi.fn(() => [
10
+ { slug: '00_backlog', name: 'Backlog', order: 0 },
11
+ { slug: '01_in_progress', name: 'In Progress', order: 1 },
12
+ { slug: '02_done', name: 'Done', order: 2 },
13
+ ]),
14
+ }));
15
+ describe('generateNewIssuePage', () => {
16
+ beforeEach(() => {
17
+ vi.clearAllMocks();
18
+ });
19
+ describe('Nominal cases', () => {
20
+ it('should generate valid HTML page for English language', () => {
21
+ const html = generateNewIssuePage('en');
22
+ // Should be valid HTML
23
+ expect(html).toContain('<!DOCTYPE html>');
24
+ expect(html).toContain('<html lang="en">');
25
+ expect(html).toContain('</html>');
26
+ });
27
+ it('should generate valid HTML page for French language', () => {
28
+ const html = generateNewIssuePage('fr');
29
+ expect(html).toContain('<!DOCTYPE html>');
30
+ expect(html).toContain('<html lang="fr">');
31
+ expect(html).toContain('</html>');
32
+ });
33
+ it('should include page title', () => {
34
+ const html = generateNewIssuePage('en');
35
+ expect(html).toContain('<title>New Issue - AutoCode</title>');
36
+ });
37
+ it('should include form elements', () => {
38
+ const html = generateNewIssuePage('en');
39
+ // Required form fields
40
+ expect(html).toContain('id="issue-title"');
41
+ expect(html).toContain('id="issue-description"');
42
+ expect(html).toContain('id="issue-priority"');
43
+ expect(html).toContain('id="issue-semver"');
44
+ expect(html).toContain('id="issue-column"');
45
+ expect(html).toContain('id="issue-labels"');
46
+ });
47
+ it('should include priority options', () => {
48
+ const html = generateNewIssuePage('en');
49
+ expect(html).toContain('value="P0"');
50
+ expect(html).toContain('value="P1"');
51
+ expect(html).toContain('value="P2"');
52
+ expect(html).toContain('value="P3"');
53
+ });
54
+ it('should include semver options', () => {
55
+ const html = generateNewIssuePage('en');
56
+ expect(html).toContain('value="patch"');
57
+ expect(html).toContain('value="minor"');
58
+ expect(html).toContain('value="major"');
59
+ expect(html).toContain('value="none"');
60
+ });
61
+ it('should include label options', () => {
62
+ const html = generateNewIssuePage('en');
63
+ expect(html).toContain('value="bug"');
64
+ expect(html).toContain('value="feature"');
65
+ expect(html).toContain('value="enhancement"');
66
+ expect(html).toContain('value="documentation"');
67
+ expect(html).toContain('value="urgent"');
68
+ expect(html).toContain('value="refactoring"');
69
+ expect(html).toContain('value="security"');
70
+ expect(html).toContain('value="performance"');
71
+ expect(html).toContain('value="ui"');
72
+ expect(html).toContain('value="api"');
73
+ });
74
+ it('should include column options from mocked getColumns', () => {
75
+ const html = generateNewIssuePage('en');
76
+ expect(html).toContain('value="00_backlog"');
77
+ expect(html).toContain('value="01_in_progress"');
78
+ expect(html).toContain('value="02_done"');
79
+ });
80
+ it('should select first column by default', () => {
81
+ const html = generateNewIssuePage('en');
82
+ // First column (00_backlog) should be selected
83
+ expect(html).toContain('value="00_backlog" selected');
84
+ });
85
+ it('should include language switcher buttons', () => {
86
+ const html = generateNewIssuePage('en');
87
+ expect(html).toContain('data-lang="en"');
88
+ expect(html).toContain('data-lang="fr"');
89
+ });
90
+ it('should include back link to dashboard', () => {
91
+ const html = generateNewIssuePage('en');
92
+ expect(html).toContain('href="/"');
93
+ expect(html).toContain('Dashboard');
94
+ });
95
+ it('should include create issue button', () => {
96
+ const html = generateNewIssuePage('en');
97
+ expect(html).toContain('id="btn-create"');
98
+ expect(html).toContain('onclick="createIssue()"');
99
+ });
100
+ it('should include cancel button', () => {
101
+ const html = generateNewIssuePage('en');
102
+ expect(html).toContain('btn-secondary');
103
+ expect(html).toContain('data-i18n="btn.cancel"');
104
+ });
105
+ it('should include acceptance criteria section', () => {
106
+ const html = generateNewIssuePage('en');
107
+ expect(html).toContain('id="criteria-list"');
108
+ expect(html).toContain('onclick="addCriteria()"');
109
+ });
110
+ it('should include notification element', () => {
111
+ const html = generateNewIssuePage('en');
112
+ expect(html).toContain('id="notification"');
113
+ expect(html).toContain('class="notification"');
114
+ });
115
+ });
116
+ describe('Internationalization (i18n)', () => {
117
+ it('should include English translations', () => {
118
+ const html = generateNewIssuePage('en');
119
+ expect(html).toContain("'newIssue.title': 'New Issue'");
120
+ expect(html).toContain("'btn.createIssue': 'Create issue'");
121
+ expect(html).toContain("'notify.titleRequired': 'Title is required'");
122
+ });
123
+ it('should include French translations', () => {
124
+ const html = generateNewIssuePage('fr');
125
+ expect(html).toContain("'newIssue.title': 'Nouveau ticket'");
126
+ expect(html).toContain("'btn.createIssue': 'Créer le ticket'");
127
+ expect(html).toContain("'notify.titleRequired': 'Le titre est requis'");
128
+ });
129
+ it('should include i18n data attributes for dynamic translation', () => {
130
+ const html = generateNewIssuePage('en');
131
+ expect(html).toContain('data-i18n="newIssue.title"');
132
+ expect(html).toContain('data-i18n="newIssue.titleLabel"');
133
+ expect(html).toContain('data-i18n="newIssue.description"');
134
+ expect(html).toContain('data-i18n="btn.createIssue"');
135
+ });
136
+ it('should include i18n placeholder attributes', () => {
137
+ const html = generateNewIssuePage('en');
138
+ expect(html).toContain('data-i18n-placeholder="newIssue.titlePlaceholder"');
139
+ expect(html).toContain('data-i18n-placeholder="newIssue.descriptionPlaceholder"');
140
+ });
141
+ });
142
+ describe('JavaScript functionality', () => {
143
+ it('should include createIssue function', () => {
144
+ const html = generateNewIssuePage('en');
145
+ expect(html).toContain('async function createIssue()');
146
+ });
147
+ it('should include label management functions', () => {
148
+ const html = generateNewIssuePage('en');
149
+ expect(html).toContain('function addLabel(');
150
+ expect(html).toContain('function removeLabel(');
151
+ expect(html).toContain('function renderLabels()');
152
+ });
153
+ it('should include criteria management functions', () => {
154
+ const html = generateNewIssuePage('en');
155
+ expect(html).toContain('function addCriteria()');
156
+ expect(html).toContain('function getCriteria()');
157
+ });
158
+ it('should include translation function', () => {
159
+ const html = generateNewIssuePage('en');
160
+ expect(html).toContain('function t(key)');
161
+ expect(html).toContain('function updateLangUI()');
162
+ });
163
+ it('should include notification function', () => {
164
+ const html = generateNewIssuePage('en');
165
+ expect(html).toContain('function showNotification(');
166
+ });
167
+ it('should include escapeHtml function for XSS protection', () => {
168
+ const html = generateNewIssuePage('en');
169
+ expect(html).toContain('function escapeHtml(');
170
+ expect(html).toContain("replace(/&/g, '&amp;')");
171
+ expect(html).toContain("replace(/</g, '&lt;')");
172
+ expect(html).toContain("replace(/>/g, '&gt;')");
173
+ });
174
+ it('should use fetch to POST to /api/issues', () => {
175
+ const html = generateNewIssuePage('en');
176
+ expect(html).toContain("fetch('/api/issues'");
177
+ expect(html).toContain("method: 'POST'");
178
+ expect(html).toContain("'Content-Type': 'application/json'");
179
+ });
180
+ it('should redirect after successful creation', () => {
181
+ const html = generateNewIssuePage('en');
182
+ expect(html).toContain("window.location.href = '/issue/' + result.data.key");
183
+ });
184
+ });
185
+ describe('CSS styling', () => {
186
+ it('should include CSS variables', () => {
187
+ const html = generateNewIssuePage('en');
188
+ expect(html).toContain(':root');
189
+ expect(html).toContain('--bg:');
190
+ expect(html).toContain('--accent:');
191
+ expect(html).toContain('--border:');
192
+ });
193
+ it('should include form styling', () => {
194
+ const html = generateNewIssuePage('en');
195
+ expect(html).toContain('.form-card');
196
+ expect(html).toContain('.form-group');
197
+ expect(html).toContain('.form-row');
198
+ });
199
+ it('should include button styling', () => {
200
+ const html = generateNewIssuePage('en');
201
+ expect(html).toContain('.btn');
202
+ expect(html).toContain('.btn-primary');
203
+ expect(html).toContain('.btn-secondary');
204
+ });
205
+ it('should include notification styling', () => {
206
+ const html = generateNewIssuePage('en');
207
+ expect(html).toContain('.notification');
208
+ expect(html).toContain('.notification.show');
209
+ expect(html).toContain('.notification.error');
210
+ });
211
+ });
212
+ });
213
+ describe('AutoComplete functionality', () => {
214
+ describe('UI elements', () => {
215
+ it('should include AutoComplete button', () => {
216
+ const html = generateNewIssuePage('en');
217
+ expect(html).toContain('id="btn-autocomplete"');
218
+ expect(html).toContain('class="btn-autocomplete"');
219
+ expect(html).toContain('onclick="autocomplete()"');
220
+ });
221
+ it('should include AutoComplete icon', () => {
222
+ const html = generateNewIssuePage('en');
223
+ expect(html).toContain('id="autocomplete-icon"');
224
+ expect(html).toContain('&#10024;'); // Sparkle emoji
225
+ });
226
+ it('should include AutoComplete button styling', () => {
227
+ const html = generateNewIssuePage('en');
228
+ expect(html).toContain('.btn-autocomplete');
229
+ expect(html).toContain('.btn-autocomplete:hover');
230
+ expect(html).toContain('.btn-autocomplete:disabled');
231
+ expect(html).toContain('.btn-autocomplete .spinner');
232
+ });
233
+ it('should include spinner animation', () => {
234
+ const html = generateNewIssuePage('en');
235
+ expect(html).toContain('@keyframes spin');
236
+ });
237
+ it('should place AutoComplete button next to title field', () => {
238
+ const html = generateNewIssuePage('en');
239
+ expect(html).toContain('class="title-row"');
240
+ // Title and button should be in same container
241
+ expect(html).toMatch(/title-row[\s\S]*?issue-title[\s\S]*?btn-autocomplete/);
242
+ });
243
+ });
244
+ describe('JavaScript functionality', () => {
245
+ it('should include autocomplete function', () => {
246
+ const html = generateNewIssuePage('en');
247
+ expect(html).toContain('async function autocomplete()');
248
+ });
249
+ it('should fetch /api/issues/autocomplete endpoint', () => {
250
+ const html = generateNewIssuePage('en');
251
+ expect(html).toContain("fetch('/api/issues/autocomplete'");
252
+ expect(html).toContain("method: 'POST'");
253
+ });
254
+ it('should send title and lang in request body', () => {
255
+ const html = generateNewIssuePage('en');
256
+ expect(html).toContain('JSON.stringify({ title, lang: currentLang })');
257
+ });
258
+ it('should validate title before calling autocomplete', () => {
259
+ const html = generateNewIssuePage('en');
260
+ expect(html).toContain("const title = document.getElementById('issue-title').value.trim()");
261
+ expect(html).toContain('if (!title)');
262
+ expect(html).toContain("t('notify.autocompleteTitleRequired')");
263
+ });
264
+ it('should disable button during autocomplete', () => {
265
+ const html = generateNewIssuePage('en');
266
+ expect(html).toContain('btn.disabled = true');
267
+ expect(html).toContain('btn.disabled = false');
268
+ });
269
+ it('should show spinner during autocomplete', () => {
270
+ const html = generateNewIssuePage('en');
271
+ expect(html).toContain("icon.innerHTML = '<div class=\"spinner\"></div>'");
272
+ });
273
+ it('should fill description field on success', () => {
274
+ const html = generateNewIssuePage('en');
275
+ expect(html).toContain("document.getElementById('issue-description').value = data.description");
276
+ });
277
+ it('should fill priority field on success', () => {
278
+ const html = generateNewIssuePage('en');
279
+ expect(html).toContain("document.getElementById('issue-priority').value = data.priority");
280
+ });
281
+ it('should fill semver field on success', () => {
282
+ const html = generateNewIssuePage('en');
283
+ expect(html).toContain("document.getElementById('issue-semver').value = data.semver");
284
+ });
285
+ it('should fill labels on success', () => {
286
+ const html = generateNewIssuePage('en');
287
+ expect(html).toContain('if (data.labels && Array.isArray(data.labels))');
288
+ expect(html).toContain('selectedLabels = data.labels');
289
+ });
290
+ it('should fill acceptance criteria on success', () => {
291
+ const html = generateNewIssuePage('en');
292
+ expect(html).toContain('if (data.acceptance_criteria && Array.isArray(data.acceptance_criteria))');
293
+ });
294
+ it('should show success notification on complete', () => {
295
+ const html = generateNewIssuePage('en');
296
+ expect(html).toContain("t('notify.autocompleteSuccess')");
297
+ });
298
+ it('should handle errors gracefully', () => {
299
+ const html = generateNewIssuePage('en');
300
+ expect(html).toContain('} catch (e) {');
301
+ expect(html).toContain("t('notify.error') + ': ' + e.message");
302
+ });
303
+ it('should restore button state in finally block', () => {
304
+ const html = generateNewIssuePage('en');
305
+ expect(html).toContain('} finally {');
306
+ expect(html).toContain("icon.innerHTML = '&#10024;'");
307
+ });
308
+ });
309
+ describe('i18n translations for AutoComplete', () => {
310
+ it('should include English AutoComplete translations', () => {
311
+ const html = generateNewIssuePage('en');
312
+ expect(html).toContain("'btn.autocomplete': 'AutoComplete'");
313
+ expect(html).toContain("'btn.autocompleting': 'Generating...'");
314
+ expect(html).toContain("'notify.autocompleteSuccess': 'Fields auto-filled!'");
315
+ expect(html).toContain("'notify.autocompleteTitleRequired': 'Enter a title first'");
316
+ });
317
+ it('should include French AutoComplete translations', () => {
318
+ const html = generateNewIssuePage('fr');
319
+ expect(html).toContain("'btn.autocomplete': 'AutoComplete'");
320
+ expect(html).toContain("'btn.autocompleting': 'Génération...'");
321
+ expect(html).toContain("'notify.autocompleteSuccess': 'Champs remplis automatiquement !'");
322
+ expect(html).toContain("'notify.autocompleteTitleRequired': 'Entrez un titre d\\'abord'");
323
+ });
324
+ it('should include i18n attribute for AutoComplete button', () => {
325
+ const html = generateNewIssuePage('en');
326
+ expect(html).toContain('data-i18n="btn.autocomplete"');
327
+ });
328
+ });
329
+ });
330
+ describe('Edge cases', () => {
331
+ it('should handle empty columns array', async () => {
332
+ // Re-mock with empty columns
333
+ const { getColumns } = await import('../../../core/column.js');
334
+ vi.mocked(getColumns).mockReturnValueOnce([]);
335
+ const html = generateNewIssuePage('en');
336
+ // Should still generate valid HTML
337
+ expect(html).toContain('<!DOCTYPE html>');
338
+ // The select element should still be rendered (even if empty)
339
+ expect(html).toContain('id="issue-column"');
340
+ });
341
+ it('should handle unknown language gracefully', () => {
342
+ // Should not throw an error
343
+ const html = generateNewIssuePage('de');
344
+ // Should still generate valid HTML
345
+ expect(html).toContain('<!DOCTYPE html>');
346
+ expect(html).toContain('<html lang="de">');
347
+ });
348
+ });
349
+ //# sourceMappingURL=new-issue.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new-issue.test.js","sourceRoot":"","sources":["../../../../src/server/dashboard/pages/new-issue.test.ts"],"names":[],"mappings":"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"}
@@ -1470,7 +1470,7 @@ export function generatePipelineConfiguratorPage(lang) {
1470
1470
  result.removed.map(s => '<li>- ' + escapeHtml(s) + '</li>').join('') + '</ul></div>';
1471
1471
  }
1472
1472
  if (result.transitioned.length) {
1473
- changes.innerHTML += '<div class="sync-group renamed"><h4>Tickets in Transition</h4><ul>' +
1473
+ changes.innerHTML += '<div class="sync-group renamed"><h4>Issues in Transition</h4><ul>' +
1474
1474
  result.transitioned.map(s => '<li>' + escapeHtml(s) + '</li>').join('') + '</ul></div>';
1475
1475
  }
1476
1476
 
@@ -2,7 +2,7 @@
2
2
  * Shared page components
3
3
  */
4
4
  /**
5
- * Generate a 404 page for ticket not found
5
+ * Generate a 404 page for issue not found
6
6
  */
7
- export declare function generate404Page(ticketKey: string, lang: string): string;
7
+ export declare function generate404Page(issueKey: string, lang: string): string;
8
8
  //# sourceMappingURL=shared.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../../src/server/dashboard/pages/shared.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAiDvE"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../../src/server/dashboard/pages/shared.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAiDtE"}
@@ -3,15 +3,15 @@
3
3
  */
4
4
  import { escapeHtml } from '../utils.js';
5
5
  /**
6
- * Generate a 404 page for ticket not found
6
+ * Generate a 404 page for issue not found
7
7
  */
8
- export function generate404Page(ticketKey, lang) {
8
+ export function generate404Page(issueKey, lang) {
9
9
  return `<!DOCTYPE html>
10
10
  <html lang="${lang}">
11
11
  <head>
12
12
  <meta charset="UTF-8">
13
13
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
14
- <title>Ticket Not Found - AutoCode</title>
14
+ <title>Issue Not Found - AutoCode</title>
15
15
  <style>
16
16
  :root {
17
17
  --bg: #0a0a0f;
@@ -48,8 +48,8 @@ export function generate404Page(ticketKey, lang) {
48
48
  </head>
49
49
  <body>
50
50
  <div class="not-found">
51
- <h1>Ticket Not Found</h1>
52
- <p>Ticket ${escapeHtml(ticketKey)} does not exist or has been archived.</p>
51
+ <h1>Issue Not Found</h1>
52
+ <p>Issue ${escapeHtml(issueKey)} does not exist or has been archived.</p>
53
53
  <a href="/">← Back to Dashboard</a>
54
54
  </div>
55
55
  </body>
@@ -1 +1 @@
1
- {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../../src/server/dashboard/pages/shared.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,SAAiB,EAAE,IAAY;IAC7D,OAAO;cACK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA0CF,UAAU,CAAC,SAAS,CAAC;;;;QAI7B,CAAC;AACT,CAAC"}
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../../src/server/dashboard/pages/shared.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB,EAAE,IAAY;IAC5D,OAAO;cACK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eA0CH,UAAU,CAAC,QAAQ,CAAC;;;;QAI3B,CAAC;AACT,CAAC"}
@@ -192,12 +192,12 @@ export function generateStatsPage() {
192
192
  background: #252525;
193
193
  }
194
194
 
195
- .history-table .ticket-link {
195
+ .history-table .issue-link {
196
196
  color: #a855f7;
197
197
  text-decoration: none;
198
198
  }
199
199
 
200
- .history-table .ticket-link:hover {
200
+ .history-table .issue-link:hover {
201
201
  text-decoration: underline;
202
202
  }
203
203
 
@@ -364,7 +364,7 @@ export function generateStatsPage() {
364
364
 
365
365
  <div class="stats-card" id="processing-card" style="display: none;">
366
366
  <h3 data-i18n="processing"></h3>
367
- <div id="processing-tickets"></div>
367
+ <div id="processing-issues"></div>
368
368
  </div>
369
369
  </div>
370
370
 
@@ -400,7 +400,7 @@ export function generateStatsPage() {
400
400
  noHistory: 'Aucun appel enregistré',
401
401
  back: 'Retour au dashboard',
402
402
  startedAt: 'Démarré le',
403
- ticket: 'Ticket',
403
+ issue: 'Ticket',
404
404
  column: 'Colonne',
405
405
  duration: 'Durée',
406
406
  date: 'Date',
@@ -423,7 +423,7 @@ export function generateStatsPage() {
423
423
  noHistory: 'No calls recorded',
424
424
  back: 'Back to dashboard',
425
425
  startedAt: 'Started at',
426
- ticket: 'Ticket',
426
+ issue: 'Issue',
427
427
  column: 'Column',
428
428
  duration: 'Duration',
429
429
  date: 'Date',
@@ -514,7 +514,7 @@ export function generateStatsPage() {
514
514
  </colgroup>
515
515
  <thead>
516
516
  <tr>
517
- <th>\${t('ticket')}</th>
517
+ <th>\${t('issue')}</th>
518
518
  <th>\${t('column')}</th>
519
519
  <th>\${t('tokensInput')}</th>
520
520
  <th>\${t('tokensOutput')}</th>
@@ -526,7 +526,7 @@ export function generateStatsPage() {
526
526
  <tbody>
527
527
  \${data.history.map(h => \`
528
528
  <tr>
529
- <td>\${h.ticket ? '<a href="/ticket/' + h.ticket + '" class="ticket-link">' + h.ticket + '</a>' : '-'}</td>
529
+ <td>\${h.issue ? '<a href="/issue/' + h.issue + '" class="issue-link">' + h.issue + '</a>' : '-'}</td>
530
530
  <td>\${h.column || '-'}</td>
531
531
  <td>\${formatNumber(h.tokensInput || 0)}</td>
532
532
  <td>\${formatNumber(h.tokensOutput || 0)}</td>
@@ -575,11 +575,11 @@ export function generateStatsPage() {
575
575
  document.getElementById('total-calls').textContent = statsData.totals.callCount || 0;
576
576
  document.getElementById('total-cost').textContent = '$' + (statsData.totals.costUsd || 0).toFixed(2);
577
577
 
578
- // Processing tickets
579
- if (statsData.processingTickets && statsData.processingTickets.length > 0) {
578
+ // Processing issues
579
+ if (statsData.processingIssues && statsData.processingIssues.length > 0) {
580
580
  document.getElementById('processing-card').style.display = 'block';
581
- document.getElementById('processing-tickets').innerHTML = statsData.processingTickets
582
- .map(ticket => '<div class="processing-indicator">' + ticket + '</div>')
581
+ document.getElementById('processing-issues').innerHTML = statsData.processingIssues
582
+ .map(issue => '<div class="processing-indicator">' + issue + '</div>')
583
583
  .join('');
584
584
  } else {
585
585
  document.getElementById('processing-card').style.display = 'none';