profclaw 0.0.1-beta.1 → 0.0.1-beta.2
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 +1 -1
- package/dist/adapters/openclaw.js +1 -1
- package/dist/agents/executor.js +38 -6
- package/dist/auth/auth-service.js +8 -6
- package/dist/auth/device-identity.js +7 -5
- package/dist/auth/github-oauth.js +3 -1
- package/dist/auth/pairing-codes.js +6 -4
- package/dist/browser/service.js +5 -3
- package/dist/chat/execution/guardrails.js +3 -1
- package/dist/chat/execution/workflows/executor.js +4 -2
- package/dist/chat/memory.js +3 -1
- package/dist/chat/proactive/index.js +13 -11
- package/dist/chat/tools.js +8 -7
- package/dist/cli/commands/auth.js +22 -13
- package/dist/cli/commands/onboard.js +248 -59
- package/dist/cli/commands/setup.js +180 -104
- package/dist/cron/issue-poller.js +1 -1
- package/dist/hooks/agent-webhook.js +10 -7
- package/dist/hooks/prompt-submit.js +5 -6
- package/dist/hooks/session-end.js +10 -6
- package/dist/hooks/tool-use.js +9 -6
- package/dist/integrations/github-ticket-sync.js +8 -6
- package/dist/integrations/github.js +8 -6
- package/dist/integrations/jira.js +5 -3
- package/dist/mcp/server.js +12 -9
- package/dist/memory/experience-store.js +15 -14
- package/dist/notifications/slack.js +4 -2
- package/dist/providers/types.d.ts +2 -2
- package/dist/queue/failure-handler.js +15 -13
- package/dist/queue/index.js +6 -4
- package/dist/queue/memory-queue.js +23 -27
- package/dist/queue/task-queue.js +18 -22
- package/dist/routes/agents.js +3 -1
- package/dist/routes/auth.js +11 -9
- package/dist/routes/devices.js +17 -15
- package/dist/routes/gateway.js +3 -1
- package/dist/routes/hooks.js +7 -5
- package/dist/routes/import.js +10 -8
- package/dist/routes/labels.js +11 -9
- package/dist/routes/oobe.js +8 -6
- package/dist/routes/openapi.js +1 -1
- package/dist/routes/projects.js +27 -25
- package/dist/routes/settings.js +7 -5
- package/dist/routes/setup.js +12 -11
- package/dist/routes/slack.js +28 -27
- package/dist/routes/stats.js +6 -4
- package/dist/routes/summaries.js +4 -3
- package/dist/routes/sync.js +7 -5
- package/dist/routes/tasks.js +10 -8
- package/dist/routes/tickets.js +26 -26
- package/dist/routes/tokens.js +5 -3
- package/dist/routes/users.js +14 -12
- package/dist/routes/webhooks.js +5 -3
- package/dist/settings/index.js +3 -1
- package/dist/storage/index.d.ts +2 -1
- package/dist/storage/index.js +9 -4
- package/dist/storage/libsql.js +29 -21
- package/dist/storage/schema.d.ts +107 -46
- package/dist/summaries/storage.js +3 -1
- package/dist/tickets/index.js +10 -8
- package/dist/utils/circuit-breaker.js +10 -5
- package/dist/utils/logger.d.ts +5 -1
- package/dist/utils/logger.js +23 -7
- package/package.json +4 -3
- package/ui/dist/assets/{ActivityView-CkPgKhwm.js → ActivityView-DIPQSJ_d.js} +1 -1
- package/ui/dist/assets/{AgentList-C3SVdeEz.js → AgentList-CqyaYrcq.js} +1 -1
- package/ui/dist/assets/{AnalyticsDashboard-DVU--vlP.js → AnalyticsDashboard-C-mjuGHT.js} +1 -1
- package/ui/dist/assets/{AreaChart-B5qMEGWj.js → AreaChart-CfYWmbtr.js} +1 -1
- package/ui/dist/assets/{CartesianChart-B50bcUJi.js → CartesianChart-BaQ3It0c.js} +1 -1
- package/ui/dist/assets/{ChatView-BZFJs7w_.js → ChatView-DxxQy6pl.js} +1 -1
- package/ui/dist/assets/CostsDashboard-CDBBcGkg.js +1 -0
- package/ui/dist/assets/{EstimateSelect-CLpB4NQO.js → EstimateSelect-CDjf5qKl.js} +1 -1
- package/ui/dist/assets/{FloatingChatbot-CBzBY9a0.js → FloatingChatbot-CZHjvJIe.js} +1 -1
- package/ui/dist/assets/{InviteCodeManagement-DsbdPa6W.js → InviteCodeManagement-DTm-IPTm.js} +1 -1
- package/ui/dist/assets/{ProjectDetail-BEM3tFXg.js → ProjectDetail-DlYUcOss.js} +1 -1
- package/ui/dist/assets/{ProjectIcon-CN1FmFAk.js → ProjectIcon-BMRpnM04.js} +1 -1
- package/ui/dist/assets/{ProjectList-DSDaNhxQ.js → ProjectList-D85TN0i0.js} +1 -1
- package/ui/dist/assets/{Settings-dPVcqC_d.js → Settings-CgPqzUvj.js} +3 -3
- package/ui/dist/assets/{StatusIndicator-DA3NAo_b.js → StatusIndicator-yig0uZEA.js} +1 -1
- package/ui/dist/assets/{SummaryDetail-Bjnf9lT8.js → SummaryDetail-CwLAfHgJ.js} +1 -1
- package/ui/dist/assets/{SummaryList-ENwKDBKW.js → SummaryList-BvS5Idnu.js} +1 -1
- package/ui/dist/assets/{TaskDetail-DnwG6MzB.js → TaskDetail-zarC1fOt.js} +1 -1
- package/ui/dist/assets/{TaskList-D9Ug_HiV.js → TaskList-CyJq3ANE.js} +1 -1
- package/ui/dist/assets/{TicketBoard-CviH1571.js → TicketBoard-BlWr3-iH.js} +1 -1
- package/ui/dist/assets/{TicketDetail-8Jk8O-33.js → TicketDetail-DmqWKj2W.js} +1 -1
- package/ui/dist/assets/{TicketList-B-iV4rRA.js → TicketList-Scj4pMWa.js} +1 -1
- package/ui/dist/assets/{UserManagement-CPZ8s7s2.js → UserManagement-BH7uG7dw.js} +1 -1
- package/ui/dist/assets/{ViewSwitcher-BUyOOWDI.js → ViewSwitcher-3HzZUdWn.js} +1 -1
- package/ui/dist/assets/{alert-dialog-BOmnTkN-.js → alert-dialog-DWPb2IfQ.js} +1 -1
- package/ui/dist/assets/{archive-D5my9zOG.js → archive-CGck7gxR.js} +1 -1
- package/ui/dist/assets/{badge-B4ov81_m.js → badge-DEmc3Z_l.js} +1 -1
- package/ui/dist/assets/{brain-C53ElFLD.js → brain-CfFdLVqb.js} +1 -1
- package/ui/dist/assets/{bug-D0TJoCYn.js → bug-DqSGPUUE.js} +1 -1
- package/ui/dist/assets/{calendar-BkWIhKa1.js → calendar-BuZ4zbPW.js} +1 -1
- package/ui/dist/assets/{chevron-up-BRTtndUZ.js → chevron-up-DcJ4LL_N.js} +1 -1
- package/ui/dist/assets/{circle-x-BN89YhbS.js → circle-x-C78PNZjF.js} +1 -1
- package/ui/dist/assets/{constants-fc7TFI7u.js → constants-DhDjZe4P.js} +1 -1
- package/ui/dist/assets/{cpu-B41x1-vV.js → cpu-Ck6AoG8c.js} +1 -1
- package/ui/dist/assets/{database-D9Cnfmzj.js → database-CA2w8Lvt.js} +1 -1
- package/ui/dist/assets/{dialog-DrWB4EYD.js → dialog-BOdGWhgE.js} +1 -1
- package/ui/dist/assets/{ellipsis-NuUWekvu.js → ellipsis-FhHKRbfl.js} +1 -1
- package/ui/dist/assets/{ellipsis-vertical-BueMfuCw.js → ellipsis-vertical-CO0UqE4-.js} +1 -1
- package/ui/dist/assets/{file-code-HR9829Jc.js → file-code-ChnhYYj1.js} +1 -1
- package/ui/dist/assets/{folder-open-C_7oYEqe.js → folder-open-CHwA1-ve.js} +1 -1
- package/ui/dist/assets/{funnel-B5gmNXGf.js → funnel-ByEjRFNB.js} +1 -1
- package/ui/dist/assets/{git-branch-BRMiJmV3.js → git-branch-GTOPQgU4.js} +1 -1
- package/ui/dist/assets/{git-commit-horizontal-CXOUQeJI.js → git-commit-horizontal-F5M84Kut.js} +1 -1
- package/ui/dist/assets/{globe-CCspjvus.js → globe-CQWfr7hT.js} +1 -1
- package/ui/dist/assets/{hash-g3102kPC.js → hash-nKC9gtLg.js} +1 -1
- package/ui/dist/assets/{history-CNqcBBrV.js → history-DfFSA9xJ.js} +1 -1
- package/ui/dist/assets/{index-kb4AJXUB.js → index--JkIxVXb.js} +3 -3
- package/ui/dist/assets/index-Ca3vk7Gq.js +1 -0
- package/ui/dist/assets/{index-C9jNQXzL.js → index-DHGvP9mp.js} +1 -1
- package/ui/dist/assets/index-DeI8lKRR.js +1 -0
- package/ui/dist/assets/{index-DURTouJI.js → index-Z4-RtZcs.js} +1 -1
- package/ui/dist/assets/{index-CEZ6R2Uw.js → index-a4Fxq0Hb.js} +1 -1
- package/ui/dist/assets/{layers-CLXiHN6o.js → layers-DFeLExSa.js} +1 -1
- package/ui/dist/assets/{layout-dashboard-B07MFhBs.js → layout-dashboard-WmgjMhWF.js} +1 -1
- package/ui/dist/assets/{lightbulb-B2dgG5ks.js → lightbulb-Bo8hEr7B.js} +1 -1
- package/ui/dist/assets/{link-2-BxNmr9hL.js → link-2-YqrpQXBH.js} +1 -1
- package/ui/dist/assets/{markdown-renderer-CjU6hBcW.js → markdown-renderer-Croje6Xe.js} +1 -1
- package/ui/dist/assets/{message-square-Bf2-CVbt.js → message-square-CD0H5hot.js} +1 -1
- package/ui/dist/assets/{pencil-D096Ey62.js → pencil-DpFnj5dn.js} +1 -1
- package/ui/dist/assets/{play-DfdcSI3x.js → play-DVgea_jT.js} +1 -1
- package/ui/dist/assets/{popover-BV0QJDQq.js → popover-JXecfWG5.js} +1 -1
- package/ui/dist/assets/{progress-DjPEDJfI.js → progress-C1ghf1Fu.js} +1 -1
- package/ui/dist/assets/{rocket-CPsTc-5G.js → rocket-BFxPYGx9.js} +1 -1
- package/ui/dist/assets/{select-LsO16slr.js → select-MADP8m6Q.js} +1 -1
- package/ui/dist/assets/{send-BDYBZDUZ.js → send-eYnW_7n-.js} +1 -1
- package/ui/dist/assets/{server-B3k6noce.js → server-CPMaysH8.js} +1 -1
- package/ui/dist/assets/{settings-2-Cu4xTjhG.js → settings-2-scXUOuE_.js} +1 -1
- package/ui/dist/assets/{sheet-BScLnPKX.js → sheet-r6NSOxi-.js} +1 -1
- package/ui/dist/assets/{shield-check-CQqkwufI.js → shield-check-PEr7nmVw.js} +1 -1
- package/ui/dist/assets/{shield-off-ZFruH9KO.js → shield-off-CLtXio62.js} +1 -1
- package/ui/dist/assets/{skeleton-CtkIA_MU.js → skeleton-C9oEzNlU.js} +1 -1
- package/ui/dist/assets/{smartphone-DnoksVkc.js → smartphone-DusFfY0U.js} +1 -1
- package/ui/dist/assets/{square-uD9ZHMfW.js → square-e1yxB2eR.js} +1 -1
- package/ui/dist/assets/{switch-MQPnwGJK.js → switch-tNs0n-kz.js} +1 -1
- package/ui/dist/assets/{table-B8cqlywA.js → table-CXxtLicg.js} +1 -1
- package/ui/dist/assets/{tag-wEJQRWlV.js → tag-tAwMmQ9G.js} +1 -1
- package/ui/dist/assets/{textarea-D5LJCOGl.js → textarea-BjiEeIWh.js} +1 -1
- package/ui/dist/assets/{timer-mbGHegmr.js → timer-Vel1N3RP.js} +1 -1
- package/ui/dist/assets/{tooltip-Df1CunSp.js → tooltip-ZMwtfr1J.js} +1 -1
- package/ui/dist/assets/{trash-2-B4oAXsX-.js → trash-2-eM-CNwsZ.js} +1 -1
- package/ui/dist/assets/{trending-up-BGWxvlmZ.js → trending-up-BGafmjRo.js} +1 -1
- package/ui/dist/assets/{wand-sparkles-CZy4xvL3.js → wand-sparkles-DPvcd9Pi.js} +1 -1
- package/ui/dist/assets/{wrench-ByZkjO6m.js → wrench-B8s3zYVV.js} +1 -1
- package/ui/dist/index.html +1 -1
- package/ui/dist/assets/CostsDashboard-ChfH8BlG.js +0 -1
- package/ui/dist/assets/index-27mTPKuh.js +0 -1
- package/ui/dist/assets/index-BMx3fH-e.js +0 -1
package/dist/routes/slack.js
CHANGED
|
@@ -11,6 +11,8 @@ import { createHmac, timingSafeEqual, randomUUID } from "crypto";
|
|
|
11
11
|
import { getDb } from "../storage/index.js";
|
|
12
12
|
import { tickets, projects } from "../storage/schema.js";
|
|
13
13
|
import { eq, desc, like } from "drizzle-orm";
|
|
14
|
+
import { createContextualLogger } from "../utils/logger.js";
|
|
15
|
+
const log = createContextualLogger('Slack');
|
|
14
16
|
import { getWebhookDedupValue, isDuplicateWebhookEvent, setWebhookDedupValue, } from "./webhook-dedup.js";
|
|
15
17
|
const slack = new Hono();
|
|
16
18
|
// Configuration
|
|
@@ -37,7 +39,7 @@ function verifySlackSignature(signingSecret, signature, timestamp, body) {
|
|
|
37
39
|
// Check timestamp is within 5 minutes
|
|
38
40
|
const fiveMinutesAgo = Math.floor(Date.now() / 1000) - 60 * 5;
|
|
39
41
|
if (parseInt(timestamp, 10) < fiveMinutesAgo) {
|
|
40
|
-
|
|
42
|
+
log.warn('Request timestamp too old');
|
|
41
43
|
return false;
|
|
42
44
|
}
|
|
43
45
|
const sigBasestring = `v0:${timestamp}:${body}`;
|
|
@@ -107,7 +109,7 @@ function extractInlineCommand(text) {
|
|
|
107
109
|
}
|
|
108
110
|
async function postSlackResponse(options) {
|
|
109
111
|
if (!SLACK_BOT_TOKEN) {
|
|
110
|
-
|
|
112
|
+
log.warn('Missing SLACK_BOT_TOKEN for inline command response');
|
|
111
113
|
return;
|
|
112
114
|
}
|
|
113
115
|
const url = options.ephemeral && options.userId
|
|
@@ -135,7 +137,7 @@ async function postSlackResponse(options) {
|
|
|
135
137
|
body: JSON.stringify(payload),
|
|
136
138
|
});
|
|
137
139
|
if (!res.ok) {
|
|
138
|
-
|
|
140
|
+
log.warn('Failed to post response', { status: res.status });
|
|
139
141
|
}
|
|
140
142
|
}
|
|
141
143
|
// COMMAND HANDLERS
|
|
@@ -204,19 +206,18 @@ async function handleTicketList(args) {
|
|
|
204
206
|
try {
|
|
205
207
|
const limit = parseInt(args.limit || "5", 10);
|
|
206
208
|
const status = args.status;
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
.from(tickets)
|
|
210
|
-
.orderBy(desc(tickets.createdAt))
|
|
211
|
-
.limit(limit);
|
|
212
|
-
if (status) {
|
|
213
|
-
query = db
|
|
209
|
+
const query = status
|
|
210
|
+
? db
|
|
214
211
|
.select()
|
|
215
212
|
.from(tickets)
|
|
216
213
|
.where(eq(tickets.status, status))
|
|
217
214
|
.orderBy(desc(tickets.createdAt))
|
|
215
|
+
.limit(limit)
|
|
216
|
+
: db
|
|
217
|
+
.select()
|
|
218
|
+
.from(tickets)
|
|
219
|
+
.orderBy(desc(tickets.createdAt))
|
|
218
220
|
.limit(limit);
|
|
219
|
-
}
|
|
220
221
|
const results = await query;
|
|
221
222
|
if (results.length === 0) {
|
|
222
223
|
return {
|
|
@@ -257,7 +258,7 @@ async function handleTicketList(args) {
|
|
|
257
258
|
};
|
|
258
259
|
}
|
|
259
260
|
catch (error) {
|
|
260
|
-
|
|
261
|
+
log.error('Error listing tickets', error instanceof Error ? error : new Error(String(error)));
|
|
261
262
|
return {
|
|
262
263
|
response_type: resolveDefaultResponseType(),
|
|
263
264
|
text: "❌ Failed to list tickets",
|
|
@@ -290,7 +291,7 @@ async function handleTicketCreate(args, userId, userName) {
|
|
|
290
291
|
const nextSequence = (lastTicket[0]?.sequence || 0) + 1;
|
|
291
292
|
// Map priority
|
|
292
293
|
const priorityMap = {
|
|
293
|
-
urgent: "
|
|
294
|
+
urgent: "critical",
|
|
294
295
|
high: "high",
|
|
295
296
|
medium: "medium",
|
|
296
297
|
low: "low",
|
|
@@ -302,13 +303,13 @@ async function handleTicketCreate(args, userId, userName) {
|
|
|
302
303
|
bug: "bug",
|
|
303
304
|
feature: "feature",
|
|
304
305
|
task: "task",
|
|
305
|
-
improvement: "
|
|
306
|
+
improvement: "feature",
|
|
306
307
|
epic: "epic",
|
|
307
308
|
};
|
|
308
309
|
const type = typeMap[args.type?.toLowerCase() || "task"] || "task";
|
|
309
310
|
const ticketId = randomUUID();
|
|
310
311
|
const now = new Date();
|
|
311
|
-
|
|
312
|
+
const ticketRow = {
|
|
312
313
|
id: ticketId,
|
|
313
314
|
sequence: nextSequence,
|
|
314
315
|
title,
|
|
@@ -316,11 +317,11 @@ async function handleTicketCreate(args, userId, userName) {
|
|
|
316
317
|
status: "backlog",
|
|
317
318
|
priority,
|
|
318
319
|
type,
|
|
319
|
-
createdBy:
|
|
320
|
-
createdByName: userName,
|
|
320
|
+
createdBy: "human",
|
|
321
321
|
createdAt: now,
|
|
322
322
|
updatedAt: now,
|
|
323
|
-
}
|
|
323
|
+
};
|
|
324
|
+
await db.insert(tickets).values(ticketRow);
|
|
324
325
|
return {
|
|
325
326
|
response_type: SLACK_SLASH_EPHEMERAL ? "ephemeral" : "in_channel",
|
|
326
327
|
blocks: [
|
|
@@ -345,7 +346,7 @@ async function handleTicketCreate(args, userId, userName) {
|
|
|
345
346
|
};
|
|
346
347
|
}
|
|
347
348
|
catch (error) {
|
|
348
|
-
|
|
349
|
+
log.error('Error creating ticket', error instanceof Error ? error : new Error(String(error)), { userId, userName });
|
|
349
350
|
return {
|
|
350
351
|
response_type: resolveDefaultResponseType(),
|
|
351
352
|
text: "❌ Failed to create ticket",
|
|
@@ -436,7 +437,7 @@ async function handleTicketShow(ticketRef) {
|
|
|
436
437
|
};
|
|
437
438
|
}
|
|
438
439
|
catch (error) {
|
|
439
|
-
|
|
440
|
+
log.error('Error showing ticket', error instanceof Error ? error : new Error(String(error)));
|
|
440
441
|
return {
|
|
441
442
|
response_type: resolveDefaultResponseType(),
|
|
442
443
|
text: "❌ Failed to fetch ticket",
|
|
@@ -493,7 +494,7 @@ async function handleTicketSearch(query) {
|
|
|
493
494
|
};
|
|
494
495
|
}
|
|
495
496
|
catch (error) {
|
|
496
|
-
|
|
497
|
+
log.error('Error searching tickets', error instanceof Error ? error : new Error(String(error)));
|
|
497
498
|
return {
|
|
498
499
|
response_type: resolveDefaultResponseType(),
|
|
499
500
|
text: "❌ Failed to search tickets",
|
|
@@ -544,7 +545,7 @@ async function handleProjectList() {
|
|
|
544
545
|
};
|
|
545
546
|
}
|
|
546
547
|
catch (error) {
|
|
547
|
-
|
|
548
|
+
log.error('Error listing projects', error instanceof Error ? error : new Error(String(error)));
|
|
548
549
|
return {
|
|
549
550
|
response_type: resolveDefaultResponseType(),
|
|
550
551
|
text: "❌ Failed to list projects",
|
|
@@ -621,7 +622,7 @@ async function handleProjectShow(projectKey) {
|
|
|
621
622
|
};
|
|
622
623
|
}
|
|
623
624
|
catch (error) {
|
|
624
|
-
|
|
625
|
+
log.error('Error showing project', error instanceof Error ? error : new Error(String(error)));
|
|
625
626
|
return {
|
|
626
627
|
response_type: resolveDefaultResponseType(),
|
|
627
628
|
text: "❌ Failed to fetch project",
|
|
@@ -731,7 +732,7 @@ slack.post("/commands", async (c) => {
|
|
|
731
732
|
if (SLACK_SIGNING_SECRET) {
|
|
732
733
|
const isValid = verifySlackSignature(SLACK_SIGNING_SECRET, signature, timestamp, rawBody);
|
|
733
734
|
if (!isValid) {
|
|
734
|
-
|
|
735
|
+
log.warn('Invalid signature');
|
|
735
736
|
return c.json({ error: "Invalid signature" }, 401);
|
|
736
737
|
}
|
|
737
738
|
}
|
|
@@ -751,7 +752,7 @@ slack.post("/commands", async (c) => {
|
|
|
751
752
|
trigger_id: params.get("trigger_id") || "",
|
|
752
753
|
api_app_id: params.get("api_app_id") || "",
|
|
753
754
|
};
|
|
754
|
-
|
|
755
|
+
log.info('Command received', { command: command.command, text: command.text, user: command.user_name });
|
|
755
756
|
const commandName = normalizeSlackCommandName(command.command);
|
|
756
757
|
if (commandName !== SLACK_COMMAND_NAME.toLowerCase()) {
|
|
757
758
|
return c.json({ error: "Unknown command" }, 404);
|
|
@@ -835,7 +836,7 @@ slack.post("/commands", async (c) => {
|
|
|
835
836
|
}
|
|
836
837
|
}
|
|
837
838
|
catch (error) {
|
|
838
|
-
|
|
839
|
+
log.error('Command error', error instanceof Error ? error : new Error(String(error)));
|
|
839
840
|
response = {
|
|
840
841
|
response_type: resolveDefaultResponseType(),
|
|
841
842
|
text: "❌ An error occurred processing your command",
|
|
@@ -871,7 +872,7 @@ slack.post("/interactive", async (c) => {
|
|
|
871
872
|
if (cachedResponse) {
|
|
872
873
|
return c.json(cachedResponse);
|
|
873
874
|
}
|
|
874
|
-
|
|
875
|
+
log.info('Interactive event received', { type: payload.type, actionId: payload.actions?.[0]?.action_id });
|
|
875
876
|
// Handle different interaction types
|
|
876
877
|
if (payload.type === "block_actions") {
|
|
877
878
|
const action = payload.actions?.[0];
|
package/dist/routes/stats.js
CHANGED
|
@@ -5,7 +5,9 @@ import { Hono } from 'hono';
|
|
|
5
5
|
import { getDb } from '../storage/index.js';
|
|
6
6
|
import { tasks, tickets, summaries, projects, sprints } from '../storage/schema.js';
|
|
7
7
|
import { eq, and, sql } from 'drizzle-orm';
|
|
8
|
+
import { createContextualLogger } from '../utils/logger.js';
|
|
8
9
|
export const statsRoutes = new Hono();
|
|
10
|
+
const log = createContextualLogger('Stats');
|
|
9
11
|
/**
|
|
10
12
|
* GET /api/stats/dashboard - Get comprehensive dashboard statistics
|
|
11
13
|
*/
|
|
@@ -144,7 +146,7 @@ statsRoutes.get('/dashboard', async (c) => {
|
|
|
144
146
|
});
|
|
145
147
|
}
|
|
146
148
|
catch (error) {
|
|
147
|
-
|
|
149
|
+
log.error('Error fetching dashboard stats', error instanceof Error ? error : new Error(String(error)));
|
|
148
150
|
return c.json({
|
|
149
151
|
tasks: { total: 0, pending: 0, queued: 0, inProgress: 0, completed: 0, failed: 0, cancelled: 0 },
|
|
150
152
|
tickets: { total: 0, open: 0, inProgress: 0, done: 0, byType: {}, byPriority: {}, aiCreated: 0 },
|
|
@@ -259,7 +261,7 @@ statsRoutes.get('/sprints/:id/burndown', async (c) => {
|
|
|
259
261
|
});
|
|
260
262
|
}
|
|
261
263
|
catch (error) {
|
|
262
|
-
|
|
264
|
+
log.error('Error fetching sprint burndown', error instanceof Error ? error : new Error(String(error)));
|
|
263
265
|
return c.json({ error: 'Failed to fetch sprint burndown' }, 500);
|
|
264
266
|
}
|
|
265
267
|
});
|
|
@@ -315,7 +317,7 @@ statsRoutes.get('/projects/:id/velocity', async (c) => {
|
|
|
315
317
|
});
|
|
316
318
|
}
|
|
317
319
|
catch (error) {
|
|
318
|
-
|
|
320
|
+
log.error('Error fetching project velocity', error instanceof Error ? error : new Error(String(error)));
|
|
319
321
|
return c.json({ error: 'Failed to fetch velocity data' }, 500);
|
|
320
322
|
}
|
|
321
323
|
});
|
|
@@ -362,7 +364,7 @@ statsRoutes.get('/projects/:id', async (c) => {
|
|
|
362
364
|
});
|
|
363
365
|
}
|
|
364
366
|
catch (error) {
|
|
365
|
-
|
|
367
|
+
log.error('Error fetching project stats', error instanceof Error ? error : new Error(String(error)));
|
|
366
368
|
return c.json({ error: 'Failed to fetch project stats' }, 500);
|
|
367
369
|
}
|
|
368
370
|
});
|
package/dist/routes/summaries.js
CHANGED
|
@@ -3,8 +3,9 @@ import { createSummary, getSummary, querySummaries, searchSummaries, getSummaryS
|
|
|
3
3
|
import { generatePRDescription, generateChangelog, generateReleaseNotes, generateCommitMessage, TASK_TYPE_TEMPLATES, } from '../summaries/templates.js';
|
|
4
4
|
import { getEmbeddingService } from '../ai/embedding-service.js';
|
|
5
5
|
import { getStorage } from '../storage/index.js';
|
|
6
|
-
import {
|
|
6
|
+
import { createContextualLogger } from '../utils/logger.js';
|
|
7
7
|
const summaries = new Hono();
|
|
8
|
+
const log = createContextualLogger('Summaries');
|
|
8
9
|
// Sparse fieldset: default fields for list view (Phase 17 optimization)
|
|
9
10
|
const SUMMARY_LIST_FIELDS = [
|
|
10
11
|
'id', 'taskId', 'sessionId', 'agent', 'model', 'title', 'taskType', 'component',
|
|
@@ -109,7 +110,7 @@ summaries.get('/semantic', async (c) => {
|
|
|
109
110
|
});
|
|
110
111
|
}
|
|
111
112
|
catch (error) {
|
|
112
|
-
|
|
113
|
+
log.error('Semantic search error', error instanceof Error ? error : new Error(String(error)));
|
|
113
114
|
return c.json({ error: 'Search failed', message: error.message }, 500);
|
|
114
115
|
}
|
|
115
116
|
});
|
|
@@ -253,7 +254,7 @@ summaries.post('/', async (c) => {
|
|
|
253
254
|
}, 201);
|
|
254
255
|
}
|
|
255
256
|
catch (error) {
|
|
256
|
-
|
|
257
|
+
log.error('Error creating summary', error instanceof Error ? error : new Error(String(error)));
|
|
257
258
|
return c.json({
|
|
258
259
|
error: 'Failed to create summary',
|
|
259
260
|
message: error instanceof Error ? error.message : 'Unknown error',
|
package/dist/routes/sync.js
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* - POST /api/sync/trigger
|
|
9
9
|
*/
|
|
10
10
|
import { Hono } from 'hono';
|
|
11
|
+
import { createContextualLogger } from '../utils/logger.js';
|
|
12
|
+
const log = createContextualLogger('Sync');
|
|
11
13
|
import { handleSyncWebhook, pushTicketToExternal, getSyncStatus } from '../sync/integration.js';
|
|
12
14
|
import { hasSyncEngine, getSyncEngine } from '../sync/engine.js';
|
|
13
15
|
import { loadSyncConfig } from '../sync/config.js';
|
|
@@ -73,7 +75,7 @@ syncRoutes.post('/webhook/linear', async (c) => {
|
|
|
73
75
|
// Verify signature if secret is configured
|
|
74
76
|
if (linearConfig.webhookSecret) {
|
|
75
77
|
if (!verifyLinearSignature(rawBody, signature, linearConfig.webhookSecret)) {
|
|
76
|
-
|
|
78
|
+
log.warn('Invalid Linear webhook signature');
|
|
77
79
|
return c.json({ error: 'Invalid signature' }, 401);
|
|
78
80
|
}
|
|
79
81
|
}
|
|
@@ -111,7 +113,7 @@ syncRoutes.post('/webhook/github', async (c) => {
|
|
|
111
113
|
// Verify signature if secret is configured
|
|
112
114
|
if (githubConfig.webhookSecret) {
|
|
113
115
|
if (!verifyGitHubSignature(rawBody, signature, githubConfig.webhookSecret)) {
|
|
114
|
-
|
|
116
|
+
log.warn('Invalid GitHub webhook signature');
|
|
115
117
|
return c.json({ error: 'Invalid signature' }, 401);
|
|
116
118
|
}
|
|
117
119
|
}
|
|
@@ -133,7 +135,7 @@ syncRoutes.post('/webhook/github', async (c) => {
|
|
|
133
135
|
try {
|
|
134
136
|
const ticketSyncResult = await processGitHubWebhookForTicketSync(eventType, payload);
|
|
135
137
|
if (ticketSyncResult.action !== 'ignored') {
|
|
136
|
-
|
|
138
|
+
log.info('GitHub ticket sync', { action: ticketSyncResult.action, result: ticketSyncResult });
|
|
137
139
|
return c.json({
|
|
138
140
|
message: `Ticket sync: ${ticketSyncResult.action}`,
|
|
139
141
|
ticketId: ticketSyncResult.ticketId,
|
|
@@ -142,7 +144,7 @@ syncRoutes.post('/webhook/github', async (c) => {
|
|
|
142
144
|
}
|
|
143
145
|
}
|
|
144
146
|
catch (error) {
|
|
145
|
-
|
|
147
|
+
log.error('Ticket sync error (falling back to legacy)', error instanceof Error ? error : new Error(String(error)));
|
|
146
148
|
}
|
|
147
149
|
// Fallback to legacy sync webhook handler (for sync engine)
|
|
148
150
|
const result = await handleSyncWebhook('github', payload);
|
|
@@ -203,7 +205,7 @@ syncRoutes.post('/trigger', async (c) => {
|
|
|
203
205
|
}
|
|
204
206
|
}
|
|
205
207
|
catch (error) {
|
|
206
|
-
|
|
208
|
+
log.error('Sync trigger failed', error instanceof Error ? error : new Error(String(error)));
|
|
207
209
|
return c.json({
|
|
208
210
|
error: error instanceof Error ? error.message : 'Sync failed',
|
|
209
211
|
}, 500);
|
package/dist/routes/tasks.js
CHANGED
|
@@ -2,7 +2,9 @@ import { Hono } from 'hono';
|
|
|
2
2
|
import { addTask, getTask, getTasks, cancelTask, retryTask } from '../queue/index.js';
|
|
3
3
|
import { CreateTaskSchema, TaskStatus } from '../types/task.js';
|
|
4
4
|
import { getStorage } from '../storage/index.js';
|
|
5
|
+
import { createContextualLogger } from '../utils/logger.js';
|
|
5
6
|
const tasks = new Hono();
|
|
7
|
+
const log = createContextualLogger('TasksRoutes');
|
|
6
8
|
const validTaskStatuses = new Set(Object.values(TaskStatus));
|
|
7
9
|
async function parseJsonBody(c) {
|
|
8
10
|
try {
|
|
@@ -119,7 +121,7 @@ tasks.get('/', async (c) => {
|
|
|
119
121
|
});
|
|
120
122
|
}
|
|
121
123
|
catch (error) {
|
|
122
|
-
|
|
124
|
+
log.error('Error loading tasks from DB, falling back to in-memory', error instanceof Error ? error : new Error(String(error)));
|
|
123
125
|
}
|
|
124
126
|
}
|
|
125
127
|
// Fallback to in-memory queue (no cursor support for in-memory)
|
|
@@ -164,7 +166,7 @@ tasks.post('/', async (c) => {
|
|
|
164
166
|
}, 201);
|
|
165
167
|
}
|
|
166
168
|
catch (error) {
|
|
167
|
-
|
|
169
|
+
log.error('Error creating task', error instanceof Error ? error : new Error(String(error)));
|
|
168
170
|
return c.json({
|
|
169
171
|
error: 'Failed to create task',
|
|
170
172
|
message: error instanceof Error ? error.message : 'Unknown error',
|
|
@@ -182,7 +184,7 @@ tasks.get('/analytics', async (c) => {
|
|
|
182
184
|
return c.json(analytics);
|
|
183
185
|
}
|
|
184
186
|
catch (error) {
|
|
185
|
-
|
|
187
|
+
log.error('Error getting task analytics', error instanceof Error ? error : new Error(String(error)));
|
|
186
188
|
return c.json({
|
|
187
189
|
error: 'Failed to get analytics',
|
|
188
190
|
message: error instanceof Error ? error.message : 'Unknown error',
|
|
@@ -251,7 +253,7 @@ tasks.get('/filter', async (c) => {
|
|
|
251
253
|
});
|
|
252
254
|
}
|
|
253
255
|
catch (error) {
|
|
254
|
-
|
|
256
|
+
log.error('Error filtering tasks', error instanceof Error ? error : new Error(String(error)));
|
|
255
257
|
return c.json({
|
|
256
258
|
error: 'Failed to filter tasks',
|
|
257
259
|
message: error instanceof Error ? error.message : 'Unknown error',
|
|
@@ -276,7 +278,7 @@ tasks.get('/archived', async (c) => {
|
|
|
276
278
|
});
|
|
277
279
|
}
|
|
278
280
|
catch (error) {
|
|
279
|
-
|
|
281
|
+
log.error('Error getting archived tasks', error instanceof Error ? error : new Error(String(error)));
|
|
280
282
|
return c.json({
|
|
281
283
|
error: 'Failed to get archived tasks',
|
|
282
284
|
message: error instanceof Error ? error.message : 'Unknown error',
|
|
@@ -306,7 +308,7 @@ tasks.post('/archive', async (c) => {
|
|
|
306
308
|
});
|
|
307
309
|
}
|
|
308
310
|
catch (error) {
|
|
309
|
-
|
|
311
|
+
log.error('Error archiving tasks', error instanceof Error ? error : new Error(String(error)));
|
|
310
312
|
return c.json({
|
|
311
313
|
error: 'Failed to archive tasks',
|
|
312
314
|
message: error instanceof Error ? error.message : 'Unknown error',
|
|
@@ -400,7 +402,7 @@ tasks.post('/import', async (c) => {
|
|
|
400
402
|
});
|
|
401
403
|
}
|
|
402
404
|
catch (error) {
|
|
403
|
-
|
|
405
|
+
log.error('Error importing tasks', error instanceof Error ? error : new Error(String(error)));
|
|
404
406
|
return c.json({
|
|
405
407
|
error: 'Import failed',
|
|
406
408
|
message: error instanceof Error ? error.message : 'Unknown error',
|
|
@@ -436,7 +438,7 @@ tasks.get('/:id/events', async (c) => {
|
|
|
436
438
|
});
|
|
437
439
|
}
|
|
438
440
|
catch (error) {
|
|
439
|
-
|
|
441
|
+
log.error('Error getting task events', error instanceof Error ? error : new Error(String(error)));
|
|
440
442
|
return c.json({
|
|
441
443
|
error: 'Failed to get task events',
|
|
442
444
|
message: error instanceof Error ? error.message : 'Unknown error',
|
package/dist/routes/tickets.js
CHANGED
|
@@ -389,7 +389,7 @@ ticketsRouter.get("/:id/history", async (c) => {
|
|
|
389
389
|
return c.json({ ticketId: id, history, count: history.length });
|
|
390
390
|
}
|
|
391
391
|
catch (error) {
|
|
392
|
-
|
|
392
|
+
log.error('Error fetching history', error instanceof Error ? error : new Error(String(error)));
|
|
393
393
|
return c.json({ error: "Failed to fetch history" }, 500);
|
|
394
394
|
}
|
|
395
395
|
});
|
|
@@ -405,7 +405,7 @@ ticketsRouter.get("/:id/relations", async (c) => {
|
|
|
405
405
|
return c.json({ ticketId: id, relations, count: relations.length });
|
|
406
406
|
}
|
|
407
407
|
catch (error) {
|
|
408
|
-
|
|
408
|
+
log.error('Error fetching relations', error instanceof Error ? error : new Error(String(error)));
|
|
409
409
|
return c.json({ error: "Failed to fetch relations" }, 500);
|
|
410
410
|
}
|
|
411
411
|
});
|
|
@@ -441,7 +441,7 @@ ticketsRouter.post("/:id/relations", async (c) => {
|
|
|
441
441
|
}, 201);
|
|
442
442
|
}
|
|
443
443
|
catch (error) {
|
|
444
|
-
|
|
444
|
+
log.error('Error creating relation', error instanceof Error ? error : new Error(String(error)));
|
|
445
445
|
return c.json({ error: "Failed to create relation" }, 500);
|
|
446
446
|
}
|
|
447
447
|
});
|
|
@@ -460,7 +460,7 @@ ticketsRouter.delete("/:id/relations/:relationId", async (c) => {
|
|
|
460
460
|
return c.json({ message: "Relation deleted" });
|
|
461
461
|
}
|
|
462
462
|
catch (error) {
|
|
463
|
-
|
|
463
|
+
log.error('Error deleting relation', error instanceof Error ? error : new Error(String(error)));
|
|
464
464
|
return c.json({ error: "Failed to delete relation" }, 500);
|
|
465
465
|
}
|
|
466
466
|
});
|
|
@@ -476,7 +476,7 @@ ticketsRouter.get("/:id/watchers", async (c) => {
|
|
|
476
476
|
return c.json({ ticketId: id, watchers, count: watchers.length });
|
|
477
477
|
}
|
|
478
478
|
catch (error) {
|
|
479
|
-
|
|
479
|
+
log.error('Error fetching watchers', error instanceof Error ? error : new Error(String(error)));
|
|
480
480
|
return c.json({ error: "Failed to fetch watchers" }, 500);
|
|
481
481
|
}
|
|
482
482
|
});
|
|
@@ -496,7 +496,7 @@ ticketsRouter.post("/:id/watchers", async (c) => {
|
|
|
496
496
|
return c.json({ message: "Watcher added", watcher }, 201);
|
|
497
497
|
}
|
|
498
498
|
catch (error) {
|
|
499
|
-
|
|
499
|
+
log.error('Error adding watcher', error instanceof Error ? error : new Error(String(error)));
|
|
500
500
|
return c.json({ error: "Failed to add watcher" }, 500);
|
|
501
501
|
}
|
|
502
502
|
});
|
|
@@ -515,7 +515,7 @@ ticketsRouter.delete("/:id/watchers/:userId", async (c) => {
|
|
|
515
515
|
return c.json({ message: "Watcher removed" });
|
|
516
516
|
}
|
|
517
517
|
catch (error) {
|
|
518
|
-
|
|
518
|
+
log.error('Error removing watcher', error instanceof Error ? error : new Error(String(error)));
|
|
519
519
|
return c.json({ error: "Failed to remove watcher" }, 500);
|
|
520
520
|
}
|
|
521
521
|
});
|
|
@@ -531,7 +531,7 @@ ticketsRouter.get("/:id/assignees", async (c) => {
|
|
|
531
531
|
return c.json({ ticketId: id, assignees, count: assignees.length });
|
|
532
532
|
}
|
|
533
533
|
catch (error) {
|
|
534
|
-
|
|
534
|
+
log.error('Error fetching assignees', error instanceof Error ? error : new Error(String(error)));
|
|
535
535
|
return c.json({ error: "Failed to fetch assignees" }, 500);
|
|
536
536
|
}
|
|
537
537
|
});
|
|
@@ -551,7 +551,7 @@ ticketsRouter.post("/:id/assignees", async (c) => {
|
|
|
551
551
|
return c.json({ message: "Assignee added", assignee }, 201);
|
|
552
552
|
}
|
|
553
553
|
catch (error) {
|
|
554
|
-
|
|
554
|
+
log.error('Error adding assignee', error instanceof Error ? error : new Error(String(error)));
|
|
555
555
|
return c.json({ error: "Failed to add assignee" }, 500);
|
|
556
556
|
}
|
|
557
557
|
});
|
|
@@ -570,7 +570,7 @@ ticketsRouter.delete("/:id/assignees/:userId", async (c) => {
|
|
|
570
570
|
return c.json({ message: "Assignee removed" });
|
|
571
571
|
}
|
|
572
572
|
catch (error) {
|
|
573
|
-
|
|
573
|
+
log.error('Error removing assignee', error instanceof Error ? error : new Error(String(error)));
|
|
574
574
|
return c.json({ error: "Failed to remove assignee" }, 500);
|
|
575
575
|
}
|
|
576
576
|
});
|
|
@@ -586,7 +586,7 @@ ticketsRouter.get("/:id/mentions", async (c) => {
|
|
|
586
586
|
return c.json({ ticketId: id, mentions, count: mentions.length });
|
|
587
587
|
}
|
|
588
588
|
catch (error) {
|
|
589
|
-
|
|
589
|
+
log.error('Error fetching mentions', error instanceof Error ? error : new Error(String(error)));
|
|
590
590
|
return c.json({ error: "Failed to fetch mentions" }, 500);
|
|
591
591
|
}
|
|
592
592
|
});
|
|
@@ -611,7 +611,7 @@ ticketsRouter.post("/:id/mentions", async (c) => {
|
|
|
611
611
|
return c.json({ message: "Mention added", mention }, 201);
|
|
612
612
|
}
|
|
613
613
|
catch (error) {
|
|
614
|
-
|
|
614
|
+
log.error('Error adding mention', error instanceof Error ? error : new Error(String(error)));
|
|
615
615
|
return c.json({ error: "Failed to add mention" }, 500);
|
|
616
616
|
}
|
|
617
617
|
});
|
|
@@ -627,7 +627,7 @@ ticketsRouter.get("/:id/attachments", async (c) => {
|
|
|
627
627
|
return c.json({ ticketId: id, attachments, count: attachments.length });
|
|
628
628
|
}
|
|
629
629
|
catch (error) {
|
|
630
|
-
|
|
630
|
+
log.error('Error fetching attachments', error instanceof Error ? error : new Error(String(error)));
|
|
631
631
|
return c.json({ error: "Failed to fetch attachments" }, 500);
|
|
632
632
|
}
|
|
633
633
|
});
|
|
@@ -662,7 +662,7 @@ ticketsRouter.post("/:id/attachments", async (c) => {
|
|
|
662
662
|
return c.json({ message: "Attachment added", attachment }, 201);
|
|
663
663
|
}
|
|
664
664
|
catch (error) {
|
|
665
|
-
|
|
665
|
+
log.error('Error adding attachment', error instanceof Error ? error : new Error(String(error)));
|
|
666
666
|
return c.json({ error: "Failed to add attachment" }, 500);
|
|
667
667
|
}
|
|
668
668
|
});
|
|
@@ -681,7 +681,7 @@ ticketsRouter.delete("/:id/attachments/:attachmentId", async (c) => {
|
|
|
681
681
|
return c.json({ message: "Attachment deleted" });
|
|
682
682
|
}
|
|
683
683
|
catch (error) {
|
|
684
|
-
|
|
684
|
+
log.error('Error deleting attachment', error instanceof Error ? error : new Error(String(error)));
|
|
685
685
|
return c.json({ error: "Failed to delete attachment" }, 500);
|
|
686
686
|
}
|
|
687
687
|
});
|
|
@@ -697,7 +697,7 @@ ticketsRouter.get("/:id/reactions", async (c) => {
|
|
|
697
697
|
return c.json({ ticketId: id, reactions, count: reactions.length });
|
|
698
698
|
}
|
|
699
699
|
catch (error) {
|
|
700
|
-
|
|
700
|
+
log.error('Error fetching reactions', error instanceof Error ? error : new Error(String(error)));
|
|
701
701
|
return c.json({ error: "Failed to fetch reactions" }, 500);
|
|
702
702
|
}
|
|
703
703
|
});
|
|
@@ -721,7 +721,7 @@ ticketsRouter.post("/:id/reactions", async (c) => {
|
|
|
721
721
|
return c.json({ message: "Reaction added", reaction }, 201);
|
|
722
722
|
}
|
|
723
723
|
catch (error) {
|
|
724
|
-
|
|
724
|
+
log.error('Error adding reaction', error instanceof Error ? error : new Error(String(error)));
|
|
725
725
|
return c.json({ error: "Failed to add reaction" }, 500);
|
|
726
726
|
}
|
|
727
727
|
});
|
|
@@ -740,7 +740,7 @@ ticketsRouter.delete("/:id/reactions/:reactionId", async (c) => {
|
|
|
740
740
|
return c.json({ message: "Reaction deleted" });
|
|
741
741
|
}
|
|
742
742
|
catch (error) {
|
|
743
|
-
|
|
743
|
+
log.error('Error deleting reaction', error instanceof Error ? error : new Error(String(error)));
|
|
744
744
|
return c.json({ error: "Failed to delete reaction" }, 500);
|
|
745
745
|
}
|
|
746
746
|
});
|
|
@@ -776,7 +776,7 @@ ticketsRouter.post("/:id/transition", async (c) => {
|
|
|
776
776
|
});
|
|
777
777
|
}
|
|
778
778
|
catch (error) {
|
|
779
|
-
|
|
779
|
+
log.error('Error transitioning ticket', error instanceof Error ? error : new Error(String(error)));
|
|
780
780
|
return c.json({ error: "Failed to transition ticket" }, 500);
|
|
781
781
|
}
|
|
782
782
|
});
|
|
@@ -799,7 +799,7 @@ ticketsRouter.post("/:id/assign-agent", async (c) => {
|
|
|
799
799
|
});
|
|
800
800
|
}
|
|
801
801
|
catch (error) {
|
|
802
|
-
|
|
802
|
+
log.error('Error assigning agent', error instanceof Error ? error : new Error(String(error)));
|
|
803
803
|
return c.json({ error: "Failed to assign agent" }, 500);
|
|
804
804
|
}
|
|
805
805
|
});
|
|
@@ -848,7 +848,7 @@ ticketsRouter.post("/ai/categorize", async (c) => {
|
|
|
848
848
|
});
|
|
849
849
|
}
|
|
850
850
|
catch (error) {
|
|
851
|
-
|
|
851
|
+
log.error('Error categorizing ticket', error instanceof Error ? error : new Error(String(error)));
|
|
852
852
|
return c.json({ error: "Failed to categorize ticket" }, 500);
|
|
853
853
|
}
|
|
854
854
|
});
|
|
@@ -877,7 +877,7 @@ ticketsRouter.post("/ai/suggest", async (c) => {
|
|
|
877
877
|
});
|
|
878
878
|
}
|
|
879
879
|
catch (error) {
|
|
880
|
-
|
|
880
|
+
log.error('Error getting suggestions', error instanceof Error ? error : new Error(String(error)));
|
|
881
881
|
return c.json({ error: "Failed to get suggestions" }, 500);
|
|
882
882
|
}
|
|
883
883
|
});
|
|
@@ -909,7 +909,7 @@ ticketsRouter.get("/:id/ai/summary", async (c) => {
|
|
|
909
909
|
});
|
|
910
910
|
}
|
|
911
911
|
catch (error) {
|
|
912
|
-
|
|
912
|
+
log.error('Error summarizing ticket', error instanceof Error ? error : new Error(String(error)));
|
|
913
913
|
return c.json({ error: "Failed to summarize ticket" }, 500);
|
|
914
914
|
}
|
|
915
915
|
});
|
|
@@ -950,7 +950,7 @@ ticketsRouter.get("/:id/similar", async (c) => {
|
|
|
950
950
|
});
|
|
951
951
|
}
|
|
952
952
|
catch (error) {
|
|
953
|
-
|
|
953
|
+
log.error('Error finding similar tickets', error instanceof Error ? error : new Error(String(error)));
|
|
954
954
|
return c.json({ error: "Failed to find similar tickets" }, 500);
|
|
955
955
|
}
|
|
956
956
|
});
|
|
@@ -1043,7 +1043,7 @@ ticketsRouter.post("/:id/comments/ai-respond", async (c) => {
|
|
|
1043
1043
|
});
|
|
1044
1044
|
}
|
|
1045
1045
|
catch (error) {
|
|
1046
|
-
|
|
1046
|
+
log.error('Error generating AI response', error instanceof Error ? error : new Error(String(error)));
|
|
1047
1047
|
return c.json({ error: "Failed to generate AI response" }, 500);
|
|
1048
1048
|
}
|
|
1049
1049
|
});
|
|
@@ -1082,7 +1082,7 @@ ticketsRouter.post("/:id/ai/analyze-comment", async (c) => {
|
|
|
1082
1082
|
});
|
|
1083
1083
|
}
|
|
1084
1084
|
catch (error) {
|
|
1085
|
-
|
|
1085
|
+
log.error('Error analyzing comment', error instanceof Error ? error : new Error(String(error)));
|
|
1086
1086
|
return c.json({ error: "Failed to analyze comment" }, 500);
|
|
1087
1087
|
}
|
|
1088
1088
|
});
|
package/dist/routes/tokens.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { Hono } from 'hono';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { createApiToken, listApiTokens, revokeApiToken, } from '../auth/api-tokens.js';
|
|
4
|
+
import { createContextualLogger } from '../utils/logger.js';
|
|
4
5
|
const tokens = new Hono();
|
|
6
|
+
const log = createContextualLogger('TokensRoutes');
|
|
5
7
|
const createTokenBodySchema = z.object({
|
|
6
8
|
name: z.string().min(1),
|
|
7
9
|
scopes: z.array(z.string()).min(1),
|
|
@@ -52,7 +54,7 @@ tokens.post('/', async (c) => {
|
|
|
52
54
|
}, 201);
|
|
53
55
|
}
|
|
54
56
|
catch (error) {
|
|
55
|
-
|
|
57
|
+
log.error('Error creating token', error instanceof Error ? error : new Error(String(error)));
|
|
56
58
|
return c.json({ error: 'Failed to create token' }, 500);
|
|
57
59
|
}
|
|
58
60
|
});
|
|
@@ -63,7 +65,7 @@ tokens.get('/', async (c) => {
|
|
|
63
65
|
return c.json({ tokens: tokenList });
|
|
64
66
|
}
|
|
65
67
|
catch (error) {
|
|
66
|
-
|
|
68
|
+
log.error('Error listing tokens', error instanceof Error ? error : new Error(String(error)));
|
|
67
69
|
return c.json({ error: 'Failed to list tokens' }, 500);
|
|
68
70
|
}
|
|
69
71
|
});
|
|
@@ -75,7 +77,7 @@ tokens.delete('/:id', async (c) => {
|
|
|
75
77
|
return c.json({ message: 'Token revoked' });
|
|
76
78
|
}
|
|
77
79
|
catch (error) {
|
|
78
|
-
|
|
80
|
+
log.error('Error revoking token', error instanceof Error ? error : new Error(String(error)));
|
|
79
81
|
return c.json({ error: 'Failed to revoke token' }, 500);
|
|
80
82
|
}
|
|
81
83
|
});
|