agkan 2.15.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +62 -238
- package/README.md +48 -241
- package/dist/board/boardRenderer.d.ts +7 -5
- package/dist/board/boardRenderer.d.ts.map +1 -1
- package/dist/board/boardRenderer.js +43 -60
- package/dist/board/boardRenderer.js.map +1 -1
- package/dist/board/boardRoutes.d.ts +2 -0
- package/dist/board/boardRoutes.d.ts.map +1 -1
- package/dist/board/boardRoutes.js +224 -16
- package/dist/board/boardRoutes.js.map +1 -1
- package/dist/board/boardStyles.d.ts +1 -1
- package/dist/board/boardStyles.d.ts.map +1 -1
- package/dist/board/boardStyles.js +49 -3
- package/dist/board/boardStyles.js.map +1 -1
- package/dist/board/client/board.js +700 -24
- package/dist/board/server.d.ts +2 -1
- package/dist/board/server.d.ts.map +1 -1
- package/dist/board/server.js +4 -2
- package/dist/board/server.js.map +1 -1
- package/dist/cli/commands/tag/add.d.ts.map +1 -1
- package/dist/cli/commands/tag/add.js +10 -11
- package/dist/cli/commands/tag/add.js.map +1 -1
- package/dist/cli/commands/tag/attach.d.ts.map +1 -1
- package/dist/cli/commands/tag/attach.js +10 -11
- package/dist/cli/commands/tag/attach.js.map +1 -1
- package/dist/cli/commands/tag/rename.d.ts.map +1 -1
- package/dist/cli/commands/tag/rename.js +10 -11
- package/dist/cli/commands/tag/rename.js.map +1 -1
- package/dist/cli/commands/task/add.d.ts.map +1 -1
- package/dist/cli/commands/task/add.js +3 -3
- package/dist/cli/commands/task/add.js.map +1 -1
- package/dist/cli/commands/task/archive.d.ts +6 -0
- package/dist/cli/commands/task/archive.d.ts.map +1 -0
- package/dist/cli/commands/task/archive.js +120 -0
- package/dist/cli/commands/task/archive.js.map +1 -0
- package/dist/cli/commands/task/copy.js +2 -2
- package/dist/cli/commands/task/copy.js.map +1 -1
- package/dist/cli/commands/task/find.js +2 -2
- package/dist/cli/commands/task/find.js.map +1 -1
- package/dist/cli/commands/task/get.d.ts.map +1 -1
- package/dist/cli/commands/task/get.js +4 -0
- package/dist/cli/commands/task/get.js.map +1 -1
- package/dist/cli/commands/task/list.d.ts.map +1 -1
- package/dist/cli/commands/task/list.js +4 -2
- package/dist/cli/commands/task/list.js.map +1 -1
- package/dist/cli/commands/task/purge.d.ts.map +1 -1
- package/dist/cli/commands/task/purge.js +2 -9
- package/dist/cli/commands/task/purge.js.map +1 -1
- package/dist/cli/commands/task/unarchive.d.ts +6 -0
- package/dist/cli/commands/task/unarchive.d.ts.map +1 -0
- package/dist/cli/commands/task/unarchive.js +86 -0
- package/dist/cli/commands/task/unarchive.js.map +1 -0
- package/dist/cli/commands/task/update-parent.d.ts.map +1 -1
- package/dist/cli/commands/task/update-parent.js +10 -11
- package/dist/cli/commands/task/update-parent.js.map +1 -1
- package/dist/cli/index.js +8 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/utils/board-daemon.d.ts.map +1 -1
- package/dist/cli/utils/board-daemon.js +10 -4
- package/dist/cli/utils/board-daemon.js.map +1 -1
- package/dist/db/adapters/sqlite-storage-backend.d.ts +2 -1
- package/dist/db/adapters/sqlite-storage-backend.d.ts.map +1 -1
- package/dist/db/adapters/sqlite-storage-backend.js +82 -5
- package/dist/db/adapters/sqlite-storage-backend.js.map +1 -1
- package/dist/db/connection.d.ts +5 -0
- package/dist/db/connection.d.ts.map +1 -1
- package/dist/db/connection.js +9 -0
- package/dist/db/connection.js.map +1 -1
- package/dist/db/migrations/20260412000000_add_archive_status.d.ts +3 -0
- package/dist/db/migrations/20260412000000_add_archive_status.d.ts.map +1 -0
- package/dist/db/migrations/20260412000000_add_archive_status.js +10 -0
- package/dist/db/migrations/20260412000000_add_archive_status.js.map +1 -0
- package/dist/db/migrations/20260412000000_add_is_archived_to_tasks.d.ts +3 -0
- package/dist/db/migrations/20260412000000_add_is_archived_to_tasks.d.ts.map +1 -0
- package/dist/db/migrations/20260412000000_add_is_archived_to_tasks.js +10 -0
- package/dist/db/migrations/20260412000000_add_is_archived_to_tasks.js.map +1 -0
- package/dist/db/migrations/index.d.ts.map +1 -1
- package/dist/db/migrations/index.js +6 -0
- package/dist/db/migrations/index.js.map +1 -1
- package/dist/db/types/repository.d.ts +40 -0
- package/dist/db/types/repository.d.ts.map +1 -1
- package/dist/errors.d.ts +27 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +51 -0
- package/dist/errors.js.map +1 -0
- package/dist/models/Task.d.ts +3 -0
- package/dist/models/Task.d.ts.map +1 -1
- package/dist/services/ClaudeProcessService.d.ts.map +1 -1
- package/dist/services/ClaudeProcessService.js +2 -1
- package/dist/services/ClaudeProcessService.js.map +1 -1
- package/dist/services/CommentService.d.ts.map +1 -1
- package/dist/services/CommentService.js +3 -2
- package/dist/services/CommentService.js.map +1 -1
- package/dist/services/ExportImportService.d.ts.map +1 -1
- package/dist/services/ExportImportService.js +17 -15
- package/dist/services/ExportImportService.js.map +1 -1
- package/dist/services/TagService.d.ts.map +1 -1
- package/dist/services/TagService.js +7 -6
- package/dist/services/TagService.js.map +1 -1
- package/dist/services/TaskBlockService.d.ts.map +1 -1
- package/dist/services/TaskBlockService.js +5 -4
- package/dist/services/TaskBlockService.js.map +1 -1
- package/dist/services/TaskService.d.ts +19 -1
- package/dist/services/TaskService.d.ts.map +1 -1
- package/dist/services/TaskService.js +68 -17
- package/dist/services/TaskService.js.map +1 -1
- package/dist/services/TaskTagService.d.ts.map +1 -1
- package/dist/services/TaskTagService.js +4 -3
- package/dist/services/TaskTagService.js.map +1 -1
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +3 -1
- package/dist/services/index.js.map +1 -1
- package/dist/utils/date.d.ts +10 -0
- package/dist/utils/date.d.ts.map +1 -0
- package/dist/utils/date.js +17 -0
- package/dist/utils/date.js.map +1 -0
- package/package.json +2 -2
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Task, TaskStatus } from '../models';
|
|
2
2
|
import { Tag } from '../models/Tag';
|
|
3
3
|
import { StorageBackend } from '../db/types/repository';
|
|
4
|
-
|
|
5
|
-
export declare const
|
|
6
|
-
export declare const
|
|
4
|
+
type BoardStatus = TaskStatus;
|
|
5
|
+
export declare const STATUSES: BoardStatus[];
|
|
6
|
+
export declare const STATUS_LABELS: Record<BoardStatus, string>;
|
|
7
|
+
export declare const STATUS_COLORS: Record<BoardStatus, string>;
|
|
7
8
|
export declare function renderCard(task: Task, tags: Tag[], blockedByIds?: number[], blockingIds?: number[]): string;
|
|
8
|
-
export declare function renderColumn(status:
|
|
9
|
+
export declare function renderColumn(status: BoardStatus, tasks: Task[], tagMap: Map<number, Tag[]>, blockMap?: Map<number, {
|
|
9
10
|
blockedBy: number[];
|
|
10
11
|
blocking: number[];
|
|
11
12
|
}>): string;
|
|
@@ -18,7 +19,7 @@ export declare function buildBoardCardsPayload(tasksByStatus: Map<TaskStatus, Ta
|
|
|
18
19
|
blockedBy: number[];
|
|
19
20
|
blocking: number[];
|
|
20
21
|
}>): {
|
|
21
|
-
status:
|
|
22
|
+
status: BoardStatus;
|
|
22
23
|
html: string;
|
|
23
24
|
count: number;
|
|
24
25
|
}[];
|
|
@@ -31,4 +32,5 @@ export declare function buildBlockMap(blocks: Array<{
|
|
|
31
32
|
blocking: number[];
|
|
32
33
|
}>;
|
|
33
34
|
export declare function getBoardUpdatedAt(database: StorageBackend): string | null;
|
|
35
|
+
export {};
|
|
34
36
|
//# sourceMappingURL=boardRenderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boardRenderer.d.ts","sourceRoot":"","sources":["../../src/board/boardRenderer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"boardRenderer.d.ts","sourceRoot":"","sources":["../../src/board/boardRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAA8B,MAAM,WAAW,CAAC;AACzE,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAIxD,KAAK,WAAW,GAAG,UAAU,CAAC;AAC9B,eAAO,MAAM,QAAQ,EAAE,WAAW,EAA8E,CAAC;AAEjH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAQrD,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAQrD,CAAC;AAWF,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,YAAY,GAAE,MAAM,EAAO,EAAE,WAAW,GAAE,MAAM,EAAO,GAAG,MAAM,CA0BnH;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,IAAI,EAAE,EACb,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,EAC1B,QAAQ,GAAE,GAAG,CAAC,MAAM,EAAE;IAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAAa,GAC7E,MAAM,CAuBR;AA8HD,wBAAgB,WAAW,CACzB,aAAa,EAAE,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,EACtC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,EAC1B,UAAU,CAAC,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,MAAM,EACd,QAAQ,GAAE,GAAG,CAAC,MAAM,EAAE;IAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAAa,GAC7E,MAAM,CA+CR;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,CAMpD;AAED,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,EACtC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,EAC1B,QAAQ,GAAE,GAAG,CAAC,MAAM,EAAE;IAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAAa,GAC7E;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAWxD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAYzE;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,KAAK,CAAC;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,CAAC,GAClE,GAAG,CAAC,MAAM,EAAE;IAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAc1D;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAEzE"}
|
|
@@ -1,37 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
3
|
exports.STATUS_COLORS = exports.STATUS_LABELS = exports.STATUSES = void 0;
|
|
37
4
|
exports.renderCard = renderCard;
|
|
@@ -42,8 +9,6 @@ exports.buildBoardCardsPayload = buildBoardCardsPayload;
|
|
|
42
9
|
exports.buildTasksByStatus = buildTasksByStatus;
|
|
43
10
|
exports.buildBlockMap = buildBlockMap;
|
|
44
11
|
exports.getBoardUpdatedAt = getBoardUpdatedAt;
|
|
45
|
-
const fs = __importStar(require("fs"));
|
|
46
|
-
const path = __importStar(require("path"));
|
|
47
12
|
const models_1 = require("../models");
|
|
48
13
|
const boardStyles_1 = require("./boardStyles");
|
|
49
14
|
const boardFavicon_1 = require("./boardFavicon");
|
|
@@ -82,11 +47,19 @@ function renderCard(task, tags, blockedByIds = [], blockingIds = []) {
|
|
|
82
47
|
const tagBadges = tags.map((t) => `<span class="tag">${escapeHtml(t.name)}</span>`).join('');
|
|
83
48
|
const dataBlockedBy = blockedByIds.length > 0 ? ` data-blocked-by="${blockedByIds.join(',')}"` : '';
|
|
84
49
|
const dataBlocking = blockingIds.length > 0 ? ` data-blocking="${blockingIds.join(',')}"` : '';
|
|
50
|
+
let cardActions = '';
|
|
51
|
+
if (['ready', 'in_progress'].includes(task.status)) {
|
|
52
|
+
cardActions = `<div class="card-actions"><div class="claude-run-split" data-task-id="${task.id}"><button class="claude-run-btn" data-task-id="${task.id}">▶ Run</button><button class="claude-run-toggle" data-task-id="${task.id}" title="More options">▼</button><div class="claude-run-menu"><button class="claude-run-menu-item" data-task-id="${task.id}" data-command="direct">▶ Run (current branch)</button><button class="claude-run-menu-item" data-task-id="${task.id}" data-command="pr">▶ Run (create PR)</button></div></div></div>`;
|
|
53
|
+
}
|
|
54
|
+
else if (!['review', 'done', 'closed'].includes(task.status)) {
|
|
55
|
+
cardActions = `<div class="card-actions"><button class="claude-plan-btn" data-task-id="${task.id}">📋 Planning</button></div>`;
|
|
56
|
+
}
|
|
85
57
|
return `
|
|
86
58
|
<div class="card" draggable="true" data-id="${task.id}" data-status="${task.status}" data-updated-at="${escapeHtml(task.updated_at)}"${dataBlockedBy}${dataBlocking}>
|
|
87
59
|
<div class="card-header">
|
|
88
60
|
<span class="card-id">#${task.id}</span>
|
|
89
61
|
${priorityBadge}
|
|
62
|
+
${cardActions}
|
|
90
63
|
</div>
|
|
91
64
|
<div class="card-title">${escapeHtml(task.title)}</div>
|
|
92
65
|
${tagBadges ? `<div class="card-tags">${tagBadges}</div>` : ''}
|
|
@@ -153,6 +126,23 @@ function getContextMenuAndToast() {
|
|
|
153
126
|
</div>
|
|
154
127
|
<div class="toast" id="toast">Failed to update task</div>`;
|
|
155
128
|
}
|
|
129
|
+
function getClaudeStreamModal() {
|
|
130
|
+
return `
|
|
131
|
+
<div class="modal-overlay" id="claude-stream-modal">
|
|
132
|
+
<div class="modal" style="width:680px;">
|
|
133
|
+
<div class="claude-stream-modal-header">
|
|
134
|
+
<h2 id="claude-stream-modal-title">Claude Output</h2>
|
|
135
|
+
<button id="claude-stream-modal-close">✕</button>
|
|
136
|
+
</div>
|
|
137
|
+
<div id="claude-stream-log" class="claude-stream-log"></div>
|
|
138
|
+
<div class="claude-stream-modal-footer">
|
|
139
|
+
<span id="claude-stream-status" class="claude-stream-status">Connecting...</span>
|
|
140
|
+
<button id="claude-stream-stop-btn" class="claude-stream-stop-btn">Stop</button>
|
|
141
|
+
<button id="claude-stream-close-btn">Close</button>
|
|
142
|
+
</div>
|
|
143
|
+
</div>
|
|
144
|
+
</div>`;
|
|
145
|
+
}
|
|
156
146
|
function getPurgeAndVersionModals() {
|
|
157
147
|
return `
|
|
158
148
|
<div class="modal-overlay" id="purge-confirm-modal">
|
|
@@ -166,6 +156,17 @@ function getPurgeAndVersionModals() {
|
|
|
166
156
|
</div>
|
|
167
157
|
</div>
|
|
168
158
|
</div>
|
|
159
|
+
<div class="modal-overlay" id="archive-confirm-modal">
|
|
160
|
+
<div class="modal">
|
|
161
|
+
<h2>Archive Tasks</h2>
|
|
162
|
+
<p style="font-size:13px;color:#64748b;margin-bottom:16px;">Archive all done/closed tasks older than 3 days. Archived tasks are hidden from the board but not deleted.</p>
|
|
163
|
+
<p id="archive-result" style="font-size:13px;color:#16a34a;min-height:18px;margin-bottom:8px;"></p>
|
|
164
|
+
<div class="modal-actions">
|
|
165
|
+
<button id="archive-cancel-btn">Cancel</button>
|
|
166
|
+
<button id="archive-confirm-btn" class="primary">Archive</button>
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
169
|
+
</div>
|
|
169
170
|
<div class="modal-overlay" id="import-modal">
|
|
170
171
|
<div class="modal" style="width:420px;">
|
|
171
172
|
<h2>Import Tasks</h2>
|
|
@@ -192,33 +193,15 @@ function getPurgeAndVersionModals() {
|
|
|
192
193
|
</div>
|
|
193
194
|
</div>`;
|
|
194
195
|
}
|
|
195
|
-
function loadClientBundle() {
|
|
196
|
-
// Try resolved path (works in compiled dist/ and in development)
|
|
197
|
-
const candidates = [
|
|
198
|
-
path.join(__dirname, 'client', 'board.js'),
|
|
199
|
-
path.join(__dirname, '..', '..', 'dist', 'board', 'client', 'board.js'),
|
|
200
|
-
];
|
|
201
|
-
for (const bundlePath of candidates) {
|
|
202
|
-
try {
|
|
203
|
-
return fs.readFileSync(bundlePath, 'utf8');
|
|
204
|
-
}
|
|
205
|
-
catch {
|
|
206
|
-
// Try next candidate
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
throw new Error(`Client bundle not found. Tried: ${candidates.join(', ')}. Run 'npm run build' to generate it.`);
|
|
210
|
-
}
|
|
211
196
|
function getBoardBodyStatic() {
|
|
212
|
-
const
|
|
213
|
-
const script = `
|
|
214
|
-
var statusColors = ${JSON.stringify(exports.STATUS_COLORS)};
|
|
197
|
+
const configScript = `var statusColors = ${JSON.stringify(exports.STATUS_COLORS)};
|
|
215
198
|
var allStatuses = ${JSON.stringify(exports.STATUSES)};
|
|
216
199
|
var statusLabels = ${JSON.stringify(exports.STATUS_LABELS)};
|
|
217
|
-
var allPriorities = ${JSON.stringify(models_1.PRIORITIES)}
|
|
218
|
-
${
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
200
|
+
var allPriorities = ${JSON.stringify(models_1.PRIORITIES)};`;
|
|
201
|
+
return `${getAddTaskModal()}${getContextMenuAndToast()}${getPurgeAndVersionModals()}${getClaudeStreamModal()}
|
|
202
|
+
<script>${configScript}
|
|
203
|
+
</script>
|
|
204
|
+
<script src="/static/board.js"></script>`;
|
|
222
205
|
}
|
|
223
206
|
function renderBoard(tasksByStatus, tagMap, boardTitle, theme, blockMap = new Map()) {
|
|
224
207
|
const columns = exports.STATUSES.map((status) => renderColumn(status, tasksByStatus.get(status) || [], tagMap, blockMap)).join('');
|
|
@@ -236,7 +219,7 @@ function renderBoard(tasksByStatus, tagMap, boardTitle, theme, blockMap = new Ma
|
|
|
236
219
|
</style>
|
|
237
220
|
</head>
|
|
238
221
|
<body>
|
|
239
|
-
<header><h1>agkan board
|
|
222
|
+
<header><h1>agkan board<div id="header-running-indicator" style="display:none"></div></h1>${titleHtml}<div class="burger-menu-wrapper"><button class="burger-menu-btn" id="burger-menu-btn" title="Menu" aria-label="Menu"><span></span><span></span><span></span></button><div class="burger-menu-dropdown" id="burger-menu-dropdown"><div class="burger-menu-item danger" id="burger-purge-tasks">🗑 Purge Tasks</div><div class="burger-menu-item" id="burger-archive-tasks">📦 Archive Tasks</div><div class="burger-menu-item" id="burger-export-tasks">↓ Export Tasks</div><div class="burger-menu-item" id="burger-import-tasks">↑ Import Tasks</div><div class="burger-menu-item" id="burger-version-info">ℹ Version Info</div><div class="burger-menu-separator"></div><div class="burger-menu-item" id="burger-theme-dark">Dark Mode</div><div class="burger-menu-item" id="burger-theme-light">Light Mode</div><div class="burger-menu-item" id="burger-theme-system">System Setting</div></div></div></header>
|
|
240
223
|
<div class="filter-bar" id="filter-bar">
|
|
241
224
|
<div class="filter-group">
|
|
242
225
|
<input type="search" id="filter-search" class="filter-search-input" placeholder="Search tasks...">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boardRenderer.js","sourceRoot":"","sources":["../../src/board/boardRenderer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"boardRenderer.js","sourceRoot":"","sources":["../../src/board/boardRenderer.ts"],"names":[],"mappings":";;;AAsCA,gCA0BC;AAED,oCA4BC;AA8HD,kCAqDC;AAED,wCAMC;AAED,wDAeC;AAED,gDAYC;AAED,sCAgBC;AAED,8CAEC;AA9UD,sCAAyE;AAGzE,+CAA6C;AAC7C,iDAAsD;AAGzC,QAAA,QAAQ,GAAkB,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;AAEpG,QAAA,aAAa,GAAgC;IACxD,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,OAAO;IACd,WAAW,EAAE,aAAa;IAC1B,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,QAAQ;CACjB,CAAC;AAEW,QAAA,aAAa,GAAgC;IACxD,MAAM,EAAE,SAAS;IACjB,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,SAAS;IAChB,WAAW,EAAE,SAAS;IACtB,MAAM,EAAE,SAAS;IACjB,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,SAAS;CAClB,CAAC;AAEF,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,IAAI;SACR,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC;AAED,SAAgB,UAAU,CAAC,IAAU,EAAE,IAAW,EAAE,eAAyB,EAAE,EAAE,cAAwB,EAAE;IACzG,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IAC/B,MAAM,aAAa,GAAG,QAAQ;QAC5B,CAAC,CAAC,kCAAkC,UAAU,CAAC,QAAQ,CAAC,KAAK,UAAU,CAAC,QAAQ,CAAC,SAAS;QAC1F,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,qBAAqB,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7F,MAAM,aAAa,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,qBAAqB,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACpG,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,mBAAmB,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAE/F,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,WAAW,GAAG,yEAAyE,IAAI,CAAC,EAAE,kDAAkD,IAAI,CAAC,EAAE,yEAAyE,IAAI,CAAC,EAAE,0HAA0H,IAAI,CAAC,EAAE,mHAAmH,IAAI,CAAC,EAAE,wEAAwE,CAAC;IAC7iB,CAAC;SAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/D,WAAW,GAAG,2EAA2E,IAAI,CAAC,EAAE,qCAAqC,CAAC;IACxI,CAAC;IAED,OAAO;kDACyC,IAAI,CAAC,EAAE,kBAAkB,IAAI,CAAC,MAAM,sBAAsB,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,aAAa,GAAG,YAAY;;iCAEtI,IAAI,CAAC,EAAE;UAC9B,aAAa;UACb,WAAW;;gCAEW,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;QAC9C,SAAS,CAAC,CAAC,CAAC,0BAA0B,SAAS,QAAQ,CAAC,CAAC,CAAC,EAAE;WACzD,CAAC;AACZ,CAAC;AAED,SAAgB,YAAY,CAC1B,MAAmB,EACnB,KAAa,EACb,MAA0B,EAC1B,WAAqE,IAAI,GAAG,EAAE;IAE9E,MAAM,KAAK,GAAG,qBAAa,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,qBAAa,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,KAAK;SAChB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QACxE,OAAO,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;IACxF,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;IAEZ,OAAO;yCACgC,MAAM;6DACc,KAAK;oDACd,KAAK,KAAK,KAAK;;yCAE1B,KAAK,CAAC,MAAM;mDACF,MAAM;;;2CAGd,MAAM;YACrC,KAAK;;aAEJ,CAAC;AACd,CAAC;AAED,MAAM,sBAAsB,GAAG,mBAAU,CAAC,GAAG,CAC3C,CAAC,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CACrH,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AAErB,SAAS,eAAe;IACtB,OAAO;;;;;;;;;;;UAWC,sBAAsB;;;;;;;;;;;;;;;;SAgBvB,CAAC;AACV,CAAC;AAED,SAAS,sBAAsB;IAC7B,OAAO;;;;4DAImD,CAAC;AAC7D,CAAC;AAED,SAAS,oBAAoB;IAC3B,OAAO;;;;;;;;;;;;;;SAcA,CAAC;AACV,CAAC;AAED,SAAS,wBAAwB;IAC/B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SA+CA,CAAC;AACV,CAAC;AAED,SAAS,kBAAkB;IACzB,MAAM,YAAY,GAAG,sBAAsB,IAAI,CAAC,SAAS,CAAC,qBAAa,CAAC;wBAClD,IAAI,CAAC,SAAS,CAAC,gBAAQ,CAAC;yBACvB,IAAI,CAAC,SAAS,CAAC,qBAAa,CAAC;0BAC5B,IAAI,CAAC,SAAS,CAAC,mBAAU,CAAC,GAAG,CAAC;IAEtD,OAAO,GAAG,eAAe,EAAE,GAAG,sBAAsB,EAAE,GAAG,wBAAwB,EAAE,GAAG,oBAAoB,EAAE;YAClG,YAAY;;2CAEmB,CAAC;AAC5C,CAAC;AAED,SAAgB,WAAW,CACzB,aAAsC,EACtC,MAA0B,EAC1B,UAAmB,EACnB,KAAc,EACd,WAAqE,IAAI,GAAG,EAAE;IAE9E,MAAM,OAAO,GAAG,gBAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CACtC,YAAY,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,CACxE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACX,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,6BAA6B,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IACjG,MAAM,eAAe,GAAG,kBAAkB,EAAE,CAAC;IAC7C,MAAM,aAAa,GAAG,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,gBAAgB,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAE5F,OAAO;iBACQ,aAAa;;;;;4CAKc,mCAAoB;WACrD,0BAAY;;;;8FAIuE,SAAS;;;;;;;;;;;;;;;;;;;;;;;;yBAwB9E,OAAO,SAAS,eAAe;;;QAGhD,CAAC;AACT,CAAC;AAED,SAAgB,cAAc,CAAC,KAAa;IAC1C,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC9B,MAAM,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,uBAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvD,MAAM,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,uBAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvD,OAAO,EAAE,GAAG,EAAE,CAAC;IACjB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,sBAAsB,CACpC,aAAsC,EACtC,MAA0B,EAC1B,WAAqE,IAAI,GAAG,EAAE;IAE9E,OAAO,gBAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC9C,MAAM,IAAI,GAAG,KAAK;aACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACT,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;YACxE,OAAO,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;QACxF,CAAC,CAAC;aACD,IAAI,CAAC,EAAE,CAAC,CAAC;QACZ,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,kBAAkB,CAAC,KAAa;IAC9C,MAAM,aAAa,GAAG,IAAI,GAAG,EAAsB,CAAC;IACpD,KAAK,MAAM,MAAM,IAAI,gBAAQ,EAAE,CAAC;QAC9B,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAChC,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7C,CAAC;IACD,KAAK,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,IAAI,aAAa,EAAE,CAAC;QAClD,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,SAAgB,aAAa,CAC3B,MAAmE;IAEnE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAuD,CAAC;IAChF,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC;YACzC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QACvE,CAAC;QACD,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,CAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAE1E,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC;YACzC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QACvE,CAAC;QACD,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,CAAE,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAgB,iBAAiB,CAAC,QAAwB;IACxD,OAAO,QAAQ,CAAC,0BAA0B,EAAE,CAAC;AAC/C,CAAC"}
|
|
@@ -5,6 +5,7 @@ import { TagService } from '../services/TagService';
|
|
|
5
5
|
import { MetadataService } from '../services/MetadataService';
|
|
6
6
|
import { CommentService } from '../services/CommentService';
|
|
7
7
|
import { TaskBlockService } from '../services/TaskBlockService';
|
|
8
|
+
import { ClaudeProcessService } from '../services/ClaudeProcessService';
|
|
8
9
|
import { StorageBackend } from '../db/types/repository';
|
|
9
10
|
export type BoardServices = {
|
|
10
11
|
ts: TaskService;
|
|
@@ -16,6 +17,7 @@ export type BoardServices = {
|
|
|
16
17
|
database: StorageBackend;
|
|
17
18
|
boardTitle?: string;
|
|
18
19
|
configDir: string;
|
|
20
|
+
claudeProcessService?: ClaudeProcessService;
|
|
19
21
|
};
|
|
20
22
|
export declare function registerTaskApiRoutes(app: Hono, services: BoardServices): void;
|
|
21
23
|
export declare function registerConfigApiRoutes(app: Hono, configDir: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boardRoutes.d.ts","sourceRoot":"","sources":["../../src/board/boardRoutes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"boardRoutes.d.ts","sourceRoot":"","sources":["../../src/board/boardRoutes.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAEhE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAGxE,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAYxD,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,WAAW,CAAC;IAChB,GAAG,EAAE,cAAc,CAAC;IACpB,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,eAAe,CAAC;IACpB,EAAE,EAAE,cAAc,CAAC;IACnB,GAAG,EAAE,gBAAgB,CAAC;IACtB,QAAQ,EAAE,cAAc,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C,CAAC;AAkUF,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI,CAO9E;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CA+B1E;AAmJD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI,CAmD5E"}
|
|
@@ -1,12 +1,51 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.registerTaskApiRoutes = registerTaskApiRoutes;
|
|
4
37
|
exports.registerConfigApiRoutes = registerConfigApiRoutes;
|
|
5
38
|
exports.registerBoardRoutes = registerBoardRoutes;
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
const logger_1 = require("../utils/logger");
|
|
6
42
|
const ExportImportService_1 = require("../services/ExportImportService");
|
|
7
43
|
const models_1 = require("../models");
|
|
44
|
+
const errors_1 = require("../errors");
|
|
8
45
|
const boardConfig_1 = require("./boardConfig");
|
|
46
|
+
const date_1 = require("../utils/date");
|
|
9
47
|
const boardRenderer_1 = require("./boardRenderer");
|
|
48
|
+
const NON_ARCHIVE_STATUSES = ['icebox', 'backlog', 'ready', 'in_progress', 'review', 'done', 'closed'];
|
|
10
49
|
function buildTaskUpdateInput(body) {
|
|
11
50
|
const input = {};
|
|
12
51
|
if (body.status !== undefined) {
|
|
@@ -30,7 +69,13 @@ function buildTaskUpdateInput(body) {
|
|
|
30
69
|
return { input };
|
|
31
70
|
}
|
|
32
71
|
function registerTaskCrudRoutes(app, ts, tts, tbs, ms, tags) {
|
|
33
|
-
app.get('/api/tasks', (c) =>
|
|
72
|
+
app.get('/api/tasks', (c) => {
|
|
73
|
+
const includeAll = c.req.query('all') === 'true' || c.req.query('all') === '1';
|
|
74
|
+
if (includeAll) {
|
|
75
|
+
return c.json({ tasks: ts.listTasks({ includeArchived: true }, 'id', 'asc') });
|
|
76
|
+
}
|
|
77
|
+
return c.json({ tasks: ts.listTasks({}, 'id', 'asc') });
|
|
78
|
+
});
|
|
34
79
|
app.post('/api/tasks', async (c) => {
|
|
35
80
|
const body = await c.req.json();
|
|
36
81
|
if (!body.title || typeof body.title !== 'string' || !body.title.trim()) {
|
|
@@ -38,16 +83,17 @@ function registerTaskCrudRoutes(app, ts, tts, tbs, ms, tags) {
|
|
|
38
83
|
}
|
|
39
84
|
const status = body.status && boardRenderer_1.STATUSES.includes(body.status) ? body.status : 'backlog';
|
|
40
85
|
const priority = body.priority && (0, models_1.isPriority)(body.priority) ? body.priority : undefined;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
86
|
+
// Resolve valid tag IDs before task creation
|
|
87
|
+
const tagIds = Array.isArray(body.tags)
|
|
88
|
+
? body.tags.map(Number).filter((n) => !isNaN(n) && tags.getTag(n))
|
|
89
|
+
: undefined;
|
|
90
|
+
const task = ts.createTask({
|
|
91
|
+
title: body.title.trim(),
|
|
92
|
+
body: body.body || undefined,
|
|
93
|
+
status,
|
|
94
|
+
priority,
|
|
95
|
+
tagIds: tagIds && tagIds.length > 0 ? tagIds : undefined,
|
|
96
|
+
});
|
|
51
97
|
// Store metadata if provided
|
|
52
98
|
if (Array.isArray(body.metadata)) {
|
|
53
99
|
for (const entry of body.metadata) {
|
|
@@ -224,9 +270,7 @@ function registerUtilityRoutes(app, ts) {
|
|
|
224
270
|
beforeDate = parsed.toISOString();
|
|
225
271
|
}
|
|
226
272
|
else {
|
|
227
|
-
|
|
228
|
-
d.setDate(d.getDate() - 3);
|
|
229
|
-
beforeDate = d.toISOString();
|
|
273
|
+
beforeDate = (0, date_1.daysAgoIso)(3);
|
|
230
274
|
}
|
|
231
275
|
const tasks = ts.purgeTasksBefore(beforeDate, ['done', 'closed'], false);
|
|
232
276
|
return c.json({
|
|
@@ -234,6 +278,43 @@ function registerUtilityRoutes(app, ts) {
|
|
|
234
278
|
tasks: tasks.map((t) => ({ id: t.id, title: t.title, status: t.status, updated_at: t.updated_at })),
|
|
235
279
|
});
|
|
236
280
|
});
|
|
281
|
+
app.post('/api/tasks/archive', async (c) => {
|
|
282
|
+
const body = (await c.req.json().catch(() => ({})));
|
|
283
|
+
let beforeDate;
|
|
284
|
+
if (body.beforeDate !== undefined) {
|
|
285
|
+
const parsed = new Date(body.beforeDate);
|
|
286
|
+
if (isNaN(parsed.getTime())) {
|
|
287
|
+
return c.json({ error: 'Invalid beforeDate. Use ISO 8601 format.' }, 400);
|
|
288
|
+
}
|
|
289
|
+
beforeDate = parsed.toISOString();
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
beforeDate = (0, date_1.daysAgoIso)(3);
|
|
293
|
+
}
|
|
294
|
+
const tasks = ts.archiveTasksBefore(beforeDate, ['done', 'closed'], false);
|
|
295
|
+
return c.json({
|
|
296
|
+
count: tasks.length,
|
|
297
|
+
tasks: tasks.map((t) => ({ id: t.id, title: t.title, status: t.status, updated_at: t.updated_at })),
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
app.post('/api/tasks/:id/unarchive', async (c) => {
|
|
301
|
+
const idStr = c.req.param('id');
|
|
302
|
+
const id = parseInt(idStr, 10);
|
|
303
|
+
if (isNaN(id)) {
|
|
304
|
+
return c.json({ error: 'Invalid task ID' }, 400);
|
|
305
|
+
}
|
|
306
|
+
const task = ts.unarchiveTask(id);
|
|
307
|
+
if (!task) {
|
|
308
|
+
return c.json({ error: 'Task not found' }, 404);
|
|
309
|
+
}
|
|
310
|
+
return c.json({
|
|
311
|
+
id: task.id,
|
|
312
|
+
title: task.title,
|
|
313
|
+
status: task.status,
|
|
314
|
+
is_archived: task.is_archived,
|
|
315
|
+
updated_at: task.updated_at,
|
|
316
|
+
});
|
|
317
|
+
});
|
|
237
318
|
app.get('/api/version', (c) => {
|
|
238
319
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
239
320
|
const { version } = require('../../package.json');
|
|
@@ -307,7 +388,7 @@ function registerConfigApiRoutes(app, configDir) {
|
|
|
307
388
|
});
|
|
308
389
|
}
|
|
309
390
|
function parseBoardCardFilters(query) {
|
|
310
|
-
const filters = {};
|
|
391
|
+
const filters = { status: NON_ARCHIVE_STATUSES };
|
|
311
392
|
if (query.tags) {
|
|
312
393
|
const tagIds = query.tags
|
|
313
394
|
.split(',')
|
|
@@ -332,10 +413,134 @@ function parseBoardCardFilters(query) {
|
|
|
332
413
|
}
|
|
333
414
|
return filters;
|
|
334
415
|
}
|
|
416
|
+
function registerClaudeRoutes(app, claudeProcess, ts) {
|
|
417
|
+
app.post('/api/claude/tasks/:taskId/run', async (c) => {
|
|
418
|
+
const taskId = Number(c.req.param('taskId'));
|
|
419
|
+
if (isNaN(taskId))
|
|
420
|
+
return c.json({ error: 'Invalid taskId' }, 400);
|
|
421
|
+
if (!ts.getTask(taskId))
|
|
422
|
+
return c.json({ error: 'Task not found' }, 404);
|
|
423
|
+
const body = (await c.req.json().catch(() => ({})));
|
|
424
|
+
const command = body.command === 'planning' ? 'planning' : body.command === 'pr' ? 'pr' : 'run';
|
|
425
|
+
const prompt = command === 'planning'
|
|
426
|
+
? `Task ID: ${taskId}\n/agkan-planning-subtask`
|
|
427
|
+
: command === 'pr'
|
|
428
|
+
? `Task ID: ${taskId}\n/agkan-subtask`
|
|
429
|
+
: `Task ID: ${taskId}\n/agkan-subtask-direct`;
|
|
430
|
+
try {
|
|
431
|
+
claudeProcess.startProcess(taskId, prompt, command);
|
|
432
|
+
}
|
|
433
|
+
catch (e) {
|
|
434
|
+
if (e instanceof errors_1.ConflictError) {
|
|
435
|
+
console.error(`[boardRoutes] 409 already running taskId=${taskId} command=${command} running=${JSON.stringify(claudeProcess.listRunningTasks())}`);
|
|
436
|
+
return c.json({ error: e.message }, 409);
|
|
437
|
+
}
|
|
438
|
+
return c.json({ error: e instanceof Error ? e.message : 'Failed to start process' }, 500);
|
|
439
|
+
}
|
|
440
|
+
if (command === 'pr' || command === 'run') {
|
|
441
|
+
const targetStatus = command === 'pr' ? 'review' : 'done';
|
|
442
|
+
const unsubscribe = claudeProcess.subscribeOutput(taskId, (evt) => {
|
|
443
|
+
if (evt.kind === 'done' && evt.exitCode === 0) {
|
|
444
|
+
ts.updateTask(taskId, { status: targetStatus });
|
|
445
|
+
}
|
|
446
|
+
if (evt.kind === 'done' || evt.kind === 'error') {
|
|
447
|
+
unsubscribe();
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
return c.json({ taskId, started: true }, 201);
|
|
452
|
+
});
|
|
453
|
+
app.delete('/api/claude/tasks/:taskId/run', (c) => {
|
|
454
|
+
const taskId = Number(c.req.param('taskId'));
|
|
455
|
+
if (isNaN(taskId))
|
|
456
|
+
return c.json({ error: 'Invalid taskId' }, 400);
|
|
457
|
+
const stopped = claudeProcess.stopProcess(taskId);
|
|
458
|
+
if (!stopped)
|
|
459
|
+
return c.json({ error: 'No running process for this taskId' }, 404);
|
|
460
|
+
return c.json({ success: true });
|
|
461
|
+
});
|
|
462
|
+
app.get('/api/claude/tasks/:taskId/stream', (c) => {
|
|
463
|
+
const taskId = Number(c.req.param('taskId'));
|
|
464
|
+
if (isNaN(taskId)) {
|
|
465
|
+
return c.json({ error: 'Invalid taskId' }, 400);
|
|
466
|
+
}
|
|
467
|
+
const stream = new ReadableStream({
|
|
468
|
+
start(controller) {
|
|
469
|
+
const encode = (event, data) => {
|
|
470
|
+
const payload = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
|
|
471
|
+
return new TextEncoder().encode(payload);
|
|
472
|
+
};
|
|
473
|
+
const stop = claudeProcess.subscribeOutput(taskId, (evt) => {
|
|
474
|
+
if (evt.kind === 'text') {
|
|
475
|
+
controller.enqueue(encode('text', { text: evt.text }));
|
|
476
|
+
}
|
|
477
|
+
else if (evt.kind === 'tool_use') {
|
|
478
|
+
controller.enqueue(encode('tool_use', { name: evt.name, input: evt.input }));
|
|
479
|
+
}
|
|
480
|
+
else if (evt.kind === 'done') {
|
|
481
|
+
controller.enqueue(encode('end', { exitCode: evt.exitCode }));
|
|
482
|
+
controller.close();
|
|
483
|
+
}
|
|
484
|
+
else if (evt.kind === 'error') {
|
|
485
|
+
controller.enqueue(encode('error', { message: evt.message }));
|
|
486
|
+
controller.close();
|
|
487
|
+
}
|
|
488
|
+
});
|
|
489
|
+
c.req.raw.signal?.addEventListener('abort', () => {
|
|
490
|
+
stop();
|
|
491
|
+
controller.close();
|
|
492
|
+
});
|
|
493
|
+
},
|
|
494
|
+
});
|
|
495
|
+
return new Response(stream, {
|
|
496
|
+
headers: {
|
|
497
|
+
'Content-Type': 'text/event-stream',
|
|
498
|
+
'Cache-Control': 'no-cache',
|
|
499
|
+
Connection: 'keep-alive',
|
|
500
|
+
},
|
|
501
|
+
});
|
|
502
|
+
});
|
|
503
|
+
app.get('/api/running-tasks', (c) => {
|
|
504
|
+
const tasks = claudeProcess.listRunningTasks();
|
|
505
|
+
return c.json({ tasks });
|
|
506
|
+
});
|
|
507
|
+
app.get('/api/claude/tasks/:taskId/run-logs', (c) => {
|
|
508
|
+
const taskId = Number(c.req.param('taskId'));
|
|
509
|
+
if (isNaN(taskId))
|
|
510
|
+
return c.json({ error: 'Invalid taskId' }, 400);
|
|
511
|
+
if (!ts.getTask(taskId))
|
|
512
|
+
return c.json({ error: 'Task not found' }, 404);
|
|
513
|
+
const logs = claudeProcess.getRunLogs(taskId);
|
|
514
|
+
return c.json({ logs });
|
|
515
|
+
});
|
|
516
|
+
}
|
|
335
517
|
function registerBoardRoutes(app, services) {
|
|
336
518
|
const { ts, tts, tbs, database, boardTitle, configDir } = services;
|
|
519
|
+
app.use('*', async (c, next) => {
|
|
520
|
+
(0, logger_1.verboseLog)(`[boardRoutes] ${c.req.method} ${c.req.path}`);
|
|
521
|
+
await next();
|
|
522
|
+
(0, logger_1.verboseLog)(`[boardRoutes] ${c.req.method} ${c.req.path} -> ${c.res.status}`);
|
|
523
|
+
});
|
|
524
|
+
app.get('/static/board.js', (c) => {
|
|
525
|
+
const candidates = [
|
|
526
|
+
path.join(__dirname, 'client', 'board.js'),
|
|
527
|
+
path.join(__dirname, '..', '..', 'dist', 'board', 'client', 'board.js'),
|
|
528
|
+
];
|
|
529
|
+
for (const bundlePath of candidates) {
|
|
530
|
+
try {
|
|
531
|
+
const content = fs.readFileSync(bundlePath, 'utf8');
|
|
532
|
+
return new Response(content, {
|
|
533
|
+
headers: { 'Content-Type': 'application/javascript; charset=utf-8' },
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
catch {
|
|
537
|
+
// Try next candidate
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
return c.notFound();
|
|
541
|
+
});
|
|
337
542
|
app.get('/', (c) => {
|
|
338
|
-
const tasksByStatus = (0, boardRenderer_1.buildTasksByStatus)(ts.listTasks({}, 'id', 'asc'));
|
|
543
|
+
const tasksByStatus = (0, boardRenderer_1.buildTasksByStatus)(ts.listTasks({ status: NON_ARCHIVE_STATUSES }, 'id', 'asc'));
|
|
339
544
|
const boardConfig = (0, boardConfig_1.readBoardConfig)(configDir);
|
|
340
545
|
const blockMap = (0, boardRenderer_1.buildBlockMap)(tbs.getAllBlocks());
|
|
341
546
|
return c.html((0, boardRenderer_1.renderBoard)(tasksByStatus, tts.getAllTaskTags(), boardTitle, boardConfig.theme, blockMap));
|
|
@@ -355,5 +560,8 @@ function registerBoardRoutes(app, services) {
|
|
|
355
560
|
});
|
|
356
561
|
registerTaskApiRoutes(app, services);
|
|
357
562
|
registerConfigApiRoutes(app, configDir);
|
|
563
|
+
if (services.claudeProcessService) {
|
|
564
|
+
registerClaudeRoutes(app, services.claudeProcessService, ts);
|
|
565
|
+
}
|
|
358
566
|
}
|
|
359
567
|
//# sourceMappingURL=boardRoutes.js.map
|