@lark-apaas/devtool-kits 1.2.10-alpha.0 → 1.2.11-alpha.1

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/dist/index.cjs CHANGED
@@ -1506,7 +1506,7 @@ function sendSimpleRedirect(req, res) {
1506
1506
  __name(sendSimpleRedirect, "sendSimpleRedirect");
1507
1507
 
1508
1508
  // src/middlewares/index.ts
1509
- var import_node_path9 = __toESM(require("path"), 1);
1509
+ var import_node_path10 = __toESM(require("path"), 1);
1510
1510
 
1511
1511
  // src/middlewares/openapi/router.ts
1512
1512
  var import_express = __toESM(require("express"), 1);
@@ -1949,10 +1949,194 @@ function serializeError(error) {
1949
1949
  __name(serializeError, "serializeError");
1950
1950
 
1951
1951
  // src/middlewares/dev-logs/controller.ts
1952
- var import_node_path7 = require("path");
1952
+ var import_node_path8 = require("path");
1953
1953
 
1954
- // src/middlewares/dev-logs/services.ts
1954
+ // src/middlewares/dev-logs/services/file-reader.ts
1955
1955
  var import_node_fs7 = require("fs");
1956
+ async function readFileReverse(filePath, chunkSize, processLine) {
1957
+ const handle = await import_node_fs7.promises.open(filePath, "r");
1958
+ try {
1959
+ const stats = await handle.stat();
1960
+ let position = stats.size;
1961
+ let remainder = "";
1962
+ while (position > 0) {
1963
+ const length = Math.min(chunkSize, position);
1964
+ position -= length;
1965
+ const buffer = Buffer.alloc(length);
1966
+ await handle.read(buffer, 0, length, position);
1967
+ let chunk = buffer.toString("utf8");
1968
+ if (remainder) {
1969
+ chunk += remainder;
1970
+ remainder = "";
1971
+ }
1972
+ const lines = chunk.split("\n");
1973
+ remainder = lines.shift() ?? "";
1974
+ for (let i = lines.length - 1; i >= 0; i -= 1) {
1975
+ if (lines[i]) {
1976
+ processLine(lines[i]);
1977
+ }
1978
+ }
1979
+ }
1980
+ if (remainder) {
1981
+ processLine(remainder);
1982
+ }
1983
+ } finally {
1984
+ await handle.close();
1985
+ }
1986
+ }
1987
+ __name(readFileReverse, "readFileReverse");
1988
+ function buildPaginatedResponse(items, page, pageSize) {
1989
+ const totalItems = items.length;
1990
+ const totalPages = totalItems === 0 ? 0 : Math.ceil(totalItems / pageSize);
1991
+ const startIndex = (page - 1) * pageSize;
1992
+ const endIndex = Math.min(startIndex + pageSize, totalItems);
1993
+ const pagedItems = items.slice(startIndex, endIndex).map((builder) => ({
1994
+ traceId: builder.traceId,
1995
+ method: builder.method,
1996
+ path: builder.path,
1997
+ startTime: builder.startTime,
1998
+ endTime: builder.endTime,
1999
+ statusCode: builder.statusCode,
2000
+ durationMs: builder.durationMs,
2001
+ entries: builder.entries.slice().reverse()
2002
+ }));
2003
+ return {
2004
+ page,
2005
+ pageSize,
2006
+ totalCalls: totalItems,
2007
+ totalPages,
2008
+ calls: pagedItems
2009
+ };
2010
+ }
2011
+ __name(buildPaginatedResponse, "buildPaginatedResponse");
2012
+
2013
+ // src/middlewares/dev-logs/services/parsers.ts
2014
+ function generateUUID() {
2015
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
2016
+ const r = Math.random() * 16 | 0;
2017
+ const v = c === "x" ? r : r & 3 | 8;
2018
+ return v.toString(16);
2019
+ });
2020
+ }
2021
+ __name(generateUUID, "generateUUID");
2022
+ function mapPinoLevelToServerLogLevel(pinoLevel) {
2023
+ if (typeof pinoLevel === "string") {
2024
+ const lower = pinoLevel.toLowerCase();
2025
+ if (lower === "fatal") return "fatal";
2026
+ if (lower === "error") return "error";
2027
+ if (lower === "warn" || lower === "warning") return "warn";
2028
+ if (lower === "info" || lower === "log") return "log";
2029
+ if (lower === "debug") return "debug";
2030
+ if (lower === "trace" || lower === "verbose") return "verbose";
2031
+ return "log";
2032
+ }
2033
+ if (pinoLevel >= 60) return "fatal";
2034
+ if (pinoLevel >= 50) return "error";
2035
+ if (pinoLevel >= 40) return "warn";
2036
+ if (pinoLevel >= 30) return "log";
2037
+ if (pinoLevel >= 20) return "debug";
2038
+ return "verbose";
2039
+ }
2040
+ __name(mapPinoLevelToServerLogLevel, "mapPinoLevelToServerLogLevel");
2041
+ function extractLogLevel(text) {
2042
+ const lower = text.toLowerCase();
2043
+ if (lower.includes("fatal") || lower.includes("critical")) return "fatal";
2044
+ if (lower.includes("error") || lower.includes("<e>") || lower.includes("\u2716")) return "error";
2045
+ if (lower.includes("warn") || lower.includes("warning") || lower.includes("<w>") || lower.includes("\u26A0")) return "warn";
2046
+ if (lower.includes("debug") || lower.includes("<d>")) return "debug";
2047
+ if (lower.includes("verbose") || lower.includes("trace")) return "verbose";
2048
+ return "log";
2049
+ }
2050
+ __name(extractLogLevel, "extractLogLevel");
2051
+ function parsePinoLog(line, source) {
2052
+ try {
2053
+ const pinoLog = JSON.parse(line);
2054
+ const id = generateUUID();
2055
+ return {
2056
+ id,
2057
+ level: mapPinoLevelToServerLogLevel(pinoLog.level),
2058
+ timestamp: new Date(pinoLog.time).getTime(),
2059
+ message: pinoLog.message || pinoLog.msg || "",
2060
+ context: pinoLog.context || null,
2061
+ traceId: pinoLog.trace_id || null,
2062
+ userId: pinoLog.user_id || null,
2063
+ appId: pinoLog.app_id || null,
2064
+ tenantId: pinoLog.tenant_id || null,
2065
+ stack: pinoLog.stack || null,
2066
+ meta: {
2067
+ pid: pinoLog.pid,
2068
+ hostname: pinoLog.hostname,
2069
+ path: pinoLog.path,
2070
+ method: pinoLog.method,
2071
+ statusCode: pinoLog.status_code,
2072
+ durationMs: pinoLog.duration_ms,
2073
+ ip: pinoLog.ip,
2074
+ requestBody: pinoLog.request_body,
2075
+ responseBody: pinoLog.response_body
2076
+ },
2077
+ tags: [
2078
+ source
2079
+ ]
2080
+ };
2081
+ } catch (error) {
2082
+ return null;
2083
+ }
2084
+ }
2085
+ __name(parsePinoLog, "parsePinoLog");
2086
+ function parseStdLog(line, source) {
2087
+ const id = generateUUID();
2088
+ const match = line.match(/^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\] \[(server|client)\] (.*)$/);
2089
+ if (!match) {
2090
+ return {
2091
+ id,
2092
+ level: "log",
2093
+ timestamp: Date.now(),
2094
+ message: line,
2095
+ context: null,
2096
+ traceId: null,
2097
+ userId: null,
2098
+ appId: null,
2099
+ tenantId: null,
2100
+ stack: null,
2101
+ meta: null,
2102
+ tags: [
2103
+ source
2104
+ ]
2105
+ };
2106
+ }
2107
+ const [, timeStr, , content] = match;
2108
+ let timestamp;
2109
+ try {
2110
+ const isoStr = timeStr.replace(" ", "T");
2111
+ timestamp = new Date(isoStr).getTime();
2112
+ if (isNaN(timestamp)) {
2113
+ timestamp = Date.now();
2114
+ }
2115
+ } catch (error) {
2116
+ timestamp = Date.now();
2117
+ }
2118
+ const level = extractLogLevel(content);
2119
+ return {
2120
+ id,
2121
+ level,
2122
+ timestamp,
2123
+ message: content,
2124
+ context: null,
2125
+ traceId: null,
2126
+ userId: null,
2127
+ appId: null,
2128
+ tenantId: null,
2129
+ stack: null,
2130
+ meta: null,
2131
+ tags: [
2132
+ source
2133
+ ]
2134
+ };
2135
+ }
2136
+ __name(parseStdLog, "parseStdLog");
2137
+
2138
+ // src/middlewares/dev-logs/services/trace.service.ts
2139
+ var import_node_fs8 = require("fs");
1956
2140
  var import_node_readline = require("readline");
1957
2141
  async function readLogEntriesByTrace(filePath, traceId, limit) {
1958
2142
  const exists = await fileExists(filePath);
@@ -1960,7 +2144,7 @@ async function readLogEntriesByTrace(filePath, traceId, limit) {
1960
2144
  return void 0;
1961
2145
  }
1962
2146
  const matches = [];
1963
- const stream = (0, import_node_fs7.createReadStream)(filePath, {
2147
+ const stream = (0, import_node_fs8.createReadStream)(filePath, {
1964
2148
  encoding: "utf8"
1965
2149
  });
1966
2150
  const rl = (0, import_node_readline.createInterface)({
@@ -2051,62 +2235,6 @@ async function readRecentTraceCalls(filePath, page, pageSize, pathFilter, method
2051
2235
  return buildPaginatedResponse(completedCalls, page, pageSize);
2052
2236
  }
2053
2237
  __name(readRecentTraceCalls, "readRecentTraceCalls");
2054
- async function readFileReverse(filePath, chunkSize, processLine) {
2055
- const handle = await import_node_fs7.promises.open(filePath, "r");
2056
- try {
2057
- const stats = await handle.stat();
2058
- let position = stats.size;
2059
- let remainder = "";
2060
- while (position > 0) {
2061
- const length = Math.min(chunkSize, position);
2062
- position -= length;
2063
- const buffer = Buffer.alloc(length);
2064
- await handle.read(buffer, 0, length, position);
2065
- let chunk = buffer.toString("utf8");
2066
- if (remainder) {
2067
- chunk += remainder;
2068
- remainder = "";
2069
- }
2070
- const lines = chunk.split("\n");
2071
- remainder = lines.shift() ?? "";
2072
- for (let i = lines.length - 1; i >= 0; i -= 1) {
2073
- if (lines[i]) {
2074
- processLine(lines[i]);
2075
- }
2076
- }
2077
- }
2078
- if (remainder) {
2079
- processLine(remainder);
2080
- }
2081
- } finally {
2082
- await handle.close();
2083
- }
2084
- }
2085
- __name(readFileReverse, "readFileReverse");
2086
- function buildPaginatedResponse(items, page, pageSize) {
2087
- const totalItems = items.length;
2088
- const totalPages = totalItems === 0 ? 0 : Math.ceil(totalItems / pageSize);
2089
- const startIndex = (page - 1) * pageSize;
2090
- const endIndex = Math.min(startIndex + pageSize, totalItems);
2091
- const pagedItems = items.slice(startIndex, endIndex).map((builder) => ({
2092
- traceId: builder.traceId,
2093
- method: builder.method,
2094
- path: builder.path,
2095
- startTime: builder.startTime,
2096
- endTime: builder.endTime,
2097
- statusCode: builder.statusCode,
2098
- durationMs: builder.durationMs,
2099
- entries: builder.entries.slice().reverse()
2100
- }));
2101
- return {
2102
- page,
2103
- pageSize,
2104
- totalCalls: totalItems,
2105
- totalPages,
2106
- calls: pagedItems
2107
- };
2108
- }
2109
- __name(buildPaginatedResponse, "buildPaginatedResponse");
2110
2238
  async function readLogFilePage(filePath, page, pageSize) {
2111
2239
  if (!await fileExists(filePath)) {
2112
2240
  return void 0;
@@ -2114,7 +2242,7 @@ async function readLogFilePage(filePath, page, pageSize) {
2114
2242
  const capacity = page * pageSize;
2115
2243
  const buffer = [];
2116
2244
  let totalLines = 0;
2117
- const stream = (0, import_node_fs7.createReadStream)(filePath, {
2245
+ const stream = (0, import_node_fs8.createReadStream)(filePath, {
2118
2246
  encoding: "utf8"
2119
2247
  });
2120
2248
  const rl = (0, import_node_readline.createInterface)({
@@ -2162,6 +2290,11 @@ async function readLogFilePage(filePath, page, pageSize) {
2162
2290
  };
2163
2291
  }
2164
2292
  __name(readLogFilePage, "readLogFilePage");
2293
+
2294
+ // src/middlewares/dev-logs/services/server-log.service.ts
2295
+ var import_node_fs9 = require("fs");
2296
+ var import_node_readline2 = require("readline");
2297
+ var import_node_path7 = require("path");
2165
2298
  async function readServerLogs(logDir, options = {}) {
2166
2299
  const limit = options.limit || 100;
2167
2300
  const offset = options.offset || 0;
@@ -2204,20 +2337,19 @@ async function readServerLogs(logDir, options = {}) {
2204
2337
  }
2205
2338
  __name(readServerLogs, "readServerLogs");
2206
2339
  async function readLogsBySource(logDir, source) {
2207
- const { join: join6 } = await import("path");
2208
2340
  let filePath;
2209
2341
  let parser;
2210
2342
  if (source === "server") {
2211
- filePath = join6(logDir, "server.log");
2343
+ filePath = (0, import_node_path7.join)(logDir, "server.log");
2212
2344
  parser = /* @__PURE__ */ __name((line) => parsePinoLog(line, "server"), "parser");
2213
2345
  } else if (source === "trace") {
2214
- filePath = join6(logDir, "trace.log");
2346
+ filePath = (0, import_node_path7.join)(logDir, "trace.log");
2215
2347
  parser = /* @__PURE__ */ __name((line) => parsePinoLog(line, "trace"), "parser");
2216
2348
  } else if (source === "server-std") {
2217
- filePath = join6(logDir, "server.std.log");
2349
+ filePath = (0, import_node_path7.join)(logDir, "server.std.log");
2218
2350
  parser = /* @__PURE__ */ __name((line) => parseStdLog(line, "server-std"), "parser");
2219
2351
  } else if (source === "client-std") {
2220
- filePath = join6(logDir, "client.std.log");
2352
+ filePath = (0, import_node_path7.join)(logDir, "client.std.log");
2221
2353
  parser = /* @__PURE__ */ __name((line) => parseStdLog(line, "client-std"), "parser");
2222
2354
  } else {
2223
2355
  console.warn(`[readLogsBySource] Unknown source: ${source}`);
@@ -2231,10 +2363,10 @@ async function readLogsBySource(logDir, source) {
2231
2363
  let stream = null;
2232
2364
  let rl = null;
2233
2365
  try {
2234
- stream = (0, import_node_fs7.createReadStream)(filePath, {
2366
+ stream = (0, import_node_fs9.createReadStream)(filePath, {
2235
2367
  encoding: "utf8"
2236
2368
  });
2237
- rl = (0, import_node_readline.createInterface)({
2369
+ rl = (0, import_node_readline2.createInterface)({
2238
2370
  input: stream,
2239
2371
  crlfDelay: Infinity
2240
2372
  });
@@ -2262,129 +2394,10 @@ async function readLogsBySource(logDir, source) {
2262
2394
  return logs;
2263
2395
  }
2264
2396
  __name(readLogsBySource, "readLogsBySource");
2265
- function parsePinoLog(line, source) {
2266
- try {
2267
- const pinoLog = JSON.parse(line);
2268
- const id = generateUUID();
2269
- return {
2270
- id,
2271
- level: mapPinoLevelToServerLogLevel(pinoLog.level),
2272
- timestamp: new Date(pinoLog.time).getTime(),
2273
- message: pinoLog.message || pinoLog.msg || "",
2274
- context: pinoLog.context || null,
2275
- traceId: pinoLog.trace_id || null,
2276
- userId: pinoLog.user_id || null,
2277
- appId: pinoLog.app_id || null,
2278
- tenantId: pinoLog.tenant_id || null,
2279
- stack: pinoLog.stack || null,
2280
- meta: {
2281
- pid: pinoLog.pid,
2282
- hostname: pinoLog.hostname,
2283
- path: pinoLog.path,
2284
- method: pinoLog.method,
2285
- statusCode: pinoLog.status_code,
2286
- durationMs: pinoLog.duration_ms,
2287
- ip: pinoLog.ip,
2288
- requestBody: pinoLog.request_body,
2289
- responseBody: pinoLog.response_body
2290
- },
2291
- tags: [
2292
- source
2293
- ]
2294
- };
2295
- } catch (error) {
2296
- return null;
2297
- }
2298
- }
2299
- __name(parsePinoLog, "parsePinoLog");
2300
- function parseStdLog(line, source) {
2301
- const id = generateUUID();
2302
- const match = line.match(/^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\] \[(server|client)\] (.*)$/);
2303
- if (!match) {
2304
- return {
2305
- id,
2306
- level: "log",
2307
- timestamp: Date.now(),
2308
- message: line,
2309
- context: null,
2310
- traceId: null,
2311
- userId: null,
2312
- appId: null,
2313
- tenantId: null,
2314
- stack: null,
2315
- meta: null,
2316
- tags: [
2317
- source
2318
- ]
2319
- };
2320
- }
2321
- const [, timeStr, , content] = match;
2322
- let timestamp;
2323
- try {
2324
- const isoStr = timeStr.replace(" ", "T");
2325
- timestamp = new Date(isoStr).getTime();
2326
- if (isNaN(timestamp)) {
2327
- timestamp = Date.now();
2328
- }
2329
- } catch (error) {
2330
- timestamp = Date.now();
2331
- }
2332
- const level = extractLogLevel(content);
2333
- return {
2334
- id,
2335
- level,
2336
- timestamp,
2337
- message: content,
2338
- context: null,
2339
- traceId: null,
2340
- userId: null,
2341
- appId: null,
2342
- tenantId: null,
2343
- stack: null,
2344
- meta: null,
2345
- tags: [
2346
- source
2347
- ]
2348
- };
2349
- }
2350
- __name(parseStdLog, "parseStdLog");
2351
- function mapPinoLevelToServerLogLevel(pinoLevel) {
2352
- if (typeof pinoLevel === "string") {
2353
- const lower = pinoLevel.toLowerCase();
2354
- if (lower === "fatal") return "fatal";
2355
- if (lower === "error") return "error";
2356
- if (lower === "warn" || lower === "warning") return "warn";
2357
- if (lower === "info" || lower === "log") return "log";
2358
- if (lower === "debug") return "debug";
2359
- if (lower === "trace" || lower === "verbose") return "verbose";
2360
- return "log";
2361
- }
2362
- if (pinoLevel >= 60) return "fatal";
2363
- if (pinoLevel >= 50) return "error";
2364
- if (pinoLevel >= 40) return "warn";
2365
- if (pinoLevel >= 30) return "log";
2366
- if (pinoLevel >= 20) return "debug";
2367
- return "verbose";
2368
- }
2369
- __name(mapPinoLevelToServerLogLevel, "mapPinoLevelToServerLogLevel");
2370
- function extractLogLevel(text) {
2371
- const lower = text.toLowerCase();
2372
- if (lower.includes("fatal") || lower.includes("critical")) return "fatal";
2373
- if (lower.includes("error") || lower.includes("<e>") || lower.includes("\u2716")) return "error";
2374
- if (lower.includes("warn") || lower.includes("warning") || lower.includes("<w>") || lower.includes("\u26A0")) return "warn";
2375
- if (lower.includes("debug") || lower.includes("<d>")) return "debug";
2376
- if (lower.includes("verbose") || lower.includes("trace")) return "verbose";
2377
- return "log";
2378
- }
2379
- __name(extractLogLevel, "extractLogLevel");
2380
- function generateUUID() {
2381
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
2382
- const r = Math.random() * 16 | 0;
2383
- const v = c === "x" ? r : r & 3 | 8;
2384
- return v.toString(16);
2385
- });
2386
- }
2387
- __name(generateUUID, "generateUUID");
2397
+
2398
+ // src/middlewares/dev-logs/services/trigger.service.ts
2399
+ var import_node_fs10 = require("fs");
2400
+ var import_node_readline3 = require("readline");
2388
2401
  async function readTriggerList(filePath, trigger, path7, limit, triggerID) {
2389
2402
  if (!await fileExists(filePath)) {
2390
2403
  return void 0;
@@ -2500,10 +2513,10 @@ async function readTriggerDetail(filePath, path7, instanceID) {
2500
2513
  return void 0;
2501
2514
  }
2502
2515
  const matches = [];
2503
- const stream = (0, import_node_fs7.createReadStream)(filePath, {
2516
+ const stream = (0, import_node_fs10.createReadStream)(filePath, {
2504
2517
  encoding: "utf8"
2505
2518
  });
2506
- const rl = (0, import_node_readline.createInterface)({
2519
+ const rl = (0, import_node_readline3.createInterface)({
2507
2520
  input: stream,
2508
2521
  crlfDelay: Infinity
2509
2522
  });
@@ -2524,6 +2537,118 @@ async function readTriggerDetail(filePath, path7, instanceID) {
2524
2537
  }
2525
2538
  __name(readTriggerDetail, "readTriggerDetail");
2526
2539
 
2540
+ // src/middlewares/dev-logs/services/capability.service.ts
2541
+ async function readCapabilityTraceList(filePath, capabilityId, limit) {
2542
+ if (!await fileExists(filePath)) {
2543
+ return void 0;
2544
+ }
2545
+ const config = {
2546
+ chunkSize: 64 * 1024
2547
+ };
2548
+ const builders = /* @__PURE__ */ new Map();
2549
+ const completedTraces = [];
2550
+ const createCapabilityTraceBuilder = /* @__PURE__ */ __name((traceId, capId) => ({
2551
+ traceId,
2552
+ capabilityId: capId,
2553
+ hasCompleted: false,
2554
+ hasStartEntry: false
2555
+ }), "createCapabilityTraceBuilder");
2556
+ const shouldIncludeInCompletedTraces = /* @__PURE__ */ __name((builder) => {
2557
+ const alreadyAdded = completedTraces.some((trace) => trace.traceId === builder.traceId);
2558
+ if (alreadyAdded) {
2559
+ return false;
2560
+ }
2561
+ return builder.capabilityId === capabilityId;
2562
+ }, "shouldIncludeInCompletedTraces");
2563
+ const updateBuilderMetadata = /* @__PURE__ */ __name((builder, entry) => {
2564
+ if (entry.plugin_key && !builder.pluginKey) {
2565
+ builder.pluginKey = String(entry.plugin_key);
2566
+ }
2567
+ if (entry.action && !builder.action) {
2568
+ builder.action = String(entry.action);
2569
+ }
2570
+ const message = entry.message || "";
2571
+ if (message.includes("Executing capability") && !builder.hasStartEntry) {
2572
+ builder.hasStartEntry = true;
2573
+ builder.startTime = entry.time;
2574
+ if (entry.input) {
2575
+ builder.input = String(entry.input);
2576
+ }
2577
+ }
2578
+ if (message.includes("executed successfully")) {
2579
+ builder.hasCompleted = true;
2580
+ builder.endTime = entry.time;
2581
+ builder.status = "success";
2582
+ if (entry.output) {
2583
+ builder.output = String(entry.output);
2584
+ }
2585
+ if (entry.duration_ms) {
2586
+ builder.durationMs = Number(entry.duration_ms);
2587
+ }
2588
+ if (shouldIncludeInCompletedTraces(builder)) {
2589
+ completedTraces.push(builder);
2590
+ }
2591
+ }
2592
+ if (message.includes("execution failed")) {
2593
+ builder.hasCompleted = true;
2594
+ builder.endTime = entry.time;
2595
+ builder.status = "failed";
2596
+ if (entry.error) {
2597
+ builder.error = {
2598
+ message: String(entry.error)
2599
+ };
2600
+ }
2601
+ if (entry.duration_ms) {
2602
+ builder.durationMs = Number(entry.duration_ms);
2603
+ }
2604
+ if (shouldIncludeInCompletedTraces(builder)) {
2605
+ completedTraces.push(builder);
2606
+ }
2607
+ }
2608
+ }, "updateBuilderMetadata");
2609
+ const processLogEntry = /* @__PURE__ */ __name((entry) => {
2610
+ const { trace_id: traceId, capability_id: capId } = entry;
2611
+ if (!traceId || !capId || capId !== capabilityId) return;
2612
+ let builder = builders.get(traceId);
2613
+ if (!builder) {
2614
+ builder = createCapabilityTraceBuilder(traceId, capId);
2615
+ builders.set(traceId, builder);
2616
+ }
2617
+ updateBuilderMetadata(builder, entry);
2618
+ }, "processLogEntry");
2619
+ const processLine = /* @__PURE__ */ __name((line) => {
2620
+ const entry = parseLogLine2(line);
2621
+ if (entry?.capability_id) {
2622
+ processLogEntry(entry);
2623
+ }
2624
+ }, "processLine");
2625
+ await readFileReverse(filePath, config.chunkSize, processLine);
2626
+ completedTraces.sort((a, b) => {
2627
+ const timeA = a.endTime ? new Date(a.endTime).getTime() : 0;
2628
+ const timeB = b.endTime ? new Date(b.endTime).getTime() : 0;
2629
+ return timeB - timeA;
2630
+ });
2631
+ const limitedTraces = limit ? completedTraces.slice(0, limit) : completedTraces;
2632
+ return {
2633
+ capabilityId,
2634
+ totalTraces: limitedTraces.length,
2635
+ traces: limitedTraces.map((builder) => ({
2636
+ traceId: builder.traceId,
2637
+ capabilityId: builder.capabilityId,
2638
+ pluginKey: builder.pluginKey,
2639
+ action: builder.action,
2640
+ startTime: builder.startTime,
2641
+ endTime: builder.endTime,
2642
+ durationMs: builder.durationMs,
2643
+ status: builder.status || "failed",
2644
+ input: builder.input,
2645
+ output: builder.output,
2646
+ error: builder.error
2647
+ }))
2648
+ };
2649
+ }
2650
+ __name(readCapabilityTraceList, "readCapabilityTraceList");
2651
+
2527
2652
  // src/middlewares/dev-logs/controller.ts
2528
2653
  function handleNotFound(res, filePath, message = "Log file not found") {
2529
2654
  res.status(404).json({
@@ -2539,7 +2664,7 @@ function handleError(res, error, message = "Failed to read log file") {
2539
2664
  }
2540
2665
  __name(handleError, "handleError");
2541
2666
  function createGetTraceEntriesHandler(logDir) {
2542
- const appLogPath = (0, import_node_path7.join)(logDir, "server.log");
2667
+ const appLogPath = (0, import_node_path8.join)(logDir, "server.log");
2543
2668
  return async (req, res) => {
2544
2669
  const traceId = (req.params.traceId || "").trim();
2545
2670
  if (!traceId) {
@@ -2566,7 +2691,7 @@ function createGetTraceEntriesHandler(logDir) {
2566
2691
  }
2567
2692
  __name(createGetTraceEntriesHandler, "createGetTraceEntriesHandler");
2568
2693
  function createGetRecentTracesHandler(logDir) {
2569
- const traceLogPath = (0, import_node_path7.join)(logDir, "trace.log");
2694
+ const traceLogPath = (0, import_node_path8.join)(logDir, "trace.log");
2570
2695
  return async (req, res) => {
2571
2696
  const page = parsePositiveInt(req.query.page, 1);
2572
2697
  const pageSize = parseLimit(req.query.pageSize, 10, 100);
@@ -2643,7 +2768,7 @@ function createGetServerLogsHandler(logDir) {
2643
2768
  }
2644
2769
  __name(createGetServerLogsHandler, "createGetServerLogsHandler");
2645
2770
  function createGetTriggerListHandler(logDir) {
2646
- const traceLogPath = (0, import_node_path7.join)(logDir, "trace.log");
2771
+ const traceLogPath = (0, import_node_path8.join)(logDir, "trace.log");
2647
2772
  return async (req, res) => {
2648
2773
  const trigger = typeof req.query.trigger === "string" ? req.query.trigger.trim() : void 0;
2649
2774
  if (!trigger) {
@@ -2671,7 +2796,7 @@ function createGetTriggerListHandler(logDir) {
2671
2796
  }
2672
2797
  __name(createGetTriggerListHandler, "createGetTriggerListHandler");
2673
2798
  function createGetTriggerDetailHandler(logDir) {
2674
- const traceLogPath = (0, import_node_path7.join)(logDir, "server.log");
2799
+ const traceLogPath = (0, import_node_path8.join)(logDir, "server.log");
2675
2800
  return async (req, res) => {
2676
2801
  const instanceID = (req.params.instanceID || "").trim();
2677
2802
  if (!instanceID) {
@@ -2695,6 +2820,31 @@ function createGetTriggerDetailHandler(logDir) {
2695
2820
  };
2696
2821
  }
2697
2822
  __name(createGetTriggerDetailHandler, "createGetTriggerDetailHandler");
2823
+ function createGetCapabilityTraceListHandler(logDir) {
2824
+ const serverLogPath = (0, import_node_path8.join)(logDir, "server.log");
2825
+ return async (req, res) => {
2826
+ const capabilityId = typeof req.query.capability_id === "string" ? req.query.capability_id.trim() : void 0;
2827
+ if (!capabilityId) {
2828
+ return res.status(400).json({
2829
+ message: "capability_id is required"
2830
+ });
2831
+ }
2832
+ const limit = parseLimit(req.query.limit, 10, 200);
2833
+ try {
2834
+ const result = await readCapabilityTraceList(serverLogPath, capabilityId, limit);
2835
+ if (!result) {
2836
+ return handleNotFound(res, serverLogPath);
2837
+ }
2838
+ res.json({
2839
+ file: getRelativePath(serverLogPath),
2840
+ ...result
2841
+ });
2842
+ } catch (error) {
2843
+ handleError(res, error, "Failed to read server log");
2844
+ }
2845
+ };
2846
+ }
2847
+ __name(createGetCapabilityTraceListHandler, "createGetCapabilityTraceListHandler");
2698
2848
 
2699
2849
  // src/middlewares/dev-logs/health.controller.ts
2700
2850
  var import_node_http2 = __toESM(require("http"), 1);
@@ -2773,6 +2923,7 @@ function createDevLogRouter(options = {}) {
2773
2923
  router.get("/server-logs", createGetServerLogsHandler(logDir));
2774
2924
  router.get("/trace/trigger/list", createGetTriggerListHandler(logDir));
2775
2925
  router.get("/trace/trigger/:instanceID", createGetTriggerDetailHandler(logDir));
2926
+ router.get("/trace/capability/list", createGetCapabilityTraceListHandler(logDir));
2776
2927
  router.get("/health", createHealthCheckHandler());
2777
2928
  return router;
2778
2929
  }
@@ -2835,18 +2986,18 @@ var import_path2 = require("path");
2835
2986
  var import_fs2 = __toESM(require("fs"), 1);
2836
2987
 
2837
2988
  // src/middlewares/collect-logs/utils.ts
2838
- var import_node_path8 = require("path");
2839
- var import_node_fs8 = __toESM(require("fs"), 1);
2989
+ var import_node_path9 = require("path");
2990
+ var import_node_fs11 = __toESM(require("fs"), 1);
2840
2991
  function resolveLogDir2(provided) {
2841
2992
  if (!provided) {
2842
- return (0, import_node_path8.join)(process.cwd(), "logs");
2993
+ return (0, import_node_path9.join)(process.cwd(), "logs");
2843
2994
  }
2844
- return (0, import_node_path8.isAbsolute)(provided) ? provided : (0, import_node_path8.join)(process.cwd(), provided);
2995
+ return (0, import_node_path9.isAbsolute)(provided) ? provided : (0, import_node_path9.join)(process.cwd(), provided);
2845
2996
  }
2846
2997
  __name(resolveLogDir2, "resolveLogDir");
2847
2998
  function ensureDir(dir) {
2848
- if (!import_node_fs8.default.existsSync(dir)) {
2849
- import_node_fs8.default.mkdirSync(dir, {
2999
+ if (!import_node_fs11.default.existsSync(dir)) {
3000
+ import_node_fs11.default.mkdirSync(dir, {
2850
3001
  recursive: true
2851
3002
  });
2852
3003
  }
@@ -2969,7 +3120,7 @@ function isGlobalMiddleware(middleware) {
2969
3120
  }
2970
3121
  __name(isGlobalMiddleware, "isGlobalMiddleware");
2971
3122
  function computeMountPath(basePath, mountPath) {
2972
- const routePath = import_node_path9.default.posix.join(basePath, mountPath);
3123
+ const routePath = import_node_path10.default.posix.join(basePath, mountPath);
2973
3124
  return routePath.startsWith("/") ? routePath : `/${routePath}`;
2974
3125
  }
2975
3126
  __name(computeMountPath, "computeMountPath");
@@ -2977,7 +3128,7 @@ function logMiddlewareRegistration(middleware, fullMountPath) {
2977
3128
  if (middleware.routes && middleware.routes.length > 0) {
2978
3129
  console.log(`[Middleware] Registered: ${middleware.name} at ${fullMountPath}`);
2979
3130
  middleware.routes.forEach((route) => {
2980
- const routePath = route.path === "/" ? fullMountPath : import_node_path9.default.posix.join(fullMountPath, route.path);
3131
+ const routePath = route.path === "/" ? fullMountPath : import_node_path10.default.posix.join(fullMountPath, route.path);
2981
3132
  console.log(` ${route.method} ${routePath} - ${route.description}`);
2982
3133
  });
2983
3134
  } else {