@cursor/july 0.1.73 → 0.1.75
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.
- package/AGENTS.md +13 -8
- package/dist/bin/agent-serve.js +7 -5
- package/dist/channels/checks.d.ts +111 -0
- package/dist/channels/checks.d.ts.map +1 -0
- package/dist/channels/checks.js +86 -0
- package/dist/channels/deployments/deployments-channel.d.ts +44 -0
- package/dist/channels/deployments/deployments-channel.d.ts.map +1 -0
- package/dist/channels/deployments/deployments-channel.js +92 -0
- package/dist/channels/deployments/index.d.ts +26 -0
- package/dist/channels/deployments/index.d.ts.map +1 -0
- package/dist/channels/deployments/index.js +25 -0
- package/dist/channels/deployments/types.d.ts +69 -0
- package/dist/channels/deployments/types.d.ts.map +1 -0
- package/dist/channels/deployments/types.js +6 -0
- package/dist/channels/github/checks.d.ts +13 -48
- package/dist/channels/github/checks.d.ts.map +1 -1
- package/dist/channels/github/checks.js +56 -64
- package/dist/channels/origin/api.d.ts +100 -0
- package/dist/channels/origin/api.d.ts.map +1 -0
- package/dist/channels/origin/api.js +225 -0
- package/dist/channels/origin/binding.d.ts +44 -0
- package/dist/channels/origin/binding.d.ts.map +1 -0
- package/dist/channels/origin/binding.js +45 -0
- package/dist/channels/origin/checks.d.ts +107 -0
- package/dist/channels/origin/checks.d.ts.map +1 -0
- package/dist/channels/origin/checks.js +145 -0
- package/dist/channels/origin/index.d.ts +3 -0
- package/dist/channels/origin/index.d.ts.map +1 -1
- package/dist/channels/origin/index.js +3 -0
- package/dist/channels/origin/origin-channel.d.ts +4 -4
- package/dist/channels/origin/origin-channel.d.ts.map +1 -1
- package/dist/channels/origin/origin-channel.js +12 -2
- package/dist/channels/origin/types.d.ts +36 -0
- package/dist/channels/origin/types.d.ts.map +1 -1
- package/dist/channels.d.ts +1 -0
- package/dist/channels.d.ts.map +1 -1
- package/dist/channels.js +1 -0
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +3 -3
- package/dist/docs/assets/{app.CdbcFD8T.js → app.b8bhB2SV.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.DGZeXVqn.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.D_NKImM7.js → VPLocalSearchBox.lLSeIyWw.js} +1 -1
- package/dist/docs/assets/chunks/{theme.CMvz7cu9.js → theme.C_owesa-.js} +2 -2
- package/dist/docs/assets/{reference_channels.md.MN8iDy8V.js → reference_channels.md.G5GysZ7e.js} +2 -2
- package/dist/docs/assets/{reference_channels.md.MN8iDy8V.lean.js → reference_channels.md.G5GysZ7e.lean.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.Cl14Jfo3.js → reference_cli.md.TAaYU8br.js} +3 -3
- package/dist/docs/assets/{reference_cli.md.Cl14Jfo3.lean.js → reference_cli.md.TAaYU8br.lean.js} +1 -1
- package/dist/docs/assets/scaffolding-agents.md.CiGsJ1aw.js +1 -0
- package/dist/docs/assets/{scaffolding-agents.md.CrWSA0Ko.lean.js → scaffolding-agents.md.CiGsJ1aw.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +3 -3
- package/dist/docs/concepts.html +3 -3
- package/dist/docs/deployment.html +3 -3
- package/dist/docs/evals.html +3 -3
- package/dist/docs/example-agents/approval-buddy.html +3 -3
- package/dist/docs/example-agents/benny.html +3 -3
- package/dist/docs/example-agents/bugbot.html +3 -3
- package/dist/docs/example-agents/codebase-wiki.html +3 -3
- package/dist/docs/example-agents/codeowners-review.html +3 -3
- package/dist/docs/example-agents/concierge.html +3 -3
- package/dist/docs/example-agents/fsd.html +3 -3
- package/dist/docs/example-agents/index.html +3 -3
- package/dist/docs/example-agents/knowledge-base.html +3 -3
- package/dist/docs/example-agents/oncall.html +3 -3
- package/dist/docs/example-agents/security-reviewer.html +3 -3
- package/dist/docs/example-agents/slack-agent.html +3 -3
- package/dist/docs/example-agents/weather-agent.html +3 -3
- package/dist/docs/guides/agent-to-agent.html +3 -3
- package/dist/docs/guides/cloud-runtime.html +3 -3
- package/dist/docs/guides/convert-automation.html +3 -3
- package/dist/docs/guides/github.html +3 -3
- package/dist/docs/guides/human-in-the-loop.html +3 -3
- package/dist/docs/guides/mcp-oauth.html +3 -3
- package/dist/docs/guides/opentelemetry.html +3 -3
- package/dist/docs/guides/slack.html +3 -3
- package/dist/docs/guides/webhooks.html +3 -3
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +3 -3
- package/dist/docs/index.html +3 -3
- package/dist/docs/quickstart.html +3 -3
- package/dist/docs/reference/agent-config.html +3 -3
- package/dist/docs/reference/artifacts.html +3 -3
- package/dist/docs/reference/channels.html +5 -5
- package/dist/docs/reference/cli.html +6 -6
- package/dist/docs/reference/connections.html +3 -3
- package/dist/docs/reference/hooks.html +3 -3
- package/dist/docs/reference/http-api.html +3 -3
- package/dist/docs/reference/instructions.html +3 -3
- package/dist/docs/reference/playground.html +3 -3
- package/dist/docs/reference/project-layout.html +3 -3
- package/dist/docs/reference/prompt.html +3 -3
- package/dist/docs/reference/schedules.html +3 -3
- package/dist/docs/reference/sessions.html +3 -3
- package/dist/docs/reference/skills.html +3 -3
- package/dist/docs/reference/subagents.html +3 -3
- package/dist/docs/reference/tools.html +3 -3
- package/dist/docs/scaffolding-agents.html +5 -5
- package/dist/docs/storage.html +3 -3
- package/dist/docs/templates/agentic-owners.html +3 -3
- package/dist/docs/templates/demo.html +3 -3
- package/dist/docs/templates/pr-autofixer.html +3 -3
- package/dist/docs/templates/security-reviewer.html +3 -3
- package/dist/docs/templates/triage.html +3 -3
- package/dist/docs/troubleshooting.html +3 -3
- package/dist/internal/cli-skills.d.ts +4 -2
- package/dist/internal/cli-skills.d.ts.map +1 -1
- package/dist/internal/cli-skills.js +8 -3
- package/dist/internal/cursor-deployment-relay.d.ts +77 -0
- package/dist/internal/cursor-deployment-relay.d.ts.map +1 -0
- package/dist/internal/cursor-deployment-relay.js +201 -0
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +1 -0
- package/dist/internal/install-cursor-skills.d.ts +71 -16
- package/dist/internal/install-cursor-skills.d.ts.map +1 -1
- package/dist/internal/install-cursor-skills.js +160 -48
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +6 -2
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +114 -5
- package/dist/playground/assets/index-BJy9UJrF.js +85 -0
- package/dist/playground/assets/index-BrSd5vff.css +1 -0
- package/dist/playground/index.html +2 -2
- package/docs/reference/channels.md +15 -0
- package/docs/reference/cli.md +16 -8
- package/docs/scaffolding-agents.md +14 -6
- package/package.json +9 -1
- package/scripts/install-cursor-skills.mjs +36 -0
- package/skills/ab/SKILL.md +1 -1
- package/skills/create-agent/SKILL.md +1 -1
- package/skills/debug/SKILL.md +1 -1
- package/skills/evals/SKILL.md +1 -1
- package/skills/framework-map/SKILL.md +1 -1
- package/skills/github/SKILL.md +1 -1
- package/skills/hillclimb/SKILL.md +1 -1
- package/skills/mcp-auth/SKILL.md +1 -1
- package/skills/otel/SKILL.md +1 -1
- package/skills/setup-slack/SKILL.md +1 -1
- package/src/bin/agent-serve.ts +7 -5
- package/src/channels/checks.ts +185 -0
- package/src/channels/deployments/deployments-channel.ts +109 -0
- package/src/channels/deployments/index.ts +26 -0
- package/src/channels/deployments/types.ts +80 -0
- package/src/channels/github/checks.ts +90 -115
- package/src/channels/origin/api.ts +318 -0
- package/src/channels/origin/binding.ts +96 -0
- package/src/channels/origin/checks.ts +250 -0
- package/src/channels/origin/index.ts +3 -0
- package/src/channels/origin/origin-channel.ts +18 -6
- package/src/channels/origin/types.ts +37 -0
- package/src/channels.ts +16 -0
- package/src/internal/cli-skills.ts +10 -2
- package/src/internal/cursor-deployment-relay.ts +274 -0
- package/src/internal/distribution.ts +1 -0
- package/src/internal/install-cursor-skills.ts +204 -49
- package/src/internal/sdk-runner.ts +6 -3
- package/src/internal/server.ts +149 -0
- package/dist/docs/assets/chunks/@localSearchIndexroot.DQad--_z.js +0 -1
- package/dist/docs/assets/scaffolding-agents.md.CrWSA0Ko.js +0 -1
- package/dist/playground/assets/index-77uhu5Kr.css +0 -1
- package/dist/playground/assets/index-D4buox4m.js +0 -85
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Offer to install the package's coding-agent skills into the user's
|
|
3
|
-
* personal Cursor skills dir under `~/.cursor/skills/
|
|
3
|
+
* personal Cursor skills dir under `~/.cursor/skills/agentsdk/<skill>/`.
|
|
4
4
|
*
|
|
5
|
-
* Cursor walks `~/.cursor/skills` recursively, so the `
|
|
5
|
+
* Cursor walks `~/.cursor/skills` recursively, so the `agentsdk/` folder is
|
|
6
6
|
* only organizational — identity comes from the leaf folder that holds
|
|
7
|
-
* SKILL.md.
|
|
7
|
+
* SKILL.md. Installed copies get `alwaysApply: true` so Cursor injects the
|
|
8
|
+
* skill body as a global rule instead of leaving it as an on-demand catalog
|
|
9
|
+
* entry. Skipped for `--json` / non-TTY hosts.
|
|
10
|
+
*
|
|
11
|
+
* Consumer installs (`npm install` / `npx` of `@cursor/july`) also copy
|
|
12
|
+
* these skills from a postinstall hook. That path never prompts and never
|
|
13
|
+
* fails the package install. The monorepo source checkout is not a consumer
|
|
14
|
+
* install, so `pnpm install` in everysphere does not overwrite `~/.cursor`.
|
|
8
15
|
*/
|
|
9
16
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
10
17
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
@@ -19,40 +26,67 @@ import { access, chmod, cp, mkdir, readdir, readFile, rm, stat, writeFile, } fro
|
|
|
19
26
|
import { homedir } from "node:os";
|
|
20
27
|
import { join } from "node:path";
|
|
21
28
|
import { CLI_COMMAND_NAME, packageRootDir } from "./distribution.js";
|
|
29
|
+
import { parseFrontmatter } from "./frontmatter.js";
|
|
22
30
|
import { stdoutPalette } from "./terminal-style.js";
|
|
23
31
|
/** Monorepo-only skill; excluded from the published package. */
|
|
24
32
|
const SKIP_SKILL_DIRS = new Set(["operate"]);
|
|
25
33
|
/** Category folder under ~/.cursor/skills (Cursor discovers nested skills). */
|
|
26
|
-
export const CURSOR_SKILLS_NAMESPACE = "
|
|
34
|
+
export const CURSOR_SKILLS_NAMESPACE = "agentsdk";
|
|
35
|
+
/** Pre-rename install folder. Install deletes this so `/agentkit-*` rows disappear. */
|
|
36
|
+
export const LEGACY_CURSOR_SKILLS_NAMESPACE = "agentkit";
|
|
27
37
|
/** How long the `init` offer waits for an answer before skipping the install. */
|
|
28
38
|
export const SKILL_PROMPT_TIMEOUT_MS = 45000;
|
|
39
|
+
/**
|
|
40
|
+
* Override the resolved `~/.cursor/skills` directory (not the user home).
|
|
41
|
+
* Used by the postinstall hook in tests and publish smoke.
|
|
42
|
+
*/
|
|
43
|
+
export const CURSOR_JULY_SKILLS_HOME_ENV = "CURSOR_JULY_SKILLS_HOME";
|
|
44
|
+
/** Set to `1` to skip the postinstall skill copy. */
|
|
45
|
+
export const CURSOR_JULY_SKIP_SKILL_INSTALL_ENV = "CURSOR_JULY_SKIP_SKILL_INSTALL";
|
|
29
46
|
export function cursorSkillsHome(home) {
|
|
30
47
|
var _a;
|
|
31
|
-
if (home
|
|
32
|
-
|
|
33
|
-
|
|
48
|
+
if (home !== undefined) {
|
|
49
|
+
return join(home.trim() === "" ? homedir() : home, ".cursor", "skills");
|
|
50
|
+
}
|
|
51
|
+
const override = (_a = process.env[CURSOR_JULY_SKILLS_HOME_ENV]) === null || _a === void 0 ? void 0 : _a.trim();
|
|
52
|
+
if (override !== undefined && override !== "") {
|
|
53
|
+
return override;
|
|
54
|
+
}
|
|
55
|
+
return join(homedir(), ".cursor", "skills");
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* True when this package root is an installed copy under `node_modules`
|
|
59
|
+
* (npm, pnpm, yarn, npx, global), not the everysphere source checkout.
|
|
60
|
+
*/
|
|
61
|
+
export function isConsumerPackageInstall(packageRoot) {
|
|
62
|
+
// Segment check only — split on both separators so a Windows path still
|
|
63
|
+
// matches when this runs (or is tested) on POSIX. Do not rewrite the path.
|
|
64
|
+
return packageRoot.split(/[\\/]/).includes("node_modules");
|
|
34
65
|
}
|
|
35
|
-
/** `~/.cursor/skills/
|
|
36
|
-
export function
|
|
66
|
+
/** `~/.cursor/skills/agentsdk` — where package skills are installed. */
|
|
67
|
+
export function agentsdkCursorSkillsDir(skillsHome = cursorSkillsHome()) {
|
|
37
68
|
return join(skillsHome, CURSOR_SKILLS_NAMESPACE);
|
|
38
69
|
}
|
|
39
|
-
/**
|
|
70
|
+
/** Pre-rename `~/.cursor/skills/agentkit`. */
|
|
71
|
+
export function legacyAgentkitCursorSkillsDir(skillsHome = cursorSkillsHome()) {
|
|
72
|
+
return join(skillsHome, LEGACY_CURSOR_SKILLS_NAMESPACE);
|
|
73
|
+
}
|
|
74
|
+
/** Absolute install path for one skill: `…/agentsdk/<leafDir>`. */
|
|
40
75
|
export function skillInstallPath(skill, skillsHome = cursorSkillsHome()) {
|
|
41
|
-
return join(
|
|
76
|
+
return join(agentsdkCursorSkillsDir(skillsHome), skill.leafDir);
|
|
42
77
|
}
|
|
43
78
|
/**
|
|
44
79
|
* Skills shipped next to the running package. Uses the frontmatter `name`
|
|
45
|
-
* when present, otherwise `
|
|
80
|
+
* when present, otherwise `agentsdk-<dir>`.
|
|
46
81
|
*/
|
|
47
82
|
export function listShippedPackageSkills() {
|
|
48
83
|
return __awaiter(this, arguments, void 0, function* (packageRoot = packageRootDir()) {
|
|
49
|
-
var _a;
|
|
50
84
|
const skillsRoot = join(packageRoot, "skills");
|
|
51
85
|
let entries;
|
|
52
86
|
try {
|
|
53
87
|
entries = yield readdir(skillsRoot, { withFileTypes: true });
|
|
54
88
|
}
|
|
55
|
-
catch (
|
|
89
|
+
catch (_a) {
|
|
56
90
|
return [];
|
|
57
91
|
}
|
|
58
92
|
const skills = [];
|
|
@@ -65,11 +99,12 @@ export function listShippedPackageSkills() {
|
|
|
65
99
|
try {
|
|
66
100
|
yield access(skillMd);
|
|
67
101
|
}
|
|
68
|
-
catch (
|
|
102
|
+
catch (_b) {
|
|
69
103
|
continue;
|
|
70
104
|
}
|
|
71
105
|
const raw = yield readFile(skillMd, "utf8");
|
|
72
|
-
const name = (
|
|
106
|
+
const name = parseFrontmatter(raw).data.name ||
|
|
107
|
+
`${CURSOR_SKILLS_NAMESPACE}-${entry.name}`;
|
|
73
108
|
skills.push({ name, leafDir: entry.name, sourceDir });
|
|
74
109
|
}
|
|
75
110
|
skills.sort((a, b) => a.leafDir.localeCompare(b.leafDir));
|
|
@@ -77,7 +112,7 @@ export function listShippedPackageSkills() {
|
|
|
77
112
|
});
|
|
78
113
|
}
|
|
79
114
|
/**
|
|
80
|
-
* Skills that do not yet have a SKILL.md under ~/.cursor/skills/
|
|
115
|
+
* Skills that do not yet have a SKILL.md under ~/.cursor/skills/agentsdk/.
|
|
81
116
|
* Install still overwrites every shipped skill when the user confirms — this
|
|
82
117
|
* helper is for messaging (fresh install vs update).
|
|
83
118
|
*/
|
|
@@ -99,13 +134,15 @@ export function findMissingCursorSkills(options) {
|
|
|
99
134
|
});
|
|
100
135
|
}
|
|
101
136
|
/**
|
|
102
|
-
* Copy each skill directory into `skillsHome/
|
|
137
|
+
* Copy each skill directory into `skillsHome/agentsdk/<leafDir>/`.
|
|
103
138
|
* Always overwrites so a package upgrade refreshes local Cursor skills.
|
|
104
|
-
* Strips monorepo-only frontmatter
|
|
139
|
+
* Strips monorepo-only frontmatter, sets `alwaysApply: true` so Cursor
|
|
140
|
+
* loads the body into context, and removes leaf dirs no longer shipped.
|
|
141
|
+
* Also deletes leftover `skillsHome/agentkit/` from the previous namespace.
|
|
105
142
|
*/
|
|
106
143
|
export function installCursorSkills(skills_1) {
|
|
107
144
|
return __awaiter(this, arguments, void 0, function* (skills, skillsHome = cursorSkillsHome()) {
|
|
108
|
-
const namespaceDir =
|
|
145
|
+
const namespaceDir = agentsdkCursorSkillsDir(skillsHome);
|
|
109
146
|
yield mkdir(namespaceDir, { recursive: true });
|
|
110
147
|
const removed = yield orphanLeaves(namespaceDir, skills);
|
|
111
148
|
for (const leaf of removed) {
|
|
@@ -128,7 +165,8 @@ export function installCursorSkills(skills_1) {
|
|
|
128
165
|
}
|
|
129
166
|
installed.push(skill.leafDir);
|
|
130
167
|
}
|
|
131
|
-
|
|
168
|
+
const removedLegacyNamespace = yield removeLegacyCursorSkillsNamespace(skillsHome);
|
|
169
|
+
return { installed, removed, removedLegacyNamespace };
|
|
132
170
|
});
|
|
133
171
|
}
|
|
134
172
|
function makeTreeWritable(root) {
|
|
@@ -171,14 +209,42 @@ function orphanLeaves(namespaceDir, skills) {
|
|
|
171
209
|
.map((entry) => entry.name);
|
|
172
210
|
});
|
|
173
211
|
}
|
|
174
|
-
/** Drop
|
|
212
|
+
/** Drop leftover `skillsHome/agentkit` from the previous install namespace. */
|
|
213
|
+
function removeLegacyCursorSkillsNamespace(skillsHome) {
|
|
214
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
215
|
+
const legacyDir = legacyAgentkitCursorSkillsDir(skillsHome);
|
|
216
|
+
try {
|
|
217
|
+
yield stat(legacyDir);
|
|
218
|
+
}
|
|
219
|
+
catch (_a) {
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
yield rm(legacyDir, { recursive: true, force: true });
|
|
223
|
+
return true;
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
function hasLegacyCursorSkillsNamespace(skillsHome) {
|
|
227
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
228
|
+
try {
|
|
229
|
+
yield stat(legacyAgentkitCursorSkillsDir(skillsHome));
|
|
230
|
+
return true;
|
|
231
|
+
}
|
|
232
|
+
catch (_a) {
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Drop monorepo `paths` globs, set `alwaysApply: true` so Cursor injects the
|
|
239
|
+
* body as a global rule, and fix package doc links for ~/.cursor installs.
|
|
240
|
+
*/
|
|
175
241
|
export function prepareSkillMarkdownForCursorInstall(content) {
|
|
176
242
|
var _a;
|
|
177
243
|
const match = /^---\r?\n([\s\S]*?)\r?\n---/.exec(content);
|
|
178
244
|
if (match === null) {
|
|
179
245
|
return content;
|
|
180
246
|
}
|
|
181
|
-
const frontmatter = stripPathsFromFrontmatter((_a = match[1]) !== null && _a !== void 0 ? _a : "");
|
|
247
|
+
const frontmatter = withAlwaysApply(stripPathsFromFrontmatter((_a = match[1]) !== null && _a !== void 0 ? _a : ""));
|
|
182
248
|
const body = content.slice(match[0].length);
|
|
183
249
|
const adjustedBody = body.replace(/\[`docs\/([^`]+)`\]\(\.\.\/\.\.\/docs\/[^)]+\)/g, "docs/$1 in the @cursor/july package");
|
|
184
250
|
return `---\n${frontmatter.trimEnd()}\n---${adjustedBody}`;
|
|
@@ -201,24 +267,42 @@ function stripPathsFromFrontmatter(frontmatter) {
|
|
|
201
267
|
}
|
|
202
268
|
return out.join("\n");
|
|
203
269
|
}
|
|
270
|
+
/** Cursor loads `alwaysApply: true` skills as global rules, not catalog rows. */
|
|
271
|
+
function withAlwaysApply(frontmatter) {
|
|
272
|
+
const without = frontmatter
|
|
273
|
+
.split(/\r?\n/)
|
|
274
|
+
.filter((line) => !/^\s*alwaysApply\s*:/.test(line))
|
|
275
|
+
.join("\n")
|
|
276
|
+
.replace(/\n+$/, "");
|
|
277
|
+
if (without === "") {
|
|
278
|
+
return "alwaysApply: true";
|
|
279
|
+
}
|
|
280
|
+
return `${without}\nalwaysApply: true`;
|
|
281
|
+
}
|
|
204
282
|
/** What an install would do, for the offer and for `install-skills`. */
|
|
205
283
|
export function planSkillInstall(options) {
|
|
206
284
|
return __awaiter(this, void 0, void 0, function* () {
|
|
207
285
|
var _a;
|
|
208
286
|
const skillsHome = (_a = options === null || options === void 0 ? void 0 : options.skillsHome) !== null && _a !== void 0 ? _a : cursorSkillsHome();
|
|
209
|
-
const directory =
|
|
287
|
+
const directory = agentsdkCursorSkillsDir(skillsHome);
|
|
210
288
|
const shipped = yield listShippedPackageSkills(options === null || options === void 0 ? void 0 : options.packageRoot);
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
289
|
+
const present = yield Promise.all(shipped.map((skill) => __awaiter(this, void 0, void 0, function* () {
|
|
290
|
+
try {
|
|
291
|
+
yield access(join(skillInstallPath(skill, skillsHome), "SKILL.md"));
|
|
292
|
+
return true;
|
|
293
|
+
}
|
|
294
|
+
catch (_a) {
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
})));
|
|
215
298
|
return {
|
|
216
299
|
shipped,
|
|
217
300
|
skillsHome,
|
|
218
301
|
directory,
|
|
219
302
|
leaves: shipped.map((skill) => skill.leafDir),
|
|
220
|
-
firstInstall:
|
|
303
|
+
firstInstall: present.every((isPresent) => !isPresent),
|
|
221
304
|
orphans: yield orphanLeaves(directory, shipped),
|
|
305
|
+
hasLegacyNamespace: yield hasLegacyCursorSkillsNamespace(skillsHome),
|
|
222
306
|
};
|
|
223
307
|
});
|
|
224
308
|
}
|
|
@@ -230,12 +314,55 @@ export function formatSkillInstall(plan, result) {
|
|
|
230
314
|
if (result.removed.length > 0) {
|
|
231
315
|
lines.push(` removed: ${result.removed.join(", ")}`);
|
|
232
316
|
}
|
|
317
|
+
if (result.removedLegacyNamespace) {
|
|
318
|
+
lines.push(` removed: ${legacyAgentkitCursorSkillsDir(plan.skillsHome)} (legacy namespace)`);
|
|
319
|
+
}
|
|
233
320
|
lines.push(` location: ${plan.directory}`);
|
|
234
321
|
return `${lines.join("\n")}\n`;
|
|
235
322
|
}
|
|
323
|
+
/**
|
|
324
|
+
* Copy shipped coding-agent skills into ~/.cursor/skills/agentsdk during a
|
|
325
|
+
* consumer `npm install` / `npx`. Never throws: a failed copy must not fail
|
|
326
|
+
* the package install. No-op in the monorepo source tree and when
|
|
327
|
+
* `CURSOR_JULY_SKIP_SKILL_INSTALL=1`.
|
|
328
|
+
*/
|
|
329
|
+
export function syncCursorSkillsOnPackageInstall() {
|
|
330
|
+
return __awaiter(this, arguments, void 0, function* (options = {}) {
|
|
331
|
+
var _a, _b, _c, _d;
|
|
332
|
+
try {
|
|
333
|
+
const env = (_a = options.env) !== null && _a !== void 0 ? _a : process.env;
|
|
334
|
+
if (env[CURSOR_JULY_SKIP_SKILL_INSTALL_ENV] === "1") {
|
|
335
|
+
return { status: "skipped", reason: "opt-out" };
|
|
336
|
+
}
|
|
337
|
+
const packageRoot = (_b = options.packageRoot) !== null && _b !== void 0 ? _b : packageRootDir();
|
|
338
|
+
const consumer = (_c = options.consumer) !== null && _c !== void 0 ? _c : isConsumerPackageInstall(packageRoot);
|
|
339
|
+
if (!consumer) {
|
|
340
|
+
return { status: "skipped", reason: "not-consumer" };
|
|
341
|
+
}
|
|
342
|
+
const plan = yield planSkillInstall({
|
|
343
|
+
packageRoot,
|
|
344
|
+
skillsHome: options.skillsHome,
|
|
345
|
+
});
|
|
346
|
+
if (plan.shipped.length === 0) {
|
|
347
|
+
return { status: "skipped", reason: "no-skills" };
|
|
348
|
+
}
|
|
349
|
+
const result = yield installCursorSkills(plan.shipped, plan.skillsHome);
|
|
350
|
+
const out = (_d = options.out) !== null && _d !== void 0 ? _d : ((text) => process.stderr.write(text));
|
|
351
|
+
out(formatSkillInstall(plan, result));
|
|
352
|
+
return {
|
|
353
|
+
status: "installed",
|
|
354
|
+
installed: result.installed,
|
|
355
|
+
removed: result.removed,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
catch (_e) {
|
|
359
|
+
return { status: "skipped", reason: "error" };
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
}
|
|
236
363
|
/**
|
|
237
364
|
* On a TTY, offer to install/update every shipped package skill into
|
|
238
|
-
* ~/.cursor/skills/
|
|
365
|
+
* ~/.cursor/skills/agentsdk (always overwriting). No-op when non-interactive
|
|
239
366
|
* or the package ships no skills. An unanswered prompt skips the install
|
|
240
367
|
* rather than blocking the caller — see `SKILL_PROMPT_TIMEOUT_MS`.
|
|
241
368
|
*/
|
|
@@ -265,6 +392,9 @@ export function offerInstallCursorSkills() {
|
|
|
265
392
|
if (plan.orphans.length > 0) {
|
|
266
393
|
out(c.dim(` (deletes ${plan.orphans.join(", ")})\n`));
|
|
267
394
|
}
|
|
395
|
+
if (plan.hasLegacyNamespace) {
|
|
396
|
+
out(c.dim(` (deletes leftover ${legacyAgentkitCursorSkillsDir(plan.skillsHome)})\n`));
|
|
397
|
+
}
|
|
268
398
|
const confirm = (_c = options.confirm) !== null && _c !== void 0 ? _c : ((q) => promptYesNo(q, {
|
|
269
399
|
defaultYes: true,
|
|
270
400
|
out,
|
|
@@ -285,24 +415,6 @@ export function offerInstallCursorSkills() {
|
|
|
285
415
|
return { installed: result.installed, skipped: false };
|
|
286
416
|
});
|
|
287
417
|
}
|
|
288
|
-
function parseSkillName(skillMd) {
|
|
289
|
-
var _a;
|
|
290
|
-
var _b;
|
|
291
|
-
const match = /^---\r?\n([\s\S]*?)\r?\n---/.exec(skillMd);
|
|
292
|
-
if (match === null) {
|
|
293
|
-
return undefined;
|
|
294
|
-
}
|
|
295
|
-
const nameLine = /^name:\s*(.+)\s*$/m.exec((_b = match[1]) !== null && _b !== void 0 ? _b : "");
|
|
296
|
-
if (nameLine === null) {
|
|
297
|
-
return undefined;
|
|
298
|
-
}
|
|
299
|
-
const raw = (_a = nameLine[1]) === null || _a === void 0 ? void 0 : _a.trim();
|
|
300
|
-
if (raw === undefined || raw === "") {
|
|
301
|
-
return undefined;
|
|
302
|
-
}
|
|
303
|
-
// Strip optional quotes around the YAML scalar.
|
|
304
|
-
return raw.replace(/^["']|["']$/g, "");
|
|
305
|
-
}
|
|
306
418
|
/**
|
|
307
419
|
* Ask a yes/no question. Resolves `undefined` when the answer never comes —
|
|
308
420
|
* the prompt timed out, or stdin closed on an empty line.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk-runner.d.ts","sourceRoot":"","sources":["../../src/internal/sdk-runner.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,
|
|
1
|
+
{"version":3,"file":"sdk-runner.d.ts","sourceRoot":"","sources":["../../src/internal/sdk-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,7 +15,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
15
15
|
});
|
|
16
16
|
};
|
|
17
17
|
import { mkdir } from "node:fs/promises";
|
|
18
|
-
import { Agent, Cursor, createAgentPlatform,
|
|
18
|
+
import { Agent, Cursor, createAgentPlatform, } from "@cursor/sdk";
|
|
19
|
+
import { SqliteLocalAgentStore } from "@cursor/sdk/sqlite";
|
|
19
20
|
import { DEFAULT_MODEL, } from "../types.js";
|
|
20
21
|
import { mapSdkTokenUsage, usageTokenSum } from "./cloud-turn-cost.js";
|
|
21
22
|
/**
|
|
@@ -399,7 +400,10 @@ export class CursorSdkRunner {
|
|
|
399
400
|
getStore(stateDir) {
|
|
400
401
|
let storePromise = this.stores.get(stateDir);
|
|
401
402
|
if (storePromise === undefined) {
|
|
402
|
-
storePromise = mkdir(stateDir, { recursive: true }).then(() =>
|
|
403
|
+
storePromise = mkdir(stateDir, { recursive: true }).then(() => SqliteLocalAgentStore.open({
|
|
404
|
+
stateRoot: stateDir,
|
|
405
|
+
workspaceRef: stateDir,
|
|
406
|
+
}));
|
|
403
407
|
this.stores.set(stateDir, storePromise);
|
|
404
408
|
}
|
|
405
409
|
return storePromise;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/internal/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/internal/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuCH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAOhB,YAAY,EACb,MAAM,aAAa,CAAC;AAwHrB,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,iBAAiB,CAAC;AAwBpE,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;CACvB;AAaD,6EAA6E;AAC7E,MAAM,WAAW,0BAA0B;IACzC,oEAAoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,UAAU,EAAE,EACpB,OAAO,GAAE,YAAY,GAAG,0BAA+B,GACtD,OAAO,CAAC,gBAAgB,CAAC,CAoxB3B"}
|
package/dist/internal/server.js
CHANGED
|
@@ -35,6 +35,7 @@ import { Buffer } from "node:buffer";
|
|
|
35
35
|
import { once } from "node:events";
|
|
36
36
|
import { createServer, } from "node:http";
|
|
37
37
|
import { join } from "node:path";
|
|
38
|
+
import { dispatchDeploymentEvent, getDeploymentsChannelOptions, } from "../channels/deployments/deployments-channel.js";
|
|
38
39
|
import { createCursorAccountGithubTokenResolver, getGithubCursorAccountRuntime, parseCursorGithubRepoScope, resolveCursorGithubPermissions, resolveCursorGithubProxyUrl, } from "../channels/github/cursor-account.js";
|
|
39
40
|
import { findGitHubChannelTargets } from "../channels/github/forward.js";
|
|
40
41
|
import { getOriginCursorAccountRuntime, parseCursorOriginRepoScope, } from "../channels/origin/cursor-account.js";
|
|
@@ -46,6 +47,7 @@ import { CursorAccountMcpBridge, collectCursorAccountConnections, cursorAccountM
|
|
|
46
47
|
import { CursorBackendClient } from "./cursor/backend-client.js";
|
|
47
48
|
import { cursorExternalApiUrl, resolveApiKey, SIGN_IN_HINT, } from "./cursor/credentials.js";
|
|
48
49
|
import { CursorGithubCredentialProvider } from "./cursor/github-credentials.js";
|
|
50
|
+
import { DeploymentEventRelay, fanOutDeploymentEvent, resolveDeploymentSubscriptions, } from "./cursor-deployment-relay.js";
|
|
49
51
|
import { CursorEventRelay, formatCursorScmDispatchOutcome, formatCursorScmEventLog, scmEventToGitHubPayload, scmMetadataToOriginPayload, } from "./cursor-event-relay.js";
|
|
50
52
|
import { AGENT_SERVE_GENERATION_ENV_VAR } from "./cursor-relay-core.js";
|
|
51
53
|
import { CursorSlackRelay, createCursorSlackApiCaller, formatCursorSlackEventLog, } from "./cursor-slack-relay.js";
|
|
@@ -536,6 +538,14 @@ export function startServer(mounts_1) {
|
|
|
536
538
|
cursorAccountOnly: options.cursorEvents === undefined &&
|
|
537
539
|
(cursorGithubTargets.length > 0 || cursorOriginTargets.length > 0),
|
|
538
540
|
});
|
|
541
|
+
// Cursor deployment-events relay: automatic when a mounted agent authored
|
|
542
|
+
// `deploymentsChannel({ ... })`.
|
|
543
|
+
const cursorDeploymentRelay = startCursorDeploymentRelay({
|
|
544
|
+
options,
|
|
545
|
+
runtimes,
|
|
546
|
+
accountKey,
|
|
547
|
+
logger,
|
|
548
|
+
});
|
|
539
549
|
const server = createServer((req, res) => {
|
|
540
550
|
void instrumentHttp(otelRuntime, req, res, () => handleRequest(router, req, res, logger));
|
|
541
551
|
});
|
|
@@ -553,6 +563,7 @@ export function startServer(mounts_1) {
|
|
|
553
563
|
});
|
|
554
564
|
}
|
|
555
565
|
catch (error) {
|
|
566
|
+
yield cursorDeploymentRelay === null || cursorDeploymentRelay === void 0 ? void 0 : cursorDeploymentRelay.stop();
|
|
556
567
|
yield cursorEventRelay === null || cursorEventRelay === void 0 ? void 0 : cursorEventRelay.stop();
|
|
557
568
|
yield cursorSlackRelay === null || cursorSlackRelay === void 0 ? void 0 : cursorSlackRelay.stop();
|
|
558
569
|
cursorGithubCredentials === null || cursorGithubCredentials === void 0 ? void 0 : cursorGithubCredentials.stop();
|
|
@@ -703,6 +714,7 @@ export function startServer(mounts_1) {
|
|
|
703
714
|
var _a;
|
|
704
715
|
var _b;
|
|
705
716
|
playgroundDev === null || playgroundDev === void 0 ? void 0 : playgroundDev.stop();
|
|
717
|
+
yield cursorDeploymentRelay === null || cursorDeploymentRelay === void 0 ? void 0 : cursorDeploymentRelay.stop();
|
|
706
718
|
yield cursorEventRelay === null || cursorEventRelay === void 0 ? void 0 : cursorEventRelay.stop();
|
|
707
719
|
yield cursorSlackRelay === null || cursorSlackRelay === void 0 ? void 0 : cursorSlackRelay.stop();
|
|
708
720
|
for (const runtime of runtimes) {
|
|
@@ -1660,13 +1672,110 @@ function collectCursorSlackTargets(runtimes) {
|
|
|
1660
1672
|
}
|
|
1661
1673
|
return targets;
|
|
1662
1674
|
}
|
|
1675
|
+
/** Every mounted `deploymentsChannel`, with its resolved subscriptions. */
|
|
1676
|
+
function collectCursorDeploymentTargets(runtimes, skipped) {
|
|
1677
|
+
const targets = [];
|
|
1678
|
+
for (const runtime of runtimes) {
|
|
1679
|
+
for (const channel of runtime.project.channels) {
|
|
1680
|
+
const options = getDeploymentsChannelOptions(channel.definition);
|
|
1681
|
+
if (options === undefined) {
|
|
1682
|
+
continue;
|
|
1683
|
+
}
|
|
1684
|
+
const subscriptions = resolveDeploymentSubscriptions(options);
|
|
1685
|
+
if (subscriptions.length === 0) {
|
|
1686
|
+
// Declared the channel but named no repositories — usually an unset
|
|
1687
|
+
// env var. Say so rather than starting a relay that receives nothing.
|
|
1688
|
+
skipped.push(`${runtime.slug || runtime.project.name}/${channel.id}`);
|
|
1689
|
+
continue;
|
|
1690
|
+
}
|
|
1691
|
+
targets.push({ runtime, channelId: channel.id, options, subscriptions });
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
return targets;
|
|
1695
|
+
}
|
|
1663
1696
|
/**
|
|
1664
|
-
*
|
|
1665
|
-
*
|
|
1666
|
-
*
|
|
1667
|
-
*
|
|
1668
|
-
*
|
|
1697
|
+
* Cursor deployment-events relay: automatic when a mounted agent authored
|
|
1698
|
+
* `deploymentsChannel({ ... })`. One relay per process reads
|
|
1699
|
+
* `/v0/deployment-events` for the union of every channel's repositories, and
|
|
1700
|
+
* each event is routed to the channels that asked for it — the same ownership
|
|
1701
|
+
* `startCursorSlackRelay` and `startCursorEventRelay` have.
|
|
1669
1702
|
*/
|
|
1703
|
+
function startCursorDeploymentRelay(input) {
|
|
1704
|
+
var _a;
|
|
1705
|
+
const { options, runtimes, accountKey, logger } = input;
|
|
1706
|
+
const skipped = [];
|
|
1707
|
+
const targets = collectCursorDeploymentTargets(runtimes, skipped);
|
|
1708
|
+
if (skipped.length > 0) {
|
|
1709
|
+
logger(`[agent-sdk] deployment-events: no repositories declared on ${skipped.join(", ")}; those channels receive nothing`);
|
|
1710
|
+
}
|
|
1711
|
+
if (targets.length === 0) {
|
|
1712
|
+
return undefined;
|
|
1713
|
+
}
|
|
1714
|
+
if (accountKey === undefined) {
|
|
1715
|
+
throw new Error(`This project has channels subscribed to deployment events (deploymentsChannel({ repos })) but the host is not signed in to Cursor. ${SIGN_IN_HINT}`);
|
|
1716
|
+
}
|
|
1717
|
+
// Union across channels: one registration per repo for the whole process,
|
|
1718
|
+
// however many channels named it. Per-channel environment and event-type
|
|
1719
|
+
// filtering happens at dispatch.
|
|
1720
|
+
const byRepo = new Map();
|
|
1721
|
+
for (const target of targets) {
|
|
1722
|
+
for (const subscription of target.subscriptions) {
|
|
1723
|
+
const existing = byRepo.get(subscription.repo);
|
|
1724
|
+
if (existing === undefined) {
|
|
1725
|
+
byRepo.set(subscription.repo, {
|
|
1726
|
+
repo: subscription.repo,
|
|
1727
|
+
environments: [...subscription.environments],
|
|
1728
|
+
events: new Set(subscription.events),
|
|
1729
|
+
});
|
|
1730
|
+
continue;
|
|
1731
|
+
}
|
|
1732
|
+
for (const event of subscription.events)
|
|
1733
|
+
existing.events.add(event);
|
|
1734
|
+
// An empty environment list means "every environment", so it absorbs.
|
|
1735
|
+
existing.environments =
|
|
1736
|
+
existing.environments.length === 0 ||
|
|
1737
|
+
subscription.environments.length === 0
|
|
1738
|
+
? []
|
|
1739
|
+
: [
|
|
1740
|
+
...new Set([
|
|
1741
|
+
...existing.environments,
|
|
1742
|
+
...subscription.environments,
|
|
1743
|
+
]),
|
|
1744
|
+
];
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
// Same host split as scm-events and slack-events: `/v0/deployment-events/*`
|
|
1748
|
+
// is on api.cursor.com, not api2.
|
|
1749
|
+
const baseStateRoot = (_a = options.stateRoot) !== null && _a !== void 0 ? _a : join(targets[0].runtime.project.rootDir, ".agent-serve");
|
|
1750
|
+
const relay = new DeploymentEventRelay({
|
|
1751
|
+
baseUrl: cursorExternalApiUrl(),
|
|
1752
|
+
apiKey: accountKey.apiKey,
|
|
1753
|
+
stateDir: join(baseStateRoot, "deployment-events"),
|
|
1754
|
+
subscriptions: [...byRepo.values()],
|
|
1755
|
+
logger,
|
|
1756
|
+
dispatch: (event) => __awaiter(this, void 0, void 0, function* () {
|
|
1757
|
+
return fanOutDeploymentEvent({
|
|
1758
|
+
event,
|
|
1759
|
+
logger,
|
|
1760
|
+
targets: targets.map((target) => ({
|
|
1761
|
+
name: `${target.runtime.slug || target.runtime.project.name}/${target.channelId}`,
|
|
1762
|
+
subscriptions: target.subscriptions,
|
|
1763
|
+
deliver: (delivered) => dispatchDeploymentEvent({
|
|
1764
|
+
options: target.options,
|
|
1765
|
+
event: delivered,
|
|
1766
|
+
args: buildChannelHandlerArgs({
|
|
1767
|
+
runtime: target.runtime,
|
|
1768
|
+
channelId: target.channelId,
|
|
1769
|
+
}),
|
|
1770
|
+
}),
|
|
1771
|
+
})),
|
|
1772
|
+
});
|
|
1773
|
+
}),
|
|
1774
|
+
});
|
|
1775
|
+
relay.start();
|
|
1776
|
+
logger(`[agent-sdk] deployment-events: relaying ${byRepo.size} repository subscription(s) to ${targets.length} channel(s)`);
|
|
1777
|
+
return relay;
|
|
1778
|
+
}
|
|
1670
1779
|
function startCursorSlackRelay(input) {
|
|
1671
1780
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1672
1781
|
var _a;
|