Sandcastle Integration

Give your Sandcastle agents persistent memory across runs using Synapse.

Sandcastle orchestrates AI coding agents in isolated sandboxes. By default, each run is stateless — the agent starts cold with no knowledge of what it did before. Synapse adds a persistent memory layer: agents load prior context at the start of each run and save key outputs at the end. Every run builds on the last.

Install

npm install @ai-hero/sandcastle

Synapse helper module

Add this file to your project. It exposes three functions: remember (write a record), recall (semantic search), and recent (fetch the latest records). These are the only Synapse calls your agent needs.

// src/synapse.ts — Synapse memory helpers for Sandcastle agents
const BASE = 'https://synapse.by-kit.com/api/v1'
const AGENT_ID = process.env.SYNAPSE_AGENT_ID || 'sandcastle-agent'

async function request(method: string, path: string, body?: object) {
  const key = process.env.SYNAPSE_API_KEY
  if (!key) throw new Error('SYNAPSE_API_KEY is required')
  const res = await fetch(`${BASE}${path}`, {
    method,
    headers: {
      Authorization: `Bearer ${key}`,
      'Content-Type': 'application/json',
    },
    body: body ? JSON.stringify(body) : undefined,
  })
  return res.json()
}

export async function remember(title: string, body: string, type = 'fact') {
  return request('POST', '/record', { agent_id: AGENT_ID, title, body, type })
}

export async function recall(query: string, limit = 5): Promise<string> {
  const records = await request('GET', `/query?q=${encodeURIComponent(query)}&limit=${limit}`, undefined)
  if (!Array.isArray(records) || records.length === 0) return 'No prior memory found.'
  return records.map((r: any) => `[${r.title}] ${r.body}`).join('\n---\n')
}

export async function recent(limit = 5): Promise<string> {
  const records = await request('GET', `/query?limit=${limit}`, undefined)
  if (!Array.isArray(records) || records.length === 0) return 'No prior memory found.'
  return records.map((r: any) => `[${r.title}] ${r.body}`).join('\n---\n')
}

Agent with persistent memory

The full pattern — load memory → inject into prompt → run agent → save outputs:

// src/run.ts — Sandcastle agent with Synapse memory
import { run, claudeCode } from '@ai-hero/sandcastle'
import { docker } from '@ai-hero/sandcastle/sandboxes/docker'
import { remember, recall, recent } from './synapse.js'

async function main() {
  // Step 1: Load prior context from Synapse
  console.log('Loading prior memory from Synapse...')
  const priorMemory = await recent(5)
  const taskContext = await recall('codebase architecture patterns', 3)

  // Step 2: Build the prompt with injected memory
  const prompt = `
You are a code analysis agent with persistent memory.

## What you remember from prior runs:
${priorMemory}

## Prior context on this codebase:
${taskContext}

## Your task for this run:
1. Analyze the codebase in the current directory
2. Identify the 3 most important architectural decisions
3. Note any patterns, anti-patterns, or tech debt
4. Write your findings to a file called ANALYSIS.md

Be specific. You have memory of prior runs — build on it, don't repeat it.
  `.trim()

  // Step 3: Run the agent in an isolated sandbox
  console.log('Starting Sandcastle agent...')
  const result = await run({
    agent: claudeCode('claude-opus-4-7'),
    sandbox: docker(),
    prompt,
  })

  console.log(`Agent completed in ${result.iterations.length} iterations`)

  // Step 4: Save key outputs back to Synapse
  const lastIteration = result.iterations[result.iterations.length - 1]
  const agentOutput = lastIteration?.output || 'No output captured'

  await remember(
    `Code analysis run ${new Date().toISOString().slice(0, 10)}`,
    agentOutput.slice(0, 2000),
    'analysis'
  )

  console.log('Memory saved to Synapse. Agent will remember this next run.')
}

main().catch(console.error)

How it works

  1. Load memory — query Synapse for recent records and task-specific context before the agent runs
  2. Inject into prompt — include that memory in the agent's system prompt so it knows what happened before
  3. Run the agent — Sandcastle spins up Claude Code in an isolated Docker sandbox
  4. Save outputs — write key findings back to Synapse so the next run has them

Full example repo

A complete working project with all files, README, and .env.example: github.com/jfulmines/synapse-sandcastle-example

Next steps