@pensar/apex 0.0.15 → 0.0.16

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.
@@ -44745,9 +44745,13 @@ Objective: ${objective}`,
44745
44745
  currentAssistantText += delta.text;
44746
44746
  const lastMessage = allMessages[allMessages.length - 1];
44747
44747
  if (lastMessage && lastMessage.role === "assistant") {
44748
- lastMessage.content = currentAssistantText;
44748
+ const updatedMessage = {
44749
+ ...lastMessage,
44750
+ content: currentAssistantText
44751
+ };
44752
+ allMessages[allMessages.length - 1] = updatedMessage;
44749
44753
  if (onSubagentMessage) {
44750
- onSubagentMessage(subagentId, lastMessage);
44754
+ onSubagentMessage(subagentId, updatedMessage);
44751
44755
  }
44752
44756
  } else {
44753
44757
  const newMessage = {
@@ -44781,10 +44785,14 @@ Objective: ${objective}`,
44781
44785
  const existingToolMessageIndex = allMessages.findIndex((msg) => msg.role === "tool" && msg.toolCallId === delta.toolCallId);
44782
44786
  if (existingToolMessageIndex !== -1) {
44783
44787
  const existingMessage = allMessages[existingToolMessageIndex];
44784
- existingMessage.status = "completed";
44785
- existingMessage.content = delta.input.toolCallDescription ? `✓ ${delta.input.toolCallDescription}` : `✓ Tool ${delta.toolName}`;
44788
+ const updatedMessage = {
44789
+ ...existingMessage,
44790
+ status: "completed",
44791
+ content: delta.input.toolCallDescription ? `✓ ${delta.input.toolCallDescription}` : `✓ Tool ${delta.toolName}`
44792
+ };
44793
+ allMessages[existingToolMessageIndex] = updatedMessage;
44786
44794
  if (onSubagentMessage) {
44787
- onSubagentMessage(subagentId, existingMessage);
44795
+ onSubagentMessage(subagentId, updatedMessage);
44788
44796
  }
44789
44797
  }
44790
44798
  }
@@ -44913,9 +44921,13 @@ Objective: ${targetInfo.objective}`,
44913
44921
  currentAssistantText += delta.text;
44914
44922
  const lastMessage = allMessages[allMessages.length - 1];
44915
44923
  if (lastMessage && lastMessage.role === "assistant") {
44916
- lastMessage.content = currentAssistantText;
44924
+ const updatedMessage = {
44925
+ ...lastMessage,
44926
+ content: currentAssistantText
44927
+ };
44928
+ allMessages[allMessages.length - 1] = updatedMessage;
44917
44929
  if (onSubagentMessage) {
44918
- onSubagentMessage(subagentId, lastMessage);
44930
+ onSubagentMessage(subagentId, updatedMessage);
44919
44931
  }
44920
44932
  } else {
44921
44933
  const newMessage = {
@@ -44949,10 +44961,14 @@ Objective: ${targetInfo.objective}`,
44949
44961
  const existingToolMessageIndex = allMessages.findIndex((msg) => msg.role === "tool" && msg.toolCallId === delta.toolCallId);
44950
44962
  if (existingToolMessageIndex !== -1) {
44951
44963
  const existingMessage = allMessages[existingToolMessageIndex];
44952
- existingMessage.status = "completed";
44953
- existingMessage.content = delta.input.toolCallDescription ? `✓ ${delta.input.toolCallDescription}` : `✓ Tool ${delta.toolName}`;
44964
+ const updatedMessage = {
44965
+ ...existingMessage,
44966
+ status: "completed",
44967
+ content: delta.input.toolCallDescription ? `✓ ${delta.input.toolCallDescription}` : `✓ Tool ${delta.toolName}`
44968
+ };
44969
+ allMessages[existingToolMessageIndex] = updatedMessage;
44954
44970
  if (onSubagentMessage) {
44955
- onSubagentMessage(subagentId, existingMessage);
44971
+ onSubagentMessage(subagentId, updatedMessage);
44956
44972
  }
44957
44973
  }
44958
44974
  }
package/build/index.js CHANGED
@@ -74997,32 +74997,24 @@ var Qt = b.parse;
74997
74997
  var Ut = x.lex;
74998
74998
 
74999
74999
  // src/tui/components/agent-display.tsx
75000
- var messageIdCacheByContext = new Map;
75001
- var idCounter2 = 0;
75002
- function getCacheForContext(contextId) {
75003
- let cache = messageIdCacheByContext.get(contextId);
75004
- if (!cache) {
75005
- cache = new WeakMap;
75006
- messageIdCacheByContext.set(contextId, cache);
75007
- }
75008
- return cache;
75000
+ import fs3 from "fs";
75001
+ var LOG_FILE = "/tmp/apex-debug.log";
75002
+ function logToFile(message, data) {
75003
+ const timestamp = new Date().toISOString();
75004
+ const logLine = `[${timestamp}] ${message} ${data ? JSON.stringify(data, null, 2) : ""}
75005
+ `;
75006
+ fs3.appendFileSync(LOG_FILE, logLine);
75009
75007
  }
75010
75008
  function getStableKey(item, contextId = "root") {
75011
- const cache = getCacheForContext(contextId);
75012
- let cachedId = cache.get(item);
75013
- if (cachedId) {
75014
- return cachedId;
75015
- }
75016
- let newId;
75017
75009
  if ("messages" in item) {
75018
- newId = `subagent-${item.id}`;
75010
+ return `subagent-${item.id}`;
75019
75011
  } else if (item.role === "tool" && "toolCallId" in item) {
75020
- newId = `${contextId}-tool-${item.toolCallId}`;
75012
+ return `${contextId}-tool-${item.toolCallId}`;
75021
75013
  } else {
75022
- newId = `${contextId}-${item.role}-${item.createdAt.getTime()}-${idCounter2++}`;
75014
+ const content = typeof item.content === "string" ? item.content : JSON.stringify(item.content);
75015
+ const contentHash = content.length;
75016
+ return `${contextId}-${item.role}-${item.createdAt.getTime()}-${contentHash}`;
75023
75017
  }
75024
- cache.set(item, newId);
75025
- return newId;
75026
75018
  }
75027
75019
  function markdownToStyledText(content) {
75028
75020
  try {
@@ -75195,8 +75187,14 @@ function AgentDisplay({
75195
75187
  ]
75196
75188
  }, undefined, true, undefined, this);
75197
75189
  }
75198
- function SubAgentDisplay({ subagent }) {
75190
+ var SubAgentDisplay = import_react19.memo(function SubAgentDisplay2({ subagent }) {
75199
75191
  const [open, setOpen] = import_react19.useState(false);
75192
+ logToFile(`[Render] SubAgentDisplay for ${subagent.id}:`, {
75193
+ name: subagent.name,
75194
+ nameLength: subagent.name?.length || 0,
75195
+ status: subagent.status,
75196
+ messageCount: subagent.messages.length
75197
+ });
75200
75198
  return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
75201
75199
  height: open ? 40 : "auto",
75202
75200
  onMouseDown: () => setOpen(!open),
@@ -75242,8 +75240,8 @@ function SubAgentDisplay({ subagent }) {
75242
75240
  }, undefined, false, undefined, this)
75243
75241
  ]
75244
75242
  }, undefined, true, undefined, this);
75245
- }
75246
- function AgentMessage({ message }) {
75243
+ });
75244
+ var AgentMessage = import_react19.memo(function AgentMessage2({ message }) {
75247
75245
  let content = "";
75248
75246
  if (typeof message.content === "string") {
75249
75247
  content = message.content;
@@ -75258,6 +75256,15 @@ function AgentMessage({ message }) {
75258
75256
  } else {
75259
75257
  content = JSON.stringify(message.content, null, 2);
75260
75258
  }
75259
+ if (message.role === "tool") {
75260
+ logToFile(`[Render] AgentMessage (tool):`, {
75261
+ toolCallId: message.toolCallId,
75262
+ content: content.substring(0, 50),
75263
+ contentLength: content.length,
75264
+ isEmpty: content === "",
75265
+ status: message.status
75266
+ });
75267
+ }
75261
75268
  const displayContent = message.role === "assistant" ? markdownToStyledText(content) : content;
75262
75269
  const isPendingTool = message.role === "tool" && message.status === "pending";
75263
75270
  return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
@@ -75304,7 +75311,7 @@ function AgentMessage({ message }) {
75304
75311
  }, undefined, false, undefined, this)
75305
75312
  ]
75306
75313
  }, undefined, true, undefined, this);
75307
- }
75314
+ });
75308
75315
  function ToolArgs({ message }) {
75309
75316
  const [open, setOpen] = import_react19.useState(false);
75310
75317
  if (message.role !== "tool" || !("args" in message)) {
@@ -75312,7 +75319,10 @@ function ToolArgs({ message }) {
75312
75319
  }
75313
75320
  const args = message.args;
75314
75321
  return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
75315
- onMouseDown: () => setOpen(!open),
75322
+ onMouseDown: (e) => {
75323
+ e.stopPropagation();
75324
+ setOpen(!open);
75325
+ },
75316
75326
  children: [
75317
75327
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
75318
75328
  flexDirection: "row",
@@ -75330,28 +75340,28 @@ function ToolArgs({ message }) {
75330
75340
  }
75331
75341
 
75332
75342
  // src/tui/components/commands/pentest-agent-display.tsx
75333
- import fs4 from "fs";
75343
+ import fs5 from "fs";
75334
75344
 
75335
75345
  // src/core/messages/index.ts
75336
- import fs3 from "fs";
75346
+ import fs4 from "fs";
75337
75347
  function getMessages(session) {
75338
- const messages = fs3.readFileSync(session.rootPath + "/messages.json", "utf8");
75348
+ const messages = fs4.readFileSync(session.rootPath + "/messages.json", "utf8");
75339
75349
  return JSON.parse(messages);
75340
75350
  }
75341
75351
  function saveMessages(session, messages) {
75342
- fs3.writeFileSync(session.rootPath + "/messages.json", JSON.stringify(messages, null, 2));
75352
+ fs4.writeFileSync(session.rootPath + "/messages.json", JSON.stringify(messages, null, 2));
75343
75353
  }
75344
75354
  function saveSubagentMessages(orchestratorSession, subagentId, messages) {
75345
75355
  const subagentDir = `${orchestratorSession.rootPath}/subagents/${subagentId}`;
75346
- if (!fs3.existsSync(`${orchestratorSession.rootPath}/subagents`)) {
75347
- fs3.mkdirSync(`${orchestratorSession.rootPath}/subagents`, {
75356
+ if (!fs4.existsSync(`${orchestratorSession.rootPath}/subagents`)) {
75357
+ fs4.mkdirSync(`${orchestratorSession.rootPath}/subagents`, {
75348
75358
  recursive: true
75349
75359
  });
75350
75360
  }
75351
- if (!fs3.existsSync(subagentDir)) {
75352
- fs3.mkdirSync(subagentDir, { recursive: true });
75361
+ if (!fs4.existsSync(subagentDir)) {
75362
+ fs4.mkdirSync(subagentDir, { recursive: true });
75353
75363
  }
75354
- fs3.writeFileSync(`${subagentDir}/messages.json`, JSON.stringify(messages, null, 2));
75364
+ fs4.writeFileSync(`${subagentDir}/messages.json`, JSON.stringify(messages, null, 2));
75355
75365
  }
75356
75366
 
75357
75367
  // src/tui/components/commands/pentest-agent-display.tsx
@@ -75492,7 +75502,7 @@ Path: ${result.session.rootPath}`,
75492
75502
  }
75493
75503
  saveMessages(result.session, allMessages);
75494
75504
  }
75495
- if (fs4.existsSync(result.session.rootPath + "/pentest-report.md")) {
75505
+ if (fs5.existsSync(result.session.rootPath + "/pentest-report.md")) {
75496
75506
  setIsCompleted(true);
75497
75507
  }
75498
75508
  setThinking(false);
@@ -75664,7 +75674,7 @@ var import_react23 = __toESM(require_react(), 1);
75664
75674
 
75665
75675
  // src/tui/components/hooks/thoroughPentestAgent.ts
75666
75676
  var import_react22 = __toESM(require_react(), 1);
75667
- import fs5 from "fs";
75677
+ import fs6 from "fs";
75668
75678
 
75669
75679
  // src/core/agent/thoroughPentestAgent/prompts.ts
75670
75680
  var SYSTEM2 = `You are an expert penetration testing orchestrator agent specializing in coordinating comprehensive security assessments. Your role is to AUTONOMOUSLY manage a complete penetration testing engagement by coordinating specialized sub-agents.
@@ -77751,9 +77761,13 @@ Objective: ${objective}`,
77751
77761
  currentAssistantText += delta.text;
77752
77762
  const lastMessage = allMessages[allMessages.length - 1];
77753
77763
  if (lastMessage && lastMessage.role === "assistant") {
77754
- lastMessage.content = currentAssistantText;
77764
+ const updatedMessage = {
77765
+ ...lastMessage,
77766
+ content: currentAssistantText
77767
+ };
77768
+ allMessages[allMessages.length - 1] = updatedMessage;
77755
77769
  if (onSubagentMessage) {
77756
- onSubagentMessage(subagentId, lastMessage);
77770
+ onSubagentMessage(subagentId, updatedMessage);
77757
77771
  }
77758
77772
  } else {
77759
77773
  const newMessage = {
@@ -77787,10 +77801,14 @@ Objective: ${objective}`,
77787
77801
  const existingToolMessageIndex = allMessages.findIndex((msg) => msg.role === "tool" && msg.toolCallId === delta.toolCallId);
77788
77802
  if (existingToolMessageIndex !== -1) {
77789
77803
  const existingMessage = allMessages[existingToolMessageIndex];
77790
- existingMessage.status = "completed";
77791
- existingMessage.content = delta.input.toolCallDescription ? `✓ ${delta.input.toolCallDescription}` : `✓ Tool ${delta.toolName}`;
77804
+ const updatedMessage = {
77805
+ ...existingMessage,
77806
+ status: "completed",
77807
+ content: delta.input.toolCallDescription ? `✓ ${delta.input.toolCallDescription}` : `✓ Tool ${delta.toolName}`
77808
+ };
77809
+ allMessages[existingToolMessageIndex] = updatedMessage;
77792
77810
  if (onSubagentMessage) {
77793
- onSubagentMessage(subagentId, existingMessage);
77811
+ onSubagentMessage(subagentId, updatedMessage);
77794
77812
  }
77795
77813
  }
77796
77814
  }
@@ -77919,9 +77937,13 @@ Objective: ${targetInfo.objective}`,
77919
77937
  currentAssistantText += delta.text;
77920
77938
  const lastMessage = allMessages[allMessages.length - 1];
77921
77939
  if (lastMessage && lastMessage.role === "assistant") {
77922
- lastMessage.content = currentAssistantText;
77940
+ const updatedMessage = {
77941
+ ...lastMessage,
77942
+ content: currentAssistantText
77943
+ };
77944
+ allMessages[allMessages.length - 1] = updatedMessage;
77923
77945
  if (onSubagentMessage) {
77924
- onSubagentMessage(subagentId, lastMessage);
77946
+ onSubagentMessage(subagentId, updatedMessage);
77925
77947
  }
77926
77948
  } else {
77927
77949
  const newMessage = {
@@ -77955,10 +77977,14 @@ Objective: ${targetInfo.objective}`,
77955
77977
  const existingToolMessageIndex = allMessages.findIndex((msg) => msg.role === "tool" && msg.toolCallId === delta.toolCallId);
77956
77978
  if (existingToolMessageIndex !== -1) {
77957
77979
  const existingMessage = allMessages[existingToolMessageIndex];
77958
- existingMessage.status = "completed";
77959
- existingMessage.content = delta.input.toolCallDescription ? `✓ ${delta.input.toolCallDescription}` : `✓ Tool ${delta.toolName}`;
77980
+ const updatedMessage = {
77981
+ ...existingMessage,
77982
+ status: "completed",
77983
+ content: delta.input.toolCallDescription ? `✓ ${delta.input.toolCallDescription}` : `✓ Tool ${delta.toolName}`
77984
+ };
77985
+ allMessages[existingToolMessageIndex] = updatedMessage;
77960
77986
  if (onSubagentMessage) {
77961
- onSubagentMessage(subagentId, existingMessage);
77987
+ onSubagentMessage(subagentId, updatedMessage);
77962
77988
  }
77963
77989
  }
77964
77990
  }
@@ -78153,6 +78179,13 @@ ${pentestSessionPaths.map((path5, idx) => `${idx + 1}. ${path5}`).join(`
78153
78179
 
78154
78180
  // src/tui/components/hooks/thoroughPentestAgent.ts
78155
78181
  import { exec as exec5 } from "child_process";
78182
+ var LOG_FILE2 = "/tmp/apex-debug.log";
78183
+ function logToFile2(message, data) {
78184
+ const timestamp = new Date().toISOString();
78185
+ const logLine = `[${timestamp}] ${message} ${data ? JSON.stringify(data, null, 2) : ""}
78186
+ `;
78187
+ fs6.appendFileSync(LOG_FILE2, logLine);
78188
+ }
78156
78189
  function useThoroughPentestAgent() {
78157
78190
  const [target, setTarget] = import_react22.useState("");
78158
78191
  const [messages, setMessages] = import_react22.useState([]);
@@ -78172,7 +78205,7 @@ function useThoroughPentestAgent() {
78172
78205
  function openReport() {
78173
78206
  if (sessionPath) {
78174
78207
  const reportPath = `${sessionPath}/comprehensive-pentest-report.md`;
78175
- if (fs5.existsSync(reportPath)) {
78208
+ if (fs6.existsSync(reportPath)) {
78176
78209
  exec5(`open "${reportPath}"`, (error46) => {
78177
78210
  if (error46) {
78178
78211
  console.error("Error opening report:", error46);
@@ -78218,30 +78251,76 @@ function useThoroughPentestAgent() {
78218
78251
  ]);
78219
78252
  },
78220
78253
  onSubagentMessage: (subagentId, message) => {
78221
- setSubagents((prev) => prev.map((sub) => {
78222
- if (sub.id !== subagentId)
78223
- return sub;
78254
+ logToFile2(`[Hook] Received message for ${subagentId}:`, {
78255
+ role: message.role,
78256
+ content: typeof message.content === "string" ? message.content.substring(0, 50) : message.content,
78257
+ contentLength: typeof message.content === "string" ? message.content.length : "not-string",
78258
+ hasContent: !!message.content,
78259
+ toolCallId: message.role === "tool" ? message.toolCallId : "n/a"
78260
+ });
78261
+ setSubagents((prev) => {
78262
+ const subIndex = prev.findIndex((s) => s.id === subagentId);
78263
+ if (subIndex === -1) {
78264
+ logToFile2(`[Hook] Subagent ${subagentId} not found!`);
78265
+ return prev;
78266
+ }
78267
+ const sub = prev[subIndex];
78224
78268
  const messages2 = [...sub.messages];
78269
+ const getMessageId = (msg) => {
78270
+ if (msg.role === "tool" && "toolCallId" in msg) {
78271
+ return `tool-${msg.toolCallId}`;
78272
+ } else if (msg.role === "assistant") {
78273
+ const content = typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content);
78274
+ return `assistant-${msg.createdAt.getTime()}-${content.length}`;
78275
+ } else {
78276
+ return `${msg.role}-${msg.createdAt.getTime()}`;
78277
+ }
78278
+ };
78279
+ const messageId = getMessageId(message);
78225
78280
  if (message.role === "tool") {
78226
78281
  const toolMsg = message;
78227
78282
  const existingIndex = messages2.findIndex((m2) => m2.role === "tool" && m2.toolCallId === toolMsg.toolCallId);
78228
78283
  if (existingIndex !== -1) {
78229
78284
  messages2[existingIndex] = message;
78230
78285
  } else {
78231
- messages2.push(message);
78286
+ const insertIndex = messages2.findIndex((m2) => m2.createdAt.getTime() > message.createdAt.getTime());
78287
+ if (insertIndex === -1) {
78288
+ messages2.push(message);
78289
+ } else {
78290
+ messages2.splice(insertIndex, 0, message);
78291
+ }
78232
78292
  }
78233
78293
  } else if (message.role === "assistant") {
78234
78294
  const lastMessage = messages2[messages2.length - 1];
78235
78295
  if (lastMessage && lastMessage.role === "assistant") {
78236
- messages2[messages2.length - 1] = message;
78296
+ if (lastMessage.createdAt.getTime() === message.createdAt.getTime()) {
78297
+ messages2[messages2.length - 1] = message;
78298
+ } else {
78299
+ messages2.push(message);
78300
+ }
78237
78301
  } else {
78238
78302
  messages2.push(message);
78239
78303
  }
78240
78304
  } else {
78241
- messages2.push(message);
78305
+ const existingIndex = messages2.findIndex((m2) => getMessageId(m2) === messageId);
78306
+ if (existingIndex === -1) {
78307
+ messages2.push(message);
78308
+ }
78242
78309
  }
78243
- return { ...sub, messages: messages2 };
78244
- }));
78310
+ const updatedSub = { ...sub, messages: messages2 };
78311
+ logToFile2(`[Hook] Updated ${subagentId}, now has ${messages2.length} messages`);
78312
+ if (message.role === "tool") {
78313
+ const toolInArray = messages2.find((m2) => m2.role === "tool" && m2.toolCallId === message.toolCallId);
78314
+ logToFile2(`[Hook] Tool message in array:`, {
78315
+ found: !!toolInArray,
78316
+ content: toolInArray?.content,
78317
+ contentLength: typeof toolInArray?.content === "string" ? toolInArray.content.length : "not-string"
78318
+ });
78319
+ }
78320
+ const newSubagents = [...prev];
78321
+ newSubagents[subIndex] = updatedSub;
78322
+ return newSubagents;
78323
+ });
78245
78324
  },
78246
78325
  onSubagentComplete: (subagentId, success2) => {
78247
78326
  setSubagents((prev) => prev.map((sub) => sub.id === subagentId ? { ...sub, status: success2 ? "completed" : "failed" } : sub));
@@ -78307,7 +78386,7 @@ Mode: Pentest (Orchestrator)`,
78307
78386
  }
78308
78387
  saveMessages(result.session, allMessages);
78309
78388
  }
78310
- if (fs5.existsSync(result.session.rootPath + "/comprehensive-pentest-report.md")) {
78389
+ if (fs6.existsSync(result.session.rootPath + "/comprehensive-pentest-report.md")) {
78311
78390
  setIsCompleted(true);
78312
78391
  }
78313
78392
  setThinking(false);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pensar/apex",
3
- "version": "0.0.15",
3
+ "version": "0.0.16",
4
4
  "description": "AI-powered penetration testing CLI tool with terminal UI",
5
5
  "module": "src/tui/index.tsx",
6
6
  "main": "build/index.js",