@lark-apaas/devtool-kits 1.2.12 → 1.2.14-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1435,8 +1435,8 @@ function checkForErrors(logs) {
1435
1435
  return false;
1436
1436
  }
1437
1437
  __name(checkForErrors, "checkForErrors");
1438
- function injectTemplateData(template, clientBasePath) {
1439
- return template.replace("{{.clientBasePath}}", clientBasePath);
1438
+ function injectTemplateData(template, clientBasePath, parentOrigin) {
1439
+ return template.replace("{{.clientBasePath}}", clientBasePath).replace("{{.parentOrigin}}", parentOrigin);
1440
1440
  }
1441
1441
  __name(injectTemplateData, "injectTemplateData");
1442
1442
  function handleDevProxyError(err, req, res, options) {
@@ -1474,7 +1474,8 @@ function handleDevProxyError(err, req, res, options) {
1474
1474
  console.log("[Proxy Error]: Compile error or non-connection error, showing error page");
1475
1475
  }
1476
1476
  const template = getErrorHtmlTemplate();
1477
- const html = injectTemplateData(template, clientBasePathWithoutSlash);
1477
+ const parentOrigin = process.env.FORCE_FRAMEWORK_DOMAIN_MAIN || "";
1478
+ const html = injectTemplateData(template, clientBasePathWithoutSlash, parentOrigin);
1478
1479
  res.writeHead(200, {
1479
1480
  "Content-Type": "text/html; charset=utf-8",
1480
1481
  "Cache-Control": "no-cache, no-store, must-revalidate",
@@ -1506,7 +1507,7 @@ function sendSimpleRedirect(req, res) {
1506
1507
  __name(sendSimpleRedirect, "sendSimpleRedirect");
1507
1508
 
1508
1509
  // src/middlewares/index.ts
1509
- var import_node_path9 = __toESM(require("path"), 1);
1510
+ var import_node_path10 = __toESM(require("path"), 1);
1510
1511
 
1511
1512
  // src/middlewares/openapi/router.ts
1512
1513
  var import_express = __toESM(require("express"), 1);
@@ -1949,10 +1950,194 @@ function serializeError(error) {
1949
1950
  __name(serializeError, "serializeError");
1950
1951
 
1951
1952
  // src/middlewares/dev-logs/controller.ts
1952
- var import_node_path7 = require("path");
1953
+ var import_node_path8 = require("path");
1953
1954
 
1954
- // src/middlewares/dev-logs/services.ts
1955
+ // src/middlewares/dev-logs/services/file-reader.ts
1955
1956
  var import_node_fs7 = require("fs");
1957
+ async function readFileReverse(filePath, chunkSize, processLine) {
1958
+ const handle = await import_node_fs7.promises.open(filePath, "r");
1959
+ try {
1960
+ const stats = await handle.stat();
1961
+ let position = stats.size;
1962
+ let remainder = "";
1963
+ while (position > 0) {
1964
+ const length = Math.min(chunkSize, position);
1965
+ position -= length;
1966
+ const buffer = Buffer.alloc(length);
1967
+ await handle.read(buffer, 0, length, position);
1968
+ let chunk = buffer.toString("utf8");
1969
+ if (remainder) {
1970
+ chunk += remainder;
1971
+ remainder = "";
1972
+ }
1973
+ const lines = chunk.split("\n");
1974
+ remainder = lines.shift() ?? "";
1975
+ for (let i = lines.length - 1; i >= 0; i -= 1) {
1976
+ if (lines[i]) {
1977
+ processLine(lines[i]);
1978
+ }
1979
+ }
1980
+ }
1981
+ if (remainder) {
1982
+ processLine(remainder);
1983
+ }
1984
+ } finally {
1985
+ await handle.close();
1986
+ }
1987
+ }
1988
+ __name(readFileReverse, "readFileReverse");
1989
+ function buildPaginatedResponse(items, page, pageSize) {
1990
+ const totalItems = items.length;
1991
+ const totalPages = totalItems === 0 ? 0 : Math.ceil(totalItems / pageSize);
1992
+ const startIndex = (page - 1) * pageSize;
1993
+ const endIndex = Math.min(startIndex + pageSize, totalItems);
1994
+ const pagedItems = items.slice(startIndex, endIndex).map((builder) => ({
1995
+ traceId: builder.traceId,
1996
+ method: builder.method,
1997
+ path: builder.path,
1998
+ startTime: builder.startTime,
1999
+ endTime: builder.endTime,
2000
+ statusCode: builder.statusCode,
2001
+ durationMs: builder.durationMs,
2002
+ entries: builder.entries.slice().reverse()
2003
+ }));
2004
+ return {
2005
+ page,
2006
+ pageSize,
2007
+ totalCalls: totalItems,
2008
+ totalPages,
2009
+ calls: pagedItems
2010
+ };
2011
+ }
2012
+ __name(buildPaginatedResponse, "buildPaginatedResponse");
2013
+
2014
+ // src/middlewares/dev-logs/services/parsers.ts
2015
+ function generateUUID() {
2016
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
2017
+ const r = Math.random() * 16 | 0;
2018
+ const v = c === "x" ? r : r & 3 | 8;
2019
+ return v.toString(16);
2020
+ });
2021
+ }
2022
+ __name(generateUUID, "generateUUID");
2023
+ function mapPinoLevelToServerLogLevel(pinoLevel) {
2024
+ if (typeof pinoLevel === "string") {
2025
+ const lower = pinoLevel.toLowerCase();
2026
+ if (lower === "fatal") return "fatal";
2027
+ if (lower === "error") return "error";
2028
+ if (lower === "warn" || lower === "warning") return "warn";
2029
+ if (lower === "info" || lower === "log") return "log";
2030
+ if (lower === "debug") return "debug";
2031
+ if (lower === "trace" || lower === "verbose") return "verbose";
2032
+ return "log";
2033
+ }
2034
+ if (pinoLevel >= 60) return "fatal";
2035
+ if (pinoLevel >= 50) return "error";
2036
+ if (pinoLevel >= 40) return "warn";
2037
+ if (pinoLevel >= 30) return "log";
2038
+ if (pinoLevel >= 20) return "debug";
2039
+ return "verbose";
2040
+ }
2041
+ __name(mapPinoLevelToServerLogLevel, "mapPinoLevelToServerLogLevel");
2042
+ function extractLogLevel(text) {
2043
+ const lower = text.toLowerCase();
2044
+ if (lower.includes("fatal") || lower.includes("critical")) return "fatal";
2045
+ if (lower.includes("error") || lower.includes("<e>") || lower.includes("\u2716")) return "error";
2046
+ if (lower.includes("warn") || lower.includes("warning") || lower.includes("<w>") || lower.includes("\u26A0")) return "warn";
2047
+ if (lower.includes("debug") || lower.includes("<d>")) return "debug";
2048
+ if (lower.includes("verbose") || lower.includes("trace")) return "verbose";
2049
+ return "log";
2050
+ }
2051
+ __name(extractLogLevel, "extractLogLevel");
2052
+ function parsePinoLog(line, source) {
2053
+ try {
2054
+ const pinoLog = JSON.parse(line);
2055
+ const id = generateUUID();
2056
+ return {
2057
+ id,
2058
+ level: mapPinoLevelToServerLogLevel(pinoLog.level),
2059
+ timestamp: new Date(pinoLog.time).getTime(),
2060
+ message: pinoLog.message || pinoLog.msg || "",
2061
+ context: pinoLog.context || null,
2062
+ traceId: pinoLog.trace_id || null,
2063
+ userId: pinoLog.user_id || null,
2064
+ appId: pinoLog.app_id || null,
2065
+ tenantId: pinoLog.tenant_id || null,
2066
+ stack: pinoLog.stack || null,
2067
+ meta: {
2068
+ pid: pinoLog.pid,
2069
+ hostname: pinoLog.hostname,
2070
+ path: pinoLog.path,
2071
+ method: pinoLog.method,
2072
+ statusCode: pinoLog.status_code,
2073
+ durationMs: pinoLog.duration_ms,
2074
+ ip: pinoLog.ip,
2075
+ requestBody: pinoLog.request_body,
2076
+ responseBody: pinoLog.response_body
2077
+ },
2078
+ tags: [
2079
+ source
2080
+ ]
2081
+ };
2082
+ } catch (error) {
2083
+ return null;
2084
+ }
2085
+ }
2086
+ __name(parsePinoLog, "parsePinoLog");
2087
+ function parseStdLog(line, source) {
2088
+ const id = generateUUID();
2089
+ const match = line.match(/^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\] \[(server|client)\] (.*)$/);
2090
+ if (!match) {
2091
+ return {
2092
+ id,
2093
+ level: "log",
2094
+ timestamp: Date.now(),
2095
+ message: line,
2096
+ context: null,
2097
+ traceId: null,
2098
+ userId: null,
2099
+ appId: null,
2100
+ tenantId: null,
2101
+ stack: null,
2102
+ meta: null,
2103
+ tags: [
2104
+ source
2105
+ ]
2106
+ };
2107
+ }
2108
+ const [, timeStr, , content] = match;
2109
+ let timestamp;
2110
+ try {
2111
+ const isoStr = timeStr.replace(" ", "T");
2112
+ timestamp = new Date(isoStr).getTime();
2113
+ if (isNaN(timestamp)) {
2114
+ timestamp = Date.now();
2115
+ }
2116
+ } catch (error) {
2117
+ timestamp = Date.now();
2118
+ }
2119
+ const level = extractLogLevel(content);
2120
+ return {
2121
+ id,
2122
+ level,
2123
+ timestamp,
2124
+ message: content,
2125
+ context: null,
2126
+ traceId: null,
2127
+ userId: null,
2128
+ appId: null,
2129
+ tenantId: null,
2130
+ stack: null,
2131
+ meta: null,
2132
+ tags: [
2133
+ source
2134
+ ]
2135
+ };
2136
+ }
2137
+ __name(parseStdLog, "parseStdLog");
2138
+
2139
+ // src/middlewares/dev-logs/services/trace.service.ts
2140
+ var import_node_fs8 = require("fs");
1956
2141
  var import_node_readline = require("readline");
1957
2142
  async function readLogEntriesByTrace(filePath, traceId, limit) {
1958
2143
  const exists = await fileExists(filePath);
@@ -1960,7 +2145,7 @@ async function readLogEntriesByTrace(filePath, traceId, limit) {
1960
2145
  return void 0;
1961
2146
  }
1962
2147
  const matches = [];
1963
- const stream = (0, import_node_fs7.createReadStream)(filePath, {
2148
+ const stream = (0, import_node_fs8.createReadStream)(filePath, {
1964
2149
  encoding: "utf8"
1965
2150
  });
1966
2151
  const rl = (0, import_node_readline.createInterface)({
@@ -2051,62 +2236,6 @@ async function readRecentTraceCalls(filePath, page, pageSize, pathFilter, method
2051
2236
  return buildPaginatedResponse(completedCalls, page, pageSize);
2052
2237
  }
2053
2238
  __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
2239
  async function readLogFilePage(filePath, page, pageSize) {
2111
2240
  if (!await fileExists(filePath)) {
2112
2241
  return void 0;
@@ -2114,7 +2243,7 @@ async function readLogFilePage(filePath, page, pageSize) {
2114
2243
  const capacity = page * pageSize;
2115
2244
  const buffer = [];
2116
2245
  let totalLines = 0;
2117
- const stream = (0, import_node_fs7.createReadStream)(filePath, {
2246
+ const stream = (0, import_node_fs8.createReadStream)(filePath, {
2118
2247
  encoding: "utf8"
2119
2248
  });
2120
2249
  const rl = (0, import_node_readline.createInterface)({
@@ -2162,6 +2291,11 @@ async function readLogFilePage(filePath, page, pageSize) {
2162
2291
  };
2163
2292
  }
2164
2293
  __name(readLogFilePage, "readLogFilePage");
2294
+
2295
+ // src/middlewares/dev-logs/services/server-log.service.ts
2296
+ var import_node_fs9 = require("fs");
2297
+ var import_node_readline2 = require("readline");
2298
+ var import_node_path7 = require("path");
2165
2299
  async function readServerLogs(logDir, options = {}) {
2166
2300
  const limit = options.limit || 100;
2167
2301
  const offset = options.offset || 0;
@@ -2204,20 +2338,19 @@ async function readServerLogs(logDir, options = {}) {
2204
2338
  }
2205
2339
  __name(readServerLogs, "readServerLogs");
2206
2340
  async function readLogsBySource(logDir, source) {
2207
- const { join: join7 } = await import("path");
2208
2341
  let filePath;
2209
2342
  let parser;
2210
2343
  if (source === "server") {
2211
- filePath = join7(logDir, "server.log");
2344
+ filePath = (0, import_node_path7.join)(logDir, "server.log");
2212
2345
  parser = /* @__PURE__ */ __name((line) => parsePinoLog(line, "server"), "parser");
2213
2346
  } else if (source === "trace") {
2214
- filePath = join7(logDir, "trace.log");
2347
+ filePath = (0, import_node_path7.join)(logDir, "trace.log");
2215
2348
  parser = /* @__PURE__ */ __name((line) => parsePinoLog(line, "trace"), "parser");
2216
2349
  } else if (source === "server-std") {
2217
- filePath = join7(logDir, "server.std.log");
2350
+ filePath = (0, import_node_path7.join)(logDir, "server.std.log");
2218
2351
  parser = /* @__PURE__ */ __name((line) => parseStdLog(line, "server-std"), "parser");
2219
2352
  } else if (source === "client-std") {
2220
- filePath = join7(logDir, "client.std.log");
2353
+ filePath = (0, import_node_path7.join)(logDir, "client.std.log");
2221
2354
  parser = /* @__PURE__ */ __name((line) => parseStdLog(line, "client-std"), "parser");
2222
2355
  } else {
2223
2356
  console.warn(`[readLogsBySource] Unknown source: ${source}`);
@@ -2231,10 +2364,10 @@ async function readLogsBySource(logDir, source) {
2231
2364
  let stream = null;
2232
2365
  let rl = null;
2233
2366
  try {
2234
- stream = (0, import_node_fs7.createReadStream)(filePath, {
2367
+ stream = (0, import_node_fs9.createReadStream)(filePath, {
2235
2368
  encoding: "utf8"
2236
2369
  });
2237
- rl = (0, import_node_readline.createInterface)({
2370
+ rl = (0, import_node_readline2.createInterface)({
2238
2371
  input: stream,
2239
2372
  crlfDelay: Infinity
2240
2373
  });
@@ -2262,129 +2395,10 @@ async function readLogsBySource(logDir, source) {
2262
2395
  return logs;
2263
2396
  }
2264
2397
  __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");
2398
+
2399
+ // src/middlewares/dev-logs/services/trigger.service.ts
2400
+ var import_node_fs10 = require("fs");
2401
+ var import_node_readline3 = require("readline");
2388
2402
  async function readTriggerList(filePath, trigger, path8, limit, triggerID) {
2389
2403
  if (!await fileExists(filePath)) {
2390
2404
  return void 0;
@@ -2500,10 +2514,10 @@ async function readTriggerDetail(filePath, path8, instanceID) {
2500
2514
  return void 0;
2501
2515
  }
2502
2516
  const matches = [];
2503
- const stream = (0, import_node_fs7.createReadStream)(filePath, {
2517
+ const stream = (0, import_node_fs10.createReadStream)(filePath, {
2504
2518
  encoding: "utf8"
2505
2519
  });
2506
- const rl = (0, import_node_readline.createInterface)({
2520
+ const rl = (0, import_node_readline3.createInterface)({
2507
2521
  input: stream,
2508
2522
  crlfDelay: Infinity
2509
2523
  });
@@ -2524,6 +2538,118 @@ async function readTriggerDetail(filePath, path8, instanceID) {
2524
2538
  }
2525
2539
  __name(readTriggerDetail, "readTriggerDetail");
2526
2540
 
2541
+ // src/middlewares/dev-logs/services/capability.service.ts
2542
+ async function readCapabilityTraceList(filePath, capabilityId, limit) {
2543
+ if (!await fileExists(filePath)) {
2544
+ return void 0;
2545
+ }
2546
+ const config = {
2547
+ chunkSize: 64 * 1024
2548
+ };
2549
+ const builders = /* @__PURE__ */ new Map();
2550
+ const completedTraces = [];
2551
+ const createCapabilityTraceBuilder = /* @__PURE__ */ __name((traceId, capId) => ({
2552
+ traceId,
2553
+ capabilityId: capId,
2554
+ hasCompleted: false,
2555
+ hasStartEntry: false
2556
+ }), "createCapabilityTraceBuilder");
2557
+ const shouldIncludeInCompletedTraces = /* @__PURE__ */ __name((builder) => {
2558
+ const alreadyAdded = completedTraces.some((trace) => trace.traceId === builder.traceId);
2559
+ if (alreadyAdded) {
2560
+ return false;
2561
+ }
2562
+ return builder.capabilityId === capabilityId;
2563
+ }, "shouldIncludeInCompletedTraces");
2564
+ const updateBuilderMetadata = /* @__PURE__ */ __name((builder, entry) => {
2565
+ if (entry.plugin_key && !builder.pluginKey) {
2566
+ builder.pluginKey = String(entry.plugin_key);
2567
+ }
2568
+ if (entry.action && !builder.action) {
2569
+ builder.action = String(entry.action);
2570
+ }
2571
+ const message = entry.message || "";
2572
+ if (message.includes("Executing capability") && !builder.hasStartEntry) {
2573
+ builder.hasStartEntry = true;
2574
+ builder.startTime = entry.time;
2575
+ if (entry.input) {
2576
+ builder.input = String(entry.input);
2577
+ }
2578
+ }
2579
+ if (message.includes("executed successfully")) {
2580
+ builder.hasCompleted = true;
2581
+ builder.endTime = entry.time;
2582
+ builder.status = "success";
2583
+ if (entry.output) {
2584
+ builder.output = String(entry.output);
2585
+ }
2586
+ if (entry.duration_ms) {
2587
+ builder.durationMs = Number(entry.duration_ms);
2588
+ }
2589
+ if (shouldIncludeInCompletedTraces(builder)) {
2590
+ completedTraces.push(builder);
2591
+ }
2592
+ }
2593
+ if (message.includes("execution failed")) {
2594
+ builder.hasCompleted = true;
2595
+ builder.endTime = entry.time;
2596
+ builder.status = "failed";
2597
+ if (entry.error) {
2598
+ builder.error = {
2599
+ message: String(entry.error)
2600
+ };
2601
+ }
2602
+ if (entry.duration_ms) {
2603
+ builder.durationMs = Number(entry.duration_ms);
2604
+ }
2605
+ if (shouldIncludeInCompletedTraces(builder)) {
2606
+ completedTraces.push(builder);
2607
+ }
2608
+ }
2609
+ }, "updateBuilderMetadata");
2610
+ const processLogEntry = /* @__PURE__ */ __name((entry) => {
2611
+ const { trace_id: traceId, capability_id: capId } = entry;
2612
+ if (!traceId || !capId || capId !== capabilityId) return;
2613
+ let builder = builders.get(traceId);
2614
+ if (!builder) {
2615
+ builder = createCapabilityTraceBuilder(traceId, capId);
2616
+ builders.set(traceId, builder);
2617
+ }
2618
+ updateBuilderMetadata(builder, entry);
2619
+ }, "processLogEntry");
2620
+ const processLine = /* @__PURE__ */ __name((line) => {
2621
+ const entry = parseLogLine2(line);
2622
+ if (entry?.capability_id) {
2623
+ processLogEntry(entry);
2624
+ }
2625
+ }, "processLine");
2626
+ await readFileReverse(filePath, config.chunkSize, processLine);
2627
+ completedTraces.sort((a, b) => {
2628
+ const timeA = a.endTime ? new Date(a.endTime).getTime() : 0;
2629
+ const timeB = b.endTime ? new Date(b.endTime).getTime() : 0;
2630
+ return timeB - timeA;
2631
+ });
2632
+ const limitedTraces = limit ? completedTraces.slice(0, limit) : completedTraces;
2633
+ return {
2634
+ capabilityId,
2635
+ totalTraces: limitedTraces.length,
2636
+ traces: limitedTraces.map((builder) => ({
2637
+ traceId: builder.traceId,
2638
+ capabilityId: builder.capabilityId,
2639
+ pluginKey: builder.pluginKey,
2640
+ action: builder.action,
2641
+ startTime: builder.startTime,
2642
+ endTime: builder.endTime,
2643
+ durationMs: builder.durationMs,
2644
+ status: builder.status || "failed",
2645
+ input: builder.input,
2646
+ output: builder.output,
2647
+ error: builder.error
2648
+ }))
2649
+ };
2650
+ }
2651
+ __name(readCapabilityTraceList, "readCapabilityTraceList");
2652
+
2527
2653
  // src/middlewares/dev-logs/controller.ts
2528
2654
  function handleNotFound(res, filePath, message = "Log file not found") {
2529
2655
  res.status(404).json({
@@ -2539,7 +2665,7 @@ function handleError(res, error, message = "Failed to read log file") {
2539
2665
  }
2540
2666
  __name(handleError, "handleError");
2541
2667
  function createGetTraceEntriesHandler(logDir) {
2542
- const appLogPath = (0, import_node_path7.join)(logDir, "server.log");
2668
+ const appLogPath = (0, import_node_path8.join)(logDir, "server.log");
2543
2669
  return async (req, res) => {
2544
2670
  const traceId = (req.params.traceId || "").trim();
2545
2671
  if (!traceId) {
@@ -2566,7 +2692,7 @@ function createGetTraceEntriesHandler(logDir) {
2566
2692
  }
2567
2693
  __name(createGetTraceEntriesHandler, "createGetTraceEntriesHandler");
2568
2694
  function createGetRecentTracesHandler(logDir) {
2569
- const traceLogPath = (0, import_node_path7.join)(logDir, "trace.log");
2695
+ const traceLogPath = (0, import_node_path8.join)(logDir, "trace.log");
2570
2696
  return async (req, res) => {
2571
2697
  const page = parsePositiveInt(req.query.page, 1);
2572
2698
  const pageSize = parseLimit(req.query.pageSize, 10, 100);
@@ -2643,7 +2769,7 @@ function createGetServerLogsHandler(logDir) {
2643
2769
  }
2644
2770
  __name(createGetServerLogsHandler, "createGetServerLogsHandler");
2645
2771
  function createGetTriggerListHandler(logDir) {
2646
- const traceLogPath = (0, import_node_path7.join)(logDir, "trace.log");
2772
+ const traceLogPath = (0, import_node_path8.join)(logDir, "trace.log");
2647
2773
  return async (req, res) => {
2648
2774
  const trigger = typeof req.query.trigger === "string" ? req.query.trigger.trim() : void 0;
2649
2775
  if (!trigger) {
@@ -2671,7 +2797,7 @@ function createGetTriggerListHandler(logDir) {
2671
2797
  }
2672
2798
  __name(createGetTriggerListHandler, "createGetTriggerListHandler");
2673
2799
  function createGetTriggerDetailHandler(logDir) {
2674
- const traceLogPath = (0, import_node_path7.join)(logDir, "server.log");
2800
+ const traceLogPath = (0, import_node_path8.join)(logDir, "server.log");
2675
2801
  return async (req, res) => {
2676
2802
  const instanceID = (req.params.instanceID || "").trim();
2677
2803
  if (!instanceID) {
@@ -2695,6 +2821,31 @@ function createGetTriggerDetailHandler(logDir) {
2695
2821
  };
2696
2822
  }
2697
2823
  __name(createGetTriggerDetailHandler, "createGetTriggerDetailHandler");
2824
+ function createGetCapabilityTraceListHandler(logDir) {
2825
+ const serverLogPath = (0, import_node_path8.join)(logDir, "server.log");
2826
+ return async (req, res) => {
2827
+ const capabilityId = typeof req.query.capability_id === "string" ? req.query.capability_id.trim() : void 0;
2828
+ if (!capabilityId) {
2829
+ return res.status(400).json({
2830
+ message: "capability_id is required"
2831
+ });
2832
+ }
2833
+ const limit = parseLimit(req.query.limit, 10, 200);
2834
+ try {
2835
+ const result = await readCapabilityTraceList(serverLogPath, capabilityId, limit);
2836
+ if (!result) {
2837
+ return handleNotFound(res, serverLogPath);
2838
+ }
2839
+ res.json({
2840
+ file: getRelativePath(serverLogPath),
2841
+ ...result
2842
+ });
2843
+ } catch (error) {
2844
+ handleError(res, error, "Failed to read server log");
2845
+ }
2846
+ };
2847
+ }
2848
+ __name(createGetCapabilityTraceListHandler, "createGetCapabilityTraceListHandler");
2698
2849
 
2699
2850
  // src/middlewares/dev-logs/health.controller.ts
2700
2851
  var import_node_http2 = __toESM(require("http"), 1);
@@ -3289,6 +3440,7 @@ function createDevLogRouter(options = {}) {
3289
3440
  router.get("/server-logs/stream", createSSEHandler(logDir));
3290
3441
  router.get("/trace/trigger/list", createGetTriggerListHandler(logDir));
3291
3442
  router.get("/trace/trigger/:instanceID", createGetTriggerDetailHandler(logDir));
3443
+ router.get("/trace/capability/list", createGetCapabilityTraceListHandler(logDir));
3292
3444
  router.get("/health", createHealthCheckHandler());
3293
3445
  return router;
3294
3446
  }
@@ -3351,18 +3503,18 @@ var import_path2 = require("path");
3351
3503
  var import_fs2 = __toESM(require("fs"), 1);
3352
3504
 
3353
3505
  // src/middlewares/collect-logs/utils.ts
3354
- var import_node_path8 = require("path");
3355
- var import_node_fs8 = __toESM(require("fs"), 1);
3506
+ var import_node_path9 = require("path");
3507
+ var import_node_fs11 = __toESM(require("fs"), 1);
3356
3508
  function resolveLogDir2(provided) {
3357
3509
  if (!provided) {
3358
- return (0, import_node_path8.join)(process.cwd(), "logs");
3510
+ return (0, import_node_path9.join)(process.cwd(), "logs");
3359
3511
  }
3360
- return (0, import_node_path8.isAbsolute)(provided) ? provided : (0, import_node_path8.join)(process.cwd(), provided);
3512
+ return (0, import_node_path9.isAbsolute)(provided) ? provided : (0, import_node_path9.join)(process.cwd(), provided);
3361
3513
  }
3362
3514
  __name(resolveLogDir2, "resolveLogDir");
3363
3515
  function ensureDir(dir) {
3364
- if (!import_node_fs8.default.existsSync(dir)) {
3365
- import_node_fs8.default.mkdirSync(dir, {
3516
+ if (!import_node_fs11.default.existsSync(dir)) {
3517
+ import_node_fs11.default.mkdirSync(dir, {
3366
3518
  recursive: true
3367
3519
  });
3368
3520
  }
@@ -3485,7 +3637,7 @@ function isGlobalMiddleware(middleware) {
3485
3637
  }
3486
3638
  __name(isGlobalMiddleware, "isGlobalMiddleware");
3487
3639
  function computeMountPath(basePath, mountPath) {
3488
- const routePath = import_node_path9.default.posix.join(basePath, mountPath);
3640
+ const routePath = import_node_path10.default.posix.join(basePath, mountPath);
3489
3641
  return routePath.startsWith("/") ? routePath : `/${routePath}`;
3490
3642
  }
3491
3643
  __name(computeMountPath, "computeMountPath");
@@ -3493,7 +3645,7 @@ function logMiddlewareRegistration(middleware, fullMountPath) {
3493
3645
  if (middleware.routes && middleware.routes.length > 0) {
3494
3646
  console.log(`[Middleware] Registered: ${middleware.name} at ${fullMountPath}`);
3495
3647
  middleware.routes.forEach((route) => {
3496
- const routePath = route.path === "/" ? fullMountPath : import_node_path9.default.posix.join(fullMountPath, route.path);
3648
+ const routePath = route.path === "/" ? fullMountPath : import_node_path10.default.posix.join(fullMountPath, route.path);
3497
3649
  console.log(` ${route.method} ${routePath} - ${route.description}`);
3498
3650
  });
3499
3651
  } else {