@pensar/apex 0.0.15 → 0.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
- # Pensar Apex
1
+ <h1 align="center">Pensar Apex</h1>
2
2
 
3
+ <p align="center">
4
+ <a href="https://www.npmjs.com/package/@pensar/apex"><img src="https://img.shields.io/npm/v/@pensar/apex" alt="npm version"></a>
3
5
  <p align="center">
4
6
  <img src="screenshot.png" alt="Pensar Apex Screenshot" width="800">
5
7
  </p>
@@ -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 {
@@ -75139,7 +75131,8 @@ function AgentDisplay({
75139
75131
  subagents,
75140
75132
  paddingLeft = 8,
75141
75133
  paddingRight = 8,
75142
- contextId = "root"
75134
+ contextId = "root",
75135
+ focused = true
75143
75136
  }) {
75144
75137
  const messagesAndSubagents = [...messages, ...subagents ?? []].sort((a, b2) => a.createdAt.getTime() - b2.createdAt.getTime());
75145
75138
  return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("scrollbox", {
@@ -75165,7 +75158,10 @@ function AgentDisplay({
75165
75158
  },
75166
75159
  stickyScroll: true,
75167
75160
  stickyStart: "bottom",
75168
- focused: true,
75161
+ focused,
75162
+ onMouseScroll: !focused ? (event) => {
75163
+ event.stopPropagation();
75164
+ } : undefined,
75169
75165
  children: [
75170
75166
  messagesAndSubagents.map((item) => {
75171
75167
  const itemKey = getStableKey(item, contextId);
@@ -75195,8 +75191,14 @@ function AgentDisplay({
75195
75191
  ]
75196
75192
  }, undefined, true, undefined, this);
75197
75193
  }
75198
- function SubAgentDisplay({ subagent }) {
75194
+ var SubAgentDisplay = import_react19.memo(function SubAgentDisplay2({ subagent }) {
75199
75195
  const [open, setOpen] = import_react19.useState(false);
75196
+ logToFile(`[Render] SubAgentDisplay for ${subagent.id}:`, {
75197
+ name: subagent.name,
75198
+ nameLength: subagent.name?.length || 0,
75199
+ status: subagent.status,
75200
+ messageCount: subagent.messages.length
75201
+ });
75200
75202
  return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
75201
75203
  height: open ? 40 : "auto",
75202
75204
  onMouseDown: () => setOpen(!open),
@@ -75238,12 +75240,13 @@ function SubAgentDisplay({ subagent }) {
75238
75240
  paddingLeft: 2,
75239
75241
  paddingRight: 2,
75240
75242
  messages: subagent.messages,
75241
- contextId: subagent.id
75243
+ contextId: subagent.id,
75244
+ focused: false
75242
75245
  }, undefined, false, undefined, this)
75243
75246
  ]
75244
75247
  }, undefined, true, undefined, this);
75245
- }
75246
- function AgentMessage({ message }) {
75248
+ });
75249
+ var AgentMessage = import_react19.memo(function AgentMessage2({ message }) {
75247
75250
  let content = "";
75248
75251
  if (typeof message.content === "string") {
75249
75252
  content = message.content;
@@ -75258,6 +75261,15 @@ function AgentMessage({ message }) {
75258
75261
  } else {
75259
75262
  content = JSON.stringify(message.content, null, 2);
75260
75263
  }
75264
+ if (message.role === "tool") {
75265
+ logToFile(`[Render] AgentMessage (tool):`, {
75266
+ toolCallId: message.toolCallId,
75267
+ content: content.substring(0, 50),
75268
+ contentLength: content.length,
75269
+ isEmpty: content === "",
75270
+ status: message.status
75271
+ });
75272
+ }
75261
75273
  const displayContent = message.role === "assistant" ? markdownToStyledText(content) : content;
75262
75274
  const isPendingTool = message.role === "tool" && message.status === "pending";
75263
75275
  return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
@@ -75304,7 +75316,7 @@ function AgentMessage({ message }) {
75304
75316
  }, undefined, false, undefined, this)
75305
75317
  ]
75306
75318
  }, undefined, true, undefined, this);
75307
- }
75319
+ });
75308
75320
  function ToolArgs({ message }) {
75309
75321
  const [open, setOpen] = import_react19.useState(false);
75310
75322
  if (message.role !== "tool" || !("args" in message)) {
@@ -75312,7 +75324,10 @@ function ToolArgs({ message }) {
75312
75324
  }
75313
75325
  const args = message.args;
75314
75326
  return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
75315
- onMouseDown: () => setOpen(!open),
75327
+ onMouseDown: (e) => {
75328
+ e.stopPropagation();
75329
+ setOpen(!open);
75330
+ },
75316
75331
  children: [
75317
75332
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
75318
75333
  flexDirection: "row",
@@ -75330,28 +75345,28 @@ function ToolArgs({ message }) {
75330
75345
  }
75331
75346
 
75332
75347
  // src/tui/components/commands/pentest-agent-display.tsx
75333
- import fs4 from "fs";
75348
+ import fs5 from "fs";
75334
75349
 
75335
75350
  // src/core/messages/index.ts
75336
- import fs3 from "fs";
75351
+ import fs4 from "fs";
75337
75352
  function getMessages(session) {
75338
- const messages = fs3.readFileSync(session.rootPath + "/messages.json", "utf8");
75353
+ const messages = fs4.readFileSync(session.rootPath + "/messages.json", "utf8");
75339
75354
  return JSON.parse(messages);
75340
75355
  }
75341
75356
  function saveMessages(session, messages) {
75342
- fs3.writeFileSync(session.rootPath + "/messages.json", JSON.stringify(messages, null, 2));
75357
+ fs4.writeFileSync(session.rootPath + "/messages.json", JSON.stringify(messages, null, 2));
75343
75358
  }
75344
75359
  function saveSubagentMessages(orchestratorSession, subagentId, messages) {
75345
75360
  const subagentDir = `${orchestratorSession.rootPath}/subagents/${subagentId}`;
75346
- if (!fs3.existsSync(`${orchestratorSession.rootPath}/subagents`)) {
75347
- fs3.mkdirSync(`${orchestratorSession.rootPath}/subagents`, {
75361
+ if (!fs4.existsSync(`${orchestratorSession.rootPath}/subagents`)) {
75362
+ fs4.mkdirSync(`${orchestratorSession.rootPath}/subagents`, {
75348
75363
  recursive: true
75349
75364
  });
75350
75365
  }
75351
- if (!fs3.existsSync(subagentDir)) {
75352
- fs3.mkdirSync(subagentDir, { recursive: true });
75366
+ if (!fs4.existsSync(subagentDir)) {
75367
+ fs4.mkdirSync(subagentDir, { recursive: true });
75353
75368
  }
75354
- fs3.writeFileSync(`${subagentDir}/messages.json`, JSON.stringify(messages, null, 2));
75369
+ fs4.writeFileSync(`${subagentDir}/messages.json`, JSON.stringify(messages, null, 2));
75355
75370
  }
75356
75371
 
75357
75372
  // src/tui/components/commands/pentest-agent-display.tsx
@@ -75492,7 +75507,7 @@ Path: ${result.session.rootPath}`,
75492
75507
  }
75493
75508
  saveMessages(result.session, allMessages);
75494
75509
  }
75495
- if (fs4.existsSync(result.session.rootPath + "/pentest-report.md")) {
75510
+ if (fs5.existsSync(result.session.rootPath + "/pentest-report.md")) {
75496
75511
  setIsCompleted(true);
75497
75512
  }
75498
75513
  setThinking(false);
@@ -75664,7 +75679,7 @@ var import_react23 = __toESM(require_react(), 1);
75664
75679
 
75665
75680
  // src/tui/components/hooks/thoroughPentestAgent.ts
75666
75681
  var import_react22 = __toESM(require_react(), 1);
75667
- import fs5 from "fs";
75682
+ import fs6 from "fs";
75668
75683
 
75669
75684
  // src/core/agent/thoroughPentestAgent/prompts.ts
75670
75685
  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 +77766,13 @@ Objective: ${objective}`,
77751
77766
  currentAssistantText += delta.text;
77752
77767
  const lastMessage = allMessages[allMessages.length - 1];
77753
77768
  if (lastMessage && lastMessage.role === "assistant") {
77754
- lastMessage.content = currentAssistantText;
77769
+ const updatedMessage = {
77770
+ ...lastMessage,
77771
+ content: currentAssistantText
77772
+ };
77773
+ allMessages[allMessages.length - 1] = updatedMessage;
77755
77774
  if (onSubagentMessage) {
77756
- onSubagentMessage(subagentId, lastMessage);
77775
+ onSubagentMessage(subagentId, updatedMessage);
77757
77776
  }
77758
77777
  } else {
77759
77778
  const newMessage = {
@@ -77787,10 +77806,14 @@ Objective: ${objective}`,
77787
77806
  const existingToolMessageIndex = allMessages.findIndex((msg) => msg.role === "tool" && msg.toolCallId === delta.toolCallId);
77788
77807
  if (existingToolMessageIndex !== -1) {
77789
77808
  const existingMessage = allMessages[existingToolMessageIndex];
77790
- existingMessage.status = "completed";
77791
- existingMessage.content = delta.input.toolCallDescription ? `✓ ${delta.input.toolCallDescription}` : `✓ Tool ${delta.toolName}`;
77809
+ const updatedMessage = {
77810
+ ...existingMessage,
77811
+ status: "completed",
77812
+ content: delta.input.toolCallDescription ? `✓ ${delta.input.toolCallDescription}` : `✓ Tool ${delta.toolName}`
77813
+ };
77814
+ allMessages[existingToolMessageIndex] = updatedMessage;
77792
77815
  if (onSubagentMessage) {
77793
- onSubagentMessage(subagentId, existingMessage);
77816
+ onSubagentMessage(subagentId, updatedMessage);
77794
77817
  }
77795
77818
  }
77796
77819
  }
@@ -77919,9 +77942,13 @@ Objective: ${targetInfo.objective}`,
77919
77942
  currentAssistantText += delta.text;
77920
77943
  const lastMessage = allMessages[allMessages.length - 1];
77921
77944
  if (lastMessage && lastMessage.role === "assistant") {
77922
- lastMessage.content = currentAssistantText;
77945
+ const updatedMessage = {
77946
+ ...lastMessage,
77947
+ content: currentAssistantText
77948
+ };
77949
+ allMessages[allMessages.length - 1] = updatedMessage;
77923
77950
  if (onSubagentMessage) {
77924
- onSubagentMessage(subagentId, lastMessage);
77951
+ onSubagentMessage(subagentId, updatedMessage);
77925
77952
  }
77926
77953
  } else {
77927
77954
  const newMessage = {
@@ -77955,10 +77982,14 @@ Objective: ${targetInfo.objective}`,
77955
77982
  const existingToolMessageIndex = allMessages.findIndex((msg) => msg.role === "tool" && msg.toolCallId === delta.toolCallId);
77956
77983
  if (existingToolMessageIndex !== -1) {
77957
77984
  const existingMessage = allMessages[existingToolMessageIndex];
77958
- existingMessage.status = "completed";
77959
- existingMessage.content = delta.input.toolCallDescription ? `✓ ${delta.input.toolCallDescription}` : `✓ Tool ${delta.toolName}`;
77985
+ const updatedMessage = {
77986
+ ...existingMessage,
77987
+ status: "completed",
77988
+ content: delta.input.toolCallDescription ? `✓ ${delta.input.toolCallDescription}` : `✓ Tool ${delta.toolName}`
77989
+ };
77990
+ allMessages[existingToolMessageIndex] = updatedMessage;
77960
77991
  if (onSubagentMessage) {
77961
- onSubagentMessage(subagentId, existingMessage);
77992
+ onSubagentMessage(subagentId, updatedMessage);
77962
77993
  }
77963
77994
  }
77964
77995
  }
@@ -78153,6 +78184,13 @@ ${pentestSessionPaths.map((path5, idx) => `${idx + 1}. ${path5}`).join(`
78153
78184
 
78154
78185
  // src/tui/components/hooks/thoroughPentestAgent.ts
78155
78186
  import { exec as exec5 } from "child_process";
78187
+ var LOG_FILE2 = "/tmp/apex-debug.log";
78188
+ function logToFile2(message, data) {
78189
+ const timestamp = new Date().toISOString();
78190
+ const logLine = `[${timestamp}] ${message} ${data ? JSON.stringify(data, null, 2) : ""}
78191
+ `;
78192
+ fs6.appendFileSync(LOG_FILE2, logLine);
78193
+ }
78156
78194
  function useThoroughPentestAgent() {
78157
78195
  const [target, setTarget] = import_react22.useState("");
78158
78196
  const [messages, setMessages] = import_react22.useState([]);
@@ -78172,7 +78210,7 @@ function useThoroughPentestAgent() {
78172
78210
  function openReport() {
78173
78211
  if (sessionPath) {
78174
78212
  const reportPath = `${sessionPath}/comprehensive-pentest-report.md`;
78175
- if (fs5.existsSync(reportPath)) {
78213
+ if (fs6.existsSync(reportPath)) {
78176
78214
  exec5(`open "${reportPath}"`, (error46) => {
78177
78215
  if (error46) {
78178
78216
  console.error("Error opening report:", error46);
@@ -78218,30 +78256,76 @@ function useThoroughPentestAgent() {
78218
78256
  ]);
78219
78257
  },
78220
78258
  onSubagentMessage: (subagentId, message) => {
78221
- setSubagents((prev) => prev.map((sub) => {
78222
- if (sub.id !== subagentId)
78223
- return sub;
78259
+ logToFile2(`[Hook] Received message for ${subagentId}:`, {
78260
+ role: message.role,
78261
+ content: typeof message.content === "string" ? message.content.substring(0, 50) : message.content,
78262
+ contentLength: typeof message.content === "string" ? message.content.length : "not-string",
78263
+ hasContent: !!message.content,
78264
+ toolCallId: message.role === "tool" ? message.toolCallId : "n/a"
78265
+ });
78266
+ setSubagents((prev) => {
78267
+ const subIndex = prev.findIndex((s) => s.id === subagentId);
78268
+ if (subIndex === -1) {
78269
+ logToFile2(`[Hook] Subagent ${subagentId} not found!`);
78270
+ return prev;
78271
+ }
78272
+ const sub = prev[subIndex];
78224
78273
  const messages2 = [...sub.messages];
78274
+ const getMessageId = (msg) => {
78275
+ if (msg.role === "tool" && "toolCallId" in msg) {
78276
+ return `tool-${msg.toolCallId}`;
78277
+ } else if (msg.role === "assistant") {
78278
+ const content = typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content);
78279
+ return `assistant-${msg.createdAt.getTime()}-${content.length}`;
78280
+ } else {
78281
+ return `${msg.role}-${msg.createdAt.getTime()}`;
78282
+ }
78283
+ };
78284
+ const messageId = getMessageId(message);
78225
78285
  if (message.role === "tool") {
78226
78286
  const toolMsg = message;
78227
78287
  const existingIndex = messages2.findIndex((m2) => m2.role === "tool" && m2.toolCallId === toolMsg.toolCallId);
78228
78288
  if (existingIndex !== -1) {
78229
78289
  messages2[existingIndex] = message;
78230
78290
  } else {
78231
- messages2.push(message);
78291
+ const insertIndex = messages2.findIndex((m2) => m2.createdAt.getTime() > message.createdAt.getTime());
78292
+ if (insertIndex === -1) {
78293
+ messages2.push(message);
78294
+ } else {
78295
+ messages2.splice(insertIndex, 0, message);
78296
+ }
78232
78297
  }
78233
78298
  } else if (message.role === "assistant") {
78234
78299
  const lastMessage = messages2[messages2.length - 1];
78235
78300
  if (lastMessage && lastMessage.role === "assistant") {
78236
- messages2[messages2.length - 1] = message;
78301
+ if (lastMessage.createdAt.getTime() === message.createdAt.getTime()) {
78302
+ messages2[messages2.length - 1] = message;
78303
+ } else {
78304
+ messages2.push(message);
78305
+ }
78237
78306
  } else {
78238
78307
  messages2.push(message);
78239
78308
  }
78240
78309
  } else {
78241
- messages2.push(message);
78310
+ const existingIndex = messages2.findIndex((m2) => getMessageId(m2) === messageId);
78311
+ if (existingIndex === -1) {
78312
+ messages2.push(message);
78313
+ }
78242
78314
  }
78243
- return { ...sub, messages: messages2 };
78244
- }));
78315
+ const updatedSub = { ...sub, messages: messages2 };
78316
+ logToFile2(`[Hook] Updated ${subagentId}, now has ${messages2.length} messages`);
78317
+ if (message.role === "tool") {
78318
+ const toolInArray = messages2.find((m2) => m2.role === "tool" && m2.toolCallId === message.toolCallId);
78319
+ logToFile2(`[Hook] Tool message in array:`, {
78320
+ found: !!toolInArray,
78321
+ content: toolInArray?.content,
78322
+ contentLength: typeof toolInArray?.content === "string" ? toolInArray.content.length : "not-string"
78323
+ });
78324
+ }
78325
+ const newSubagents = [...prev];
78326
+ newSubagents[subIndex] = updatedSub;
78327
+ return newSubagents;
78328
+ });
78245
78329
  },
78246
78330
  onSubagentComplete: (subagentId, success2) => {
78247
78331
  setSubagents((prev) => prev.map((sub) => sub.id === subagentId ? { ...sub, status: success2 ? "completed" : "failed" } : sub));
@@ -78307,7 +78391,7 @@ Mode: Pentest (Orchestrator)`,
78307
78391
  }
78308
78392
  saveMessages(result.session, allMessages);
78309
78393
  }
78310
- if (fs5.existsSync(result.session.rootPath + "/comprehensive-pentest-report.md")) {
78394
+ if (fs6.existsSync(result.session.rootPath + "/comprehensive-pentest-report.md")) {
78311
78395
  setIsCompleted(true);
78312
78396
  }
78313
78397
  setThinking(false);
package/package.json CHANGED
@@ -1,10 +1,14 @@
1
1
  {
2
2
  "name": "@pensar/apex",
3
- "version": "0.0.15",
3
+ "version": "0.0.17",
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",
7
7
  "type": "module",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/pensarai/apex.git"
11
+ },
8
12
  "bin": {
9
13
  "pensar": "./bin/pensar.js"
10
14
  },