
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
agui-react-wrapper
Advanced tools
A streamlined npm package for AG-UI LangGraph agent chat interface with separate ChatPanel and EventLog components, standalone sendMessage function, React components, and custom hooks
agui-react-wrapper is a production-ready npm package that wraps the AG-UI LangGraph agent functionality into reusable React components. It provides a complete solution for integrating agent-based chat functionality into React applications.
| Feature | Description |
|---|---|
| Real-time Streaming | Live message streaming from LangGraph agents with Server-Sent Events |
| Event Tracking | Comprehensive event tracking (runs, steps, tool calls, state changes) |
| Dynamic Parameters | Runtime-configurable parameters with automatic UI generation |
| Flexible Composition | Use components standalone or combine them for custom layouts |
| TypeScript Support | Full type definitions for all exports |
| Standalone Utilities | Non-React functions for programmatic usage |
| Zero Dependencies | No external styling dependencies (inline styles) |
npm install agui-react-wrapper
This package requires React 18+ and React DOM 18+:
npm install react@^18.0.0 react-dom@^18.0.0
| Property | Value |
|---|---|
| Package Name | agui-react-wrapper |
| Version | 1.0.0 |
| License | MIT |
| Main Entry | ./dist/index.js |
| Module Entry | ./dist/index.es.js |
| Type Definitions | ./dist/index.d.ts |
The simplest way to get started is using the combined ChatWithEventLog component:
import React from "react";
import { ChatWithEventLog, type AGUIConfig } from "agui-react-wrapper";
function App() {
const config: AGUIConfig = {
backendUrl: "http://localhost:8899/api/get_deviation_analysis",
parameters: {
application_id: "APP-002",
user_email: "user@example.com",
},
title: "Agent Chat",
subtitle: "Chat with your LangGraph agent",
};
return <ChatWithEventLog config={config} />;
}
For more control, use components separately:
import React from "react";
import { ChatPanel, EventLog, useEventLog } from "agui-react-wrapper";
function App() {
const { eventLog, addEvent } = useEventLog();
return (
<div style={{ display: "flex", gap: "1rem" }}>
<ChatPanel
backendUrl="http://localhost:8899/api/endpoint"
parameters={{ application_id: "APP-002" }}
onEvent={addEvent}
/>
<EventLog events={eventLog} />
</div>
);
}
agui-react-wrapper/
├── components/
│ ├── ChatPanel/ # Standalone chat interface
│ │ ├── ChatPanel.tsx
│ │ ├── MessageList.tsx
│ │ ├── MessageBubble.tsx
│ │ └── MessageInput.tsx
│ ├── EventLog/ # Standalone event log display
│ │ ├── EventLog.tsx
│ │ └── EventLogEntry.tsx
│ └── ChatWithEventLog/ # Combined component
│ └── ChatWithEventLog.tsx
├── hooks/
│ ├── useAgentChat.ts # Chat state management
│ ├── useEventLog.ts # Event log state management
│ ├── useEventStream.ts # Event forwarding utilities
│ └── useParameters.ts # Parameter state management
├── utils/
│ ├── sendMessage.ts # Standalone message sending
│ ├── getEventIcon.ts # Event icon mapping
│ └── getEventBadgeColor.ts # Event color mapping
├── classes/
│ └── CustomHttpAgent.class.ts # Extended HttpAgent with parameters
└── interfaces/
└── EventLogEntry.interface.ts # Event log entry type
┌─────────────┐
│ User Input │
└──────┬──────┘
│
▼
┌─────────────────┐ ┌──────────────────┐
│ MessageInput │────▶│ useAgentChat │
└─────────────────┘ └────────┬─────────┘
│
▼
┌──────────────────┐
│ CustomHttpAgent │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ Event Stream │
└────────┬─────────┘
│
┌─────────────┴─────────────┐
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ useEventLog │ │ useAgentChat │
└────────┬─────────┘ └────────┬─────────┘
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ EventLog │ │ MessageList │
└──────────────────┘ └──────────────────┘
ChatWithEventLog (Combined Component)
│
├── ChatPanel
│ ├── MessageList
│ │ └── MessageBubble[] (for each message)
│ └── MessageInput
│ └── ParameterFields[] (dynamic, based on parameters)
│
└── EventLog
└── EventLogEntry[] (for each event)
ChatWithEventLog / AGUIComponentThe combined component that includes both chat and event log panels in a side-by-side layout.
Import:
import { ChatWithEventLog, AGUIComponent } from "agui-react-wrapper";
// Note: AGUIComponent is an alias for ChatWithEventLog (backward compatibility)
Props:
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
config | AGUIConfig | ✅ | - | Configuration object for the component |
onParametersChange | (params: Record<string, any>) => void | ❌ | - | Callback when parameters are updated |
Example:
<ChatWithEventLog
config={{
backendUrl: "http://localhost:8899/api/endpoint",
parameters: { application_id: "APP-002" },
showEventLog: true,
showParameterFields: true,
title: "My Chat",
subtitle: "Chat with the agent",
}}
onParametersChange={(params) => console.log(params)}
/>
Features:
ChatPanelStandalone chat interface component with real-time message streaming.
Import:
import { ChatPanel } from "agui-react-wrapper";
Props:
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
backendUrl | string | ✅ | - | Backend API endpoint URL |
parameters | Record<string, any> | ❌ | {} | Request parameters to send with each message |
headers | Record<string, string> | ❌ | - | Custom HTTP headers |
title | string | ❌ | - | Chat interface title |
subtitle | string | ❌ | - | Chat interface subtitle |
showParameterFields | boolean | ❌ | true | Show parameter input fields |
onParametersChange | (params: Record<string, any>) => void | ❌ | - | Callback when parameters are updated |
onEvent | (event: BaseEvent) => void | ❌ | - | Callback when events occur |
compact | boolean | ❌ | false | Skip full-page wrapper (for custom layouts) |
Example:
<ChatPanel
backendUrl="http://localhost:8899/api/endpoint"
parameters={{
application_id: "APP-002",
user_email: "user@example.com",
}}
headers={{
Authorization: "Bearer token",
}}
title="My Chat"
subtitle="Chat with the agent"
showParameterFields={true}
onEvent={(event) => console.log("Event:", event)}
compact={false}
/>
Features:
EventLogStandalone event log component for displaying agent events in real-time.
Import:
import { EventLog } from "agui-react-wrapper";
Props:
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
events | EventLogEntry[] | ✅ | - | Array of event log entries to display |
onEvent | (event: any) => void | ❌ | - | External event handler (for uncontrolled mode) |
autoScroll | boolean | ❌ | true | Auto-scroll to bottom when new events arrive |
title | string | ❌ | "Event Log" | Title for the event log |
Example:
<EventLog events={eventLog} autoScroll={true} title="Agent Events" />
Features:
MessageListComponent for displaying chat messages.
Props:
interface MessageListProps {
messages: Message[];
chatEndRef: React.RefObject<HTMLDivElement>;
}
MessageBubbleIndividual message bubble component.
Props:
interface MessageBubbleProps {
message: Message;
}
MessageInputInput component with parameter fields and message input.
Props:
interface MessageInputProps {
onSendMessage: (input: string) => void;
parameters: Record<string, any>;
onParametersChange: (params: Record<string, any>) => void;
showParameterFields?: boolean;
}
Parameter Field Types:
EventLogEntryIndividual event log entry component.
Props:
interface EventLogEntryProps {
entry: EventLogEntry;
}
useAgentChatHook for managing agent chat state and execution.
Import:
import { useAgentChat } from "agui-react-wrapper";
Signature:
function useAgentChat(
options: UseAgentChatOptions,
callbacks?: RunAgentCallbacks
): UseAgentChatReturn;
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
options | UseAgentChatOptions | ✅ | Configuration options |
callbacks | RunAgentCallbacks | ❌ | Additional event callbacks |
Options Interface:
interface UseAgentChatOptions {
backendUrl: string;
parameters: Record<string, any>;
headers?: Record<string, string>;
onEvent?: (event: BaseEvent) => void;
}
Returns:
| Property | Type | Description |
|---|---|---|
messages | Message[] | Array of chat messages |
sendMessage | (input: string) => Promise<void> | Function to send a message |
clearMessages | () => void | Function to clear all messages |
chatEndRef | React.RefObject<HTMLDivElement> | Ref for auto-scrolling |
Example:
const { messages, sendMessage, clearMessages, chatEndRef } = useAgentChat({
backendUrl: "http://localhost:8899/api/endpoint",
parameters: { application_id: "APP-002" },
headers: { Authorization: "Bearer token" },
onEvent: (event) => console.log(event),
});
Features:
useEventLogHook for managing event log state.
Import:
import { useEventLog } from "agui-react-wrapper";
Signature:
function useEventLog(autoScroll?: boolean): UseEventLogReturn;
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
autoScroll | boolean | ❌ | true | Enable auto-scrolling |
Returns:
| Property | Type | Description |
|---|---|---|
eventLog | EventLogEntry[] | Array of event log entries |
addEvent | (event: BaseEvent) => void | Function to add an event |
clearEventLog | () => void | Function to clear all events |
eventLogEndRef | React.RefObject<HTMLDivElement> | Ref for auto-scrolling |
Example:
const { eventLog, addEvent, clearEventLog, eventLogEndRef } = useEventLog(true);
Features:
useEventStreamHook that creates event callbacks to forward all events to a handler function.
Import:
import { useEventStream } from "agui-react-wrapper";
Signature:
function useEventStream(
addEvent: (event: BaseEvent) => void
): RunAgentCallbacks;
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
addEvent | (event: BaseEvent) => void | ✅ | Function to handle events |
Returns:
| Property | Type | Description |
|---|---|---|
RunAgentCallbacks | RunAgentCallbacks | Complete callback object for agent events |
Example:
const { addEvent } = useEventLog();
const eventCallbacks = useEventStream(addEvent);
// Use with sendMessage or agent.runAgent
await sendMessage({
url: "...",
input: "Hello",
callbacks: eventCallbacks,
});
Features:
useParametersHook for managing dynamic parameters state.
Import:
import { useParameters } from "agui-react-wrapper";
Signature:
function useParameters(
initialParameters?: Record<string, any>,
onParametersChange?: (params: Record<string, any>) => void
): UseParametersReturn;
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
initialParameters | Record<string, any> | ❌ | {} | Initial parameter values |
onParametersChange | (params: Record<string, any>) => void | ❌ | - | Callback when parameters change |
Returns:
| Property | Type | Description |
|---|---|---|
parameters | Record<string, any> | Current parameter values |
setParameters | (params: Record<string, any>) => void | Function to set all parameters |
updateParameter | (key: string, value: any) => void | Function to update a single parameter |
Example:
const { parameters, setParameters, updateParameter } = useParameters(
{ application_id: "APP-002" },
(params) => console.log("Parameters changed:", params)
);
Features:
sendMessageStandalone function to send a message to an AG-UI agent endpoint without React.
Import:
import { sendMessage } from "agui-react-wrapper";
Signature:
async function sendMessage(
options: SendMessageOptions
): Promise<SendMessageResult>;
Options:
| Option | Type | Required | Description |
|---|---|---|---|
url | string | ✅ | Backend API endpoint URL |
input | string | ✅ | Message text to send |
parameters | Record<string, any> | ❌ | Request parameters |
headers | Record<string, string> | ❌ | Custom HTTP headers |
onEvent | (event: BaseEvent) => void | ❌ | Event callback |
callbacks | RunAgentCallbacks | ❌ | Additional event callbacks |
messages | Message[] | ❌ | Initial message history |
Returns:
| Property | Type | Description |
|---|---|---|
answer | string | Final answer text from the agent |
result | any | Full result from the agent run |
newMessages | Message[] | New messages from the agent |
Example:
import { sendMessage } from "agui-react-wrapper";
const result = await sendMessage({
url: "http://localhost:8899/api/endpoint",
input: "Hello, agent!",
parameters: {
application_id: "APP-002",
user_email: "user@example.com",
},
headers: {
Authorization: "Bearer token",
},
onEvent: (event) => {
console.log("Event:", event);
},
callbacks: {
onTextMessageContentEvent: ({ event }) => {
console.log("Content delta:", (event as any).delta);
},
},
});
console.log("Final answer:", result.answer);
console.log("Result:", result.result);
console.log("New messages:", result.newMessages);
Features:
getEventIconUtility function to get an icon for an event type.
Import:
import { getEventIcon } from "agui-react-wrapper";
Signature:
function getEventIcon(eventType: string): string;
Returns:
| Event Type | Icon |
|---|---|
| RUN events | "▶" |
| STEP events | "▸" |
| TOOL events | "⚙" |
| TEXT_MESSAGE events | "💬" |
| STATE events | "📊" |
| Other events | "•" |
getEventBadgeColorUtility function to get color scheme for an event type badge.
Import:
import { getEventBadgeColor } from "agui-react-wrapper";
Signature:
function getEventBadgeColor(eventType: string): {
bg: string;
text: string;
border: string;
};
Returns: Color scheme object with background, text, and border colors.
AGUIConfigConfiguration object for combined components.
interface AGUIConfig {
backendUrl: string;
parameters?: Record<string, any>;
headers?: Record<string, string>;
title?: string;
subtitle?: string;
showEventLog?: boolean;
showParameterFields?: boolean;
}
EventLogEntryEvent log entry interface.
interface EventLogEntry {
id: string;
timestamp: Date;
event: BaseEvent;
eventType: string;
}
RunAgentCallbacksComplete event callback interface.
interface RunAgentCallbacks {
onRunStartedEvent?: ({ event }: { event: BaseEvent }) => void;
onRunFinishedEvent?: ({ event }: { event: BaseEvent }) => void;
onRunErrorEvent?: ({ event }: { event: BaseEvent }) => void;
onStepStartedEvent?: ({ event }: { event: BaseEvent }) => void;
onStepFinishedEvent?: ({ event }: { event: BaseEvent }) => void;
onTextMessageStartEvent?: ({ event }: { event: BaseEvent }) => void;
onTextMessageContentEvent?: ({ event }: { event: BaseEvent }) => void;
onTextMessageEndEvent?: ({ event }: { event: BaseEvent }) => void;
onToolCallStartEvent?: ({ event }: { event: BaseEvent }) => void;
onToolCallArgsEvent?: ({ event }: { event: BaseEvent }) => void;
onToolCallEndEvent?: ({ event }: { event: BaseEvent }) => void;
onToolCallResultEvent?: ({ event }: { event: BaseEvent }) => void;
onStateDeltaEvent?: ({ event }: { event: BaseEvent }) => void;
onStateSnapshotEvent?: ({ event }: { event: BaseEvent }) => void;
onRawEvent?: ({ event }: { event: BaseEvent }) => void;
onCustomEvent?: ({ event }: { event: BaseEvent }) => void;
}
Type Imports:
import type {
AGUIConfig,
ChatPanelProps,
EventLogProps,
UseAgentChatOptions,
UseAgentChatReturn,
EventLogEntry,
SendMessageOptions,
SendMessageResult,
} from "agui-react-wrapper";
import React from "react";
import { ChatWithEventLog, type AGUIConfig } from "agui-react-wrapper";
function App() {
const config: AGUIConfig = {
backendUrl: "http://localhost:8899/api/get_deviation_analysis",
parameters: {
application_id: "APP-002",
user_email: "user@example.com",
subject: "Email subject",
body: "Email body content",
},
title: "Deviation Analysis Chat",
subtitle: "Analyze deviations with AI assistance",
showEventLog: true,
showParameterFields: true,
};
return <ChatWithEventLog config={config} />;
}
import React from "react";
import { ChatPanel, EventLog, useEventLog } from "agui-react-wrapper";
import { BaseEvent, EventType } from "@ag-ui/core";
function CustomChatApp() {
const { eventLog, addEvent, clearEventLog } = useEventLog(true);
const handleChatEvent = (event: BaseEvent) => {
// Clear event log on new run start
if (event.type === EventType.RUN_STARTED) {
clearEventLog();
}
addEvent(event);
};
return (
<div style={{ display: "flex", gap: "1.5rem", padding: "2rem" }}>
<div style={{ flex: 1 }}>
<ChatPanel
backendUrl="http://localhost:8899/api/endpoint"
parameters={{ application_id: "APP-002" }}
onEvent={handleChatEvent}
compact={true}
/>
</div>
<div style={{ flex: 1 }}>
<EventLog events={eventLog} />
</div>
</div>
);
}
import React, { useState } from "react";
import {
useAgentChat,
MessageList,
MessageInput,
} from "agui-react-wrapper";
function CustomChat() {
const { messages, sendMessage, chatEndRef } = useAgentChat({
backendUrl: "http://localhost:8899/api/endpoint",
parameters: { application_id: "APP-002" },
onEvent: (event) => {
console.log("Event:", event);
},
});
const [input, setInput] = useState("");
return (
<div>
<MessageList messages={messages} chatEndRef={chatEndRef} />
<input
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter") {
sendMessage(input);
setInput("");
}
}}
/>
</div>
);
}
import { sendMessage } from "agui-react-wrapper";
async function sendAgentMessage() {
try {
const result = await sendMessage({
url: "http://localhost:8899/api/endpoint",
input: "Analyze this data",
parameters: {
application_id: "APP-002",
user_email: "user@example.com",
},
headers: {
Authorization: "Bearer your-token",
},
onEvent: (event) => {
console.log("Event received:", event);
},
});
console.log("Agent response:", result.answer);
return result;
} catch (error) {
console.error("Error:", error);
throw error;
}
}
import React, { useState } from "react";
import { ChatPanel } from "agui-react-wrapper";
function DynamicParamsExample() {
const [params, setParams] = useState({
application_id: "APP-002",
user_email: "user@example.com",
priority: 1,
description: "Long description text that will be rendered as a textarea",
});
return (
<ChatPanel
backendUrl="http://localhost:8899/api/endpoint"
parameters={params}
onParametersChange={(newParams) => {
console.log("Parameters updated:", newParams);
setParams(newParams);
}}
showParameterFields={true}
/>
);
}
import React from "react";
import { ChatPanel, useEventLog } from "agui-react-wrapper";
function MultiChatApp() {
const chat1Events = useEventLog();
const chat2Events = useEventLog();
return (
<div
style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "1rem" }}
>
<ChatPanel
backendUrl="http://localhost:8899/api/endpoint1"
parameters={{ application_id: "APP-001" }}
onEvent={chat1Events.addEvent}
/>
<ChatPanel
backendUrl="http://localhost:8899/api/endpoint2"
parameters={{ application_id: "APP-002" }}
onEvent={chat2Events.addEvent}
/>
</div>
);
}
import React, { useState } from "react";
import { ChatPanel, EventLog, useEventLog } from "agui-react-wrapper";
function ConditionalEventLog() {
const [showLog, setShowLog] = useState(false);
const { eventLog, addEvent } = useEventLog(showLog);
return (
<div>
<button onClick={() => setShowLog(!showLog)}>
{showLog ? "Hide" : "Show"} Event Log
</button>
<div style={{ display: "flex", gap: "1rem" }}>
<ChatPanel
backendUrl="http://localhost:8899/api/endpoint"
onEvent={addEvent}
/>
{showLog && <EventLog events={eventLog} />}
</div>
</div>
);
}
import React from "react";
import { ChatPanel, useEventLog } from "agui-react-wrapper";
import { BaseEvent, EventType } from "@ag-ui/core";
function CustomEventProcessing() {
const { eventLog, addEvent } = useEventLog();
const handleEvent = (event: BaseEvent) => {
// Custom processing
if (event.type === EventType.TOOL_CALL_START) {
console.log("Tool call started:", event);
// Send analytics event
analytics.track("tool_call_started", { tool: (event as any).tool });
}
// Add to event log
addEvent(event);
};
return (
<ChatPanel
backendUrl="http://localhost:8899/api/endpoint"
onEvent={handleEvent}
/>
);
}
import React, { useState } from "react";
import { ChatPanel } from "agui-react-wrapper";
function ValidatedParams() {
const [params, setParams] = useState({
application_id: "",
user_email: "",
});
const handleParamsChange = (newParams: Record<string, any>) => {
// Validate email
if (newParams.user_email && !newParams.user_email.includes("@")) {
alert("Invalid email address");
return;
}
// Validate application ID
if (newParams.application_id && newParams.application_id.length < 3) {
alert("Application ID must be at least 3 characters");
return;
}
setParams(newParams);
};
return (
<ChatPanel
backendUrl="http://localhost:8899/api/endpoint"
parameters={params}
onParametersChange={handleParamsChange}
/>
);
}
To build the package for distribution:
npm run build:lib
This command:
dist directory.d.ts)Output Files:
dist/index.js - CommonJS bundledist/index.es.js - ES module bundledist/index.d.ts - TypeScript declarationsFor local development with hot reload:
npm run dev
To preview the built package:
npm run serve
npm run clean
Before publishing, ensure:
package.jsonnpm run build:libThen publish:
npm publish
The prepublishOnly script will automatically run build:lib before publishing.
Possible Causes:
onEvent callback is not connectedSolution:
// Ensure onEvent is connected
<ChatPanel
backendUrl="..."
onEvent={addEvent} // ✅ Make sure this is set
/>
Possible Causes:
CustomHttpAgent is not properly extending HttpAgentSolution:
// Verify parameters structure
<ChatPanel
backendUrl="..."
parameters={{
application_id: "APP-002", // ✅ Ensure proper structure
user_email: "user@example.com",
}}
/>
Possible Causes:
onTextMessageContentEvent callbacks not workingSolution:
Possible Causes:
Solution:
npm install --save-dev @types/react@^18.0.0 @types/react-dom@^18.0.0
npm install react@^18.0.0 react-dom@^18.0.0
| Package | Version | Purpose |
|---|---|---|
react | ^18.0.0 | React library |
react-dom | ^18.0.0 | React DOM rendering |
| Package | Version | Purpose |
|---|---|---|
@ag-ui/client | ^0.0.41 | AG-UI client library |
@ag-ui/core | ^0.0.41 | AG-UI core types and utilities |
rxjs | ^7.0.0 | Reactive extensions (used by AG-UI) |
This package is written in TypeScript and includes full type definitions. All exports are typed, including:
The package supports all AG-UI event types:
| Event Type | Description |
|---|---|
RUN_STARTED | Agent run started |
RUN_FINISHED | Agent run completed |
RUN_ERROR | Agent run error |
STEP_STARTED | Step execution started |
STEP_FINISHED | Step execution finished |
TEXT_MESSAGE_START | Text message streaming started |
TEXT_MESSAGE_CONTENT | Text message content delta |
TEXT_MESSAGE_END | Text message streaming finished |
TOOL_CALL_START | Tool call started |
TOOL_CALL_ARGS | Tool call arguments |
TOOL_CALL_END | Tool call finished |
TOOL_CALL_RESULT | Tool call result |
STATE_DELTA | State delta update |
STATE_SNAPSHOT | State snapshot |
RAW_EVENT | Raw event |
CUSTOM | Custom event |
The package uses inline styles and does not require any external CSS. All components are self-contained with their styling.
Design System:
Customization Options:
This package supports all modern browsers that support:
This is a published npm package. For contributions:
npm run build:libMIT
For issues, questions, or contributions, please refer to the package repository or contact the maintainers.
Version: 1.0.0
Last Updated: 2024
Made with ❤️ for the AG-UI community
FAQs
A streamlined npm package for AG-UI LangGraph agent chat interface with separate ChatPanel and EventLog components, standalone sendMessage function, React components, and custom hooks
We found that agui-react-wrapper demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.