@autocode-cli/autocode 0.1.15 → 0.1.18
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.
- package/README.md +38 -38
- package/dist/cli/commands/comment.d.ts +1 -1
- package/dist/cli/commands/comment.js +11 -11
- package/dist/cli/commands/comment.js.map +1 -1
- package/dist/cli/commands/init.js +1 -1
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/list.d.ts +1 -1
- package/dist/cli/commands/list.d.ts.map +1 -1
- package/dist/cli/commands/list.js +65 -22
- package/dist/cli/commands/list.js.map +1 -1
- package/dist/cli/commands/move.d.ts +1 -1
- package/dist/cli/commands/move.js +12 -12
- package/dist/cli/commands/move.js.map +1 -1
- package/dist/cli/commands/new.d.ts +1 -1
- package/dist/cli/commands/new.d.ts.map +1 -1
- package/dist/cli/commands/new.js +26 -13
- package/dist/cli/commands/new.js.map +1 -1
- package/dist/cli/commands/next.d.ts +1 -1
- package/dist/cli/commands/next.js +15 -15
- package/dist/cli/commands/next.js.map +1 -1
- package/dist/cli/commands/parent.d.ts +9 -0
- package/dist/cli/commands/parent.d.ts.map +1 -0
- package/dist/cli/commands/parent.js +94 -0
- package/dist/cli/commands/parent.js.map +1 -0
- package/dist/cli/commands/serve.js +8 -8
- package/dist/cli/commands/serve.js.map +1 -1
- package/dist/cli/commands/show.d.ts +1 -1
- package/dist/cli/commands/show.d.ts.map +1 -1
- package/dist/cli/commands/show.js +51 -31
- package/dist/cli/commands/show.js.map +1 -1
- package/dist/cli/commands/stats.js +2 -2
- package/dist/cli/commands/stats.js.map +1 -1
- package/dist/cli/commands/sync.js +3 -3
- package/dist/cli/commands/sync.js.map +1 -1
- package/dist/cli/parser.d.ts.map +1 -1
- package/dist/cli/parser.js +5 -3
- package/dist/cli/parser.js.map +1 -1
- package/dist/core/column.js +2 -2
- package/dist/core/column.js.map +1 -1
- package/dist/core/hierarchy.d.ts +97 -0
- package/dist/core/hierarchy.d.ts.map +1 -0
- package/dist/core/hierarchy.js +274 -0
- package/dist/core/hierarchy.js.map +1 -0
- package/dist/core/issue.d.ts +62 -0
- package/dist/core/issue.d.ts.map +1 -0
- package/dist/core/issue.js +247 -0
- package/dist/core/issue.js.map +1 -0
- package/dist/core/sync.d.ts +9 -9
- package/dist/core/sync.d.ts.map +1 -1
- package/dist/core/sync.js +61 -58
- package/dist/core/sync.js.map +1 -1
- package/dist/core/workflow.d.ts +22 -20
- package/dist/core/workflow.d.ts.map +1 -1
- package/dist/core/workflow.js +68 -51
- package/dist/core/workflow.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/server/api-autocomplete.test.d.ts +6 -0
- package/dist/server/api-autocomplete.test.d.ts.map +1 -0
- package/dist/server/api-autocomplete.test.js +249 -0
- package/dist/server/api-autocomplete.test.js.map +1 -0
- package/dist/server/api.d.ts.map +1 -1
- package/dist/server/api.js +216 -106
- package/dist/server/api.js.map +1 -1
- package/dist/server/dashboard/pages/column-prompt.d.ts +1 -1
- package/dist/server/dashboard/pages/column-prompt.d.ts.map +1 -1
- package/dist/server/dashboard/pages/column-prompt.js +11 -11
- package/dist/server/dashboard/pages/column-prompt.js.map +1 -1
- package/dist/server/dashboard/pages/column-terminal.d.ts +1 -1
- package/dist/server/dashboard/pages/column-terminal.d.ts.map +1 -1
- package/dist/server/dashboard/pages/column-terminal.js +14 -14
- package/dist/server/dashboard/pages/column-terminal.js.map +1 -1
- package/dist/server/dashboard/pages/index.d.ts +3 -1
- package/dist/server/dashboard/pages/index.d.ts.map +1 -1
- package/dist/server/dashboard/pages/index.js +3 -1
- package/dist/server/dashboard/pages/index.js.map +1 -1
- package/dist/server/dashboard/pages/issue-graph.d.ts +9 -0
- package/dist/server/dashboard/pages/issue-graph.d.ts.map +1 -0
- package/dist/server/dashboard/pages/issue-graph.js +581 -0
- package/dist/server/dashboard/pages/issue-graph.js.map +1 -0
- package/dist/server/dashboard/pages/issue-view.d.ts +8 -0
- package/dist/server/dashboard/pages/issue-view.d.ts.map +1 -0
- package/dist/server/dashboard/pages/{ticket-view.js → issue-view.js} +128 -128
- package/dist/server/dashboard/pages/issue-view.js.map +1 -0
- package/dist/server/dashboard/pages/main-dashboard.d.ts.map +1 -1
- package/dist/server/dashboard/pages/main-dashboard.js +23 -22
- package/dist/server/dashboard/pages/main-dashboard.js.map +1 -1
- package/dist/server/dashboard/pages/new-issue.d.ts +8 -0
- package/dist/server/dashboard/pages/new-issue.d.ts.map +1 -0
- package/dist/server/dashboard/pages/new-issue.js +648 -0
- package/dist/server/dashboard/pages/new-issue.js.map +1 -0
- package/dist/server/dashboard/pages/new-issue.test.d.ts +6 -0
- package/dist/server/dashboard/pages/new-issue.test.d.ts.map +1 -0
- package/dist/server/dashboard/pages/new-issue.test.js +349 -0
- package/dist/server/dashboard/pages/new-issue.test.js.map +1 -0
- package/dist/server/dashboard/pages/pipeline-configurator.js +1 -1
- package/dist/server/dashboard/pages/shared.d.ts +2 -2
- package/dist/server/dashboard/pages/shared.d.ts.map +1 -1
- package/dist/server/dashboard/pages/shared.js +5 -5
- package/dist/server/dashboard/pages/shared.js.map +1 -1
- package/dist/server/dashboard/pages/stats-page.js +11 -11
- package/dist/server/dashboard/scripts/index.js +134 -134
- package/dist/server/dashboard/styles/base.js +2 -2
- package/dist/server/dashboard/styles/board.d.ts +1 -1
- package/dist/server/dashboard/styles/board.js +10 -10
- package/dist/server/dashboard.d.ts +1 -1
- package/dist/server/dashboard.d.ts.map +1 -1
- package/dist/server/dashboard.js +1 -1
- package/dist/server/dashboard.js.map +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +40 -24
- package/dist/server/index.js.map +1 -1
- package/dist/server/websocket.d.ts +6 -6
- package/dist/server/websocket.d.ts.map +1 -1
- package/dist/server/websocket.js +10 -10
- package/dist/server/websocket.js.map +1 -1
- package/dist/services/claude.d.ts +13 -13
- package/dist/services/claude.d.ts.map +1 -1
- package/dist/services/claude.js +98 -98
- package/dist/services/claude.js.map +1 -1
- package/dist/services/issue-io.d.ts +81 -0
- package/dist/services/issue-io.d.ts.map +1 -0
- package/dist/services/{ticket-io.js → issue-io.js} +54 -53
- package/dist/services/issue-io.js.map +1 -0
- package/dist/services/stats.d.ts +1 -1
- package/dist/services/stats.d.ts.map +1 -1
- package/dist/types/index.d.ts +6 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/fs.d.ts +2 -2
- package/dist/utils/fs.d.ts.map +1 -1
- package/dist/utils/fs.js +2 -2
- package/dist/utils/fs.js.map +1 -1
- package/package.json +3 -3
- package/templates/catalog.yaml +2 -2
- package/templates/prompts/api-endpoints-test.en.md +2 -2
- package/templates/prompts/api-endpoints-test.fr.md +2 -2
- package/templates/prompts/backlog.en.md +6 -6
- package/templates/prompts/backlog.fr.md +1 -1
- package/templates/prompts/changelog.en.md +6 -6
- package/templates/prompts/changelog.fr.md +3 -3
- package/templates/prompts/dashboard-responsive.en.md +1 -1
- package/templates/prompts/deploy-prod.en.md +3 -3
- package/templates/prompts/deploy-prod.fr.md +3 -3
- package/templates/prompts/deploy-staging.en.md +3 -3
- package/templates/prompts/deploy-staging.fr.md +3 -3
- package/templates/prompts/design.en.md +5 -5
- package/templates/prompts/design.fr.md +3 -3
- package/templates/prompts/dev.en.md +4 -4
- package/templates/prompts/dev.fr.md +3 -3
- package/templates/prompts/done.en.md +5 -5
- package/templates/prompts/done.fr.md +2 -2
- package/templates/prompts/error-handling-review.en.md +1 -1
- package/templates/prompts/error-handling-review.fr.md +1 -1
- package/templates/prompts/file-watcher-test.en.md +4 -4
- package/templates/prompts/file-watcher-test.fr.md +1 -1
- package/templates/prompts/git-commit.en.md +5 -5
- package/templates/prompts/git-commit.fr.md +3 -3
- package/templates/prompts/git-push.en.md +3 -3
- package/templates/prompts/git-push.fr.md +3 -3
- package/templates/prompts/git-tag.en.md +3 -3
- package/templates/prompts/git-tag.fr.md +3 -3
- package/templates/prompts/in-progress.en.md +6 -6
- package/templates/prompts/in-progress.fr.md +3 -3
- package/templates/prompts/qualification.en.md +8 -8
- package/templates/prompts/qualification.fr.md +3 -3
- package/templates/prompts/retest-cypress.en.md +3 -3
- package/templates/prompts/retest-cypress.fr.md +3 -3
- package/templates/prompts/retest-playwright.en.md +4 -4
- package/templates/prompts/retest-playwright.fr.md +3 -3
- package/templates/prompts/retest.en.md +4 -4
- package/templates/prompts/retest.fr.md +3 -3
- package/templates/prompts/review-best-practices.en.md +3 -3
- package/templates/prompts/review-best-practices.fr.md +3 -3
- package/templates/prompts/review-code.en.md +4 -4
- package/templates/prompts/review-code.fr.md +3 -3
- package/templates/prompts/review-consistency.en.md +3 -3
- package/templates/prompts/review-consistency.fr.md +3 -3
- package/templates/prompts/review-no-duplication.en.md +3 -3
- package/templates/prompts/review-no-duplication.fr.md +3 -3
- package/templates/prompts/review-security.en.md +4 -4
- package/templates/prompts/review-security.fr.md +3 -3
- package/templates/prompts/specification.en.md +5 -5
- package/templates/prompts/specification.fr.md +3 -3
- package/templates/prompts/splitter.en.md +13 -13
- package/templates/prompts/splitter.fr.md +3 -3
- package/templates/prompts/template-validation.en.md +1 -1
- package/templates/prompts/template-validation.fr.md +1 -1
- package/templates/prompts/testing-coverage.en.md +1 -1
- package/templates/prompts/testing-coverage.fr.md +1 -1
- package/templates/prompts/testing-cypress.en.md +4 -4
- package/templates/prompts/testing-cypress.fr.md +3 -3
- package/templates/prompts/testing-integration.en.md +4 -4
- package/templates/prompts/testing-integration.fr.md +3 -3
- package/templates/prompts/testing-playwright.en.md +4 -4
- package/templates/prompts/testing-playwright.fr.md +3 -3
- package/templates/prompts/testing-unit.en.md +4 -4
- package/templates/prompts/testing-unit.fr.md +3 -3
- package/templates/prompts/update-docs.en.md +3 -3
- package/templates/prompts/update-docs.fr.md +3 -3
- package/templates/prompts/validate-staging.en.md +3 -3
- package/templates/prompts/validate-staging.fr.md +3 -3
- package/templates/prompts/websocket-test.en.md +1 -1
- package/dist/core/ticket.d.ts +0 -50
- package/dist/core/ticket.d.ts.map +0 -1
- package/dist/core/ticket.js +0 -224
- package/dist/core/ticket.js.map +0 -1
- package/dist/server/dashboard/pages/ticket-view.d.ts +0 -8
- package/dist/server/dashboard/pages/ticket-view.d.ts.map +0 -1
- package/dist/server/dashboard/pages/ticket-view.js.map +0 -1
- package/dist/services/ticket-io.d.ts +0 -80
- package/dist/services/ticket-io.d.ts.map +0 -1
- package/dist/services/ticket-io.js.map +0 -1
|
@@ -18,8 +18,8 @@ export function getScript() {
|
|
|
18
18
|
'filter.allPriorities': 'All priorities',
|
|
19
19
|
'filter.search': 'Search...',
|
|
20
20
|
// Buttons
|
|
21
|
-
'btn.
|
|
22
|
-
'btn.
|
|
21
|
+
'btn.newIssue': '+ New issue',
|
|
22
|
+
'btn.createIssue': 'Create issue',
|
|
23
23
|
'btn.update': 'Update',
|
|
24
24
|
'btn.cancel': 'Cancel',
|
|
25
25
|
'btn.archive': 'Archive',
|
|
@@ -29,8 +29,8 @@ export function getScript() {
|
|
|
29
29
|
'btn.save': 'Save',
|
|
30
30
|
'btn.reload': 'Reload',
|
|
31
31
|
// Modal
|
|
32
|
-
'modal.
|
|
33
|
-
'modal.
|
|
32
|
+
'modal.newIssue': 'New issue',
|
|
33
|
+
'modal.editIssue': 'Edit',
|
|
34
34
|
'modal.title': 'Title *',
|
|
35
35
|
'modal.titlePlaceholder': 'E.g.: Fix the login bug',
|
|
36
36
|
'modal.description': 'Description',
|
|
@@ -78,11 +78,11 @@ export function getScript() {
|
|
|
78
78
|
// Notifications
|
|
79
79
|
'notify.titleRequired': 'Title required',
|
|
80
80
|
'notify.titleMandatory': 'Title is mandatory',
|
|
81
|
-
'notify.
|
|
82
|
-
'notify.
|
|
83
|
-
'notify.
|
|
84
|
-
'notify.
|
|
85
|
-
'notify.
|
|
81
|
+
'notify.issueUpdated': 'Issue updated',
|
|
82
|
+
'notify.issueCreated': 'Issue created',
|
|
83
|
+
'notify.issueAdvanced': 'Issue advanced',
|
|
84
|
+
'notify.issueArchived': 'Issue archived',
|
|
85
|
+
'notify.issueMoved': 'moved',
|
|
86
86
|
'notify.moveTo': 'To',
|
|
87
87
|
'notify.commentAdded': 'Comment added',
|
|
88
88
|
'notify.actionUpdated': 'updated',
|
|
@@ -109,8 +109,8 @@ export function getScript() {
|
|
|
109
109
|
'filter.allPriorities': 'Toutes priorités',
|
|
110
110
|
'filter.search': 'Rechercher...',
|
|
111
111
|
// Buttons
|
|
112
|
-
'btn.
|
|
113
|
-
'btn.
|
|
112
|
+
'btn.newIssue': '+ Nouveau ticket',
|
|
113
|
+
'btn.createIssue': 'Créer le ticket',
|
|
114
114
|
'btn.update': 'Mettre à jour',
|
|
115
115
|
'btn.cancel': 'Annuler',
|
|
116
116
|
'btn.archive': 'Archiver',
|
|
@@ -120,8 +120,8 @@ export function getScript() {
|
|
|
120
120
|
'btn.save': 'Enregistrer',
|
|
121
121
|
'btn.reload': 'Recharger',
|
|
122
122
|
// Modal
|
|
123
|
-
'modal.
|
|
124
|
-
'modal.
|
|
123
|
+
'modal.newIssue': 'Nouveau ticket',
|
|
124
|
+
'modal.editIssue': 'Modifier',
|
|
125
125
|
'modal.title': 'Titre *',
|
|
126
126
|
'modal.titlePlaceholder': 'Ex: Corriger le bug de connexion',
|
|
127
127
|
'modal.description': 'Description',
|
|
@@ -169,11 +169,11 @@ export function getScript() {
|
|
|
169
169
|
// Notifications
|
|
170
170
|
'notify.titleRequired': 'Titre requis',
|
|
171
171
|
'notify.titleMandatory': 'Le titre est obligatoire',
|
|
172
|
-
'notify.
|
|
173
|
-
'notify.
|
|
174
|
-
'notify.
|
|
175
|
-
'notify.
|
|
176
|
-
'notify.
|
|
172
|
+
'notify.issueUpdated': 'Ticket mis à jour',
|
|
173
|
+
'notify.issueCreated': 'Ticket créé',
|
|
174
|
+
'notify.issueAdvanced': 'Ticket avancé',
|
|
175
|
+
'notify.issueArchived': 'Ticket archivé',
|
|
176
|
+
'notify.issueMoved': 'déplacé',
|
|
177
177
|
'notify.moveTo': 'Vers',
|
|
178
178
|
'notify.commentAdded': 'Commentaire ajouté',
|
|
179
179
|
'notify.actionUpdated': 'mis à jour',
|
|
@@ -251,13 +251,13 @@ export function getScript() {
|
|
|
251
251
|
let criteriaCount = 0;
|
|
252
252
|
let editingKey = null;
|
|
253
253
|
let currentComments = [];
|
|
254
|
-
let
|
|
255
|
-
let
|
|
254
|
+
let contextMenuIssue = null;
|
|
255
|
+
let draggedIssue = null;
|
|
256
256
|
let draggedFromColumn = null;
|
|
257
257
|
let currentActionSlug = null;
|
|
258
258
|
let currentActionLang = localStorage.getItem('autocode-lang') || 'fr';
|
|
259
259
|
let originalActionContent = '';
|
|
260
|
-
let
|
|
260
|
+
let claudeProcessingIssues = new Set();
|
|
261
261
|
let claudeStats = { session: { tokensInput: 0, tokensOutput: 0, callCount: 0 } };
|
|
262
262
|
|
|
263
263
|
// Initialize language switcher on page load
|
|
@@ -302,19 +302,19 @@ export function getScript() {
|
|
|
302
302
|
let stats = { total: 0, byPriority: { P0: 0, P1: 0, P2: 0, P3: 0 } };
|
|
303
303
|
|
|
304
304
|
COLUMNS.forEach(col => {
|
|
305
|
-
let
|
|
306
|
-
if (filterPriority)
|
|
305
|
+
let issues = ISSUES.filter(t => t.column_slug === col.slug);
|
|
306
|
+
if (filterPriority) issues = issues.filter(t => t.priority === filterPriority);
|
|
307
307
|
if (filterSearch) {
|
|
308
308
|
const s = filterSearch.toLowerCase();
|
|
309
|
-
|
|
309
|
+
issues = issues.filter(t => t.title.toLowerCase().includes(s) || t.key.toLowerCase().includes(s));
|
|
310
310
|
}
|
|
311
|
-
|
|
311
|
+
issues.sort((a, b) => {
|
|
312
312
|
const p = { P0: 0, P1: 1, P2: 2, P3: 3 };
|
|
313
313
|
return p[a.priority] - p[b.priority];
|
|
314
314
|
});
|
|
315
315
|
|
|
316
|
-
stats.total +=
|
|
317
|
-
|
|
316
|
+
stats.total += issues.length;
|
|
317
|
+
issues.forEach(t => stats.byPriority[t.priority] = (stats.byPriority[t.priority] || 0) + 1);
|
|
318
318
|
|
|
319
319
|
const div = document.createElement('div');
|
|
320
320
|
div.className = 'column';
|
|
@@ -327,20 +327,20 @@ export function getScript() {
|
|
|
327
327
|
'<span class="column-title">' + col.name + '</span>' +
|
|
328
328
|
'<div class="column-header-actions">' +
|
|
329
329
|
'<a class="btn-action" title="ACTION.md" href="/column/' + col.slug + '/edit">\\u{1F4D8}</a>' +
|
|
330
|
-
'<span class="column-count">' +
|
|
330
|
+
'<span class="column-count">' + issues.length + '</span>' +
|
|
331
331
|
'</div></div>' +
|
|
332
332
|
'<div class="column-body">' +
|
|
333
|
-
(
|
|
334
|
-
const isProcessing =
|
|
335
|
-
return '<div class="
|
|
336
|
-
'onclick="
|
|
333
|
+
(issues.length ? issues.map(tk => {
|
|
334
|
+
const isProcessing = claudeProcessingIssues.has(tk.key);
|
|
335
|
+
return '<div class="issue' + (isProcessing ? ' claude-processing' : '') + '" draggable="true" ' +
|
|
336
|
+
'onclick="onIssueClick(\\'' + tk.key + '\\')" ' +
|
|
337
337
|
'oncontextmenu="showContextMenu(event,\\'' + tk.key + '\\')" ' +
|
|
338
338
|
'ondragstart="onDragStart(event,\\'' + tk.key + '\\',\\'' + col.slug + '\\')" ' +
|
|
339
339
|
'ondragend="onDragEnd(event)">' +
|
|
340
|
-
'<div class="
|
|
341
|
-
'<div class="
|
|
342
|
-
'<div class="
|
|
343
|
-
(isProcessing ? '<div class="
|
|
340
|
+
'<div class="issue-key">' + tk.key + '</div>' +
|
|
341
|
+
'<div class="issue-title">' + escapeHtml(tk.title) + '</div>' +
|
|
342
|
+
'<div class="issue-meta"><span class="priority ' + tk.priority + '">' + tk.priority + '</span></div>' +
|
|
343
|
+
(isProcessing ? '<div class="issue-claude-indicator"><span class="claude-dot"></span>\\u{1F916} ' + t('status.processing') + '</div>' : '') +
|
|
344
344
|
'</div>';
|
|
345
345
|
}).join('') : '<div class="empty">' + t('board.empty') + '</div>') +
|
|
346
346
|
'</div>';
|
|
@@ -375,7 +375,7 @@ export function getScript() {
|
|
|
375
375
|
document.getElementById('filter-search').oninput = e => { filterSearch = e.target.value.toLowerCase(); render(); };
|
|
376
376
|
|
|
377
377
|
// ========================================
|
|
378
|
-
// MODAL
|
|
378
|
+
// MODAL ISSUE
|
|
379
379
|
// ========================================
|
|
380
380
|
function openModal(key = null) {
|
|
381
381
|
editingKey = key;
|
|
@@ -390,16 +390,16 @@ export function getScript() {
|
|
|
390
390
|
const attachmentsSection = document.getElementById('attachments-section');
|
|
391
391
|
|
|
392
392
|
if (key) {
|
|
393
|
-
modalTitle.textContent = t('modal.
|
|
393
|
+
modalTitle.textContent = t('modal.editIssue') + ' ' + key;
|
|
394
394
|
saveBtn.textContent = t('btn.update');
|
|
395
395
|
nextBtn.style.display = 'inline-block';
|
|
396
396
|
archiveBtn.style.display = 'inline-block';
|
|
397
397
|
commentsSection.style.display = 'block';
|
|
398
398
|
attachmentsSection.style.display = 'block';
|
|
399
|
-
|
|
399
|
+
loadIssueForEdit(key);
|
|
400
400
|
} else {
|
|
401
|
-
modalTitle.textContent = t('modal.
|
|
402
|
-
saveBtn.textContent = t('btn.
|
|
401
|
+
modalTitle.textContent = t('modal.newIssue');
|
|
402
|
+
saveBtn.textContent = t('btn.createIssue');
|
|
403
403
|
nextBtn.style.display = 'none';
|
|
404
404
|
archiveBtn.style.display = 'none';
|
|
405
405
|
commentsSection.style.display = 'none';
|
|
@@ -419,40 +419,40 @@ export function getScript() {
|
|
|
419
419
|
}
|
|
420
420
|
|
|
421
421
|
function resetForm() {
|
|
422
|
-
document.getElementById('
|
|
423
|
-
document.getElementById('
|
|
424
|
-
document.getElementById('
|
|
425
|
-
document.getElementById('
|
|
426
|
-
document.getElementById('
|
|
422
|
+
document.getElementById('issue-title').value = '';
|
|
423
|
+
document.getElementById('issue-description').value = '';
|
|
424
|
+
document.getElementById('issue-priority').value = 'P2';
|
|
425
|
+
document.getElementById('issue-semver').value = 'patch';
|
|
426
|
+
document.getElementById('issue-labels').value = '';
|
|
427
427
|
selectedLabels = [];
|
|
428
428
|
criteriaCount = 0;
|
|
429
429
|
document.getElementById('selected-labels').innerHTML = '';
|
|
430
430
|
document.getElementById('criteria-list').innerHTML = '';
|
|
431
431
|
}
|
|
432
432
|
|
|
433
|
-
async function
|
|
433
|
+
async function loadIssueForEdit(key) {
|
|
434
434
|
try {
|
|
435
|
-
const res = await fetch('/api/
|
|
436
|
-
if (!res.ok) throw new Error('
|
|
435
|
+
const res = await fetch('/api/issues/' + key);
|
|
436
|
+
if (!res.ok) throw new Error('Issue not found');
|
|
437
437
|
const json = await res.json();
|
|
438
|
-
if (!json.success || !json.data) throw new Error('
|
|
439
|
-
const
|
|
438
|
+
if (!json.success || !json.data) throw new Error('Issue not found');
|
|
439
|
+
const issue = json.data;
|
|
440
440
|
|
|
441
|
-
document.getElementById('
|
|
442
|
-
document.getElementById('
|
|
443
|
-
document.getElementById('
|
|
444
|
-
document.getElementById('
|
|
441
|
+
document.getElementById('issue-title').value = issue.title || '';
|
|
442
|
+
document.getElementById('issue-description').value = issue.description || '';
|
|
443
|
+
document.getElementById('issue-priority').value = issue.priority || 'P2';
|
|
444
|
+
document.getElementById('issue-semver').value = issue.semver || 'patch';
|
|
445
445
|
|
|
446
|
-
selectedLabels = Array.isArray(
|
|
446
|
+
selectedLabels = Array.isArray(issue.labels) ? [...issue.labels] : [];
|
|
447
447
|
renderLabels();
|
|
448
448
|
|
|
449
449
|
criteriaCount = 0;
|
|
450
450
|
document.getElementById('criteria-list').innerHTML = '';
|
|
451
|
-
if (Array.isArray(
|
|
452
|
-
|
|
451
|
+
if (Array.isArray(issue.acceptance_criteria)) {
|
|
452
|
+
issue.acceptance_criteria.forEach(c => addCriteria(c));
|
|
453
453
|
}
|
|
454
454
|
|
|
455
|
-
renderComments(
|
|
455
|
+
renderComments(issue.comments || []);
|
|
456
456
|
loadAttachments(key);
|
|
457
457
|
fetchLog(key);
|
|
458
458
|
} catch (e) {
|
|
@@ -462,11 +462,11 @@ export function getScript() {
|
|
|
462
462
|
}
|
|
463
463
|
}
|
|
464
464
|
|
|
465
|
-
async function
|
|
466
|
-
const title = document.getElementById('
|
|
467
|
-
const description = document.getElementById('
|
|
468
|
-
const priority = document.getElementById('
|
|
469
|
-
const semver = document.getElementById('
|
|
465
|
+
async function saveIssue() {
|
|
466
|
+
const title = document.getElementById('issue-title').value.trim();
|
|
467
|
+
const description = document.getElementById('issue-description').value.trim();
|
|
468
|
+
const priority = document.getElementById('issue-priority').value;
|
|
469
|
+
const semver = document.getElementById('issue-semver').value;
|
|
470
470
|
const criteria = getCriteria();
|
|
471
471
|
|
|
472
472
|
if (!title) {
|
|
@@ -480,45 +480,45 @@ export function getScript() {
|
|
|
480
480
|
try {
|
|
481
481
|
if (editingKey) {
|
|
482
482
|
btn.textContent = t('btn.updating');
|
|
483
|
-
await fetch('/api/
|
|
483
|
+
await fetch('/api/issues/' + editingKey, {
|
|
484
484
|
method: 'PATCH',
|
|
485
485
|
headers: { 'Content-Type': 'application/json' },
|
|
486
486
|
body: JSON.stringify({ title, description, priority, semver, labels: selectedLabels, acceptance_criteria: criteria })
|
|
487
487
|
});
|
|
488
|
-
showNotification('success', t('notify.
|
|
488
|
+
showNotification('success', t('notify.issueUpdated'), editingKey);
|
|
489
489
|
} else {
|
|
490
490
|
btn.textContent = t('btn.creating');
|
|
491
|
-
const res = await fetch('/api/
|
|
491
|
+
const res = await fetch('/api/issues', {
|
|
492
492
|
method: 'POST',
|
|
493
493
|
headers: { 'Content-Type': 'application/json' },
|
|
494
494
|
body: JSON.stringify({ title, priority, labels: selectedLabels, description, semver, acceptance_criteria: criteria })
|
|
495
495
|
});
|
|
496
496
|
const data = await res.json();
|
|
497
|
-
showNotification('success', t('notify.
|
|
497
|
+
showNotification('success', t('notify.issueCreated'), data.key || '');
|
|
498
498
|
}
|
|
499
499
|
closeModal();
|
|
500
|
-
|
|
500
|
+
loadIssuesFromAPI();
|
|
501
501
|
} catch (e) {
|
|
502
502
|
showNotification('error', t('notify.error'), e.message);
|
|
503
503
|
btn.disabled = false;
|
|
504
|
-
btn.textContent = editingKey ? t('btn.update') : t('btn.
|
|
504
|
+
btn.textContent = editingKey ? t('btn.update') : t('btn.createIssue');
|
|
505
505
|
}
|
|
506
506
|
}
|
|
507
507
|
|
|
508
|
-
async function
|
|
508
|
+
async function advanceIssue() {
|
|
509
509
|
if (!editingKey) return;
|
|
510
510
|
const btn = document.getElementById('btn-next');
|
|
511
511
|
btn.disabled = true;
|
|
512
512
|
btn.textContent = t('btn.moving');
|
|
513
513
|
try {
|
|
514
|
-
await fetch('/api/
|
|
514
|
+
await fetch('/api/issues/' + editingKey + '/next', {
|
|
515
515
|
method: 'POST',
|
|
516
516
|
headers: { 'Content-Type': 'application/json' },
|
|
517
517
|
body: JSON.stringify({ lang: currentLang })
|
|
518
518
|
});
|
|
519
|
-
showNotification('info', t('notify.
|
|
519
|
+
showNotification('info', t('notify.issueAdvanced'), editingKey);
|
|
520
520
|
closeModal();
|
|
521
|
-
|
|
521
|
+
loadIssuesFromAPI();
|
|
522
522
|
} catch (e) {
|
|
523
523
|
showNotification('error', t('notify.error'), e.message);
|
|
524
524
|
btn.disabled = false;
|
|
@@ -526,7 +526,7 @@ export function getScript() {
|
|
|
526
526
|
}
|
|
527
527
|
}
|
|
528
528
|
|
|
529
|
-
async function
|
|
529
|
+
async function archiveIssue() {
|
|
530
530
|
if (!editingKey) return;
|
|
531
531
|
if (!confirm(t('confirm.archive') + ' ' + editingKey + '?')) return;
|
|
532
532
|
|
|
@@ -535,14 +535,14 @@ export function getScript() {
|
|
|
535
535
|
btn.textContent = t('btn.archiving');
|
|
536
536
|
try {
|
|
537
537
|
const lastColumn = COLUMNS[COLUMNS.length - 1];
|
|
538
|
-
await fetch('/api/
|
|
538
|
+
await fetch('/api/issues/' + editingKey + '/move', {
|
|
539
539
|
method: 'POST',
|
|
540
540
|
headers: { 'Content-Type': 'application/json' },
|
|
541
541
|
body: JSON.stringify({ column: lastColumn.slug, force: true, lang: currentLang })
|
|
542
542
|
});
|
|
543
|
-
showNotification('info', t('notify.
|
|
543
|
+
showNotification('info', t('notify.issueArchived'), editingKey);
|
|
544
544
|
closeModal();
|
|
545
|
-
|
|
545
|
+
loadIssuesFromAPI();
|
|
546
546
|
} catch (e) {
|
|
547
547
|
showNotification('error', t('notify.error'), e.message);
|
|
548
548
|
btn.disabled = false;
|
|
@@ -673,7 +673,7 @@ export function getScript() {
|
|
|
673
673
|
btn.textContent = t('btn.sending');
|
|
674
674
|
|
|
675
675
|
try {
|
|
676
|
-
const res = await fetch('/api/
|
|
676
|
+
const res = await fetch('/api/issues/' + editingKey + '/comments', {
|
|
677
677
|
method: 'POST',
|
|
678
678
|
headers: { 'Content-Type': 'application/json' },
|
|
679
679
|
body: JSON.stringify({ text })
|
|
@@ -706,7 +706,7 @@ export function getScript() {
|
|
|
706
706
|
|
|
707
707
|
async function loadAttachments(key) {
|
|
708
708
|
try {
|
|
709
|
-
const res = await fetch('/api/
|
|
709
|
+
const res = await fetch('/api/issues/' + key + '/attachments');
|
|
710
710
|
const json = await res.json();
|
|
711
711
|
if (json.success) {
|
|
712
712
|
currentAttachments = json.data || [];
|
|
@@ -759,7 +759,7 @@ export function getScript() {
|
|
|
759
759
|
}
|
|
760
760
|
|
|
761
761
|
try {
|
|
762
|
-
const res = await fetch('/api/
|
|
762
|
+
const res = await fetch('/api/issues/' + editingKey + '/attachments', {
|
|
763
763
|
method: 'POST',
|
|
764
764
|
body: formData
|
|
765
765
|
});
|
|
@@ -782,7 +782,7 @@ export function getScript() {
|
|
|
782
782
|
if (!confirm('Delete ' + filename + '?')) return;
|
|
783
783
|
|
|
784
784
|
try {
|
|
785
|
-
const res = await fetch('/api/
|
|
785
|
+
const res = await fetch('/api/issues/' + editingKey + '/attachments/' + encodeURIComponent(filename), {
|
|
786
786
|
method: 'DELETE'
|
|
787
787
|
});
|
|
788
788
|
const json = await res.json();
|
|
@@ -801,7 +801,7 @@ export function getScript() {
|
|
|
801
801
|
// DRAG & DROP
|
|
802
802
|
// ========================================
|
|
803
803
|
function onDragStart(e, key, columnSlug) {
|
|
804
|
-
|
|
804
|
+
draggedIssue = key;
|
|
805
805
|
draggedFromColumn = columnSlug;
|
|
806
806
|
e.target.classList.add('dragging');
|
|
807
807
|
e.dataTransfer.effectAllowed = 'move';
|
|
@@ -835,25 +835,25 @@ export function getScript() {
|
|
|
835
835
|
e.preventDefault();
|
|
836
836
|
document.querySelectorAll('.column').forEach(c => c.classList.remove('drag-over'));
|
|
837
837
|
|
|
838
|
-
if (!
|
|
838
|
+
if (!draggedIssue) return;
|
|
839
839
|
if (draggedFromColumn === targetColumnSlug) {
|
|
840
|
-
|
|
840
|
+
draggedIssue = null;
|
|
841
841
|
draggedFromColumn = null;
|
|
842
842
|
return;
|
|
843
843
|
}
|
|
844
844
|
|
|
845
|
-
const key =
|
|
846
|
-
|
|
845
|
+
const key = draggedIssue;
|
|
846
|
+
draggedIssue = null;
|
|
847
847
|
draggedFromColumn = null;
|
|
848
848
|
|
|
849
849
|
try {
|
|
850
|
-
await fetch('/api/
|
|
850
|
+
await fetch('/api/issues/' + key + '/move', {
|
|
851
851
|
method: 'POST',
|
|
852
852
|
headers: { 'Content-Type': 'application/json' },
|
|
853
853
|
body: JSON.stringify({ column: targetColumnSlug, force: true, lang: currentLang })
|
|
854
854
|
});
|
|
855
|
-
showNotification('info', key + ' ' + t('notify.
|
|
856
|
-
|
|
855
|
+
showNotification('info', key + ' ' + t('notify.issueMoved'), t('notify.moveTo') + ' "' + targetColumnName + '"');
|
|
856
|
+
loadIssuesFromAPI();
|
|
857
857
|
} catch (err) {
|
|
858
858
|
showNotification('error', t('notify.error'), err.message);
|
|
859
859
|
}
|
|
@@ -864,7 +864,7 @@ export function getScript() {
|
|
|
864
864
|
// ========================================
|
|
865
865
|
function showContextMenu(e, key) {
|
|
866
866
|
e.preventDefault();
|
|
867
|
-
|
|
867
|
+
contextMenuIssue = key;
|
|
868
868
|
const menu = document.getElementById('context-menu');
|
|
869
869
|
menu.style.left = e.clientX + 'px';
|
|
870
870
|
menu.style.top = e.clientY + 'px';
|
|
@@ -873,29 +873,29 @@ export function getScript() {
|
|
|
873
873
|
|
|
874
874
|
function hideContextMenu() {
|
|
875
875
|
document.getElementById('context-menu').classList.remove('active');
|
|
876
|
-
|
|
876
|
+
contextMenuIssue = null;
|
|
877
877
|
}
|
|
878
878
|
|
|
879
879
|
function editFromContext() {
|
|
880
|
-
if (
|
|
880
|
+
if (contextMenuIssue) openModal(contextMenuIssue);
|
|
881
881
|
hideContextMenu();
|
|
882
882
|
}
|
|
883
883
|
|
|
884
884
|
async function archiveFromContext() {
|
|
885
|
-
if (!
|
|
886
|
-
const key =
|
|
885
|
+
if (!contextMenuIssue) return;
|
|
886
|
+
const key = contextMenuIssue;
|
|
887
887
|
hideContextMenu();
|
|
888
888
|
|
|
889
889
|
if (confirm(t('confirm.archive') + ' ' + key + '?')) {
|
|
890
890
|
try {
|
|
891
891
|
const lastColumn = COLUMNS[COLUMNS.length - 1];
|
|
892
|
-
await fetch('/api/
|
|
892
|
+
await fetch('/api/issues/' + key + '/move', {
|
|
893
893
|
method: 'POST',
|
|
894
894
|
headers: { 'Content-Type': 'application/json' },
|
|
895
895
|
body: JSON.stringify({ column: lastColumn.slug, force: true, lang: currentLang })
|
|
896
896
|
});
|
|
897
|
-
showNotification('info', t('notify.
|
|
898
|
-
|
|
897
|
+
showNotification('info', t('notify.issueArchived'), key);
|
|
898
|
+
loadIssuesFromAPI();
|
|
899
899
|
} catch (err) {
|
|
900
900
|
showNotification('error', t('notify.error'), err.message);
|
|
901
901
|
}
|
|
@@ -1030,27 +1030,27 @@ export function getScript() {
|
|
|
1030
1030
|
const data = JSON.parse(event.data);
|
|
1031
1031
|
switch (data.type) {
|
|
1032
1032
|
case 'refresh':
|
|
1033
|
-
case '
|
|
1034
|
-
case '
|
|
1035
|
-
case '
|
|
1036
|
-
|
|
1033
|
+
case 'issue_updated':
|
|
1034
|
+
case 'issue_created':
|
|
1035
|
+
case 'issue_moved':
|
|
1036
|
+
loadIssuesFromAPI();
|
|
1037
1037
|
break;
|
|
1038
1038
|
case 'claude_start':
|
|
1039
|
-
onClaudeStart(data.
|
|
1039
|
+
onClaudeStart(data.issue);
|
|
1040
1040
|
break;
|
|
1041
1041
|
case 'claude_stream':
|
|
1042
|
-
onClaudeStream(data.
|
|
1042
|
+
onClaudeStream(data.issue);
|
|
1043
1043
|
break;
|
|
1044
1044
|
case 'claude_end':
|
|
1045
|
-
onClaudeEnd(data.
|
|
1046
|
-
|
|
1045
|
+
onClaudeEnd(data.issue, data.success, data.duration);
|
|
1046
|
+
loadIssuesFromAPI();
|
|
1047
1047
|
loadClaudeStats();
|
|
1048
1048
|
break;
|
|
1049
1049
|
case 'claude_complete':
|
|
1050
1050
|
if (data.success) {
|
|
1051
|
-
showNotification('claude', t('notify.claudeFinished') + ' ' + data.
|
|
1051
|
+
showNotification('claude', t('notify.claudeFinished') + ' ' + data.issue, t('notify.processingSuccess'));
|
|
1052
1052
|
} else {
|
|
1053
|
-
showNotification('error', t('notify.claudeFailed') + ' ' + data.
|
|
1053
|
+
showNotification('error', t('notify.claudeFailed') + ' ' + data.issue, t('notify.checkLogs'));
|
|
1054
1054
|
}
|
|
1055
1055
|
break;
|
|
1056
1056
|
}
|
|
@@ -1065,7 +1065,7 @@ export function getScript() {
|
|
|
1065
1065
|
// CLAUDE LOG (in modal)
|
|
1066
1066
|
// ========================================
|
|
1067
1067
|
let logPollingInterval = null;
|
|
1068
|
-
let
|
|
1068
|
+
let claudeProcessingIssue = null;
|
|
1069
1069
|
|
|
1070
1070
|
function startLogPolling(key) {
|
|
1071
1071
|
stopLogPolling();
|
|
@@ -1212,7 +1212,7 @@ export function getScript() {
|
|
|
1212
1212
|
|
|
1213
1213
|
async function fetchLog(key) {
|
|
1214
1214
|
try {
|
|
1215
|
-
const res = await fetch('/api/
|
|
1215
|
+
const res = await fetch('/api/issues/' + key + '/log');
|
|
1216
1216
|
const json = await res.json();
|
|
1217
1217
|
if (json.success && json.data) {
|
|
1218
1218
|
const section = document.getElementById('claude-log-section');
|
|
@@ -1229,9 +1229,9 @@ export function getScript() {
|
|
|
1229
1229
|
}
|
|
1230
1230
|
}
|
|
1231
1231
|
|
|
1232
|
-
function onClaudeStart(
|
|
1233
|
-
|
|
1234
|
-
|
|
1232
|
+
function onClaudeStart(issue) {
|
|
1233
|
+
claudeProcessingIssue = issue;
|
|
1234
|
+
claudeProcessingIssues.add(issue);
|
|
1235
1235
|
render();
|
|
1236
1236
|
|
|
1237
1237
|
const status = document.getElementById('claude-log-status');
|
|
@@ -1239,26 +1239,26 @@ export function getScript() {
|
|
|
1239
1239
|
status.className = 'claude-log-status processing';
|
|
1240
1240
|
status.textContent = '\\u{1F916} ' + t('status.processing');
|
|
1241
1241
|
}
|
|
1242
|
-
if (editingKey ===
|
|
1242
|
+
if (editingKey === issue) {
|
|
1243
1243
|
document.getElementById('claude-log-section').style.display = 'block';
|
|
1244
|
-
startLogPolling(
|
|
1244
|
+
startLogPolling(issue);
|
|
1245
1245
|
}
|
|
1246
|
-
showNotification('claude', t('notify.claudeStarted'),
|
|
1246
|
+
showNotification('claude', t('notify.claudeStarted'), issue);
|
|
1247
1247
|
}
|
|
1248
1248
|
|
|
1249
|
-
function onClaudeStream(
|
|
1250
|
-
if (editingKey ===
|
|
1251
|
-
fetchLog(
|
|
1249
|
+
function onClaudeStream(issue) {
|
|
1250
|
+
if (editingKey === issue) {
|
|
1251
|
+
fetchLog(issue);
|
|
1252
1252
|
}
|
|
1253
1253
|
}
|
|
1254
1254
|
|
|
1255
|
-
function onClaudeEnd(
|
|
1256
|
-
|
|
1257
|
-
|
|
1255
|
+
function onClaudeEnd(issue, success, duration) {
|
|
1256
|
+
claudeProcessingIssue = null;
|
|
1257
|
+
claudeProcessingIssues.delete(issue);
|
|
1258
1258
|
render();
|
|
1259
1259
|
|
|
1260
1260
|
const status = document.getElementById('claude-log-status');
|
|
1261
|
-
if (status && editingKey ===
|
|
1261
|
+
if (status && editingKey === issue) {
|
|
1262
1262
|
if (success) {
|
|
1263
1263
|
status.className = 'claude-log-status success';
|
|
1264
1264
|
status.textContent = '\\u2705 ' + t('status.completed') + ' (' + (duration / 1000).toFixed(1) + 's)';
|
|
@@ -1266,26 +1266,26 @@ export function getScript() {
|
|
|
1266
1266
|
status.className = 'claude-log-status error';
|
|
1267
1267
|
status.textContent = '\\u274C ' + t('status.failed');
|
|
1268
1268
|
}
|
|
1269
|
-
fetchLog(
|
|
1269
|
+
fetchLog(issue);
|
|
1270
1270
|
stopLogPolling();
|
|
1271
1271
|
}
|
|
1272
1272
|
if (success) {
|
|
1273
|
-
showNotification('success', t('notify.claudeFinished'),
|
|
1273
|
+
showNotification('success', t('notify.claudeFinished'), issue);
|
|
1274
1274
|
} else {
|
|
1275
|
-
showNotification('error', t('notify.claudeFailed'),
|
|
1275
|
+
showNotification('error', t('notify.claudeFailed'), issue);
|
|
1276
1276
|
}
|
|
1277
1277
|
}
|
|
1278
1278
|
|
|
1279
1279
|
// ========================================
|
|
1280
1280
|
// API
|
|
1281
1281
|
// ========================================
|
|
1282
|
-
async function
|
|
1282
|
+
async function loadIssuesFromAPI() {
|
|
1283
1283
|
try {
|
|
1284
|
-
const res = await fetch('/api/
|
|
1284
|
+
const res = await fetch('/api/issues');
|
|
1285
1285
|
const json = await res.json();
|
|
1286
1286
|
if (json.success && json.data) {
|
|
1287
|
-
|
|
1288
|
-
(json.data.
|
|
1287
|
+
ISSUES.length = 0;
|
|
1288
|
+
(json.data.issues || []).forEach(tk => ISSUES.push(tk));
|
|
1289
1289
|
COLUMNS.length = 0;
|
|
1290
1290
|
(json.data.columns || []).forEach(c => COLUMNS.push(c));
|
|
1291
1291
|
render();
|
|
@@ -1299,8 +1299,8 @@ export function getScript() {
|
|
|
1299
1299
|
try {
|
|
1300
1300
|
const res = await fetch('/api/status');
|
|
1301
1301
|
const json = await res.json();
|
|
1302
|
-
if (json.success && json.data && json.data.
|
|
1303
|
-
|
|
1302
|
+
if (json.success && json.data && json.data.processingIssues) {
|
|
1303
|
+
claudeProcessingIssues = new Set(json.data.processingIssues);
|
|
1304
1304
|
render();
|
|
1305
1305
|
}
|
|
1306
1306
|
} catch (e) {
|
|
@@ -1321,8 +1321,8 @@ export function getScript() {
|
|
|
1321
1321
|
}
|
|
1322
1322
|
}
|
|
1323
1323
|
|
|
1324
|
-
function
|
|
1325
|
-
window.location.href = '/
|
|
1324
|
+
function onIssueClick(key) {
|
|
1325
|
+
window.location.href = '/issue/' + key;
|
|
1326
1326
|
}
|
|
1327
1327
|
|
|
1328
1328
|
// ========================================
|
|
@@ -51,14 +51,14 @@ export function getBaseStyles() {
|
|
|
51
51
|
border-left: 1px solid var(--border);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
.
|
|
54
|
+
.header-icon-link {
|
|
55
55
|
font-size: 1.2rem;
|
|
56
56
|
text-decoration: none;
|
|
57
57
|
opacity: 0.6;
|
|
58
58
|
transition: opacity 0.2s;
|
|
59
59
|
margin-left: 8px;
|
|
60
60
|
}
|
|
61
|
-
.
|
|
61
|
+
.header-icon-link:hover {
|
|
62
62
|
opacity: 1;
|
|
63
63
|
}
|
|
64
64
|
|