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

@robinpath/core

v0.40.0

Published

RobinPath - A lightweight, fast, and easy-to-use scripting language for automation and data processing.

Readme

@robinpath/core

The core runtime for RobinPath — a scripting language with a built-in AI workflow engine. Write automations in plain English, let AI handle the routing.

ask "Paste customer feedback:" into $feedback

@known @desc "Route positive reviews to marketing"
def positive_review $feedback
  slack.send "#wins" $feedback
enddef

@known @desc "Create Jira ticket for bugs"
def bug_report $feedback
  jira.create "BUG" $feedback
enddef

think tools [@known]
  Review this feedback and handle it: $feedback
endthink

Installation

npm i @robinpath/core

Quick Start

import { RobinPath } from '@robinpath/core';

const rp = new RobinPath();

await rp.executeScript(`
  $items = ["apples", "bananas", "cherries"]
  for $item in $items
    log "Item: " + $item
  endfor
`);

AI Workflow Engine

RobinPath replaces complex if/else trees with AI-powered routing. Define actions, let the AI decide which to run.

The Pattern: input -> AI decides -> human approves -> execute

# 1. Get input
ask "Customer email:" into $email
ask "Plan:" ["starter", "pro", "enterprise"] into $plan

# 2. Define available actions
@known @desc "Create Salesforce account"
def create_account $email $plan
  salesforce.create $plan $email
enddef

@known @desc "Send welcome email"
def send_welcome $email $plan
  gmail.send $email "Welcome to " + $plan + "!"
enddef

@known @desc "Notify team on Slack"
def notify_slack $channel $message
  slack.send $channel $message
enddef

# 3. AI creates an execution plan
think as plan into $steps tools [@known]
  New customer: email=$email, plan=$plan
  Create the right onboarding steps.
endthink

# 4. Execute with human approval
run $steps "approve"

This replaces what would be 60+ if/else branches with a single AI decision.

Three Routing Options

Option A — AI decides AND executes (automatic):

think tools [@known]
  Review this feedback and route it: $feedback
endthink

Option B — AI decides, script controls execution:

think guard ["billing", "hr", "engineering"] into $dept
  Which department handles this? $feedback
endthink
approve "Route to " + $dept + "?"
call $dept $feedback

Option C — AI creates a multi-step plan:

think as plan into $steps tools [@known]
  Onboard this enterprise customer in EU.
endthink
run $steps "approve"

Key Features

| Feature | Syntax | Purpose | |---------|--------|---------| | ask | ask "prompt" into $var | Interactive input (supports choices) | | approve | approve "message" | Human approval gate | | think | think [options] ... endthink | AI reasoning and routing | | @known | @known def func ... enddef | Mark function as AI-callable | | @by | @by "model" | Restrict which AI model can call it | | call | call $func_name | Dynamic function dispatch | | run | run $plan "approve" | Execute plan with approval gates | | remember | remember ... endremember | Persistent AI memory | | as plan | think as plan into $steps | AI returns execution plan | | tools [@known] | think tools [@known] | Auto-discover @known functions |

Named AI Agents

# Register agents with different models and personas
# rp.registerAgent("support", { model: "claude-sonnet-4.6", systemPrompt: "You are a support specialist." })

think support into $reply
  Customer says: $message
  Draft a helpful response.
endthink

Persistent Memory

remember "customer_prefs"
  customer prefers email over phone
  customer is on enterprise plan
endremember

# Later, AI can reference this context
think memory "customer_prefs"
  How should we reach out to this customer?
endthink

# Remove specific memories
unremember "customer_prefs"
  customer prefers email over phone
endunremember

Host Integration

Unified Setup (Recommended)

Configure everything with one call via RobinPathHost:

import { RobinPath, RobinPathHost } from '@robinpath/core';

const rp = new RobinPath();

rp.setHost({
  think: myAIProvider,
  ask: {
    ask: async (prompt, options) => {
      // Show prompt in your UI, return user's response
      // options.choices contains constrained options if provided
      return await showInputDialog(prompt, options);
    },
    approve: async (message, options) => {
      // Show approval dialog, return true/false
      return await showConfirmDialog(message);
    },
  },
  remember: {
    load: async (key) => db.get(`memory:${key}`) || [],
    save: async (key, entries) => db.set(`memory:${key}`, entries),
    clear: async (key) => db.delete(`memory:${key}`),
    list: async () => db.keys('memory:*'),
  },
  onStreamToken: (delta) => process.stdout.write(delta),
});

Individual setters also work: setThinkHandler(), setAskHandler(), setRememberHandler(), registerAgent().

Console fallbacks: When no handler is set, ask falls back to stdin readline and approve auto-approves with a warning — scripts are testable without full host setup.

Language Basics

Variables and Last Value

$name = "Alice"
$age = 25

math.add 10 20
log $              # 30 — $ holds last result

math.add 5 3 into $sum
log $sum           # 8

Control Flow

if $score >= 90
  log "Grade: A"
elseif $score >= 80
  log "Grade: B"
else
  log "Grade: F"
endif

for $item in $items
  log $item
endfor

for $i from 1 to 10
  log $i
endfor

Functions

@desc "Calculate total with tax"
@param number $amount "Base amount"
@param number $rate "Tax rate"
def withTax $amount $rate
  return $amount + ($amount * $rate)
enddef

withTax 100 0.2 into $total
log $total   # 120

Do Blocks and Error Handling

do
  $result = http.get "https://api.example.com/data"
catch $err
  log "Failed: " + $err
enddo

Parallel Execution

together
  do into $users
    http.get "https://api.example.com/users"
  enddo
  do into $posts
    http.get "https://api.example.com/posts"
  enddo
endtogether

Think Blocks (AI Reasoning)

# Simple prompt
think into $answer
  What is the capital of France?
endthink

# Structured output
think as json { name: string, sentiment: string } into $analysis
  Analyze: $review
endthink

# Constrained output
think guard ["bug", "feature", "question"] into $category
  Classify this issue: $title
endthink

# Agent tool loop
think tools [http, file] into $result
  Fetch weather data and save to weather.json
endthink

Decorators

@desc "Fetch with retry"
@retry 3
@timeout 10000
do
  http.get "https://flaky-api.example.com"
enddo

@known                            # AI-callable
@by "anthropic/claude-haiku-4.5"  # Model restriction
@desc "Quick text classification"
@pos 100 200                      # Visual canvas position
def classify $text
  think.classify $text ["positive", "negative", "neutral"]
enddef

250+ Modules

Install external modules for real integrations:

npm i @robinpath/slack @robinpath/jira @robinpath/gmail
slack.send "#general" "Hello from RobinPath!"
jira.create "BUG" "Login page broken"
gmail.send "[email protected]" "Report" $report

Available modules include: slack, jira, github, gmail, notion, airtable, salesforce, hubspot, shopify, discord, telegram, whatsapp, twilio, zendesk, linear, mongodb, postgres, redis, s3, firebase, supabase, google-sheets, google-drive, google-calendar, excel, pdf, openai, anthropic, and 200+ more.

Advanced SDK

REPL Mode

const rp = new RobinPath();
await rp.executeLine('$x = 10');
await rp.executeLine('math.add $x 20');
console.log(rp.getLastValue()); // 30

Threads

const rp = new RobinPath({ threadControl: true });
const thread = rp.createThread('user-123');
await thread.executeScript('$count = 10');

Custom Builtins and Modules

rp.registerBuiltin('greet', (args) => `Hello, ${args[0]}!`);

rp.registerModule('myapp', {
  process: (args) => processData(args[0]),
  validate: (args) => isValid(args[0]),
});

Execution Control

rp.pause();     // Pause execution
rp.resume();    // Resume
rp.cancel();    // Cancel
rp.step();      // Execute single step

Full Language Reference

See CORE.md for the complete language specification.

License

MIT