@cursor/bdk 0.2.26 → 0.2.27
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/dist/docs/404.html +2 -2
- package/dist/docs/assets/{app.BITbgXMP.js → app.wA5xBBcd.js} +4 -4
- package/dist/docs/assets/changelog.md.BvHRIiMH.js +1 -0
- package/dist/docs/assets/{changelog.md.sdD6ctqK.lean.js → changelog.md.BvHRIiMH.lean.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BoDEJQWv.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.3qo4-bX9.js → VPLocalSearchBox.C29HLCVL.js} +1 -1
- package/dist/docs/assets/chunks/{arc.CTrZocKU.js → arc.BOaoYWmh.js} +1 -1
- package/dist/docs/assets/chunks/{architectureDiagram-Q4EWVU46.BkgIqxrv.js → architectureDiagram-Q4EWVU46.MfG0itQh.js} +1 -1
- package/dist/docs/assets/chunks/{baseUniq.5w0JfVgo.js → baseUniq.CUeJciCF.js} +1 -1
- package/dist/docs/assets/chunks/{blockDiagram-DXYQGD6D.BVLtPjQc.js → blockDiagram-DXYQGD6D.BrXMZRtK.js} +1 -1
- package/dist/docs/assets/chunks/{c4Diagram-AHTNJAMY.CQ7neZTW.js → c4Diagram-AHTNJAMY.DfkDHeB9.js} +1 -1
- package/dist/docs/assets/chunks/channel.D2BTz0L-.js +1 -0
- package/dist/docs/assets/chunks/{chunk-4BX2VUAB.D-hJ7uKM.js → chunk-4BX2VUAB.xKz8CiXK.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-4TB4RGXK.RBYX5ywX.js → chunk-4TB4RGXK.kkfBh4zk.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-55IACEB6.Br05HoEb.js → chunk-55IACEB6.BClJGb94.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-EDXVE4YY.BD_7QS60.js → chunk-EDXVE4YY.P9BpQ9L3.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-FMBD7UC4.BOPnMabX.js → chunk-FMBD7UC4.R4iYi58S.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-OYMX7WX6.DmGIdP8i.js → chunk-OYMX7WX6.Cpn8L1dw.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-QZHKN3VN.CGHmolCB.js → chunk-QZHKN3VN.BLftECqU.js} +1 -1
- package/dist/docs/assets/chunks/{chunk-YZCP3GAM.C_Uhs25v.js → chunk-YZCP3GAM.BWDV1AYt.js} +1 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.DqByliAC.js +1 -0
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.DqByliAC.js +1 -0
- package/dist/docs/assets/chunks/clone.CldT1lbQ.js +1 -0
- package/dist/docs/assets/chunks/{cose-bilkent-S5V4N54A.DsU6xpcZ.js → cose-bilkent-S5V4N54A.DGpAcJ55.js} +1 -1
- package/dist/docs/assets/chunks/{dagre-KV5264BT.BqQLDcoU.js → dagre-KV5264BT.BBXxGEaD.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-5BDNPKRD.Cgv8uUNF.js → diagram-5BDNPKRD.EKqOwmK2.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-G4DWMVQ6.BXHPSXh_.js → diagram-G4DWMVQ6.CB8pdkoZ.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-MMDJMWI5.CgJzo8f_.js → diagram-MMDJMWI5.aHh4WGg9.js} +1 -1
- package/dist/docs/assets/chunks/{diagram-TYMM5635.CfiN6lgT.js → diagram-TYMM5635.YIsbRH20.js} +1 -1
- package/dist/docs/assets/chunks/{erDiagram-SMLLAGMA.8n_hHzAd.js → erDiagram-SMLLAGMA.B3bTCW_e.js} +1 -1
- package/dist/docs/assets/chunks/{flowDiagram-DWJPFMVM.B2pb1Dv_.js → flowDiagram-DWJPFMVM.M81hXIXZ.js} +1 -1
- package/dist/docs/assets/chunks/{ganttDiagram-T4ZO3ILL.BFih4ucI.js → ganttDiagram-T4ZO3ILL.BKg7WY--.js} +1 -1
- package/dist/docs/assets/chunks/{gitGraphDiagram-UUTBAWPF.CqZ8PTl8.js → gitGraphDiagram-UUTBAWPF.CLEMZgO3.js} +1 -1
- package/dist/docs/assets/chunks/{graph.0ufsI9gu.js → graph.DS38W_Q-.js} +1 -1
- package/dist/docs/assets/chunks/{infoDiagram-42DDH7IO.BkPRFww4.js → infoDiagram-42DDH7IO.BTiWTi82.js} +1 -1
- package/dist/docs/assets/chunks/{ishikawaDiagram-UXIWVN3A.DCRK-cVX.js → ishikawaDiagram-UXIWVN3A.DcqY_KQL.js} +1 -1
- package/dist/docs/assets/chunks/{journeyDiagram-VCZTEJTY.BFyAJo33.js → journeyDiagram-VCZTEJTY.0lQNZ40U.js} +1 -1
- package/dist/docs/assets/chunks/{kanban-definition-6JOO6SKY.CmA2SoGc.js → kanban-definition-6JOO6SKY.L5sKlf7X.js} +1 -1
- package/dist/docs/assets/chunks/{layout.CYY-CbMr.js → layout.7u4gFhQa.js} +1 -1
- package/dist/docs/assets/chunks/{linear.DeeDV4Oq.js → linear.D5v33SOb.js} +1 -1
- package/dist/docs/assets/chunks/{min.BL3XTBN2.js → min.Dc9uCxf9.js} +1 -1
- package/dist/docs/assets/chunks/{mindmap-definition-QFDTVHPH.BcbY-G6H.js → mindmap-definition-QFDTVHPH.B56nGoB_.js} +1 -1
- package/dist/docs/assets/chunks/{pieDiagram-DEJITSTG.dzDcQnPE.js → pieDiagram-DEJITSTG.Cba8e8lS.js} +1 -1
- package/dist/docs/assets/chunks/{quadrantDiagram-34T5L4WZ.RxR0m5iK.js → quadrantDiagram-34T5L4WZ.2YjBycHF.js} +1 -1
- package/dist/docs/assets/chunks/{requirementDiagram-MS252O5E.DflaXb6Q.js → requirementDiagram-MS252O5E.D4P5RqVI.js} +1 -1
- package/dist/docs/assets/chunks/{sankeyDiagram-XADWPNL6.BteLKQAe.js → sankeyDiagram-XADWPNL6.C0Hn8NUm.js} +1 -1
- package/dist/docs/assets/chunks/{sequenceDiagram-FGHM5R23.BD8jM8oz.js → sequenceDiagram-FGHM5R23.BZm7EaoT.js} +1 -1
- package/dist/docs/assets/chunks/{stateDiagram-FHFEXIEX.C8SBkbPH.js → stateDiagram-FHFEXIEX.DcR4f3X2.js} +1 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.Bb4oMe0P.js +1 -0
- package/dist/docs/assets/chunks/{theme.DiViIOLe.js → theme.DvfKzyXq.js} +2 -2
- package/dist/docs/assets/chunks/{timeline-definition-GMOUNBTQ.D64XF5dV.js → timeline-definition-GMOUNBTQ.CgDh96vg.js} +1 -1
- package/dist/docs/assets/chunks/{vennDiagram-DHZGUBPP.CwmeYan-.js → vennDiagram-DHZGUBPP.B4fagbC8.js} +1 -1
- package/dist/docs/assets/chunks/{wardley-RL74JXVD.DmAlXlpu.js → wardley-RL74JXVD.Ck68omim.js} +1 -1
- package/dist/docs/assets/chunks/{wardleyDiagram-NUSXRM2D.5VJ2-5K0.js → wardleyDiagram-NUSXRM2D.DBUg0bvz.js} +1 -1
- package/dist/docs/assets/chunks/{xychartDiagram-5P7HB3ND.Cl6_fZVC.js → xychartDiagram-5P7HB3ND.DnKSGQE1.js} +1 -1
- package/dist/docs/assets/{reference_agent-config.md.CGSx8COP.js → reference_agent-config.md.CZrbHOfT.js} +4 -4
- package/dist/docs/assets/{reference_agent-config.md.CGSx8COP.lean.js → reference_agent-config.md.CZrbHOfT.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +35 -35
- package/dist/docs/changelog.html +36 -36
- package/dist/docs/changelog.md +28 -0
- package/dist/docs/deployment.html +35 -35
- package/dist/docs/evals.html +35 -35
- package/dist/docs/guides/agent-to-agent.html +35 -35
- package/dist/docs/guides/bitbucket.html +35 -35
- package/dist/docs/guides/cloud-agents.html +35 -35
- package/dist/docs/guides/convert-automation.html +35 -35
- package/dist/docs/guides/export-grokbot.html +35 -35
- package/dist/docs/guides/github.html +35 -35
- package/dist/docs/guides/gitlab.html +35 -35
- package/dist/docs/guides/grokbot-agents.html +35 -35
- package/dist/docs/guides/hooks.html +35 -35
- package/dist/docs/guides/improve.html +35 -35
- package/dist/docs/guides/jev.html +35 -35
- package/dist/docs/guides/mcp-oauth.html +35 -35
- package/dist/docs/guides/migrate.html +35 -35
- package/dist/docs/guides/opentelemetry.html +35 -35
- package/dist/docs/guides/pagerduty.html +35 -35
- package/dist/docs/guides/slack.html +35 -35
- package/dist/docs/guides/webhooks.html +35 -35
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +35 -35
- package/dist/docs/index.html +35 -35
- package/dist/docs/llms-full.txt +37 -0
- package/dist/docs/quickstart.html +35 -35
- package/dist/docs/reference/agent-config.html +38 -38
- package/dist/docs/reference/agent-config.md +9 -0
- package/dist/docs/reference/artifacts.html +35 -35
- package/dist/docs/reference/channels.html +35 -35
- package/dist/docs/reference/cli.html +35 -35
- package/dist/docs/reference/connections.html +35 -35
- package/dist/docs/reference/evals.html +35 -35
- package/dist/docs/reference/extensions.html +35 -35
- package/dist/docs/reference/hooks.html +35 -35
- package/dist/docs/reference/http-api.html +35 -35
- package/dist/docs/reference/instructions.html +35 -35
- package/dist/docs/reference/memory.html +35 -35
- package/dist/docs/reference/playground.html +35 -35
- package/dist/docs/reference/project-layout.html +35 -35
- package/dist/docs/reference/prompt.html +35 -35
- package/dist/docs/reference/schedules.html +35 -35
- package/dist/docs/reference/sessions.html +35 -35
- package/dist/docs/reference/skills.html +35 -35
- package/dist/docs/reference/subagents.html +35 -35
- package/dist/docs/reference/tools.html +35 -35
- package/dist/docs/templates/agentic-owners.html +35 -35
- package/dist/docs/templates/grokbot-agents.html +35 -35
- package/dist/docs/templates/security-reviewer.html +35 -35
- package/dist/docs/templates/thermo-quality-review.html +35 -35
- package/dist/docs/templates/thermo-review.html +35 -35
- package/dist/docs/templates/triage.html +35 -35
- package/dist/docs/troubleshooting.html +35 -35
- package/dist/extensions/cursor-cloud-agents/lib/backend.d.ts +4 -1
- package/dist/extensions/cursor-cloud-agents/lib/backend.d.ts.map +1 -1
- package/dist/extensions/cursor-cloud-agents/lib/backend.js +1 -5
- package/dist/filesystem.d.ts +26 -5
- package/dist/filesystem.d.ts.map +1 -1
- package/dist/filesystem.js +91 -18
- package/dist/internal/discovery/agent.d.ts.map +1 -1
- package/dist/internal/discovery/agent.js +29 -9
- package/dist/internal/docs-site.d.ts +2 -5
- package/dist/internal/docs-site.d.ts.map +1 -1
- package/dist/internal/docs-site.js +2 -5
- package/dist/internal/sdk-runner.d.ts +6 -0
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +41 -1
- package/dist/internal/session-engine.d.ts +8 -3
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +64 -20
- package/dist/internal/workspace.d.ts +10 -0
- package/dist/internal/workspace.d.ts.map +1 -1
- package/dist/internal/workspace.js +47 -1
- package/dist/playground/assets/cursor-icons-16-DfKNljMZ.woff2 +0 -0
- package/dist/playground/assets/{index-DpbzbqFY.js → index-B3_YohwW.js} +38 -38
- package/dist/playground/assets/index-Cn3-adsJ.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/types.d.ts +41 -7
- package/dist/types.d.ts.map +1 -1
- package/docs/changelog.md +28 -0
- package/docs/reference/agent-config.md +9 -0
- package/package.json +5 -2
- package/dist/docs/assets/changelog.md.sdD6ctqK.js +0 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.B45uCZp9.js +0 -1
- package/dist/docs/assets/chunks/channel.Cv2w64wj.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-6PBFFD2Q.CtO2atCr.js +0 -1
- package/dist/docs/assets/chunks/classDiagram-v2-HSJHXN6E.CtO2atCr.js +0 -1
- package/dist/docs/assets/chunks/clone.hfsCtgP4.js +0 -1
- package/dist/docs/assets/chunks/stateDiagram-v2-QKLJ7IA2.BLz7Qyo3.js +0 -1
- package/dist/playground/assets/cursor-icons-16-DmHBTm1-.woff2 +0 -0
- package/dist/playground/assets/index-CyPkf2y7.css +0 -1
|
@@ -15,7 +15,7 @@ import { SlackAskDedupeStore, SlackNudgeStore } from "../channels/slack/nudge-st
|
|
|
15
15
|
import { resolveDedicatedSlackHostBinding } from "../channels/slack/slack-channel.js";
|
|
16
16
|
import { AGENT_SERVE_USER_STORE_FILES_SOURCE_ID, agentStoreKeys, DEPLOYMENT_STORE_MOUNT_PATH, USER_STORE_MOUNT_PATH, } from "../files.js";
|
|
17
17
|
import { cursorHostedFiles, isCursorHostedFilesAvailable, isCursorUserStoreFilesAvailable, } from "../files-backends/cursor-hosted.js";
|
|
18
|
-
import { isFileSystemToolAlias, isMutatingFileSystemTool, localFileSystem, resolveFileSystemTools, resolveHostHarnessToolOptions,
|
|
18
|
+
import { isFileNotFoundError, isFileSystemToolAlias, isMutatingFileSystemTool, localFileSystem, readOnlyFs, resolveFileSystemTools, resolveHostHarnessToolOptions, sessionFileSystem, writeWorkspaceFilesToRoot, } from "../filesystem.js";
|
|
19
19
|
import { storageKeysForArchitecture } from "../storage.js";
|
|
20
20
|
import { DEFAULT_MODEL, DIRECT_TOOL_CALL_CHANNEL_ID, isCursorAccountTransport, isHostOauthConnectionTransport, isSymbolicConnectionTransport, } from "../types.js";
|
|
21
21
|
import { resolveAdvertisedTools } from "./advertise-tools.js";
|
|
@@ -67,7 +67,7 @@ import { TurnGovernor } from "./turn-governor.js";
|
|
|
67
67
|
import { TurnLeaseStore } from "./turn-lease-store.js";
|
|
68
68
|
import { TurnOutbox } from "./turn-outbox.js";
|
|
69
69
|
import { isCursorManagedV2Hosting, resolveAgentV2Hosting } from "./v2-hosting.js";
|
|
70
|
-
import { buildAgentsMdContent, buildCloudMemorySection, buildCloudSessionWorkspaceSection, buildCloudWorkspaceSection, ensureOwnGitRoot, isNestedInGitRepo, materializeWorkspace, SERVER_TOOLS_MCP_SERVER_NAME, withIdentityPreamble, } from "./workspace.js";
|
|
70
|
+
import { buildAgentsMdContent, buildCloudMemorySection, buildCloudSessionWorkspaceSection, buildCloudWorkspaceSection, ensureOwnGitRoot, isNestedInGitRepo, materializeWorkspace, SERVER_TOOLS_MCP_SERVER_NAME, SKILLS_MOUNT_PATH, skillsFileSystem, withIdentityPreamble, } from "./workspace.js";
|
|
71
71
|
import { syncSessionWorkspaceFiles, syncWorkspaceToStore, WorkspaceFileRefusal, wipeSessionWorkspace, } from "./workspace-sync.js";
|
|
72
72
|
export const HTTP_CHANNEL_ID = "http";
|
|
73
73
|
export { mergeChannelStateSkipNull } from "./channel-state.js";
|
|
@@ -266,11 +266,11 @@ export class SessionEngine {
|
|
|
266
266
|
this.cloudUsageBackfillDone = new Set();
|
|
267
267
|
/** Deduped in-flight cloud usage backfills, keyed by session id. */
|
|
268
268
|
this.cloudUsageBackfill = new Map();
|
|
269
|
-
/** Per-session
|
|
269
|
+
/** Per-session authored `fs` and skills handles (not tree snapshots). */
|
|
270
270
|
this.sessionRoots = new Map();
|
|
271
271
|
/** In-flight factory resolves, so the first turn and a racing callTool share one handle. */
|
|
272
272
|
this.sessionRootInflight = new Map();
|
|
273
|
-
/** Per-turn
|
|
273
|
+
/** Per-turn union of the authored tree, `/agent/skills`, and `/tmp`. Dropped at end of turn. */
|
|
274
274
|
this.turnRoots = new Map();
|
|
275
275
|
this.project = options.project;
|
|
276
276
|
applyAgentContinuationDefaults(this.project);
|
|
@@ -1388,10 +1388,14 @@ export class SessionEngine {
|
|
|
1388
1388
|
return this.interrupt(existing.sessionId);
|
|
1389
1389
|
}
|
|
1390
1390
|
hasRootOverride() {
|
|
1391
|
-
return this.project.agent.root !== undefined;
|
|
1391
|
+
return this.project.agent.fs !== undefined || this.project.agent.root !== undefined;
|
|
1392
|
+
}
|
|
1393
|
+
/** The field the author set, for messages. Discovery copies a lone `root` onto `fs`. */
|
|
1394
|
+
authoredFsField() {
|
|
1395
|
+
return this.project.agent.root === undefined ? "fs" : "root";
|
|
1392
1396
|
}
|
|
1393
1397
|
/**
|
|
1394
|
-
* FileSystem for this turn or `callTool`. Authored `
|
|
1398
|
+
* FileSystem for this turn or `callTool`. Authored `fs` (static or
|
|
1395
1399
|
* factory) is cached per session when `cache` is set; unscoped
|
|
1396
1400
|
* `callTool` passes the invocation id and does not cache, so factories
|
|
1397
1401
|
* cannot share one tree across callers. A static handle is used as
|
|
@@ -1400,20 +1404,21 @@ export class SessionEngine {
|
|
|
1400
1404
|
* the Cursor SDK natives, always through the synthesized tools.
|
|
1401
1405
|
*/
|
|
1402
1406
|
async resolveFileSystem(options) {
|
|
1403
|
-
|
|
1404
|
-
if (authored === undefined) {
|
|
1407
|
+
if (!this.hasRootOverride()) {
|
|
1405
1408
|
return localFileSystem({ cwd: options.cwd });
|
|
1406
1409
|
}
|
|
1407
|
-
const
|
|
1410
|
+
const authored = await this.resolveAuthoredFileSystem(options);
|
|
1408
1411
|
if (options.cache) {
|
|
1409
1412
|
const existing = this.turnRoots.get(options.sessionId);
|
|
1410
1413
|
if (existing !== undefined) {
|
|
1411
1414
|
return existing.root;
|
|
1412
1415
|
}
|
|
1413
1416
|
}
|
|
1414
|
-
const root =
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
+
const root = sessionFileSystem({
|
|
1418
|
+
authored: authored.fs,
|
|
1419
|
+
skills: authored.skills === undefined
|
|
1420
|
+
? undefined
|
|
1421
|
+
: { path: SKILLS_MOUNT_PATH, fs: authored.skills },
|
|
1417
1422
|
});
|
|
1418
1423
|
if (options.cache && this.isTurnRunning(options.sessionId)) {
|
|
1419
1424
|
this.turnRoots.set(options.sessionId, { root, cwd: options.cwd });
|
|
@@ -1421,9 +1426,10 @@ export class SessionEngine {
|
|
|
1421
1426
|
return root;
|
|
1422
1427
|
}
|
|
1423
1428
|
async resolveAuthoredFileSystem(options) {
|
|
1424
|
-
const
|
|
1429
|
+
const agent = this.project.agent;
|
|
1430
|
+
const authored = agent.fs ?? agent.root;
|
|
1425
1431
|
if (authored === undefined) {
|
|
1426
|
-
throw new Error("resolveAuthoredFileSystem requires an authored
|
|
1432
|
+
throw new Error("resolveAuthoredFileSystem requires an authored fs");
|
|
1427
1433
|
}
|
|
1428
1434
|
if (options.cache) {
|
|
1429
1435
|
const cached = this.sessionRoots.get(options.sessionId);
|
|
@@ -1435,14 +1441,14 @@ export class SessionEngine {
|
|
|
1435
1441
|
return inflight;
|
|
1436
1442
|
}
|
|
1437
1443
|
}
|
|
1438
|
-
const
|
|
1444
|
+
const resolveFs = async () => {
|
|
1439
1445
|
if (typeof authored !== "function") {
|
|
1440
1446
|
return authored;
|
|
1441
1447
|
}
|
|
1442
1448
|
const host = this.hostForSession(options.cache ? options.sessionId : undefined);
|
|
1443
1449
|
const ctx = {
|
|
1444
1450
|
sessionId: options.sessionId,
|
|
1445
|
-
agentName:
|
|
1451
|
+
agentName: agent.name,
|
|
1446
1452
|
...(options.continuationKey === undefined
|
|
1447
1453
|
? {}
|
|
1448
1454
|
: { continuationKey: options.continuationKey }),
|
|
@@ -1450,6 +1456,37 @@ export class SessionEngine {
|
|
|
1450
1456
|
};
|
|
1451
1457
|
return await authored(ctx);
|
|
1452
1458
|
};
|
|
1459
|
+
const resolve = async () => {
|
|
1460
|
+
const fs = await resolveFs();
|
|
1461
|
+
if (agent.skillsMount === false) {
|
|
1462
|
+
return { fs, skills: undefined };
|
|
1463
|
+
}
|
|
1464
|
+
let skillsOccupied = false;
|
|
1465
|
+
try {
|
|
1466
|
+
skillsOccupied = (await fs.stat(SKILLS_MOUNT_PATH)).kind !== "missing";
|
|
1467
|
+
}
|
|
1468
|
+
catch (error) {
|
|
1469
|
+
if (!isFileNotFoundError(error)) {
|
|
1470
|
+
throw error;
|
|
1471
|
+
}
|
|
1472
|
+
skillsOccupied = false;
|
|
1473
|
+
}
|
|
1474
|
+
if (skillsOccupied) {
|
|
1475
|
+
throw new Error(`Agent "${agent.name}" ${this.authoredFsField()} already has ${SKILLS_MOUNT_PATH}, where BDK mounts the agent's skills. Remove ${SKILLS_MOUNT_PATH} from ${this.authoredFsField()}, or set skills: false to keep yours.`);
|
|
1476
|
+
}
|
|
1477
|
+
const skills = await this.baseSkillsFileSystem();
|
|
1478
|
+
if (agent.skillsMount === undefined) {
|
|
1479
|
+
return { fs, skills };
|
|
1480
|
+
}
|
|
1481
|
+
return {
|
|
1482
|
+
fs,
|
|
1483
|
+
skills: readOnlyFs(await agent.skillsMount({
|
|
1484
|
+
skills,
|
|
1485
|
+
sessionId: options.sessionId,
|
|
1486
|
+
continuationKey: options.continuationKey,
|
|
1487
|
+
})),
|
|
1488
|
+
};
|
|
1489
|
+
};
|
|
1453
1490
|
if (!options.cache) {
|
|
1454
1491
|
return resolve();
|
|
1455
1492
|
}
|
|
@@ -1464,6 +1501,13 @@ export class SessionEngine {
|
|
|
1464
1501
|
this.sessionRootInflight.delete(options.sessionId);
|
|
1465
1502
|
}
|
|
1466
1503
|
}
|
|
1504
|
+
baseSkillsFileSystem() {
|
|
1505
|
+
this.baseSkills ??= skillsFileSystem(this.project.agent.skills).catch((error) => {
|
|
1506
|
+
this.baseSkills = undefined;
|
|
1507
|
+
throw error;
|
|
1508
|
+
});
|
|
1509
|
+
return this.baseSkills;
|
|
1510
|
+
}
|
|
1467
1511
|
dropTurnFileSystem(sessionId) {
|
|
1468
1512
|
this.turnRoots.delete(sessionId);
|
|
1469
1513
|
}
|
|
@@ -2121,11 +2165,11 @@ export class SessionEngine {
|
|
|
2121
2165
|
//
|
|
2122
2166
|
// Factory roots omit `allowedTools` at discovery (the live handle is
|
|
2123
2167
|
// resolved per session). The allowlist guard below therefore never
|
|
2124
|
-
// fires for `defineAgent({
|
|
2168
|
+
// fires for `defineAgent({ fs: (ctx) => … })` with omitted `tools`,
|
|
2125
2169
|
// and a per-send `cloud` attach would skip the virtual-root allowlist
|
|
2126
|
-
// and run unrestricted on a VM. Any authored
|
|
2170
|
+
// and run unrestricted on a VM. Any authored fs refuses non-local turns.
|
|
2127
2171
|
if (runtime !== "local" && this.hasRootOverride()) {
|
|
2128
|
-
throw new Error(`Agent "${agent.name}" declares
|
|
2172
|
+
throw new Error(`Agent "${agent.name}" declares ${this.authoredFsField()}, which cannot be served on ${runtime} turns. Refusing the session rather than running it against the host VM.`);
|
|
2129
2173
|
}
|
|
2130
2174
|
if (runtime !== "local" && agent.allowedTools !== undefined) {
|
|
2131
2175
|
throw new Error(`Agent "${agent.name}" declares a built-in tool allowlist (tools), which cannot be enforced on ${runtime} turns. Refusing the session rather than running it unrestricted.`);
|
|
@@ -2252,7 +2296,7 @@ export class SessionEngine {
|
|
|
2252
2296
|
// synthesized file tools and embedded script bodies.
|
|
2253
2297
|
const localInstructions = runtime === "local"
|
|
2254
2298
|
? authoredRoot
|
|
2255
|
-
? buildAgentsMdContent({ ...instructionsAgent, tools: [...instructionsAgent.tools, ...synthesized] }, { includeScripts: true })
|
|
2299
|
+
? buildAgentsMdContent({ ...instructionsAgent, tools: [...instructionsAgent.tools, ...synthesized] }, { includeScripts: true, skillsIndex: agent.skillsMount !== false })
|
|
2256
2300
|
: buildAgentsMdContent(instructionsAgent, {
|
|
2257
2301
|
includeScripts: this.hasBorrowedWorkspace(record),
|
|
2258
2302
|
})
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* deliver them as the harness system prompt ({@link buildAgentsMdContent}),
|
|
9
9
|
* and cloud / grokbot harnesses never read the session workspace.
|
|
10
10
|
*/
|
|
11
|
+
import { type FileSystem } from "../filesystem.js";
|
|
11
12
|
import type { DiscoveredSkill, DiscoveredTool, ResolvedAgent } from "../types.js";
|
|
12
13
|
export interface MaterializeWorkspaceOptions {
|
|
13
14
|
agent: ResolvedAgent;
|
|
@@ -102,7 +103,16 @@ export declare function buildServerToolsCatalog(tools: DiscoveredTool[], options
|
|
|
102
103
|
export declare function buildAgentsMdContent(agent: ResolvedAgent, options: {
|
|
103
104
|
includeScripts: boolean;
|
|
104
105
|
serverToolsMcpName?: string;
|
|
106
|
+
skillsIndex?: boolean;
|
|
105
107
|
}): string;
|
|
108
|
+
/** Where an authored `fs` sees {@link skillsFileSystem}. */
|
|
109
|
+
export declare const SKILLS_MOUNT_PATH = "/agent/skills";
|
|
110
|
+
export declare const FS_AND_ROOT_CONFLICT = "Set `fs` or `root`, not both; `root` is a deprecated alias of `fs`.";
|
|
111
|
+
/**
|
|
112
|
+
* The discovered skills as a read-only tree: `/<name>/SKILL.md`, the same
|
|
113
|
+
* bytes {@link materializeSkill} writes, plus each skill's sibling files.
|
|
114
|
+
*/
|
|
115
|
+
export declare function skillsFileSystem(skills: readonly DiscoveredSkill[]): Promise<FileSystem>;
|
|
106
116
|
/**
|
|
107
117
|
* True when `dir` sits strictly inside a git repository (a `.git` exists in
|
|
108
118
|
* an ancestor directory but not in `dir` itself). The Cursor harness resolves
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/internal/workspace.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAmBH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAMlF,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,aAAa,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,IAAI,EAAE,OAAO,CAAC;IACd;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAOjE;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAM9D;AAED;;;;GAIG;AACH,wBAAgB,iCAAiC,CAC/C,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,SAAS,MAAM,EAAE,GAC1B,MAAM,CAOR;AAED,+EAA+E;AAC/E,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,mBAAmB,CAAC;AAE7D;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GAAG,SAAS,GAC/B,MAAM,GAAG,SAAS,CAapB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,GAAE;IAAE,cAAc,EAAE,OAAO,CAAA;CAA8B,GAC/D,MAAM,CA8CR;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GACjC,MAAM,CA6BR;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE;IAAE,cAAc,EAAE,OAAO,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/internal/workspace.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,11 +9,12 @@
|
|
|
9
9
|
* and cloud / grokbot harnesses never read the session workspace.
|
|
10
10
|
*/
|
|
11
11
|
import { execFile } from "node:child_process";
|
|
12
|
-
import { chmod, copyFile, lstat, mkdir, readlink, rm, stat, symlink, writeFile, } from "node:fs/promises";
|
|
12
|
+
import { chmod, copyFile, lstat, mkdir, readFile, readlink, rm, stat, symlink, writeFile, } from "node:fs/promises";
|
|
13
13
|
import { homedir } from "node:os";
|
|
14
14
|
import { dirname, join, parse, relative, resolve, sep } from "node:path";
|
|
15
15
|
import { promisify } from "node:util";
|
|
16
16
|
import { agentStoreKeys, DEPLOYMENT_STORE_MOUNT_PATH } from "../files.js";
|
|
17
|
+
import { readOnlyFs, tempFs } from "../filesystem.js";
|
|
17
18
|
import { MEMORY_DIR_NAME } from "./memory-dir.js";
|
|
18
19
|
import { parseFrontmatter, serializeFrontmatter } from "./frontmatter.js";
|
|
19
20
|
import { buildIdentitySection } from "./prompt-context.js";
|
|
@@ -209,10 +210,55 @@ export function buildAgentsMdContent(agent, options) {
|
|
|
209
210
|
buildAgentToolsCatalog(agent.tools, {
|
|
210
211
|
includeScripts: options.includeScripts,
|
|
211
212
|
}),
|
|
213
|
+
options.skillsIndex === true ? buildSkillsIndex(agent.skills) : "",
|
|
212
214
|
]
|
|
213
215
|
.filter((part) => part !== "")
|
|
214
216
|
.join("\n\n");
|
|
215
217
|
}
|
|
218
|
+
/** Where an authored `fs` sees {@link skillsFileSystem}. */
|
|
219
|
+
export const SKILLS_MOUNT_PATH = "/agent/skills";
|
|
220
|
+
export const FS_AND_ROOT_CONFLICT = "Set `fs` or `root`, not both; `root` is a deprecated alias of `fs`.";
|
|
221
|
+
/**
|
|
222
|
+
* Index of the discovered skills under {@link SKILLS_MOUNT_PATH}. An `fs`
|
|
223
|
+
* agent has no `.cursor/skills/` for the harness to discover, so the
|
|
224
|
+
* instructions name each SKILL.md instead.
|
|
225
|
+
*/
|
|
226
|
+
function buildSkillsIndex(skills) {
|
|
227
|
+
if (skills.length === 0) {
|
|
228
|
+
return "";
|
|
229
|
+
}
|
|
230
|
+
return [
|
|
231
|
+
"## Skills",
|
|
232
|
+
"",
|
|
233
|
+
`Skills are on-demand procedures under \`${SKILLS_MOUNT_PATH}\`. When a task matches a skill's description, read its \`SKILL.md\` before acting on that part of the task and follow it.`,
|
|
234
|
+
"",
|
|
235
|
+
...skills.map((skill) => `- \`${skill.name}\` (\`${SKILLS_MOUNT_PATH}/${skill.name}/SKILL.md\`): ${skill.description.trim()}`),
|
|
236
|
+
].join("\n");
|
|
237
|
+
}
|
|
238
|
+
function skillFilePath(skillName, relativePath) {
|
|
239
|
+
const parts = relativePath.split("/");
|
|
240
|
+
if (relativePath.includes("\0") ||
|
|
241
|
+
relativePath.startsWith("/") ||
|
|
242
|
+
parts.some((part) => part === "" || part === "..")) {
|
|
243
|
+
throw new Error(`Skill "${skillName}" file "${relativePath}" escapes its directory.`);
|
|
244
|
+
}
|
|
245
|
+
return `/${skillName}/${relativePath}`;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* The discovered skills as a read-only tree: `/<name>/SKILL.md`, the same
|
|
249
|
+
* bytes {@link materializeSkill} writes, plus each skill's sibling files.
|
|
250
|
+
*/
|
|
251
|
+
export async function skillsFileSystem(skills) {
|
|
252
|
+
const files = {};
|
|
253
|
+
for (const skill of skills) {
|
|
254
|
+
files[`/${skill.name}/SKILL.md`] = buildSkillMd(skill);
|
|
255
|
+
for (const [relativePath, source] of Object.entries(skill.files)) {
|
|
256
|
+
files[skillFilePath(skill.name, relativePath)] =
|
|
257
|
+
"contents" in source ? source.contents : await readFile(source.sourcePath);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return readOnlyFs(tempFs(files));
|
|
261
|
+
}
|
|
216
262
|
/**
|
|
217
263
|
* True when `dir` sits strictly inside a git repository (a `.git` exists in
|
|
218
264
|
* an ancestor directory but not in `dir` itself). The Cursor harness resolves
|
|
Binary file
|