
Research
Shai-Hulud Descends to Hades: Miasma Worm Campaign Spreads with New PyPI Wave
Socket found 37 malicious PyPI wheels that abuse Python startup hooks to launch a Bun-powered credential stealer tied to Mini Shai-Hulud/Miasma.
@aoagents/ao-core
Advanced tools
Core library — types, config, session manager, lifecycle manager, event bus
Core services, types, and configuration for the Agent Orchestrator system.
src/types.ts — All TypeScript interfaces (Runtime, Agent, Workspace, Tracker, SCM, Notifier, Terminal, Session, events)src/services/ — Core services (SessionManager, LifecycleManager, PluginRegistry)src/config.ts — Configuration loading + Zod schemassrc/utils/ — Shared utilities (shell escaping, metadata parsing, etc.)src/types.ts — The Source of TruthEvery interface the system uses is defined here. If you're working on any part of the orchestrator, start by reading this file.
Main interfaces:
Runtime — where sessions execute (tmux on Unix, process / ConPTY via node-pty on Windows, docker, k8s)Agent — AI coding tool adapter (claude-code, codex, aider)Workspace — code isolation (worktree, clone)Tracker — issue tracking (GitHub Issues, Linear)SCM — PR/CI/reviews (GitHub, GitLab)Notifier — push notifications (desktop, Slack, webhook)Terminal — human interaction UI (iTerm2, web)Session — running agent instance (state, metadata, handles)OrchestratorEvent — events emitted by lifecycle managerPluginModule — what every plugin exportssrc/services/session-manager.ts — Session CRUDHandles session lifecycle:
spawn(config) — create new session (workspace + runtime + agent)list(projectId?) — list all sessionsget(sessionId) — get session detailskill(sessionId) — terminate sessioncleanup(projectId?) — kill completed/merged sessionssend(sessionId, message) — send message to agentData flow in spawn():
Tracker.getIssue() (if issueId provided, fails-fast if not found)Workspace.create()Tracker.generatePrompt()buildPrompt() into systemPrompt + taskPromptsystemPromptFile for the session and, for OpenCode workers, write OPENCODE_CONFIGAgent.getLaunchCommand()Runtime.create()Agent.postLaunchSetup() (optional)Note: If issue validation fails (not found, auth error), spawn fails before creating any resources (no workspace, no runtime, no session ID). This prevents spawning sessions with broken issue references.
Worker sessions keep persistent instructions in the prompt file. OpenCode workers consume that file through OPENCODE_CONFIG, while OpenCode orchestrators continue to project their system prompt into workspace AGENTS.md.
src/services/lifecycle-manager.ts — State Machine + ReactionsPolls sessions, detects state changes, triggers reactions:
State machine:
spawning → working → pr_open → ci_failed/review_pending/approved → mergeable → merged
Reactions:
ci-failed → send fix prompt to agentchanges-requested → send review comments to agentapproved-and-green → notify human (or auto-merge)agent-stuck → notify humanPolling loop:
Agent.getActivityState())SCM.getCISummary()), review state (SCM.getReviewDecision())src/services/plugin-registry.ts — Plugin Discovery + LoadingLoads plugins and provides access to them:
register(plugin, config?) — register a plugin instanceget<T>(slot, name) — get plugin by slot + namelist(slot) — list all plugins for a slotloadBuiltins(config?) — load built-in plugins (runtime-tmux, agent-claude-code, etc.)loadFromConfig(config) — load built-ins today; external plugin descriptors are the marketplace extension pointBuilt-in plugins (loaded by default):
src/config.ts — Configuration LoadingLoads and validates agent-orchestrator.yaml:
Main config sections:
~/.agent-orchestrator/{hash}-{projectId}/port — web dashboard port (default 3000, set different values for multiple projects)terminalPort — terminal WebSocket port (auto-detected if not set)directTerminalPort — direct terminal WebSocket port (auto-detected if not set)defaults — default plugins (runtime, agent, workspace, notifiers)plugins — installer-managed external plugin descriptors (registry, npm, or local)projects — per-project config (repo, path, branch, symlinks, reactions, agentRules)notifiers — notification channel config (Slack webhooks, etc.)notificationRouting — which notifiers get which priority eventsreactions — auto-response config (ci-failed, changes-requested, approved-and-green, etc.)Zod schemas validate all config at load time.
src/types.ts → Session interfacesrc/services/session-manager.ts → initialize field in spawn()pnpm --filter @aoagents/ao-core buildsrc/types.ts → EventType unioneventEmitter.emit() in relevant servicesrc/services/lifecycle-manager.tssrc/services/lifecycle-manager.ts → add handler functionsrc/config.ts if new reaction type@aoagents/ao-core exports two structured feedback tool contracts:
bug_reportimprovement_suggestionBoth share the same required input fields:
titlebodyevidence (array of strings)sessionsourceconfidence (0..1)Example:
import { FEEDBACK_TOOL_NAMES, FeedbackReportStore, getFeedbackReportsDir } from "@aoagents/ao-core";
const reportsDir = getFeedbackReportsDir(configPath, projectPath);
const store = new FeedbackReportStore(reportsDir);
const saved = store.persist(FEEDBACK_TOOL_NAMES.BUG_REPORT, {
title: "SSO login loop",
body: "Google SSO redirects back to /login repeatedly.",
evidence: ["trace_id=abc123", "screenshot: login-loop.png"],
session: "ao-22",
source: "agent",
confidence: 0.84,
});
Storage format:
~/.agent-orchestrator/{hash}-{projectId}/feedback-reportsreport_<timestamp>_<id>.kv) for easy inspectionsha256, 16 hex chars) is generated from normalized tool+contentMigration notes:
feedback-reports directory is created lazily on first persisted report# Run all core tests
pnpm --filter @aoagents/ao-core test
# Run in watch mode
pnpm --filter @aoagents/ao-core test -- --watch
# Run specific test
pnpm --filter @aoagents/ao-core test -- session-manager.test.ts
Tests are in src/__tests__/:
session-manager.test.ts — session CRUD, spawn, cleanuplifecycle-manager.test.ts — state machine, reactionsplugin-registry.test.ts — plugin loading, resolutiontmux.test.ts — tmux utility functions (not a plugin test)prompt-builder.test.ts — prompt generation utilities# Build core
pnpm --filter @aoagents/ao-core build
# Typecheck
pnpm --filter @aoagents/ao-core typecheck
This package is a dependency of all other packages. Build it first if working on the codebase.
Why flat metadata files?
cat ~/.agent-orchestrator/<hash>-my-app/sessions/app-3 shows full stateWhy polling instead of webhooks?
Why plugin slots?
process (ConPTY) on Windows, docker in CI, k8s in prod — same agent/workspace stack across all of themFAQs
Core library — types, config, session manager, lifecycle manager, event bus
The npm package @aoagents/ao-core receives a total of 294 weekly downloads. As such, @aoagents/ao-core popularity was classified as not popular.
We found that @aoagents/ao-core 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.

Research
Socket found 37 malicious PyPI wheels that abuse Python startup hooks to launch a Bun-powered credential stealer tied to Mini Shai-Hulud/Miasma.

Security News
RubyGems and Bundler 4.0.13 introduced an opt-in cooldown feature that delays newly published gems during dependency resolution.

Security News
pnpm 11.5 now recognizes npm staged publish approvals in release metadata, preventing those releases from being mistaken for lower-trust package publishes.