@paperclipai/adapter-cursor-local 0.3.0-canary.0

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 (54) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cli/format-event.d.ts +2 -0
  3. package/dist/cli/format-event.d.ts.map +1 -0
  4. package/dist/cli/format-event.js +296 -0
  5. package/dist/cli/format-event.js.map +1 -0
  6. package/dist/cli/index.d.ts +2 -0
  7. package/dist/cli/index.d.ts.map +1 -0
  8. package/dist/cli/index.js +2 -0
  9. package/dist/cli/index.js.map +1 -0
  10. package/dist/index.d.ts +9 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +81 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/server/execute.d.ts +10 -0
  15. package/dist/server/execute.d.ts.map +1 -0
  16. package/dist/server/execute.js +392 -0
  17. package/dist/server/execute.js.map +1 -0
  18. package/dist/server/execute.skills.test.d.ts +2 -0
  19. package/dist/server/execute.skills.test.d.ts.map +1 -0
  20. package/dist/server/execute.skills.test.js +79 -0
  21. package/dist/server/execute.skills.test.js.map +1 -0
  22. package/dist/server/index.d.ts +6 -0
  23. package/dist/server/index.d.ts.map +1 -0
  24. package/dist/server/index.js +61 -0
  25. package/dist/server/index.js.map +1 -0
  26. package/dist/server/parse.d.ts +13 -0
  27. package/dist/server/parse.d.ts.map +1 -0
  28. package/dist/server/parse.js +139 -0
  29. package/dist/server/parse.js.map +1 -0
  30. package/dist/server/test.d.ts +3 -0
  31. package/dist/server/test.d.ts.map +1 -0
  32. package/dist/server/test.js +188 -0
  33. package/dist/server/test.js.map +1 -0
  34. package/dist/shared/stream.d.ts +5 -0
  35. package/dist/shared/stream.d.ts.map +1 -0
  36. package/dist/shared/stream.js +13 -0
  37. package/dist/shared/stream.js.map +1 -0
  38. package/dist/shared/trust.d.ts +2 -0
  39. package/dist/shared/trust.d.ts.map +1 -0
  40. package/dist/shared/trust.js +7 -0
  41. package/dist/shared/trust.js.map +1 -0
  42. package/dist/ui/build-config.d.ts +3 -0
  43. package/dist/ui/build-config.d.ts.map +1 -0
  44. package/dist/ui/build-config.js +90 -0
  45. package/dist/ui/build-config.js.map +1 -0
  46. package/dist/ui/index.d.ts +3 -0
  47. package/dist/ui/index.d.ts.map +1 -0
  48. package/dist/ui/index.js +3 -0
  49. package/dist/ui/index.js.map +1 -0
  50. package/dist/ui/parse-stdout.d.ts +3 -0
  51. package/dist/ui/parse-stdout.d.ts.map +1 -0
  52. package/dist/ui/parse-stdout.js +367 -0
  53. package/dist/ui/parse-stdout.js.map +1 -0
  54. package/package.json +45 -0
@@ -0,0 +1,392 @@
1
+ import fs from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { asString, asNumber, asStringArray, parseObject, buildPaperclipEnv, redactEnvForLogs, ensureAbsoluteDirectory, ensureCommandResolvable, ensurePathInEnv, renderTemplate, runChildProcess, } from "@paperclipai/adapter-utils/server-utils";
6
+ import { DEFAULT_CURSOR_LOCAL_MODEL } from "../index.js";
7
+ import { parseCursorJsonl, isCursorUnknownSessionError } from "./parse.js";
8
+ import { normalizeCursorStreamLine } from "../shared/stream.js";
9
+ import { hasCursorTrustBypassArg } from "../shared/trust.js";
10
+ const __moduleDir = path.dirname(fileURLToPath(import.meta.url));
11
+ const PAPERCLIP_SKILLS_CANDIDATES = [
12
+ path.resolve(__moduleDir, "../../skills"),
13
+ path.resolve(__moduleDir, "../../../../../skills"),
14
+ ];
15
+ function firstNonEmptyLine(text) {
16
+ return (text
17
+ .split(/\r?\n/)
18
+ .map((line) => line.trim())
19
+ .find(Boolean) ?? "");
20
+ }
21
+ function hasNonEmptyEnvValue(env, key) {
22
+ const raw = env[key];
23
+ return typeof raw === "string" && raw.trim().length > 0;
24
+ }
25
+ function resolveCursorBillingType(env) {
26
+ return hasNonEmptyEnvValue(env, "CURSOR_API_KEY") || hasNonEmptyEnvValue(env, "OPENAI_API_KEY")
27
+ ? "api"
28
+ : "subscription";
29
+ }
30
+ function resolveProviderFromModel(model) {
31
+ const trimmed = model.trim().toLowerCase();
32
+ if (!trimmed)
33
+ return null;
34
+ const slash = trimmed.indexOf("/");
35
+ if (slash > 0)
36
+ return trimmed.slice(0, slash);
37
+ if (trimmed.includes("sonnet") || trimmed.includes("claude"))
38
+ return "anthropic";
39
+ if (trimmed.startsWith("gpt") || trimmed.startsWith("o"))
40
+ return "openai";
41
+ return null;
42
+ }
43
+ function normalizeMode(rawMode) {
44
+ const mode = rawMode.trim().toLowerCase();
45
+ if (mode === "plan" || mode === "ask")
46
+ return mode;
47
+ return null;
48
+ }
49
+ function renderPaperclipEnvNote(env) {
50
+ const paperclipKeys = Object.keys(env)
51
+ .filter((key) => key.startsWith("PAPERCLIP_"))
52
+ .sort();
53
+ if (paperclipKeys.length === 0)
54
+ return "";
55
+ return [
56
+ "Paperclip runtime note:",
57
+ `The following PAPERCLIP_* environment variables are available in this run: ${paperclipKeys.join(", ")}`,
58
+ "Do not assume these variables are missing without checking your shell environment.",
59
+ "",
60
+ "",
61
+ ].join("\n");
62
+ }
63
+ function cursorSkillsHome() {
64
+ return path.join(os.homedir(), ".cursor", "skills");
65
+ }
66
+ async function resolvePaperclipSkillsDir() {
67
+ for (const candidate of PAPERCLIP_SKILLS_CANDIDATES) {
68
+ const isDir = await fs.stat(candidate).then((s) => s.isDirectory()).catch(() => false);
69
+ if (isDir)
70
+ return candidate;
71
+ }
72
+ return null;
73
+ }
74
+ export async function ensureCursorSkillsInjected(onLog, options = {}) {
75
+ const skillsDir = options.skillsDir ?? await resolvePaperclipSkillsDir();
76
+ if (!skillsDir)
77
+ return;
78
+ const skillsHome = options.skillsHome ?? cursorSkillsHome();
79
+ try {
80
+ await fs.mkdir(skillsHome, { recursive: true });
81
+ }
82
+ catch (err) {
83
+ await onLog("stderr", `[paperclip] Failed to prepare Cursor skills directory ${skillsHome}: ${err instanceof Error ? err.message : String(err)}\n`);
84
+ return;
85
+ }
86
+ let entries;
87
+ try {
88
+ entries = await fs.readdir(skillsDir, { withFileTypes: true });
89
+ }
90
+ catch (err) {
91
+ await onLog("stderr", `[paperclip] Failed to read Paperclip skills from ${skillsDir}: ${err instanceof Error ? err.message : String(err)}\n`);
92
+ return;
93
+ }
94
+ const linkSkill = options.linkSkill ?? ((source, target) => fs.symlink(source, target));
95
+ for (const entry of entries) {
96
+ if (!entry.isDirectory())
97
+ continue;
98
+ const source = path.join(skillsDir, entry.name);
99
+ const target = path.join(skillsHome, entry.name);
100
+ const existing = await fs.lstat(target).catch(() => null);
101
+ if (existing)
102
+ continue;
103
+ try {
104
+ await linkSkill(source, target);
105
+ await onLog("stderr", `[paperclip] Injected Cursor skill "${entry.name}" into ${skillsHome}\n`);
106
+ }
107
+ catch (err) {
108
+ await onLog("stderr", `[paperclip] Failed to inject Cursor skill "${entry.name}" into ${skillsHome}: ${err instanceof Error ? err.message : String(err)}\n`);
109
+ }
110
+ }
111
+ }
112
+ export async function execute(ctx) {
113
+ const { runId, agent, runtime, config, context, onLog, onMeta, authToken } = ctx;
114
+ const promptTemplate = asString(config.promptTemplate, "You are agent {{agent.id}} ({{agent.name}}). Continue your Paperclip work.");
115
+ const command = asString(config.command, "agent");
116
+ const model = asString(config.model, DEFAULT_CURSOR_LOCAL_MODEL).trim();
117
+ const mode = normalizeMode(asString(config.mode, ""));
118
+ const workspaceContext = parseObject(context.paperclipWorkspace);
119
+ const workspaceCwd = asString(workspaceContext.cwd, "");
120
+ const workspaceSource = asString(workspaceContext.source, "");
121
+ const workspaceId = asString(workspaceContext.workspaceId, "");
122
+ const workspaceRepoUrl = asString(workspaceContext.repoUrl, "");
123
+ const workspaceRepoRef = asString(workspaceContext.repoRef, "");
124
+ const workspaceHints = Array.isArray(context.paperclipWorkspaces)
125
+ ? context.paperclipWorkspaces.filter((value) => typeof value === "object" && value !== null)
126
+ : [];
127
+ const configuredCwd = asString(config.cwd, "");
128
+ const useConfiguredInsteadOfAgentHome = workspaceSource === "agent_home" && configuredCwd.length > 0;
129
+ const effectiveWorkspaceCwd = useConfiguredInsteadOfAgentHome ? "" : workspaceCwd;
130
+ const cwd = effectiveWorkspaceCwd || configuredCwd || process.cwd();
131
+ await ensureAbsoluteDirectory(cwd, { createIfMissing: true });
132
+ await ensureCursorSkillsInjected(onLog);
133
+ const envConfig = parseObject(config.env);
134
+ const hasExplicitApiKey = typeof envConfig.PAPERCLIP_API_KEY === "string" && envConfig.PAPERCLIP_API_KEY.trim().length > 0;
135
+ const env = { ...buildPaperclipEnv(agent) };
136
+ env.PAPERCLIP_RUN_ID = runId;
137
+ const wakeTaskId = (typeof context.taskId === "string" && context.taskId.trim().length > 0 && context.taskId.trim()) ||
138
+ (typeof context.issueId === "string" && context.issueId.trim().length > 0 && context.issueId.trim()) ||
139
+ null;
140
+ const wakeReason = typeof context.wakeReason === "string" && context.wakeReason.trim().length > 0
141
+ ? context.wakeReason.trim()
142
+ : null;
143
+ const wakeCommentId = (typeof context.wakeCommentId === "string" && context.wakeCommentId.trim().length > 0 && context.wakeCommentId.trim()) ||
144
+ (typeof context.commentId === "string" && context.commentId.trim().length > 0 && context.commentId.trim()) ||
145
+ null;
146
+ const approvalId = typeof context.approvalId === "string" && context.approvalId.trim().length > 0
147
+ ? context.approvalId.trim()
148
+ : null;
149
+ const approvalStatus = typeof context.approvalStatus === "string" && context.approvalStatus.trim().length > 0
150
+ ? context.approvalStatus.trim()
151
+ : null;
152
+ const linkedIssueIds = Array.isArray(context.issueIds)
153
+ ? context.issueIds.filter((value) => typeof value === "string" && value.trim().length > 0)
154
+ : [];
155
+ if (wakeTaskId) {
156
+ env.PAPERCLIP_TASK_ID = wakeTaskId;
157
+ }
158
+ if (wakeReason) {
159
+ env.PAPERCLIP_WAKE_REASON = wakeReason;
160
+ }
161
+ if (wakeCommentId) {
162
+ env.PAPERCLIP_WAKE_COMMENT_ID = wakeCommentId;
163
+ }
164
+ if (approvalId) {
165
+ env.PAPERCLIP_APPROVAL_ID = approvalId;
166
+ }
167
+ if (approvalStatus) {
168
+ env.PAPERCLIP_APPROVAL_STATUS = approvalStatus;
169
+ }
170
+ if (linkedIssueIds.length > 0) {
171
+ env.PAPERCLIP_LINKED_ISSUE_IDS = linkedIssueIds.join(",");
172
+ }
173
+ if (effectiveWorkspaceCwd) {
174
+ env.PAPERCLIP_WORKSPACE_CWD = effectiveWorkspaceCwd;
175
+ }
176
+ if (workspaceSource) {
177
+ env.PAPERCLIP_WORKSPACE_SOURCE = workspaceSource;
178
+ }
179
+ if (workspaceId) {
180
+ env.PAPERCLIP_WORKSPACE_ID = workspaceId;
181
+ }
182
+ if (workspaceRepoUrl) {
183
+ env.PAPERCLIP_WORKSPACE_REPO_URL = workspaceRepoUrl;
184
+ }
185
+ if (workspaceRepoRef) {
186
+ env.PAPERCLIP_WORKSPACE_REPO_REF = workspaceRepoRef;
187
+ }
188
+ if (workspaceHints.length > 0) {
189
+ env.PAPERCLIP_WORKSPACES_JSON = JSON.stringify(workspaceHints);
190
+ }
191
+ for (const [k, v] of Object.entries(envConfig)) {
192
+ if (typeof v === "string")
193
+ env[k] = v;
194
+ }
195
+ if (!hasExplicitApiKey && authToken) {
196
+ env.PAPERCLIP_API_KEY = authToken;
197
+ }
198
+ const billingType = resolveCursorBillingType(env);
199
+ const runtimeEnv = ensurePathInEnv({ ...process.env, ...env });
200
+ await ensureCommandResolvable(command, cwd, runtimeEnv);
201
+ const timeoutSec = asNumber(config.timeoutSec, 0);
202
+ const graceSec = asNumber(config.graceSec, 20);
203
+ const extraArgs = (() => {
204
+ const fromExtraArgs = asStringArray(config.extraArgs);
205
+ if (fromExtraArgs.length > 0)
206
+ return fromExtraArgs;
207
+ return asStringArray(config.args);
208
+ })();
209
+ const autoTrustEnabled = !hasCursorTrustBypassArg(extraArgs);
210
+ const runtimeSessionParams = parseObject(runtime.sessionParams);
211
+ const runtimeSessionId = asString(runtimeSessionParams.sessionId, runtime.sessionId ?? "");
212
+ const runtimeSessionCwd = asString(runtimeSessionParams.cwd, "");
213
+ const canResumeSession = runtimeSessionId.length > 0 &&
214
+ (runtimeSessionCwd.length === 0 || path.resolve(runtimeSessionCwd) === path.resolve(cwd));
215
+ const sessionId = canResumeSession ? runtimeSessionId : null;
216
+ if (runtimeSessionId && !canResumeSession) {
217
+ await onLog("stderr", `[paperclip] Cursor session "${runtimeSessionId}" was saved for cwd "${runtimeSessionCwd}" and will not be resumed in "${cwd}".\n`);
218
+ }
219
+ const instructionsFilePath = asString(config.instructionsFilePath, "").trim();
220
+ const instructionsDir = instructionsFilePath ? `${path.dirname(instructionsFilePath)}/` : "";
221
+ let instructionsPrefix = "";
222
+ if (instructionsFilePath) {
223
+ try {
224
+ const instructionsContents = await fs.readFile(instructionsFilePath, "utf8");
225
+ instructionsPrefix =
226
+ `${instructionsContents}\n\n` +
227
+ `The above agent instructions were loaded from ${instructionsFilePath}. ` +
228
+ `Resolve any relative file references from ${instructionsDir}.\n\n`;
229
+ await onLog("stderr", `[paperclip] Loaded agent instructions file: ${instructionsFilePath}\n`);
230
+ }
231
+ catch (err) {
232
+ const reason = err instanceof Error ? err.message : String(err);
233
+ await onLog("stderr", `[paperclip] Warning: could not read agent instructions file "${instructionsFilePath}": ${reason}\n`);
234
+ }
235
+ }
236
+ const commandNotes = (() => {
237
+ const notes = [];
238
+ if (autoTrustEnabled) {
239
+ notes.push("Auto-added --yolo to bypass interactive prompts.");
240
+ }
241
+ notes.push("Prompt is piped to Cursor via stdin.");
242
+ if (!instructionsFilePath)
243
+ return notes;
244
+ if (instructionsPrefix.length > 0) {
245
+ notes.push(`Loaded agent instructions from ${instructionsFilePath}`, `Prepended instructions + path directive to prompt (relative references from ${instructionsDir}).`);
246
+ return notes;
247
+ }
248
+ notes.push(`Configured instructionsFilePath ${instructionsFilePath}, but file could not be read; continuing without injected instructions.`);
249
+ return notes;
250
+ })();
251
+ const renderedPrompt = renderTemplate(promptTemplate, {
252
+ agentId: agent.id,
253
+ companyId: agent.companyId,
254
+ runId,
255
+ company: { id: agent.companyId },
256
+ agent,
257
+ run: { id: runId, source: "on_demand" },
258
+ context,
259
+ });
260
+ const paperclipEnvNote = renderPaperclipEnvNote(env);
261
+ const prompt = `${instructionsPrefix}${paperclipEnvNote}${renderedPrompt}`;
262
+ const buildArgs = (resumeSessionId) => {
263
+ const args = ["-p", "--output-format", "stream-json", "--workspace", cwd];
264
+ if (resumeSessionId)
265
+ args.push("--resume", resumeSessionId);
266
+ if (model)
267
+ args.push("--model", model);
268
+ if (mode)
269
+ args.push("--mode", mode);
270
+ if (autoTrustEnabled)
271
+ args.push("--yolo");
272
+ if (extraArgs.length > 0)
273
+ args.push(...extraArgs);
274
+ return args;
275
+ };
276
+ const runAttempt = async (resumeSessionId) => {
277
+ const args = buildArgs(resumeSessionId);
278
+ if (onMeta) {
279
+ await onMeta({
280
+ adapterType: "cursor",
281
+ command,
282
+ cwd,
283
+ commandNotes,
284
+ commandArgs: args,
285
+ env: redactEnvForLogs(env),
286
+ prompt,
287
+ context,
288
+ });
289
+ }
290
+ let stdoutLineBuffer = "";
291
+ const emitNormalizedStdoutLine = async (rawLine) => {
292
+ const normalized = normalizeCursorStreamLine(rawLine);
293
+ if (!normalized.line)
294
+ return;
295
+ await onLog(normalized.stream ?? "stdout", `${normalized.line}\n`);
296
+ };
297
+ const flushStdoutChunk = async (chunk, finalize = false) => {
298
+ const combined = `${stdoutLineBuffer}${chunk}`;
299
+ const lines = combined.split(/\r?\n/);
300
+ stdoutLineBuffer = lines.pop() ?? "";
301
+ for (const line of lines) {
302
+ await emitNormalizedStdoutLine(line);
303
+ }
304
+ if (finalize) {
305
+ const trailing = stdoutLineBuffer.trim();
306
+ stdoutLineBuffer = "";
307
+ if (trailing) {
308
+ await emitNormalizedStdoutLine(trailing);
309
+ }
310
+ }
311
+ };
312
+ const proc = await runChildProcess(runId, command, args, {
313
+ cwd,
314
+ env,
315
+ timeoutSec,
316
+ graceSec,
317
+ stdin: prompt,
318
+ onLog: async (stream, chunk) => {
319
+ if (stream !== "stdout") {
320
+ await onLog(stream, chunk);
321
+ return;
322
+ }
323
+ await flushStdoutChunk(chunk);
324
+ },
325
+ });
326
+ await flushStdoutChunk("", true);
327
+ return {
328
+ proc,
329
+ parsed: parseCursorJsonl(proc.stdout),
330
+ };
331
+ };
332
+ const providerFromModel = resolveProviderFromModel(model);
333
+ const toResult = (attempt, clearSessionOnMissingSession = false) => {
334
+ if (attempt.proc.timedOut) {
335
+ return {
336
+ exitCode: attempt.proc.exitCode,
337
+ signal: attempt.proc.signal,
338
+ timedOut: true,
339
+ errorMessage: `Timed out after ${timeoutSec}s`,
340
+ clearSession: clearSessionOnMissingSession,
341
+ };
342
+ }
343
+ const resolvedSessionId = attempt.parsed.sessionId ?? runtimeSessionId ?? runtime.sessionId ?? null;
344
+ const resolvedSessionParams = resolvedSessionId
345
+ ? {
346
+ sessionId: resolvedSessionId,
347
+ cwd,
348
+ ...(workspaceId ? { workspaceId } : {}),
349
+ ...(workspaceRepoUrl ? { repoUrl: workspaceRepoUrl } : {}),
350
+ ...(workspaceRepoRef ? { repoRef: workspaceRepoRef } : {}),
351
+ }
352
+ : null;
353
+ const parsedError = typeof attempt.parsed.errorMessage === "string" ? attempt.parsed.errorMessage.trim() : "";
354
+ const stderrLine = firstNonEmptyLine(attempt.proc.stderr);
355
+ const fallbackErrorMessage = parsedError ||
356
+ stderrLine ||
357
+ `Cursor exited with code ${attempt.proc.exitCode ?? -1}`;
358
+ return {
359
+ exitCode: attempt.proc.exitCode,
360
+ signal: attempt.proc.signal,
361
+ timedOut: false,
362
+ errorMessage: (attempt.proc.exitCode ?? 0) === 0
363
+ ? null
364
+ : fallbackErrorMessage,
365
+ usage: attempt.parsed.usage,
366
+ sessionId: resolvedSessionId,
367
+ sessionParams: resolvedSessionParams,
368
+ sessionDisplayId: resolvedSessionId,
369
+ provider: providerFromModel,
370
+ model,
371
+ billingType,
372
+ costUsd: attempt.parsed.costUsd,
373
+ resultJson: {
374
+ stdout: attempt.proc.stdout,
375
+ stderr: attempt.proc.stderr,
376
+ },
377
+ summary: attempt.parsed.summary,
378
+ clearSession: Boolean(clearSessionOnMissingSession && !resolvedSessionId),
379
+ };
380
+ };
381
+ const initial = await runAttempt(sessionId);
382
+ if (sessionId &&
383
+ !initial.proc.timedOut &&
384
+ (initial.proc.exitCode ?? 0) !== 0 &&
385
+ isCursorUnknownSessionError(initial.proc.stdout, initial.proc.stderr)) {
386
+ await onLog("stderr", `[paperclip] Cursor resume session "${sessionId}" is unavailable; retrying with a fresh session.\n`);
387
+ const retry = await runAttempt(null);
388
+ return toResult(retry, true);
389
+ }
390
+ return toResult(initial);
391
+ }
392
+ //# sourceMappingURL=execute.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute.js","sourceRoot":"","sources":["../../src/server/execute.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=execute.skills.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute.skills.test.d.ts","sourceRoot":"","sources":["../../src/server/execute.skills.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,79 @@
1
+ import fs from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { afterEach, describe, expect, it } from "vitest";
5
+ import { ensureCursorSkillsInjected } from "./execute.js";
6
+ async function makeTempDir(prefix) {
7
+ return fs.mkdtemp(path.join(os.tmpdir(), prefix));
8
+ }
9
+ async function createSkillDir(root, name) {
10
+ await fs.mkdir(path.join(root, name), { recursive: true });
11
+ }
12
+ describe("cursor skill injection", () => {
13
+ const cleanupDirs = new Set();
14
+ afterEach(async () => {
15
+ await Promise.all(Array.from(cleanupDirs).map((dir) => fs.rm(dir, { recursive: true, force: true })));
16
+ cleanupDirs.clear();
17
+ });
18
+ it("links missing Paperclip skills into Cursor skills home", async () => {
19
+ const skillsDir = await makeTempDir("paperclip-cursor-skills-src-");
20
+ const skillsHome = await makeTempDir("paperclip-cursor-skills-home-");
21
+ cleanupDirs.add(skillsDir);
22
+ cleanupDirs.add(skillsHome);
23
+ await createSkillDir(skillsDir, "paperclip");
24
+ await createSkillDir(skillsDir, "paperclip-create-agent");
25
+ await fs.writeFile(path.join(skillsDir, "README.txt"), "ignore", "utf8");
26
+ const logs = [];
27
+ await ensureCursorSkillsInjected(async (_stream, chunk) => {
28
+ logs.push(chunk);
29
+ }, { skillsDir, skillsHome });
30
+ const injectedA = path.join(skillsHome, "paperclip");
31
+ const injectedB = path.join(skillsHome, "paperclip-create-agent");
32
+ expect((await fs.lstat(injectedA)).isSymbolicLink()).toBe(true);
33
+ expect((await fs.lstat(injectedB)).isSymbolicLink()).toBe(true);
34
+ expect(await fs.realpath(injectedA)).toBe(path.join(skillsDir, "paperclip"));
35
+ expect(await fs.realpath(injectedB)).toBe(path.join(skillsDir, "paperclip-create-agent"));
36
+ expect(logs.some((line) => line.includes('Injected Cursor skill "paperclip"'))).toBe(true);
37
+ expect(logs.some((line) => line.includes('Injected Cursor skill "paperclip-create-agent"'))).toBe(true);
38
+ });
39
+ it("preserves existing targets and only links missing skills", async () => {
40
+ const skillsDir = await makeTempDir("paperclip-cursor-preserve-src-");
41
+ const skillsHome = await makeTempDir("paperclip-cursor-preserve-home-");
42
+ cleanupDirs.add(skillsDir);
43
+ cleanupDirs.add(skillsHome);
44
+ await createSkillDir(skillsDir, "paperclip");
45
+ await createSkillDir(skillsDir, "paperclip-create-agent");
46
+ const existingTarget = path.join(skillsHome, "paperclip");
47
+ await fs.mkdir(existingTarget, { recursive: true });
48
+ await fs.writeFile(path.join(existingTarget, "keep.txt"), "keep", "utf8");
49
+ await ensureCursorSkillsInjected(async () => { }, { skillsDir, skillsHome });
50
+ expect((await fs.lstat(existingTarget)).isDirectory()).toBe(true);
51
+ expect(await fs.readFile(path.join(existingTarget, "keep.txt"), "utf8")).toBe("keep");
52
+ expect((await fs.lstat(path.join(skillsHome, "paperclip-create-agent"))).isSymbolicLink()).toBe(true);
53
+ });
54
+ it("logs per-skill link failures and continues without throwing", async () => {
55
+ const skillsDir = await makeTempDir("paperclip-cursor-fail-src-");
56
+ const skillsHome = await makeTempDir("paperclip-cursor-fail-home-");
57
+ cleanupDirs.add(skillsDir);
58
+ cleanupDirs.add(skillsHome);
59
+ await createSkillDir(skillsDir, "ok-skill");
60
+ await createSkillDir(skillsDir, "fail-skill");
61
+ const logs = [];
62
+ await ensureCursorSkillsInjected(async (_stream, chunk) => {
63
+ logs.push(chunk);
64
+ }, {
65
+ skillsDir,
66
+ skillsHome,
67
+ linkSkill: async (source, target) => {
68
+ if (target.endsWith(`${path.sep}fail-skill`)) {
69
+ throw new Error("simulated link failure");
70
+ }
71
+ await fs.symlink(source, target);
72
+ },
73
+ });
74
+ expect((await fs.lstat(path.join(skillsHome, "ok-skill"))).isSymbolicLink()).toBe(true);
75
+ await expect(fs.lstat(path.join(skillsHome, "fail-skill"))).rejects.toThrow();
76
+ expect(logs.some((line) => line.includes('Failed to inject Cursor skill "fail-skill"'))).toBe(true);
77
+ });
78
+ });
79
+ //# sourceMappingURL=execute.skills.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute.skills.test.js","sourceRoot":"","sources":["../../src/server/execute.skills.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export { execute, ensureCursorSkillsInjected } from "./execute.js";
2
+ export { testEnvironment } from "./test.js";
3
+ export { parseCursorJsonl, isCursorUnknownSessionError } from "./parse.js";
4
+ import type { AdapterSessionCodec } from "@paperclipai/adapter-utils";
5
+ export declare const sessionCodec: AdapterSessionCodec;
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAMtE,eAAO,MAAM,YAAY,EAAE,mBAsD1B,CAAC"}
@@ -0,0 +1,61 @@
1
+ export { execute, ensureCursorSkillsInjected } from "./execute.js";
2
+ export { testEnvironment } from "./test.js";
3
+ export { parseCursorJsonl, isCursorUnknownSessionError } from "./parse.js";
4
+ function readNonEmptyString(value) {
5
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
6
+ }
7
+ export const sessionCodec = {
8
+ deserialize(raw) {
9
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw))
10
+ return null;
11
+ const record = raw;
12
+ const sessionId = readNonEmptyString(record.sessionId) ??
13
+ readNonEmptyString(record.session_id) ??
14
+ readNonEmptyString(record.sessionID);
15
+ if (!sessionId)
16
+ return null;
17
+ const cwd = readNonEmptyString(record.cwd) ??
18
+ readNonEmptyString(record.workdir) ??
19
+ readNonEmptyString(record.folder);
20
+ const workspaceId = readNonEmptyString(record.workspaceId) ?? readNonEmptyString(record.workspace_id);
21
+ const repoUrl = readNonEmptyString(record.repoUrl) ?? readNonEmptyString(record.repo_url);
22
+ const repoRef = readNonEmptyString(record.repoRef) ?? readNonEmptyString(record.repo_ref);
23
+ return {
24
+ sessionId,
25
+ ...(cwd ? { cwd } : {}),
26
+ ...(workspaceId ? { workspaceId } : {}),
27
+ ...(repoUrl ? { repoUrl } : {}),
28
+ ...(repoRef ? { repoRef } : {}),
29
+ };
30
+ },
31
+ serialize(params) {
32
+ if (!params)
33
+ return null;
34
+ const sessionId = readNonEmptyString(params.sessionId) ??
35
+ readNonEmptyString(params.session_id) ??
36
+ readNonEmptyString(params.sessionID);
37
+ if (!sessionId)
38
+ return null;
39
+ const cwd = readNonEmptyString(params.cwd) ??
40
+ readNonEmptyString(params.workdir) ??
41
+ readNonEmptyString(params.folder);
42
+ const workspaceId = readNonEmptyString(params.workspaceId) ?? readNonEmptyString(params.workspace_id);
43
+ const repoUrl = readNonEmptyString(params.repoUrl) ?? readNonEmptyString(params.repo_url);
44
+ const repoRef = readNonEmptyString(params.repoRef) ?? readNonEmptyString(params.repo_ref);
45
+ return {
46
+ sessionId,
47
+ ...(cwd ? { cwd } : {}),
48
+ ...(workspaceId ? { workspaceId } : {}),
49
+ ...(repoUrl ? { repoUrl } : {}),
50
+ ...(repoRef ? { repoRef } : {}),
51
+ };
52
+ },
53
+ getDisplayId(params) {
54
+ if (!params)
55
+ return null;
56
+ return (readNonEmptyString(params.sessionId) ??
57
+ readNonEmptyString(params.session_id) ??
58
+ readNonEmptyString(params.sessionID));
59
+ },
60
+ };
61
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export declare function parseCursorJsonl(stdout: string): {
2
+ sessionId: string | null;
3
+ summary: string;
4
+ usage: {
5
+ inputTokens: number;
6
+ cachedInputTokens: number;
7
+ outputTokens: number;
8
+ };
9
+ costUsd: number | null;
10
+ errorMessage: string | null;
11
+ };
12
+ export declare function isCursorUnknownSessionError(stdout: string, stderr: string): boolean;
13
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/server/parse.ts"],"names":[],"mappings":"AAmDA,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;EAkG9C;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAUnF"}