raysurfer 0.3.7 → 0.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +110 -89
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,113 +1,84 @@
1
1
  # RaySurfer TypeScript SDK
2
2
 
3
- TypeScript SDK for RaySurfer - code block caching and retrieval for AI agents with Claude Agent SDK integration.
3
+ Drop-in replacement for Claude Agent SDK with automatic code caching.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
8
  npm install raysurfer
9
- # or
10
- bun add raysurfer
11
9
  ```
12
10
 
13
- ## Quick Start
11
+ ## Setup
14
12
 
15
- ### Basic Client (Store/Retrieve Code Blocks)
13
+ Set your API key:
16
14
 
17
- ```typescript
18
- import { RaySurfer } from "raysurfer";
19
-
20
- const client = new RaySurfer({ apiKey: "rs_..." });
15
+ ```bash
16
+ export RAYSURFER_API_KEY=your_api_key_here
17
+ ```
21
18
 
22
- // Store a code block
23
- const result = await client.storeCodeBlock({
24
- name: "GitHub User Fetcher",
25
- source: "async function fetchUser(username) { ... }",
26
- entrypoint: "fetchUser",
27
- language: "typescript",
28
- });
19
+ Get your key from the [dashboard](https://raysurfer.com/dashboard/api-keys).
29
20
 
30
- // Retrieve code blocks for a task
31
- const response = await client.retrieve({ task: "Fetch GitHub user data" });
32
- for (const match of response.codeBlocks) {
33
- console.log(match.codeBlock.name, match.verdictScore);
34
- }
35
- ```
21
+ ## Usage
36
22
 
37
- ### Claude Agent SDK Integration
23
+ Swap your client class and method names. Options come directly from `@anthropic-ai/claude-agent-sdk`:
38
24
 
39
25
  ```typescript
26
+ // Before
27
+ import { ClaudeSDKClient, ClaudeAgentOptions } from "@anthropic-ai/claude-agent-sdk";
28
+
29
+ // After
40
30
  import { RaysurferClient } from "raysurfer";
31
+ import { ClaudeAgentOptions } from "@anthropic-ai/claude-agent-sdk";
41
32
 
42
- const client = new RaysurferClient({
43
- raysurferApiKey: "rs_...",
44
- model: "claude-sonnet-4-5",
45
- systemPrompt: "You are a helpful assistant.",
33
+ const options: ClaudeAgentOptions = {
46
34
  allowedTools: ["Read", "Write", "Bash"],
47
- });
35
+ systemPrompt: "You are a helpful assistant.",
36
+ };
48
37
 
49
- // Pre-fetches code files, downloads to sandbox, injects into prompt
50
- for await (const message of client.query("Fetch user data from GitHub API")) {
51
- if (message.type === "assistant") {
52
- console.log(message.content);
53
- }
38
+ const client = new RaysurferClient(options);
39
+
40
+ for await (const msg of client.raysurferQuery("Generate quarterly report")) {
41
+ console.log(msg);
54
42
  }
55
43
  ```
56
44
 
57
- ## How It Works
45
+ ## Method Mapping
58
46
 
59
- 1. **On `query()`**: RaysurferClient calls the backend to get relevant code files
60
- 2. **Downloads to sandbox**: Files are written to `~/.raysurfer/sandbox/`
61
- 3. **Injects into prompt**: Code snippets are added to the system prompt
62
- 4. **Agent executes**: Agent can run the code using the Bash tool within the sandbox
63
- 5. **Caches results**: On success, generated code is stored back to the cache
47
+ | Claude SDK | Raysurfer |
48
+ |------------|-----------|
49
+ | `new ClaudeSDKClient(options)` | `new RaysurferClient(options)` |
50
+ | `client.query(prompt)` | `client.raysurferQuery(prompt)` |
64
51
 
65
- ## RaysurferAgentOptions
52
+ ## How It Works
66
53
 
67
- ```typescript
68
- interface RaysurferAgentOptions {
69
- // Raysurfer-specific
70
- raysurferApiKey?: string;
71
- raysurferBaseUrl?: string;
72
- prefetchCount?: number; // default: 5
73
- minVerdictScore?: number; // default: 0.3
74
- preferComplete?: boolean; // default: true
75
- sandboxDir?: string; // default: ~/.raysurfer/sandbox
76
- cleanupSandbox?: boolean; // default: true
77
- cleanupOnError?: boolean; // default: false
78
-
79
- // Standard Claude Agent SDK options
80
- model?: string; // default: "claude-sonnet-4-5"
81
- workingDirectory?: string;
82
- systemPrompt?: string;
83
- permissionMode?: "default" | "acceptEdits" | "plan" | "bypassPermissions";
84
- maxBudgetUsd?: number;
85
- allowedTools?: string[];
86
- disallowedTools?: string[];
87
- maxTurns?: number;
88
- env?: Record<string, string>;
89
- mcpServers?: Record<string, unknown>;
90
- }
91
- ```
54
+ 1. **On `raysurferQuery()`**: Retrieves cached code blocks matching your task
55
+ 2. **Downloads to sandbox**: Files ready for the agent to execute
56
+ 3. **Injects into prompt**: Agent sees proven code snippets
57
+ 4. **After success**: New code is cached for next time
58
+
59
+ Caching is enabled automatically when `RAYSURFER_API_KEY` is set.
92
60
 
93
61
  ## Snippet Retrieval Scope
94
62
 
95
- Control which snippets are retrieved using `publicSnips` and `snipsDesired`:
63
+ Control which cached snippets are retrieved using `publicSnips` and `snipsDesired`:
96
64
 
97
65
  ```typescript
98
- import { RaySurfer } from "raysurfer";
66
+ import { RaysurferClient } from "raysurfer";
67
+ import { ClaudeAgentOptions } from "@anthropic-ai/claude-agent-sdk";
68
+
69
+ const options: ClaudeAgentOptions = {
70
+ allowedTools: ["Read", "Write", "Bash"],
71
+ };
99
72
 
100
73
  // Include both public and company snippets
101
- const client = new RaySurfer({
102
- apiKey: "rs_...",
103
- publicSnips: true, // Include public/shared snippets
104
- snipsDesired: "company", // Also include company-level snippets (Team/Enterprise)
74
+ const client = new RaysurferClient(options, {
75
+ publicSnips: true, // Include public/shared snippets
76
+ snipsDesired: "company", // Also include company-level snippets
105
77
  });
106
78
 
107
79
  // Enterprise: Retrieve client-specific snippets only
108
- const enterpriseClient = new RaySurfer({
109
- apiKey: "rs_...",
110
- snipsDesired: "client", // Client workspace snippets (Enterprise only)
80
+ const enterpriseClient = new RaysurferClient(options, {
81
+ snipsDesired: "client", // Client workspace snippets (Enterprise only)
111
82
  });
112
83
  ```
113
84
 
@@ -117,26 +88,76 @@ const enterpriseClient = new RaySurfer({
117
88
  | `snipsDesired: "company"` | TEAM or ENTERPRISE |
118
89
  | `snipsDesired: "client"` | ENTERPRISE only |
119
90
 
120
- ## API Reference
91
+ ## Full Example
121
92
 
122
- ### RaySurfer Client
93
+ ```typescript
94
+ import { RaysurferClient } from "raysurfer";
95
+ import { ClaudeAgentOptions } from "@anthropic-ai/claude-agent-sdk";
96
+
97
+ process.env.RAYSURFER_API_KEY = "your_api_key";
98
+
99
+ const options: ClaudeAgentOptions = {
100
+ allowedTools: ["Read", "Write", "Bash"],
101
+ systemPrompt: "You are a helpful assistant.",
102
+ };
103
+
104
+ const client = new RaysurferClient(options);
105
+
106
+ // First run: generates and caches code
107
+ for await (const msg of client.raysurferQuery("Fetch GitHub trending repos")) {
108
+ console.log(msg);
109
+ }
110
+
111
+ // Second run: retrieves from cache (instant)
112
+ for await (const msg of client.raysurferQuery("Fetch GitHub trending repos")) {
113
+ console.log(msg);
114
+ }
115
+ ```
116
+
117
+ ## Without Caching
118
+
119
+ If `RAYSURFER_API_KEY` is not set, `RaysurferClient` behaves exactly like `ClaudeSDKClient` — no caching, just a pass-through wrapper.
120
+
121
+ ## Low-Level API
122
+
123
+ For custom integrations, use the `RaySurfer` client directly with three core methods:
123
124
 
124
125
  ```typescript
125
- const client = new RaySurfer({ apiKey: "rs_..." });
126
-
127
- // Store
128
- await client.storeCodeBlock({ name, source, entrypoint, language, ... });
129
- await client.storeExecution({ codeBlockId, triggeringTask, inputData, outputData, ... });
130
- await client.submitExecutionResult(task, filesWritten, succeeded);
131
-
132
- // Retrieve
133
- await client.retrieve({ task, topK, minVerdictScore });
134
- await client.retrieveBest({ task, topK, minVerdictScore });
135
- await client.getFewShotExamples(task, k);
136
- await client.getTaskPatterns({ task, codeBlockId, minThumbsUp, topK });
137
- await client.getCodeFiles({ task, topK, minVerdictScore, preferComplete });
126
+ import { RaySurfer } from "raysurfer";
127
+
128
+ const client = new RaySurfer({ apiKey: "your_api_key" });
129
+
130
+ // 1. Get cached code snippets for a task
131
+ const snips = await client.getCodeSnips({ task: "Fetch GitHub trending repos" });
132
+ for (const match of snips.codeBlocks) {
133
+ console.log(`${match.codeBlock.name}: ${match.score}`);
134
+ }
135
+
136
+ // 2. Upload new code snippets after execution
137
+ await client.uploadNewCodeSnips(
138
+ "Fetch GitHub trending repos",
139
+ [{ filename: "fetch_repos.ts", content: "function fetch() { ... }" }],
140
+ true // succeeded
141
+ );
142
+
143
+ // 3. Vote on whether a cached snippet was useful
144
+ await client.voteCodeSnip({
145
+ task: "Fetch GitHub trending repos",
146
+ codeBlockId: "abc123",
147
+ codeBlockName: "github_fetcher",
148
+ codeBlockDescription: "Fetches trending repos from GitHub",
149
+ succeeded: true,
150
+ });
138
151
  ```
139
152
 
153
+ ### Method Reference
154
+
155
+ | Method | Description |
156
+ |--------|-------------|
157
+ | `getCodeSnips({ task, topK?, minVerdictScore? })` | Retrieve cached code snippets by semantic search |
158
+ | `uploadNewCodeSnips(task, filesWritten, succeeded)` | Store new code files for future reuse |
159
+ | `voteCodeSnip({ task, codeBlockId, codeBlockName, codeBlockDescription, succeeded })` | Vote on snippet usefulness |
160
+
140
161
  ## License
141
162
 
142
163
  MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "raysurfer",
3
- "version": "0.3.7",
3
+ "version": "0.3.8",
4
4
  "description": "Drop-in replacement for Claude Agent SDK with automatic code caching - just swap your import",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",