@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.js CHANGED
@@ -1908,10 +1908,194 @@ function serializeError(error) {
1908
1908
  __name(serializeError, "serializeError");
1909
1909
 
1910
1910
  // src/middlewares/dev-logs/controller.ts
1911
- import { join as join3 } from "path";
1911
+ import { join as join4 } from "path";
1912
+
1913
+ // src/middlewares/dev-logs/services/file-reader.ts
1914
+ import { promises as fs8 } from "fs";
1915
+ async function readFileReverse(filePath, chunkSize, processLine) {
1916
+ const handle = await fs8.open(filePath, "r");
1917
+ try {
1918
+ const stats = await handle.stat();
1919
+ let position = stats.size;
1920
+ let remainder = "";
1921
+ while (position > 0) {
1922
+ const length = Math.min(chunkSize, position);
1923
+ position -= length;
1924
+ const buffer = Buffer.alloc(length);
1925
+ await handle.read(buffer, 0, length, position);
1926
+ let chunk = buffer.toString("utf8");
1927
+ if (remainder) {
1928
+ chunk += remainder;
1929
+ remainder = "";
1930
+ }
1931
+ const lines = chunk.split("\n");
1932
+ remainder = lines.shift() ?? "";
1933
+ for (let i = lines.length - 1; i >= 0; i -= 1) {
1934
+ if (lines[i]) {
1935
+ processLine(lines[i]);
1936
+ }
1937
+ }
1938
+ }
1939
+ if (remainder) {
1940
+ processLine(remainder);
1941
+ }
1942
+ } finally {
1943
+ await handle.close();
1944
+ }
1945
+ }
1946
+ __name(readFileReverse, "readFileReverse");
1947
+ function buildPaginatedResponse(items, page, pageSize) {
1948
+ const totalItems = items.length;
1949
+ const totalPages = totalItems === 0 ? 0 : Math.ceil(totalItems / pageSize);
1950
+ const startIndex = (page - 1) * pageSize;
1951
+ const endIndex = Math.min(startIndex + pageSize, totalItems);
1952
+ const pagedItems = items.slice(startIndex, endIndex).map((builder) => ({
1953
+ traceId: builder.traceId,
1954
+ method: builder.method,
1955
+ path: builder.path,
1956
+ startTime: builder.startTime,
1957
+ endTime: builder.endTime,
1958
+ statusCode: builder.statusCode,
1959
+ durationMs: builder.durationMs,
1960
+ entries: builder.entries.slice().reverse()
1961
+ }));
1962
+ return {
1963
+ page,
1964
+ pageSize,
1965
+ totalCalls: totalItems,
1966
+ totalPages,
1967
+ calls: pagedItems
1968
+ };
1969
+ }
1970
+ __name(buildPaginatedResponse, "buildPaginatedResponse");
1912
1971
 
1913
- // src/middlewares/dev-logs/services.ts
1914
- import { createReadStream, promises as fs8 } from "fs";
1972
+ // src/middlewares/dev-logs/services/parsers.ts
1973
+ function generateUUID() {
1974
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
1975
+ const r = Math.random() * 16 | 0;
1976
+ const v = c === "x" ? r : r & 3 | 8;
1977
+ return v.toString(16);
1978
+ });
1979
+ }
1980
+ __name(generateUUID, "generateUUID");
1981
+ function mapPinoLevelToServerLogLevel(pinoLevel) {
1982
+ if (typeof pinoLevel === "string") {
1983
+ const lower = pinoLevel.toLowerCase();
1984
+ if (lower === "fatal") return "fatal";
1985
+ if (lower === "error") return "error";
1986
+ if (lower === "warn" || lower === "warning") return "warn";
1987
+ if (lower === "info" || lower === "log") return "log";
1988
+ if (lower === "debug") return "debug";
1989
+ if (lower === "trace" || lower === "verbose") return "verbose";
1990
+ return "log";
1991
+ }
1992
+ if (pinoLevel >= 60) return "fatal";
1993
+ if (pinoLevel >= 50) return "error";
1994
+ if (pinoLevel >= 40) return "warn";
1995
+ if (pinoLevel >= 30) return "log";
1996
+ if (pinoLevel >= 20) return "debug";
1997
+ return "verbose";
1998
+ }
1999
+ __name(mapPinoLevelToServerLogLevel, "mapPinoLevelToServerLogLevel");
2000
+ function extractLogLevel(text) {
2001
+ const lower = text.toLowerCase();
2002
+ if (lower.includes("fatal") || lower.includes("critical")) return "fatal";
2003
+ if (lower.includes("error") || lower.includes("<e>") || lower.includes("\u2716")) return "error";
2004
+ if (lower.includes("warn") || lower.includes("warning") || lower.includes("<w>") || lower.includes("\u26A0")) return "warn";
2005
+ if (lower.includes("debug") || lower.includes("<d>")) return "debug";
2006
+ if (lower.includes("verbose") || lower.includes("trace")) return "verbose";
2007
+ return "log";
2008
+ }
2009
+ __name(extractLogLevel, "extractLogLevel");
2010
+ function parsePinoLog(line, source) {
2011
+ try {
2012
+ const pinoLog = JSON.parse(line);
2013
+ const id = generateUUID();
2014
+ return {
2015
+ id,
2016
+ level: mapPinoLevelToServerLogLevel(pinoLog.level),
2017
+ timestamp: new Date(pinoLog.time).getTime(),
2018
+ message: pinoLog.message || pinoLog.msg || "",
2019
+ context: pinoLog.context || null,
2020
+ traceId: pinoLog.trace_id || null,
2021
+ userId: pinoLog.user_id || null,
2022
+ appId: pinoLog.app_id || null,
2023
+ tenantId: pinoLog.tenant_id || null,
2024
+ stack: pinoLog.stack || null,
2025
+ meta: {
2026
+ pid: pinoLog.pid,
2027
+ hostname: pinoLog.hostname,
2028
+ path: pinoLog.path,
2029
+ method: pinoLog.method,
2030
+ statusCode: pinoLog.status_code,
2031
+ durationMs: pinoLog.duration_ms,
2032
+ ip: pinoLog.ip,
2033
+ requestBody: pinoLog.request_body,
2034
+ responseBody: pinoLog.response_body
2035
+ },
2036
+ tags: [
2037
+ source
2038
+ ]
2039
+ };
2040
+ } catch (error) {
2041
+ return null;
2042
+ }
2043
+ }
2044
+ __name(parsePinoLog, "parsePinoLog");
2045
+ function parseStdLog(line, source) {
2046
+ const id = generateUUID();
2047
+ const match = line.match(/^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\] \[(server|client)\] (.*)$/);
2048
+ if (!match) {
2049
+ return {
2050
+ id,
2051
+ level: "log",
2052
+ timestamp: Date.now(),
2053
+ message: line,
2054
+ context: null,
2055
+ traceId: null,
2056
+ userId: null,
2057
+ appId: null,
2058
+ tenantId: null,
2059
+ stack: null,
2060
+ meta: null,
2061
+ tags: [
2062
+ source
2063
+ ]
2064
+ };
2065
+ }
2066
+ const [, timeStr, , content] = match;
2067
+ let timestamp;
2068
+ try {
2069
+ const isoStr = timeStr.replace(" ", "T");
2070
+ timestamp = new Date(isoStr).getTime();
2071
+ if (isNaN(timestamp)) {
2072
+ timestamp = Date.now();
2073
+ }
2074
+ } catch (error) {
2075
+ timestamp = Date.now();
2076
+ }
2077
+ const level = extractLogLevel(content);
2078
+ return {
2079
+ id,
2080
+ level,
2081
+ timestamp,
2082
+ message: content,
2083
+ context: null,
2084
+ traceId: null,
2085
+ userId: null,
2086
+ appId: null,
2087
+ tenantId: null,
2088
+ stack: null,
2089
+ meta: null,
2090
+ tags: [
2091
+ source
2092
+ ]
2093
+ };
2094
+ }
2095
+ __name(parseStdLog, "parseStdLog");
2096
+
2097
+ // src/middlewares/dev-logs/services/trace.service.ts
2098
+ import { createReadStream } from "fs";
1915
2099
  import { createInterface } from "readline";
1916
2100
  async function readLogEntriesByTrace(filePath, traceId, limit) {
1917
2101
  const exists = await fileExists(filePath);
@@ -2010,62 +2194,6 @@ async function readRecentTraceCalls(filePath, page, pageSize, pathFilter, method
2010
2194
  return buildPaginatedResponse(completedCalls, page, pageSize);
2011
2195
  }
2012
2196
  __name(readRecentTraceCalls, "readRecentTraceCalls");
2013
- async function readFileReverse(filePath, chunkSize, processLine) {
2014
- const handle = await fs8.open(filePath, "r");
2015
- try {
2016
- const stats = await handle.stat();
2017
- let position = stats.size;
2018
- let remainder = "";
2019
- while (position > 0) {
2020
- const length = Math.min(chunkSize, position);
2021
- position -= length;
2022
- const buffer = Buffer.alloc(length);
2023
- await handle.read(buffer, 0, length, position);
2024
- let chunk = buffer.toString("utf8");
2025
- if (remainder) {
2026
- chunk += remainder;
2027
- remainder = "";
2028
- }
2029
- const lines = chunk.split("\n");
2030
- remainder = lines.shift() ?? "";
2031
- for (let i = lines.length - 1; i >= 0; i -= 1) {
2032
- if (lines[i]) {
2033
- processLine(lines[i]);
2034
- }
2035
- }
2036
- }
2037
- if (remainder) {
2038
- processLine(remainder);
2039
- }
2040
- } finally {
2041
- await handle.close();
2042
- }
2043
- }
2044
- __name(readFileReverse, "readFileReverse");
2045
- function buildPaginatedResponse(items, page, pageSize) {
2046
- const totalItems = items.length;
2047
- const totalPages = totalItems === 0 ? 0 : Math.ceil(totalItems / pageSize);
2048
- const startIndex = (page - 1) * pageSize;
2049
- const endIndex = Math.min(startIndex + pageSize, totalItems);
2050
- const pagedItems = items.slice(startIndex, endIndex).map((builder) => ({
2051
- traceId: builder.traceId,
2052
- method: builder.method,
2053
- path: builder.path,
2054
- startTime: builder.startTime,
2055
- endTime: builder.endTime,
2056
- statusCode: builder.statusCode,
2057
- durationMs: builder.durationMs,
2058
- entries: builder.entries.slice().reverse()
2059
- }));
2060
- return {
2061
- page,
2062
- pageSize,
2063
- totalCalls: totalItems,
2064
- totalPages,
2065
- calls: pagedItems
2066
- };
2067
- }
2068
- __name(buildPaginatedResponse, "buildPaginatedResponse");
2069
2197
  async function readLogFilePage(filePath, page, pageSize) {
2070
2198
  if (!await fileExists(filePath)) {
2071
2199
  return void 0;
@@ -2121,6 +2249,11 @@ async function readLogFilePage(filePath, page, pageSize) {
2121
2249
  };
2122
2250
  }
2123
2251
  __name(readLogFilePage, "readLogFilePage");
2252
+
2253
+ // src/middlewares/dev-logs/services/server-log.service.ts
2254
+ import { createReadStream as createReadStream2 } from "fs";
2255
+ import { createInterface as createInterface2 } from "readline";
2256
+ import { join as join3 } from "path";
2124
2257
  async function readServerLogs(logDir, options = {}) {
2125
2258
  const limit = options.limit || 100;
2126
2259
  const offset = options.offset || 0;
@@ -2163,20 +2296,19 @@ async function readServerLogs(logDir, options = {}) {
2163
2296
  }
2164
2297
  __name(readServerLogs, "readServerLogs");
2165
2298
  async function readLogsBySource(logDir, source) {
2166
- const { join: join6 } = await import("path");
2167
2299
  let filePath;
2168
2300
  let parser;
2169
2301
  if (source === "server") {
2170
- filePath = join6(logDir, "server.log");
2302
+ filePath = join3(logDir, "server.log");
2171
2303
  parser = /* @__PURE__ */ __name((line) => parsePinoLog(line, "server"), "parser");
2172
2304
  } else if (source === "trace") {
2173
- filePath = join6(logDir, "trace.log");
2305
+ filePath = join3(logDir, "trace.log");
2174
2306
  parser = /* @__PURE__ */ __name((line) => parsePinoLog(line, "trace"), "parser");
2175
2307
  } else if (source === "server-std") {
2176
- filePath = join6(logDir, "server.std.log");
2308
+ filePath = join3(logDir, "server.std.log");
2177
2309
  parser = /* @__PURE__ */ __name((line) => parseStdLog(line, "server-std"), "parser");
2178
2310
  } else if (source === "client-std") {
2179
- filePath = join6(logDir, "client.std.log");
2311
+ filePath = join3(logDir, "client.std.log");
2180
2312
  parser = /* @__PURE__ */ __name((line) => parseStdLog(line, "client-std"), "parser");
2181
2313
  } else {
2182
2314
  console.warn(`[readLogsBySource] Unknown source: ${source}`);
@@ -2190,10 +2322,10 @@ async function readLogsBySource(logDir, source) {
2190
2322
  let stream = null;
2191
2323
  let rl = null;
2192
2324
  try {
2193
- stream = createReadStream(filePath, {
2325
+ stream = createReadStream2(filePath, {
2194
2326
  encoding: "utf8"
2195
2327
  });
2196
- rl = createInterface({
2328
+ rl = createInterface2({
2197
2329
  input: stream,
2198
2330
  crlfDelay: Infinity
2199
2331
  });
@@ -2221,129 +2353,10 @@ async function readLogsBySource(logDir, source) {
2221
2353
  return logs;
2222
2354
  }
2223
2355
  __name(readLogsBySource, "readLogsBySource");
2224
- function parsePinoLog(line, source) {
2225
- try {
2226
- const pinoLog = JSON.parse(line);
2227
- const id = generateUUID();
2228
- return {
2229
- id,
2230
- level: mapPinoLevelToServerLogLevel(pinoLog.level),
2231
- timestamp: new Date(pinoLog.time).getTime(),
2232
- message: pinoLog.message || pinoLog.msg || "",
2233
- context: pinoLog.context || null,
2234
- traceId: pinoLog.trace_id || null,
2235
- userId: pinoLog.user_id || null,
2236
- appId: pinoLog.app_id || null,
2237
- tenantId: pinoLog.tenant_id || null,
2238
- stack: pinoLog.stack || null,
2239
- meta: {
2240
- pid: pinoLog.pid,
2241
- hostname: pinoLog.hostname,
2242
- path: pinoLog.path,
2243
- method: pinoLog.method,
2244
- statusCode: pinoLog.status_code,
2245
- durationMs: pinoLog.duration_ms,
2246
- ip: pinoLog.ip,
2247
- requestBody: pinoLog.request_body,
2248
- responseBody: pinoLog.response_body
2249
- },
2250
- tags: [
2251
- source
2252
- ]
2253
- };
2254
- } catch (error) {
2255
- return null;
2256
- }
2257
- }
2258
- __name(parsePinoLog, "parsePinoLog");
2259
- function parseStdLog(line, source) {
2260
- const id = generateUUID();
2261
- const match = line.match(/^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\] \[(server|client)\] (.*)$/);
2262
- if (!match) {
2263
- return {
2264
- id,
2265
- level: "log",
2266
- timestamp: Date.now(),
2267
- message: line,
2268
- context: null,
2269
- traceId: null,
2270
- userId: null,
2271
- appId: null,
2272
- tenantId: null,
2273
- stack: null,
2274
- meta: null,
2275
- tags: [
2276
- source
2277
- ]
2278
- };
2279
- }
2280
- const [, timeStr, , content] = match;
2281
- let timestamp;
2282
- try {
2283
- const isoStr = timeStr.replace(" ", "T");
2284
- timestamp = new Date(isoStr).getTime();
2285
- if (isNaN(timestamp)) {
2286
- timestamp = Date.now();
2287
- }
2288
- } catch (error) {
2289
- timestamp = Date.now();
2290
- }
2291
- const level = extractLogLevel(content);
2292
- return {
2293
- id,
2294
- level,
2295
- timestamp,
2296
- message: content,
2297
- context: null,
2298
- traceId: null,
2299
- userId: null,
2300
- appId: null,
2301
- tenantId: null,
2302
- stack: null,
2303
- meta: null,
2304
- tags: [
2305
- source
2306
- ]
2307
- };
2308
- }
2309
- __name(parseStdLog, "parseStdLog");
2310
- function mapPinoLevelToServerLogLevel(pinoLevel) {
2311
- if (typeof pinoLevel === "string") {
2312
- const lower = pinoLevel.toLowerCase();
2313
- if (lower === "fatal") return "fatal";
2314
- if (lower === "error") return "error";
2315
- if (lower === "warn" || lower === "warning") return "warn";
2316
- if (lower === "info" || lower === "log") return "log";
2317
- if (lower === "debug") return "debug";
2318
- if (lower === "trace" || lower === "verbose") return "verbose";
2319
- return "log";
2320
- }
2321
- if (pinoLevel >= 60) return "fatal";
2322
- if (pinoLevel >= 50) return "error";
2323
- if (pinoLevel >= 40) return "warn";
2324
- if (pinoLevel >= 30) return "log";
2325
- if (pinoLevel >= 20) return "debug";
2326
- return "verbose";
2327
- }
2328
- __name(mapPinoLevelToServerLogLevel, "mapPinoLevelToServerLogLevel");
2329
- function extractLogLevel(text) {
2330
- const lower = text.toLowerCase();
2331
- if (lower.includes("fatal") || lower.includes("critical")) return "fatal";
2332
- if (lower.includes("error") || lower.includes("<e>") || lower.includes("\u2716")) return "error";
2333
- if (lower.includes("warn") || lower.includes("warning") || lower.includes("<w>") || lower.includes("\u26A0")) return "warn";
2334
- if (lower.includes("debug") || lower.includes("<d>")) return "debug";
2335
- if (lower.includes("verbose") || lower.includes("trace")) return "verbose";
2336
- return "log";
2337
- }
2338
- __name(extractLogLevel, "extractLogLevel");
2339
- function generateUUID() {
2340
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
2341
- const r = Math.random() * 16 | 0;
2342
- const v = c === "x" ? r : r & 3 | 8;
2343
- return v.toString(16);
2344
- });
2345
- }
2346
- __name(generateUUID, "generateUUID");
2356
+
2357
+ // src/middlewares/dev-logs/services/trigger.service.ts
2358
+ import { createReadStream as createReadStream3 } from "fs";
2359
+ import { createInterface as createInterface3 } from "readline";
2347
2360
  async function readTriggerList(filePath, trigger, path7, limit, triggerID) {
2348
2361
  if (!await fileExists(filePath)) {
2349
2362
  return void 0;
@@ -2459,10 +2472,10 @@ async function readTriggerDetail(filePath, path7, instanceID) {
2459
2472
  return void 0;
2460
2473
  }
2461
2474
  const matches = [];
2462
- const stream = createReadStream(filePath, {
2475
+ const stream = createReadStream3(filePath, {
2463
2476
  encoding: "utf8"
2464
2477
  });
2465
- const rl = createInterface({
2478
+ const rl = createInterface3({
2466
2479
  input: stream,
2467
2480
  crlfDelay: Infinity
2468
2481
  });
@@ -2483,6 +2496,118 @@ async function readTriggerDetail(filePath, path7, instanceID) {
2483
2496
  }
2484
2497
  __name(readTriggerDetail, "readTriggerDetail");
2485
2498
 
2499
+ // src/middlewares/dev-logs/services/capability.service.ts
2500
+ async function readCapabilityTraceList(filePath, capabilityId, limit) {
2501
+ if (!await fileExists(filePath)) {
2502
+ return void 0;
2503
+ }
2504
+ const config = {
2505
+ chunkSize: 64 * 1024
2506
+ };
2507
+ const builders = /* @__PURE__ */ new Map();
2508
+ const completedTraces = [];
2509
+ const createCapabilityTraceBuilder = /* @__PURE__ */ __name((traceId, capId) => ({
2510
+ traceId,
2511
+ capabilityId: capId,
2512
+ hasCompleted: false,
2513
+ hasStartEntry: false
2514
+ }), "createCapabilityTraceBuilder");
2515
+ const shouldIncludeInCompletedTraces = /* @__PURE__ */ __name((builder) => {
2516
+ const alreadyAdded = completedTraces.some((trace) => trace.traceId === builder.traceId);
2517
+ if (alreadyAdded) {
2518
+ return false;
2519
+ }
2520
+ return builder.capabilityId === capabilityId;
2521
+ }, "shouldIncludeInCompletedTraces");
2522
+ const updateBuilderMetadata = /* @__PURE__ */ __name((builder, entry) => {
2523
+ if (entry.plugin_key && !builder.pluginKey) {
2524
+ builder.pluginKey = String(entry.plugin_key);
2525
+ }
2526
+ if (entry.action && !builder.action) {
2527
+ builder.action = String(entry.action);
2528
+ }
2529
+ const message = entry.message || "";
2530
+ if (message.includes("Executing capability") && !builder.hasStartEntry) {
2531
+ builder.hasStartEntry = true;
2532
+ builder.startTime = entry.time;
2533
+ if (entry.input) {
2534
+ builder.input = String(entry.input);
2535
+ }
2536
+ }
2537
+ if (message.includes("executed successfully")) {
2538
+ builder.hasCompleted = true;
2539
+ builder.endTime = entry.time;
2540
+ builder.status = "success";
2541
+ if (entry.output) {
2542
+ builder.output = String(entry.output);
2543
+ }
2544
+ if (entry.duration_ms) {
2545
+ builder.durationMs = Number(entry.duration_ms);
2546
+ }
2547
+ if (shouldIncludeInCompletedTraces(builder)) {
2548
+ completedTraces.push(builder);
2549
+ }
2550
+ }
2551
+ if (message.includes("execution failed")) {
2552
+ builder.hasCompleted = true;
2553
+ builder.endTime = entry.time;
2554
+ builder.status = "failed";
2555
+ if (entry.error) {
2556
+ builder.error = {
2557
+ message: String(entry.error)
2558
+ };
2559
+ }
2560
+ if (entry.duration_ms) {
2561
+ builder.durationMs = Number(entry.duration_ms);
2562
+ }
2563
+ if (shouldIncludeInCompletedTraces(builder)) {
2564
+ completedTraces.push(builder);
2565
+ }
2566
+ }
2567
+ }, "updateBuilderMetadata");
2568
+ const processLogEntry = /* @__PURE__ */ __name((entry) => {
2569
+ const { trace_id: traceId, capability_id: capId } = entry;
2570
+ if (!traceId || !capId || capId !== capabilityId) return;
2571
+ let builder = builders.get(traceId);
2572
+ if (!builder) {
2573
+ builder = createCapabilityTraceBuilder(traceId, capId);
2574
+ builders.set(traceId, builder);
2575
+ }
2576
+ updateBuilderMetadata(builder, entry);
2577
+ }, "processLogEntry");
2578
+ const processLine = /* @__PURE__ */ __name((line) => {
2579
+ const entry = parseLogLine2(line);
2580
+ if (entry?.capability_id) {
2581
+ processLogEntry(entry);
2582
+ }
2583
+ }, "processLine");
2584
+ await readFileReverse(filePath, config.chunkSize, processLine);
2585
+ completedTraces.sort((a, b) => {
2586
+ const timeA = a.endTime ? new Date(a.endTime).getTime() : 0;
2587
+ const timeB = b.endTime ? new Date(b.endTime).getTime() : 0;
2588
+ return timeB - timeA;
2589
+ });
2590
+ const limitedTraces = limit ? completedTraces.slice(0, limit) : completedTraces;
2591
+ return {
2592
+ capabilityId,
2593
+ totalTraces: limitedTraces.length,
2594
+ traces: limitedTraces.map((builder) => ({
2595
+ traceId: builder.traceId,
2596
+ capabilityId: builder.capabilityId,
2597
+ pluginKey: builder.pluginKey,
2598
+ action: builder.action,
2599
+ startTime: builder.startTime,
2600
+ endTime: builder.endTime,
2601
+ durationMs: builder.durationMs,
2602
+ status: builder.status || "failed",
2603
+ input: builder.input,
2604
+ output: builder.output,
2605
+ error: builder.error
2606
+ }))
2607
+ };
2608
+ }
2609
+ __name(readCapabilityTraceList, "readCapabilityTraceList");
2610
+
2486
2611
  // src/middlewares/dev-logs/controller.ts
2487
2612
  function handleNotFound(res, filePath, message = "Log file not found") {
2488
2613
  res.status(404).json({
@@ -2498,7 +2623,7 @@ function handleError(res, error, message = "Failed to read log file") {
2498
2623
  }
2499
2624
  __name(handleError, "handleError");
2500
2625
  function createGetTraceEntriesHandler(logDir) {
2501
- const appLogPath = join3(logDir, "server.log");
2626
+ const appLogPath = join4(logDir, "server.log");
2502
2627
  return async (req, res) => {
2503
2628
  const traceId = (req.params.traceId || "").trim();
2504
2629
  if (!traceId) {
@@ -2525,7 +2650,7 @@ function createGetTraceEntriesHandler(logDir) {
2525
2650
  }
2526
2651
  __name(createGetTraceEntriesHandler, "createGetTraceEntriesHandler");
2527
2652
  function createGetRecentTracesHandler(logDir) {
2528
- const traceLogPath = join3(logDir, "trace.log");
2653
+ const traceLogPath = join4(logDir, "trace.log");
2529
2654
  return async (req, res) => {
2530
2655
  const page = parsePositiveInt(req.query.page, 1);
2531
2656
  const pageSize = parseLimit(req.query.pageSize, 10, 100);
@@ -2602,7 +2727,7 @@ function createGetServerLogsHandler(logDir) {
2602
2727
  }
2603
2728
  __name(createGetServerLogsHandler, "createGetServerLogsHandler");
2604
2729
  function createGetTriggerListHandler(logDir) {
2605
- const traceLogPath = join3(logDir, "trace.log");
2730
+ const traceLogPath = join4(logDir, "trace.log");
2606
2731
  return async (req, res) => {
2607
2732
  const trigger = typeof req.query.trigger === "string" ? req.query.trigger.trim() : void 0;
2608
2733
  if (!trigger) {
@@ -2630,7 +2755,7 @@ function createGetTriggerListHandler(logDir) {
2630
2755
  }
2631
2756
  __name(createGetTriggerListHandler, "createGetTriggerListHandler");
2632
2757
  function createGetTriggerDetailHandler(logDir) {
2633
- const traceLogPath = join3(logDir, "server.log");
2758
+ const traceLogPath = join4(logDir, "server.log");
2634
2759
  return async (req, res) => {
2635
2760
  const instanceID = (req.params.instanceID || "").trim();
2636
2761
  if (!instanceID) {
@@ -2654,6 +2779,31 @@ function createGetTriggerDetailHandler(logDir) {
2654
2779
  };
2655
2780
  }
2656
2781
  __name(createGetTriggerDetailHandler, "createGetTriggerDetailHandler");
2782
+ function createGetCapabilityTraceListHandler(logDir) {
2783
+ const serverLogPath = join4(logDir, "server.log");
2784
+ return async (req, res) => {
2785
+ const capabilityId = typeof req.query.capability_id === "string" ? req.query.capability_id.trim() : void 0;
2786
+ if (!capabilityId) {
2787
+ return res.status(400).json({
2788
+ message: "capability_id is required"
2789
+ });
2790
+ }
2791
+ const limit = parseLimit(req.query.limit, 10, 200);
2792
+ try {
2793
+ const result = await readCapabilityTraceList(serverLogPath, capabilityId, limit);
2794
+ if (!result) {
2795
+ return handleNotFound(res, serverLogPath);
2796
+ }
2797
+ res.json({
2798
+ file: getRelativePath(serverLogPath),
2799
+ ...result
2800
+ });
2801
+ } catch (error) {
2802
+ handleError(res, error, "Failed to read server log");
2803
+ }
2804
+ };
2805
+ }
2806
+ __name(createGetCapabilityTraceListHandler, "createGetCapabilityTraceListHandler");
2657
2807
 
2658
2808
  // src/middlewares/dev-logs/health.controller.ts
2659
2809
  import http2 from "http";
@@ -2732,6 +2882,7 @@ function createDevLogRouter(options = {}) {
2732
2882
  router.get("/server-logs", createGetServerLogsHandler(logDir));
2733
2883
  router.get("/trace/trigger/list", createGetTriggerListHandler(logDir));
2734
2884
  router.get("/trace/trigger/:instanceID", createGetTriggerDetailHandler(logDir));
2885
+ router.get("/trace/capability/list", createGetCapabilityTraceListHandler(logDir));
2735
2886
  router.get("/health", createHealthCheckHandler());
2736
2887
  return router;
2737
2888
  }
@@ -2790,17 +2941,17 @@ __name(createDevLogsMiddleware, "createDevLogsMiddleware");
2790
2941
  import express3 from "express";
2791
2942
 
2792
2943
  // src/middlewares/collect-logs/controller.ts
2793
- import { join as join5 } from "path";
2944
+ import { join as join6 } from "path";
2794
2945
  import fs10 from "fs";
2795
2946
 
2796
2947
  // src/middlewares/collect-logs/utils.ts
2797
- import { isAbsolute as isAbsolute2, join as join4 } from "path";
2948
+ import { isAbsolute as isAbsolute2, join as join5 } from "path";
2798
2949
  import fs9 from "fs";
2799
2950
  function resolveLogDir2(provided) {
2800
2951
  if (!provided) {
2801
- return join4(process.cwd(), "logs");
2952
+ return join5(process.cwd(), "logs");
2802
2953
  }
2803
- return isAbsolute2(provided) ? provided : join4(process.cwd(), provided);
2954
+ return isAbsolute2(provided) ? provided : join5(process.cwd(), provided);
2804
2955
  }
2805
2956
  __name(resolveLogDir2, "resolveLogDir");
2806
2957
  function ensureDir(dir) {
@@ -2823,7 +2974,7 @@ __name(serializeError2, "serializeError");
2823
2974
 
2824
2975
  // src/middlewares/collect-logs/controller.ts
2825
2976
  function collectLogsHandler(logDir, fileName) {
2826
- const filePath = join5(logDir, fileName);
2977
+ const filePath = join6(logDir, fileName);
2827
2978
  ensureDir(logDir);
2828
2979
  return async (req, res) => {
2829
2980
  try {
@@ -2848,7 +2999,7 @@ function collectLogsHandler(logDir, fileName) {
2848
2999
  }
2849
3000
  __name(collectLogsHandler, "collectLogsHandler");
2850
3001
  function collectLogsBatchHandler(logDir, fileName) {
2851
- const filePath = join5(logDir, fileName);
3002
+ const filePath = join6(logDir, fileName);
2852
3003
  ensureDir(logDir);
2853
3004
  return async (req, res) => {
2854
3005
  try {