npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@loopstack/code-agent

v0.4.6

Published

AI-powered code agent workflows for Loopstack — codebase exploration, analysis, and more

Downloads

493

Readme


title: Code Agent Module description: AI-powered codebase exploration for Loopstack — ExploreTask tool launches AgentWorkflow sub-agent with glob/grep/read tools, CodeAgentModule registration, forFeature() LLM config, TransitionInput envelope for sub-workflow completion

@loopstack/code-agent

Agent workflow module for the Loopstack automation framework.

AI-powered code exploration for Loopstack workflows. Provides a tool that launches a sub-agent workflow to search, read, and synthesize findings from a remote workspace using glob, grep, and read tools from @loopstack/remote-client.

When to Use

  • You need a workflow to answer questions about a codebase before acting — locating functions, summarizing features, understanding architecture
  • You want to delegate exploration as a single tool call from a parent workflow or agent
  • You need a self-contained agent that iteratively searches and reads files on a remote workspace and returns a synthesized answer
  • Use @loopstack/remote-client directly if you only need individual file operations without the agent loop

Installation

npm install @loopstack/code-agent

Register the module in your application:

import { Module } from '@nestjs/common';
import { CodeAgentModule } from '@loopstack/code-agent';

@Module({
  imports: [CodeAgentModule],
})
export class AppModule {}

CodeAgentModule imports AgentModule from @loopstack/agent, which in turn requires LlmProviderModule and RemoteClientModule to be configured in your app.

To override the LLM provider or model for this module specifically:

@Module({
  imports: [CodeAgentModule.forFeature({ llm: { provider: 'claude', model: 'claude-sonnet-4-20250514' } })],
})
export class AppModule {}

Quick Start

The most common pattern is launching the code agent from a parent workflow using AgentWorkflow directly:

import { Module } from '@nestjs/common';
import { z } from 'zod';
import { AgentWorkflow } from '@loopstack/agent';
import { CodeAgentModule } from '@loopstack/code-agent';
import { BaseWorkflow, MessageDocument, Transition, type TransitionInput, Workflow } from '@loopstack/common';

const ExploreResponseSchema = z.object({ response: z.string() });

@Workflow({ title: 'Code Agent Example' })
export class MyWorkflow extends BaseWorkflow {
  constructor(private readonly agentWorkflow: AgentWorkflow) {
    super();
  }

  @Transition({ to: 'exploring' })
  async start(state: Record<string, unknown>) {
    await this.agentWorkflow.run(
      {
        system: 'You are a codebase exploration agent. Search and read source code to answer the question thoroughly.',
        tools: ['glob', 'grep', 'read'],
        userMessage: 'Find the entry-point module and list its top-level providers.',
      },
      { callback: { transition: 'onExploreComplete' }, show: 'inline', label: 'Exploring codebase...' },
    );
  }

  @Transition({ from: 'exploring', to: 'end', wait: true, schema: ExploreResponseSchema })
  async onExploreComplete(state: Record<string, unknown>, input: TransitionInput<{ response: string }>) {
    await this.documentStore.save(MessageDocument, {
      role: 'assistant',
      text: input.data.response,
    });
  }
}

@Module({
  imports: [CodeAgentModule],
  providers: [MyWorkflow],
  exports: [MyWorkflow, CodeAgentModule],
})
export class MyModule {}

How It Works

State Machine

start ──► exploring (wait) ──► end
             │                   ▲
             └── callback ───────┘
  1. The parent workflow calls agentWorkflow.run() with a system prompt, tool list, and user message
  2. The AgentWorkflow sub-workflow starts its own agent loop: LLM generates text, calls tools (glob, grep, read), loops until it produces a final answer
  3. The orchestrator renders the sub-workflow inline in the parent's UI based on the show option ('inline' by default)
  4. When the agent finishes, it calls back to the parent workflow's wait transition with { data: { response } }
  5. The parent receives the synthesized answer and can display it or act on it

ExploreTask Tool

The module also provides ExploreTask, a tool wrapper around AgentWorkflow that can be used by other agents:

Parent Agent ──► explore_task tool call ──► AgentWorkflow sub-agent
                                                  │
                                            glob/grep/read loop
                                                  │
                                            synthesized answer
                                                  │
                                           ◄── complete() callback

ExploreTask launches the sub-agent and returns { workflowId } with pending status. The orchestrator renders the sub-agent inline in the parent's view. When the sub-agent completes, ExploreTask.complete() returns the response text.

Args Reference

AgentWorkflow.run()

| Arg | Type | Required | Description | | ------------- | ---------- | -------- | -------------------------------------------------------------- | | system | string | Yes | System prompt for the agent | | tools | string[] | Yes | Tool names to make available (e.g. ['glob', 'grep', 'read']) | | userMessage | string | Yes | The question or instruction for the agent | | context | string | No | Additional context to include in the conversation |

Second argument (options):

| Arg | Type | Required | Description | | --------------------- | -------- | -------- | ----------------------------------------------- | | callback.transition | string | No | Transition name to call when the agent finishes |

Returns: QueueResult with { workflowId: string }

Callback Envelope

The parent's wait transition receives a TransitionInput<TData>. Pass only the data shape as the schema — the framework wraps it:

const ExploreResponseSchema = z.object({ response: z.string() });
// Receiver: input: TransitionInput<{ response: string }>

| Field | Type | Description | | --------------------- | ---------------- | --------------------------------------------------------- | | input.workflowId | string | ID of the completed sub-workflow | | input.status | enum | 'completed' / 'failed' / 'canceled' | | input.hasError | boolean | Whether the sub-agent terminated in failure | | input.errorMessage | string \| null | Error description when hasError | | input.data.response | string | The agent's synthesized text answer (validated by schema) |

Tools Reference

explore_task

| Field | Value | | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Name | explore_task | | Description | Launch a sub-agent to explore and analyze the codebase. The agent uses glob, grep, and read tools to search for files and code patterns, then returns a synthesized summary. |

Args (Zod schema):

| Arg | Type | Required | Description | | -------------- | -------- | -------- | --------------------------------------------------------- | | instructions | string | Yes | Detailed instructions for what to explore in the codebase |

Returns: ToolEnvelope<ExploreTaskResult>

  • On launch: { data: { workflowId }, pending: { workflowId } }
  • On complete: { data: string } — the agent's synthesized response text

Configuration

CodeAgentModule.forFeature()

Override the LLM provider or model for the code agent specifically:

CodeAgentModule.forFeature({
  llm: {
    provider: 'claude', // LLM provider name
    model: 'claude-sonnet-4-20250514', // Model identifier
  },
});

| Option | Type | Required | Description | | -------------- | -------- | -------- | ----------------- | | llm.provider | string | No | LLM provider name | | llm.model | string | No | Model identifier |

Public API

  • Module: CodeAgentModule
  • Tool: ExploreTask
  • Type: ExploreTaskResult

Dependencies

| Package | Role | | -------------------------- | ------------------------------------------------------------- | | @loopstack/agent | AgentWorkflow — generic LLM agent loop with tool calling | | @loopstack/common | BaseTool, BaseWorkflow, decorators, document types | | @loopstack/core | Workflow engine, scheduling, state management | | @loopstack/remote-client | glob, grep, read tools executed on the remote workspace | | @nestjs/common | NestJS dependency injection | | zod | Schema validation |

Related

About

Author: Jakob Klippel

License: MIT