NE

neuralscape-adapter

A guide and toolkit for adding new agent framework adapters to the NeuralScape conversation capture pipeline.

Install

mkdir -p .claude/skills/neuralscape-adapter && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/18245" && unzip -o skill.zip -d .claude/skills/neuralscape-adapter && rm skill.zip

Installs to .claude/skills/neuralscape-adapter

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Add new agent framework adapters to NeuralScape's unified conversation hook system. Use when integrating a new AI client (Cursor, Copilot, custom agent), adding a client adapter, or extending the plugin to support another agent framework. Covers adapter creation, client detection, hook manifest, and build config.
314 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Advanced

Key capabilities

  • Extract conversation turns from client events
  • Extract session-end metadata from client events
  • Register new client adapters in `detect.ts`
  • Handle session-end flush behavior
  • Build and test the plugin with sample payloads

How it works

The skill guides the creation of an adapter file that extracts conversation turns and session-end metadata from a new AI client's JSON input, then registers this adapter for client detection and processing.

Inputs & outputs

You give it
JSON data from a new AI client via stdin
You get back
Extracted `ConversationTurn` objects or `SessionEndInput` metadata

When to use neuralscape-adapter

  • Integrate a new AI client
  • Add an agent framework adapter
  • Extend conversation plugin

About this skill

NeuralScape Client Adapter

Guide for adding support for a new agent framework to NeuralScape's conversation capture system.

Architecture

NeuralScape uses an adapter pattern to support multiple AI clients. All clients share the same processing pipeline — only the input extraction differs.

stdin JSON → detect client → adapter extracts turns → core/flush → NeuralScape API

Key files

FilePurpose
neuralscape-plugin/src/core/types.tsConversationTurn, TurnExtractor, SessionEndExtractor interfaces
neuralscape-plugin/src/core/flush.tsShared filter + flush logic (ALL clients use this)
neuralscape-plugin/src/core/compile.tsShared compile trigger (ALL clients use this)
neuralscape-plugin/src/adapters/detect.tsClient detection + extractor lookup
neuralscape-plugin/src/adapters/openclaw.tsReference: OpenClaw adapter (1 turn per event)
neuralscape-plugin/src/adapters/claude-code.tsReference: Claude Code adapter (N turns from transcript)
neuralscape-plugin/src/adapters/generic.tsReference: simplest adapter (direct JSON)
neuralscape-plugin/src/hooks/conversation-turn.tsEntry point: detect → adapter → flush
neuralscape-plugin/src/hooks/session-end.tsEntry point: detect → adapter → flush + compile
neuralscape-plugin/src/utils.tsHTTP client, stdin parsing, identity helpers

Shared interfaces (from core/types.ts)

interface ConversationTurn {
  userMessage: string;
  assistantResponse: string;
  sessionId: string;
  channel: string;        // e.g. "cursor", "copilot", "my-agent"
  timestamp: string;      // ISO 8601
  projectId?: string;
  userId: string;
}

interface SessionEndInput {
  date: string;           // YYYY-MM-DD
  userId: string;
  shouldCompile: boolean;
}

type TurnExtractor = (raw: Record<string, unknown>) => ConversationTurn[] | Promise<ConversationTurn[]>;
type SessionEndExtractor = (raw: Record<string, unknown>) => SessionEndInput | Promise<SessionEndInput>;

Instructions

Step 1: Understand the client's data shape

Before writing code, determine what JSON the new client sends via stdin when a conversation turn completes or a session ends. Document:

  1. What fields identify this client (for detection)?
  2. Where is the user message? The assistant response?
  3. Is there a session ID? A project/workspace path?
  4. Does the client send one turn at a time, or a full transcript?
  5. What event fires at session end?

Step 2: Create the adapter file

Create neuralscape-plugin/src/adapters/{client-name}.ts:

/**
 * {ClientName} adapter — extracts conversation turns from {ClientName}'s event format.
 *
 * Input: { ... describe the expected stdin shape ... }
 * Output: ConversationTurn[] 
 */

import type { ConversationTurn, SessionEndInput } from "../core/types.js";
import { getUserId, getProjectId } from "../utils.js";

/**
 * Extract conversation turns from a {ClientName} event.
 */
export function extract{ClientName}Turns(
  raw: Record<string, unknown>
): ConversationTurn[] {
  // Map client-specific fields to ConversationTurn
  return [
    {
      userMessage: /* extract from raw */,
      assistantResponse: /* extract from raw */,
      sessionId: /* extract or default to "unknown" */,
      channel: "{client-name}",
      timestamp: /* extract or default to new Date().toISOString() */,
      projectId: /* extract workspace/project if available */,
      userId: getUserId(),
    },
  ];
}

/**
 * Extract session-end metadata from a {ClientName} event.
 */
export function extract{ClientName}SessionEnd(
  raw: Record<string, unknown>
): SessionEndInput {
  return {
    date: /* extract or default to today */,
    userId: getUserId(),
    shouldCompile: true,
  };
}

Key rules:

  • Always return ConversationTurn[] (even for a single turn, wrap in array)
  • Use getUserId() from utils for the user ID
  • Use getProjectId(cwd) if the client provides a working directory
  • Set channel to a unique string identifying this client
  • Default missing fields gracefully — never throw on missing optional data

Step 3: Register the adapter in detect.ts

Edit neuralscape-plugin/src/adapters/detect.ts:

  1. Add the new client type to ClientType:
export type ClientType = "openclaw" | "claude-code" | "{client-name}" | "generic";
  1. Add the import:
import { extract{ClientName}Turns, extract{ClientName}SessionEnd } from "./{client-name}.js";
  1. Add detection logic in detectClient() — add BEFORE the "generic" fallback:
export function detectClient(raw: Record<string, unknown>): ClientType {
  if (raw.transcript_path || raw.hook_event_name) return "claude-code";
  if (raw.type && raw.action) return "openclaw";
  if (raw.{unique_field}) return "{client-name}";  // ADD THIS
  return "generic";
}
  1. Add cases to both switch statements in getTurnExtractor() and getSessionEndExtractor():
case "{client-name}":
  return extract{ClientName}Turns;

Step 4: Handle session-end behavior (if needed)

If the new client needs to flush turns at session end (like Claude Code does with transcripts), edit neuralscape-plugin/src/hooks/session-end.ts:

// Add the client to the flush-before-compile block
if (client === "claude-code" || client === "{client-name}") {
  const turnExtractor = getTurnExtractor(client);
  const turns = await turnExtractor(raw);
  await flushTurns(turns);
}

Only do this if the client sends conversation data at session end rather than per-turn.

Step 5: Create a hook manifest (if the client uses one)

If the new client has its own hook configuration format, create neuralscape-plugin/hooks/{client-name}-hooks.json. Use the OpenClaw manifest as a template:

{
  "description": "NeuralScape memory hooks for {ClientName}",
  "hooks": {
    "{conversation-event}": [
      {
        "matcher": ".*",
        "hooks": [
          {
            "type": "command",
            "command": "node \"${PLUGIN_ROOT}/scripts/conversation-turn.js\"",
            "timeout": 15,
            "async": true
          }
        ]
      }
    ],
    "{session-end-event}": [
      {
        "matcher": ".*",
        "hooks": [
          {
            "type": "command",
            "command": "node \"${PLUGIN_ROOT}/scripts/session-end.js\"",
            "timeout": 15,
            "async": true
          }
        ]
      }
    ]
  }
}

Step 6: Build and test

cd neuralscape-plugin
npm run build

Test with a sample payload:

echo '{ ... client-specific JSON ... }' | node scripts/conversation-turn.js

Expected output: {"continue":true,"suppressOutput":true} followed by either a successful flush or a connection error (if NeuralScape isn't running).

Test session end:

echo '{ ... client-specific JSON ... }' | node scripts/session-end.js

Step 7: Verify the full pipeline

With NeuralScape running (cd neuralscape-service && uv run python main.py):

  1. Pipe a conversation turn — check that /flush is called and facts appear in the vault
  2. Pipe a session end — check that /compile is called
  3. Verify the daily log has the entry (Daily/{date}.md)
  4. Verify the category folder has the entry (e.g., Semantic/Preferences/entries.md)

Reference adapters

Simplest: generic.ts (start here)

Single turn from direct JSON. No detection logic needed (it's the fallback). Good starting point — copy and modify.

File: neuralscape-plugin/src/adapters/generic.ts

Per-turn: openclaw.ts

Extracts one turn from an event payload. Demonstrates field mapping from a nested context object.

File: neuralscape-plugin/src/adapters/openclaw.ts

Batch/transcript: claude-code.ts

Reads a transcript file, pairs user/assistant messages, tracks offset to avoid re-flushing. Demonstrates async extraction with file I/O.

File: neuralscape-plugin/src/adapters/claude-code.ts

Checklist

Before submitting:

  • Adapter file created at src/adapters/{client-name}.ts
  • Exports extract{ClientName}Turns (returns ConversationTurn[])
  • Exports extract{ClientName}SessionEnd (returns SessionEndInput)
  • ClientType union updated in detect.ts
  • Detection condition added in detectClient() — before "generic" fallback
  • Both getTurnExtractor() and getSessionEndExtractor() have new cases
  • session-end.ts updated if client needs flush-before-compile
  • Hook manifest created (if client uses one)
  • npm run build succeeds
  • Tested with sample stdin payload
  • Channel name is unique and descriptive

When not to use it

  • When the goal is not to integrate a new AI client or agent framework
  • When the client does not send JSON via stdin for conversation turns or session ends
  • When the client does not provide a working directory for project ID

Limitations

  • Requires the new client to send JSON via stdin
  • Client detection relies on unique fields in the raw JSON input
  • Default missing fields gracefully, never throw on missing optional data

How it compares

This skill provides a structured adapter pattern for integrating diverse AI clients into a unified conversation hook system, abstracting client-specific input formats into a common interface, unlike direct parsing for each client.

Compared to similar skills

neuralscape-adapter side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
neuralscape-adapter (this skill)02moReviewAdvanced
mcporter72moNo flagsIntermediate
calcom-api23moNo flagsIntermediate
dust-mcp-server110dReviewAdvanced

Try saying

Example prompts that trigger this skill in your AI assistant.

You might also like

mcporter

openclaw

Use the mcporter CLI to list, configure, auth, and call MCP servers/tools directly (HTTP or stdio), including ad-hoc servers, config edits, and CLI/type generation.

726

calcom-api

calcom

Interact with the Cal.com API v2 to manage scheduling, bookings, event types, availability, and calendars. Use this skill when building integrations that need to create or manage bookings, check availability, configure event types, or sync calendars with Cal.com's scheduling infrastructure.

216

dust-mcp-server

dust-tt

Step-by-step guide for creating new internal MCP server integrations in Dust that connect to remote platforms (Jira, HubSpot, Salesforce, etc.). Use when adding a new MCP server, implementing a platform integration, or connecting Dust to a new external service.

19

developing-genkit-tooling

firebase

Best practices for authoring Genkit tooling, including CLI commands and MCP server tools. Covers naming conventions, architectural patterns, and consistency guidelines.

27

juicebox-rate-limits

jeremylongshore

Implement Juicebox rate limiting and backoff. Use when handling API quotas, implementing retry logic, or optimizing request throughput. Trigger with phrases like "juicebox rate limit", "juicebox quota", "juicebox throttling", "juicebox backoff".

23

clay-sdk-patterns

jeremylongshore

Apply production-ready Clay SDK patterns for TypeScript and Python. Use when implementing Clay integrations, refactoring SDK usage, or establishing team coding standards for Clay. Trigger with phrases like "clay SDK patterns", "clay best practices", "clay code patterns", "idiomatic clay".

04

Search skills

Search the agent skills registry