subharness 0.0.3 → 0.0.5
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/README.md +39 -9
- package/dist/adapters/approval-context.d.ts +2 -0
- package/dist/adapters/approval-context.js +9 -0
- package/dist/adapters/approval-context.js.map +1 -0
- package/dist/adapters/approval-lifetime.d.ts +8 -0
- package/dist/adapters/approval-lifetime.js +50 -0
- package/dist/adapters/approval-lifetime.js.map +1 -0
- package/dist/adapters/claude-approvals.d.ts +4 -0
- package/dist/adapters/claude-approvals.js +32 -0
- package/dist/adapters/claude-approvals.js.map +1 -0
- package/dist/adapters/claude-permissions.js +1 -1
- package/dist/adapters/claude-permissions.js.map +1 -1
- package/dist/adapters/claude-process.d.ts +3 -0
- package/dist/adapters/claude-process.js +11 -1
- package/dist/adapters/claude-process.js.map +1 -1
- package/dist/adapters/claude-result.d.ts +2 -0
- package/dist/adapters/claude-result.js +22 -0
- package/dist/adapters/claude-result.js.map +1 -0
- package/dist/adapters/claude.js +60 -12
- package/dist/adapters/claude.js.map +1 -1
- package/dist/adapters/codex-approvals.d.ts +6 -0
- package/dist/adapters/codex-approvals.js +111 -0
- package/dist/adapters/codex-approvals.js.map +1 -0
- package/dist/adapters/codex.js +36 -3
- package/dist/adapters/codex.js.map +1 -1
- package/dist/adapters/copilot-permissions.d.ts +26 -0
- package/dist/adapters/copilot-permissions.js +121 -0
- package/dist/adapters/copilot-permissions.js.map +1 -0
- package/dist/adapters/copilot-tools.d.ts +12 -0
- package/dist/adapters/copilot-tools.js +61 -0
- package/dist/adapters/copilot-tools.js.map +1 -0
- package/dist/adapters/copilot.d.ts +108 -0
- package/dist/adapters/copilot.js +819 -0
- package/dist/adapters/copilot.js.map +1 -0
- package/dist/adapters/cursor-cli-approvals.d.ts +2 -0
- package/dist/adapters/cursor-cli-approvals.js +83 -0
- package/dist/adapters/cursor-cli-approvals.js.map +1 -0
- package/dist/adapters/cursor-cli-model.d.ts +4 -0
- package/dist/adapters/cursor-cli-model.js +64 -0
- package/dist/adapters/cursor-cli-model.js.map +1 -0
- package/dist/adapters/cursor-cli-session.d.ts +32 -0
- package/dist/adapters/cursor-cli-session.js +316 -0
- package/dist/adapters/cursor-cli-session.js.map +1 -0
- package/dist/adapters/cursor-cli-tools.d.ts +20 -0
- package/dist/adapters/cursor-cli-tools.js +181 -0
- package/dist/adapters/cursor-cli-tools.js.map +1 -0
- package/dist/adapters/cursor-cli.d.ts +2 -0
- package/dist/adapters/cursor-cli.js +306 -0
- package/dist/adapters/cursor-cli.js.map +1 -0
- package/dist/adapters/cursor-model.d.ts +7 -0
- package/dist/adapters/cursor-model.js +67 -0
- package/dist/adapters/cursor-model.js.map +1 -0
- package/dist/adapters/cursor-rpc.d.ts +42 -0
- package/dist/adapters/cursor-rpc.js +271 -0
- package/dist/adapters/cursor-rpc.js.map +1 -0
- package/dist/adapters/cursor-session.d.ts +4 -0
- package/dist/adapters/cursor-session.js +327 -0
- package/dist/adapters/cursor-session.js.map +1 -0
- package/dist/adapters/cursor-startup.d.ts +16 -0
- package/dist/adapters/cursor-startup.js +74 -0
- package/dist/adapters/cursor-startup.js.map +1 -0
- package/dist/adapters/cursor-tools.d.ts +11 -0
- package/dist/adapters/cursor-tools.js +49 -0
- package/dist/adapters/cursor-tools.js.map +1 -0
- package/dist/adapters/cursor.d.ts +6 -0
- package/dist/adapters/cursor.js +17 -0
- package/dist/adapters/cursor.js.map +1 -0
- package/dist/adapters/fx-approvals.d.ts +2 -0
- package/dist/adapters/fx-approvals.js +14 -0
- package/dist/adapters/fx-approvals.js.map +1 -0
- package/dist/adapters/fx-auth.d.ts +12 -2
- package/dist/adapters/fx-auth.js +51 -61
- package/dist/adapters/fx-auth.js.map +1 -1
- package/dist/adapters/fx-profile.d.ts +8 -0
- package/dist/adapters/fx-profile.js +101 -0
- package/dist/adapters/fx-profile.js.map +1 -0
- package/dist/adapters/fx-rpc.d.ts +2 -0
- package/dist/adapters/fx-rpc.js +30 -4
- package/dist/adapters/fx-rpc.js.map +1 -1
- package/dist/adapters/fx-status.d.ts +2 -0
- package/dist/adapters/fx-status.js +96 -0
- package/dist/adapters/fx-status.js.map +1 -0
- package/dist/adapters/fx.js +77 -30
- package/dist/adapters/fx.js.map +1 -1
- package/dist/adapters/opencode-access.d.ts +13 -0
- package/dist/adapters/opencode-access.js +76 -0
- package/dist/adapters/opencode-access.js.map +1 -0
- package/dist/adapters/opencode-config.d.ts +11 -0
- package/dist/adapters/opencode-config.js +238 -0
- package/dist/adapters/opencode-config.js.map +1 -0
- package/dist/adapters/opencode-http.d.ts +28 -0
- package/dist/adapters/opencode-http.js +297 -0
- package/dist/adapters/opencode-http.js.map +1 -0
- package/dist/adapters/opencode-tools.d.ts +19 -0
- package/dist/adapters/opencode-tools.js +127 -0
- package/dist/adapters/opencode-tools.js.map +1 -0
- package/dist/adapters/opencode.d.ts +2 -0
- package/dist/adapters/opencode.js +569 -0
- package/dist/adapters/opencode.js.map +1 -0
- package/dist/adapters/rpc.d.ts +3 -0
- package/dist/adapters/rpc.js +45 -4
- package/dist/adapters/rpc.js.map +1 -1
- package/dist/adapters/types.d.ts +7 -0
- package/dist/adapters/types.js.map +1 -1
- package/dist/approvals/schema.d.ts +4 -0
- package/dist/approvals/schema.js +70 -0
- package/dist/approvals/schema.js.map +1 -0
- package/dist/approvals/types.d.ts +47 -0
- package/dist/approvals/types.js +2 -0
- package/dist/approvals/types.js.map +1 -0
- package/dist/cli/args.d.ts +3 -2
- package/dist/cli/args.js +24 -3
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/dashboard-client.d.ts +5 -1
- package/dist/cli/dashboard-client.js +162 -15
- package/dist/cli/dashboard-client.js.map +1 -1
- package/dist/cli/dashboard-controller.d.ts +7 -0
- package/dist/cli/dashboard-controller.js +27 -0
- package/dist/cli/dashboard-controller.js.map +1 -0
- package/dist/cli/dashboard-detail-view.d.ts +16 -0
- package/dist/cli/dashboard-detail-view.js +162 -0
- package/dist/cli/dashboard-detail-view.js.map +1 -0
- package/dist/cli/dashboard-history-view.d.ts +29 -0
- package/dist/cli/dashboard-history-view.js +211 -0
- package/dist/cli/dashboard-history-view.js.map +1 -0
- package/dist/cli/dashboard-input.d.ts +14 -0
- package/dist/cli/dashboard-input.js +128 -0
- package/dist/cli/dashboard-input.js.map +1 -0
- package/dist/cli/dashboard-layout.d.ts +12 -1
- package/dist/cli/dashboard-layout.js +32 -30
- package/dist/cli/dashboard-layout.js.map +1 -1
- package/dist/cli/dashboard-renderer.d.ts +30 -2
- package/dist/cli/dashboard-renderer.js +125 -7
- package/dist/cli/dashboard-renderer.js.map +1 -1
- package/dist/cli/dashboard-style.d.ts +9 -0
- package/dist/cli/dashboard-style.js +36 -0
- package/dist/cli/dashboard-style.js.map +1 -0
- package/dist/cli/dashboard.d.ts +5 -3
- package/dist/cli/dashboard.js +102 -12
- package/dist/cli/dashboard.js.map +1 -1
- package/dist/cli/help.d.ts +1 -1
- package/dist/cli/help.js +37 -12
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/input.d.ts +1 -0
- package/dist/cli/input.js +23 -17
- package/dist/cli/input.js.map +1 -1
- package/dist/cli/main.js +6 -2
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/output.js +17 -1
- package/dist/cli/output.js.map +1 -1
- package/dist/config/access-provenance.d.ts +10 -0
- package/dist/config/access-provenance.js +31 -0
- package/dist/config/access-provenance.js.map +1 -0
- package/dist/config/access.d.ts +12 -2
- package/dist/config/access.js +125 -27
- package/dist/config/access.js.map +1 -1
- package/dist/config/loader.js +1 -0
- package/dist/config/loader.js.map +1 -1
- package/dist/config/oidc.js +4 -2
- package/dist/config/oidc.js.map +1 -1
- package/dist/config/project.js +2 -1
- package/dist/config/project.js.map +1 -1
- package/dist/config/resolve-access.js +24 -10
- package/dist/config/resolve-access.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/process-diagnostics.d.ts +2 -0
- package/dist/process-diagnostics.js +11 -0
- package/dist/process-diagnostics.js.map +1 -0
- package/dist/runtime/access-errors.d.ts +4 -0
- package/dist/runtime/access-errors.js +25 -0
- package/dist/runtime/access-errors.js.map +1 -0
- package/dist/runtime/approval-registry.d.ts +27 -0
- package/dist/runtime/approval-registry.js +126 -0
- package/dist/runtime/approval-registry.js.map +1 -0
- package/dist/runtime/client.js +54 -14
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/coordinator.d.ts +17 -1
- package/dist/runtime/coordinator.js +124 -6
- package/dist/runtime/coordinator.js.map +1 -1
- package/dist/runtime/dashboard-sanitize.d.ts +2 -0
- package/dist/runtime/dashboard-sanitize.js +7 -0
- package/dist/runtime/dashboard-sanitize.js.map +1 -0
- package/dist/runtime/dashboard.d.ts +43 -1
- package/dist/runtime/dashboard.js +2 -3
- package/dist/runtime/dashboard.js.map +1 -1
- package/dist/runtime/definition.js +11 -1
- package/dist/runtime/definition.js.map +1 -1
- package/dist/runtime/select-native.d.ts +2 -1
- package/dist/runtime/select-native.js +28 -10
- package/dist/runtime/select-native.js.map +1 -1
- package/dist/runtime/service.js +24 -1
- package/dist/runtime/service.js.map +1 -1
- package/dist/runtime/types.d.ts +9 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/runtime/worker-approvals.d.ts +21 -0
- package/dist/runtime/worker-approvals.js +51 -0
- package/dist/runtime/worker-approvals.js.map +1 -0
- package/dist/runtime/worker-client.js +73 -20
- package/dist/runtime/worker-client.js.map +1 -1
- package/dist/runtime/worker-server.d.ts +2 -0
- package/dist/runtime/worker-server.js +39 -10
- package/dist/runtime/worker-server.js.map +1 -1
- package/dist/sdk/definitions.d.ts +4 -1
- package/dist/sdk/definitions.js +16 -2
- package/dist/sdk/definitions.js.map +1 -1
- package/dist/sdk/permission-validation.js +10 -1
- package/dist/sdk/permission-validation.js.map +1 -1
- package/dist/sdk/types.d.ts +29 -1
- package/dist/sdk/types.js.map +1 -1
- package/package.json +4 -1
- package/sdk/access-config.md +86 -4
- package/sdk/adapter-contract.md +7 -13
- package/sdk/additional-harnesses.md +43 -0
- package/sdk/agent-skill.md +7 -4
- package/sdk/agent.md +5 -3
- package/sdk/approvals.md +120 -0
- package/sdk/authentication.md +1 -1
- package/sdk/cli/dashboard-design.md +44 -4
- package/sdk/cli/dashboard-inspection.md +25 -0
- package/sdk/cli/index.md +20 -11
- package/sdk/cli/output.md +10 -4
- package/sdk/completion-notifications.md +2 -0
- package/sdk/config.md +1 -1
- package/sdk/copilot.md +53 -0
- package/sdk/cursor.md +68 -0
- package/sdk/diagnostics.md +29 -0
- package/sdk/distribution.md +53 -1
- package/sdk/evals.md +10 -4
- package/sdk/fx.md +51 -6
- package/sdk/harnesses.md +13 -13
- package/sdk/index.md +4 -2
- package/sdk/message-delivery.md +1 -1
- package/sdk/opencode.md +57 -0
- package/sdk/permissions.md +7 -5
- package/sdk/pr-integration.md +1 -1
- package/sdk/project-team.md +2 -0
- package/sdk/sessions.md +4 -1
- package/sdk/tools.md +1 -1
- package/sdk/v1-runtime.md +6 -6
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { chmod, mkdir, mkdtemp, readFile, rm, stat, writeFile } from "node:fs/promises";
|
|
3
|
+
import { homedir, tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { AgentError } from "../errors.js";
|
|
6
|
+
import { applyCursorCliModel, selectCursorCliModel } from "./cursor-cli-model.js";
|
|
7
|
+
import { CursorCliSession } from "./cursor-cli-session.js";
|
|
8
|
+
import { startCursorCliTools } from "./cursor-cli-tools.js";
|
|
9
|
+
import { CursorRpc, CursorRpcNativeError } from "./cursor-rpc.js";
|
|
10
|
+
const SUPPORTED_VERSION = "2026.09.23-86fc751";
|
|
11
|
+
const CONTROL_TIMEOUT_MS = 15_000;
|
|
12
|
+
const POLICY_KEYS = ["permissions", "approvalMode", "autoAcceptWebSearch", "sandbox", "network"];
|
|
13
|
+
const FIXED_OVERRIDES = [
|
|
14
|
+
"AGENT_CLI_CREDENTIAL_STORE",
|
|
15
|
+
"CURSOR_API_ENDPOINT", "CURSOR_API_BASE_URL", "CURSOR_API_URL", "CURSOR_BACKEND_URL", "CURSOR_WEBSITE_URL",
|
|
16
|
+
"CURSOR_LOCAL_AGENT_BASE_URL", "CURSOR_LOCAL_AGENT_API_KEY", "CURSOR_LOCAL_AGENT_API_KEY_HELPER",
|
|
17
|
+
"CURSOR_LOCAL_AGENT_HEADERS",
|
|
18
|
+
"CURSOR_ENABLE_AUTHLESS", "CURSOR_AGENT_CLI_AUTHLESS_MODE", "CURSOR_AGENT_CLI_LOCAL_MODE",
|
|
19
|
+
"ANTHROPIC_BASE_URL", "ANTHROPIC_AUTH_TOKEN",
|
|
20
|
+
"CURSOR_ENABLE_BEDROCK", "CURSOR_ENABLE_LOCAL_BEDROCK",
|
|
21
|
+
];
|
|
22
|
+
export async function openCursorCli(options) {
|
|
23
|
+
validateOptions(options);
|
|
24
|
+
rejectOverrides(options.env);
|
|
25
|
+
const state = await privateState(options.env);
|
|
26
|
+
let rpc;
|
|
27
|
+
let tools;
|
|
28
|
+
try {
|
|
29
|
+
const version = (await runControl("cursor-agent", ["--version"], options.cwd, state.env)).trim();
|
|
30
|
+
if (version !== SUPPORTED_VERSION) {
|
|
31
|
+
throw new AgentError("HARNESS_UNAVAILABLE", `Cursor subscription access requires cursor-agent ${SUPPORTED_VERSION}.`);
|
|
32
|
+
}
|
|
33
|
+
verifyStatus(await runControl("cursor-agent", ["status", "--format", "json"], options.cwd, state.env));
|
|
34
|
+
tools = await startCursorCliTools(options.agent);
|
|
35
|
+
const startedRpc = new CursorRpc("cursor-agent", ["acp"], options.cwd, state.env);
|
|
36
|
+
rpc = startedRpc;
|
|
37
|
+
let startupFailure;
|
|
38
|
+
startedRpc.setFailureHandler(error => { startupFailure ??= error; });
|
|
39
|
+
startedRpc.onMessage = message => {
|
|
40
|
+
if (message.id === undefined)
|
|
41
|
+
return;
|
|
42
|
+
try {
|
|
43
|
+
startedRpc.send({ id: message.id, result: { outcome: { outcome: "cancelled" } } });
|
|
44
|
+
}
|
|
45
|
+
catch { }
|
|
46
|
+
startupFailure ??= new AgentError("INPUT_REQUIRED", "Cursor requested interactive input during startup.");
|
|
47
|
+
};
|
|
48
|
+
tools.onFailure(error => {
|
|
49
|
+
startupFailure ??= error;
|
|
50
|
+
void startedRpc.close().catch(() => { });
|
|
51
|
+
});
|
|
52
|
+
const initialized = record(await boundedControl(startedRpc.request("initialize", {
|
|
53
|
+
protocolVersion: 1,
|
|
54
|
+
clientCapabilities: { _meta: { parameterizedModelPicker: true } },
|
|
55
|
+
clientInfo: { name: "subharness", version: "0.0.3" },
|
|
56
|
+
}, CONTROL_TIMEOUT_MS), "Cursor ACP initialization timed out."), "Cursor returned an invalid ACP initialization response.");
|
|
57
|
+
if (initialized.protocolVersion !== 1) {
|
|
58
|
+
throw new AgentError("HARNESS_UNAVAILABLE", "The installed Cursor ACP protocol is not compatible with version 1.");
|
|
59
|
+
}
|
|
60
|
+
let created;
|
|
61
|
+
try {
|
|
62
|
+
created = record(await boundedControl(startedRpc.request("session/new", {
|
|
63
|
+
cwd: options.cwd,
|
|
64
|
+
mcpServers: tools.descriptor ? [tools.descriptor] : [],
|
|
65
|
+
}, CONTROL_TIMEOUT_MS), "Cursor native session creation timed out."), "Cursor returned an invalid native session.");
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
if (error instanceof CursorRpcNativeError) {
|
|
69
|
+
if (error.nativeCode === -32000) {
|
|
70
|
+
throw new AgentError("ACCESS_UNAVAILABLE", "Cursor could not use the saved native login. Run cursor-agent login outside Subharness.");
|
|
71
|
+
}
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
if (typeof created.sessionId !== "string" || !created.sessionId) {
|
|
77
|
+
throw new AgentError("PROTOCOL_ERROR", "Cursor did not return a native session identifier.");
|
|
78
|
+
}
|
|
79
|
+
await tools.waitReady(CONTROL_TIMEOUT_MS);
|
|
80
|
+
const selected = selectCursorCliModel(created, options.harness.model);
|
|
81
|
+
await boundedControl(applyCursorCliModel(startedRpc, created.sessionId, selected), "Cursor model configuration timed out.");
|
|
82
|
+
if (startupFailure)
|
|
83
|
+
throw startupFailure;
|
|
84
|
+
return new CursorCliSession(startedRpc, created.sessionId, selected, options, tools, state.cleanup);
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
let closeFailure;
|
|
88
|
+
try {
|
|
89
|
+
await rpc?.close();
|
|
90
|
+
}
|
|
91
|
+
catch (failure) {
|
|
92
|
+
closeFailure = failure;
|
|
93
|
+
}
|
|
94
|
+
await tools?.close().catch(() => { });
|
|
95
|
+
if ((!rpc || !closeFailure) && !(error instanceof AgentError && error.code === "CANCELLATION_FAILED"))
|
|
96
|
+
await state.cleanup();
|
|
97
|
+
if (closeFailure instanceof AgentError)
|
|
98
|
+
throw closeFailure;
|
|
99
|
+
if (error instanceof AgentError)
|
|
100
|
+
throw error;
|
|
101
|
+
throw new AgentError("HARNESS_UNAVAILABLE", "Cursor subscription access could not start.");
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function validateOptions(options) {
|
|
105
|
+
const harness = options.harness;
|
|
106
|
+
if (harness.kind !== "cursor")
|
|
107
|
+
throw new AgentError("INVALID_CONFIG", "Cursor received configuration for a different harness.");
|
|
108
|
+
if (typeof harness.model !== "string" || !harness.model.trim())
|
|
109
|
+
throw new AgentError("INVALID_CONFIG", "Cursor requires an explicit nonempty model.");
|
|
110
|
+
if (options.access.type !== "subscription")
|
|
111
|
+
throw new AgentError("INVALID_CONFIG", "Cursor CLI access requires an explicit subscription connection.");
|
|
112
|
+
if (harness.sandboxMode !== undefined)
|
|
113
|
+
throw new AgentError("UNSUPPORTED_OPTION", "Cursor subscription access does not expose a verified sandbox control.");
|
|
114
|
+
if (process.platform === "win32")
|
|
115
|
+
throw new AgentError("UNSUPPORTED_OPTION", "Cursor subscription access is supported only on macOS and Linux.");
|
|
116
|
+
}
|
|
117
|
+
function rejectOverrides(env) {
|
|
118
|
+
for (const key of Object.keys(env)) {
|
|
119
|
+
if ((FIXED_OVERRIDES.includes(key) || key.startsWith("CURSOR_BEDROCK_")) && env[key]?.trim()) {
|
|
120
|
+
throw new AgentError("UNSUPPORTED_OPTION", "Cursor endpoint and alternate-provider overrides are unsupported for subscription access.");
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async function privateState(source) {
|
|
125
|
+
const root = await mkdtemp(join(tmpdir(), "subharness-cursor-"));
|
|
126
|
+
await chmod(root, 0o700);
|
|
127
|
+
const config = join(root, "config");
|
|
128
|
+
const data = join(root, "data");
|
|
129
|
+
await mkdir(config, { mode: 0o700 });
|
|
130
|
+
await mkdir(data, { mode: 0o700 });
|
|
131
|
+
try {
|
|
132
|
+
const policy = await nativePolicy(source);
|
|
133
|
+
if (Object.keys(policy).length)
|
|
134
|
+
await writeFile(join(config, "cli-config.json"), `${JSON.stringify(policy, null, 2)}\n`, { mode: 0o600 });
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
await rm(root, { recursive: true, force: true });
|
|
138
|
+
if (error instanceof AgentError)
|
|
139
|
+
throw error;
|
|
140
|
+
throw new AgentError("INVALID_CONFIG", "Cursor native permission and network configuration could not be isolated.");
|
|
141
|
+
}
|
|
142
|
+
const env = { ...source, CURSOR_CONFIG_DIR: config, CURSOR_DATA_DIR: data };
|
|
143
|
+
delete env.CURSOR_API_KEY;
|
|
144
|
+
delete env.CURSOR_AUTH_TOKEN;
|
|
145
|
+
return { env, cleanup: async () => { await rm(root, { recursive: true, force: true }); } };
|
|
146
|
+
}
|
|
147
|
+
async function nativePolicy(env) {
|
|
148
|
+
const configured = env.CURSOR_CONFIG_DIR?.trim();
|
|
149
|
+
const home = env.HOME?.trim() || homedir();
|
|
150
|
+
const base = configured || (env.XDG_CONFIG_HOME?.trim() ? join(env.XDG_CONFIG_HOME, "cursor") : join(home, ".cursor"));
|
|
151
|
+
const path = join(base, "cli-config.json");
|
|
152
|
+
let raw;
|
|
153
|
+
try {
|
|
154
|
+
const info = await stat(path);
|
|
155
|
+
if (info.size > 1024 * 1024)
|
|
156
|
+
throw new AgentError("INVALID_CONFIG", "Cursor native configuration is too large to isolate safely.");
|
|
157
|
+
raw = await readFile(path, "utf8");
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
if (error.code === "ENOENT")
|
|
161
|
+
return {};
|
|
162
|
+
throw error;
|
|
163
|
+
}
|
|
164
|
+
let value;
|
|
165
|
+
try {
|
|
166
|
+
value = JSON.parse(raw);
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
throw new AgentError("INVALID_CONFIG", "Cursor native configuration is malformed.");
|
|
170
|
+
}
|
|
171
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
172
|
+
throw new AgentError("INVALID_CONFIG", "Cursor native configuration is malformed.");
|
|
173
|
+
const source = value;
|
|
174
|
+
const retained = {};
|
|
175
|
+
for (const key of POLICY_KEYS)
|
|
176
|
+
if (source[key] !== undefined)
|
|
177
|
+
retained[key] = structuredClone(source[key]);
|
|
178
|
+
return retained;
|
|
179
|
+
}
|
|
180
|
+
function verifyStatus(stdout) {
|
|
181
|
+
let value;
|
|
182
|
+
try {
|
|
183
|
+
value = JSON.parse(stdout);
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
throw new AgentError("PROTOCOL_ERROR", "Cursor returned invalid native authentication status.");
|
|
187
|
+
}
|
|
188
|
+
const status = record(value, "Cursor returned invalid native authentication status.");
|
|
189
|
+
const authenticated = status.status === "authenticated" && status.isAuthenticated === true
|
|
190
|
+
&& status.hasAccessToken === true && status.hasRefreshToken === true;
|
|
191
|
+
const unauthenticated = (status.status === "unauthenticated" && status.isAuthenticated === false
|
|
192
|
+
&& status.hasAccessToken === false && status.hasRefreshToken === false)
|
|
193
|
+
|| (status.status === "partially-authenticated" && status.isAuthenticated === false
|
|
194
|
+
&& status.hasAccessToken === true && status.hasRefreshToken === false);
|
|
195
|
+
if (authenticated)
|
|
196
|
+
return;
|
|
197
|
+
if (unauthenticated)
|
|
198
|
+
throw new AgentError("ACCESS_UNAVAILABLE", "Cursor native login is unavailable. Run cursor-agent login outside Subharness.");
|
|
199
|
+
throw new AgentError("PROTOCOL_ERROR", "Cursor returned invalid native authentication status.");
|
|
200
|
+
}
|
|
201
|
+
function record(value, message) {
|
|
202
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
203
|
+
throw new AgentError("PROTOCOL_ERROR", message);
|
|
204
|
+
return value;
|
|
205
|
+
}
|
|
206
|
+
function runControl(executable, args, cwd, env) {
|
|
207
|
+
return new Promise((resolve, reject) => {
|
|
208
|
+
const child = spawn(executable, args, { cwd, env, detached: true, stdio: ["ignore", "pipe", "pipe"] });
|
|
209
|
+
const chunks = [];
|
|
210
|
+
let bytes = 0;
|
|
211
|
+
let failure;
|
|
212
|
+
let spawnFailure;
|
|
213
|
+
let closed = false;
|
|
214
|
+
let exitCode = null;
|
|
215
|
+
let settleExit;
|
|
216
|
+
let forceRetirement;
|
|
217
|
+
const exited = new Promise(accept => { settleExit = accept; });
|
|
218
|
+
const forced = new Promise(accept => { forceRetirement = accept; });
|
|
219
|
+
const timer = setTimeout(() => {
|
|
220
|
+
failure ??= new AgentError("HARNESS_FAILED", "Cursor native readiness check timed out.");
|
|
221
|
+
forceRetirement();
|
|
222
|
+
}, CONTROL_TIMEOUT_MS);
|
|
223
|
+
timer.unref();
|
|
224
|
+
child.stdout.on("data", chunk => {
|
|
225
|
+
bytes += chunk.length;
|
|
226
|
+
if (bytes > 1024 * 1024) {
|
|
227
|
+
failure = new AgentError("PROTOCOL_ERROR", "Cursor returned oversized native control output.");
|
|
228
|
+
forceRetirement();
|
|
229
|
+
}
|
|
230
|
+
else
|
|
231
|
+
chunks.push(chunk);
|
|
232
|
+
});
|
|
233
|
+
child.stderr.resume();
|
|
234
|
+
child.once("error", error => {
|
|
235
|
+
spawnFailure = error;
|
|
236
|
+
settleExit();
|
|
237
|
+
});
|
|
238
|
+
child.once("close", code => {
|
|
239
|
+
closed = true;
|
|
240
|
+
exitCode = code;
|
|
241
|
+
settleExit();
|
|
242
|
+
});
|
|
243
|
+
void (async () => {
|
|
244
|
+
const winner = await Promise.race([exited.then(() => "exit"), forced.then(() => "force")]);
|
|
245
|
+
clearTimeout(timer);
|
|
246
|
+
if (winner === "force" || !groupGone(child.pid)) {
|
|
247
|
+
try {
|
|
248
|
+
if (child.pid !== undefined)
|
|
249
|
+
process.kill(-child.pid, "SIGTERM");
|
|
250
|
+
}
|
|
251
|
+
catch { }
|
|
252
|
+
if (!await waitForControlExit(() => closed && groupGone(child.pid), 250)) {
|
|
253
|
+
try {
|
|
254
|
+
if (child.pid !== undefined)
|
|
255
|
+
process.kill(-child.pid, "SIGKILL");
|
|
256
|
+
}
|
|
257
|
+
catch { }
|
|
258
|
+
if (!await waitForControlExit(() => closed && groupGone(child.pid), 1_000)) {
|
|
259
|
+
return reject(new AgentError("CANCELLATION_FAILED", "Cursor native readiness process termination could not be confirmed."));
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (spawnFailure) {
|
|
264
|
+
return reject(new AgentError(spawnFailure.code === "ENOENT" ? "HARNESS_UNAVAILABLE" : "HARNESS_FAILED", "Cannot start the Cursor native executable."));
|
|
265
|
+
}
|
|
266
|
+
if (failure)
|
|
267
|
+
return reject(failure);
|
|
268
|
+
if (exitCode !== 0)
|
|
269
|
+
return reject(new AgentError("HARNESS_FAILED", "Cursor native readiness check failed."));
|
|
270
|
+
resolve(Buffer.concat(chunks).toString("utf8"));
|
|
271
|
+
})().catch(() => reject(new AgentError("HARNESS_FAILED", "Cursor native readiness check failed.")));
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
function groupGone(pid) {
|
|
275
|
+
if (pid === undefined)
|
|
276
|
+
return true;
|
|
277
|
+
try {
|
|
278
|
+
process.kill(-pid, 0);
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
catch (error) {
|
|
282
|
+
return error.code === "ESRCH";
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
async function waitForControlExit(retired, milliseconds) {
|
|
286
|
+
const deadline = Date.now() + milliseconds;
|
|
287
|
+
while (Date.now() < deadline) {
|
|
288
|
+
if (retired())
|
|
289
|
+
return true;
|
|
290
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
291
|
+
}
|
|
292
|
+
return retired();
|
|
293
|
+
}
|
|
294
|
+
async function boundedControl(promise, message) {
|
|
295
|
+
let timer;
|
|
296
|
+
try {
|
|
297
|
+
return await Promise.race([promise, new Promise((_resolve, reject) => {
|
|
298
|
+
timer = setTimeout(() => reject(new AgentError("HARNESS_FAILED", message)), CONTROL_TIMEOUT_MS);
|
|
299
|
+
timer.unref();
|
|
300
|
+
})]);
|
|
301
|
+
}
|
|
302
|
+
finally {
|
|
303
|
+
clearTimeout(timer);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
//# sourceMappingURL=cursor-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-cli.js","sourceRoot":"","sources":["../../src/adapters/cursor-cli.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { chmod, mkdir, mkdtemp, readFile, rm, stat, writeFile } from \"node:fs/promises\";\nimport { homedir, tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { AgentError } from \"../errors.js\";\nimport type { AdapterOptions, NativeSession } from \"./types.js\";\nimport { applyCursorCliModel, selectCursorCliModel } from \"./cursor-cli-model.js\";\nimport { CursorCliSession } from \"./cursor-cli-session.js\";\nimport { startCursorCliTools } from \"./cursor-cli-tools.js\";\nimport { CursorRpc, CursorRpcNativeError, type CursorRpcEnvelope } from \"./cursor-rpc.js\";\n\nconst SUPPORTED_VERSION = \"2026.09.23-86fc751\";\nconst CONTROL_TIMEOUT_MS = 15_000;\nconst POLICY_KEYS = [\"permissions\", \"approvalMode\", \"autoAcceptWebSearch\", \"sandbox\", \"network\"] as const;\nconst FIXED_OVERRIDES = [\n \"AGENT_CLI_CREDENTIAL_STORE\",\n \"CURSOR_API_ENDPOINT\", \"CURSOR_API_BASE_URL\", \"CURSOR_API_URL\", \"CURSOR_BACKEND_URL\", \"CURSOR_WEBSITE_URL\",\n \"CURSOR_LOCAL_AGENT_BASE_URL\", \"CURSOR_LOCAL_AGENT_API_KEY\", \"CURSOR_LOCAL_AGENT_API_KEY_HELPER\",\n \"CURSOR_LOCAL_AGENT_HEADERS\",\n \"CURSOR_ENABLE_AUTHLESS\", \"CURSOR_AGENT_CLI_AUTHLESS_MODE\", \"CURSOR_AGENT_CLI_LOCAL_MODE\",\n \"ANTHROPIC_BASE_URL\", \"ANTHROPIC_AUTH_TOKEN\",\n \"CURSOR_ENABLE_BEDROCK\", \"CURSOR_ENABLE_LOCAL_BEDROCK\",\n] as const;\n\ntype PrivateState = { env: NodeJS.ProcessEnv; cleanup(): Promise<void> };\n\nexport async function openCursorCli(options: AdapterOptions): Promise<NativeSession> {\n validateOptions(options);\n rejectOverrides(options.env);\n const state = await privateState(options.env);\n let rpc: CursorRpc | undefined;\n let tools: Awaited<ReturnType<typeof startCursorCliTools>> | undefined;\n try {\n const version = (await runControl(\"cursor-agent\", [\"--version\"], options.cwd, state.env)).trim();\n if (version !== SUPPORTED_VERSION) {\n throw new AgentError(\"HARNESS_UNAVAILABLE\", `Cursor subscription access requires cursor-agent ${SUPPORTED_VERSION}.`);\n }\n verifyStatus(await runControl(\"cursor-agent\", [\"status\", \"--format\", \"json\"], options.cwd, state.env));\n tools = await startCursorCliTools(options.agent);\n const startedRpc = new CursorRpc(\"cursor-agent\", [\"acp\"], options.cwd, state.env);\n rpc = startedRpc;\n let startupFailure: AgentError | undefined;\n startedRpc.setFailureHandler(error => { startupFailure ??= error; });\n startedRpc.onMessage = message => {\n if (message.id === undefined) return;\n try { startedRpc.send({ id: message.id, result: { outcome: { outcome: \"cancelled\" } } }); } catch {}\n startupFailure ??= new AgentError(\"INPUT_REQUIRED\", \"Cursor requested interactive input during startup.\");\n };\n tools.onFailure(error => {\n startupFailure ??= error;\n void startedRpc.close().catch(() => {});\n });\n const initialized = record(await boundedControl(startedRpc.request(\"initialize\", {\n protocolVersion: 1,\n clientCapabilities: { _meta: { parameterizedModelPicker: true } },\n clientInfo: { name: \"subharness\", version: \"0.0.3\" },\n }, CONTROL_TIMEOUT_MS), \"Cursor ACP initialization timed out.\"), \"Cursor returned an invalid ACP initialization response.\");\n if (initialized.protocolVersion !== 1) {\n throw new AgentError(\"HARNESS_UNAVAILABLE\", \"The installed Cursor ACP protocol is not compatible with version 1.\");\n }\n let created: Record<string, any>;\n try {\n created = record(await boundedControl(startedRpc.request(\"session/new\", {\n cwd: options.cwd,\n mcpServers: tools.descriptor ? [tools.descriptor] : [],\n }, CONTROL_TIMEOUT_MS), \"Cursor native session creation timed out.\"), \"Cursor returned an invalid native session.\");\n } catch (error) {\n if (error instanceof CursorRpcNativeError) {\n if (error.nativeCode === -32000) {\n throw new AgentError(\"ACCESS_UNAVAILABLE\", \"Cursor could not use the saved native login. Run cursor-agent login outside Subharness.\");\n }\n throw error;\n }\n throw error;\n }\n if (typeof created.sessionId !== \"string\" || !created.sessionId) {\n throw new AgentError(\"PROTOCOL_ERROR\", \"Cursor did not return a native session identifier.\");\n }\n await tools.waitReady(CONTROL_TIMEOUT_MS);\n const selected = selectCursorCliModel(created, options.harness.model!);\n await boundedControl(applyCursorCliModel(startedRpc, created.sessionId, selected), \"Cursor model configuration timed out.\");\n if (startupFailure) throw startupFailure;\n return new CursorCliSession(startedRpc, created.sessionId, selected, options, tools, state.cleanup);\n } catch (error) {\n let closeFailure: unknown;\n try { await rpc?.close(); } catch (failure) { closeFailure = failure; }\n await tools?.close().catch(() => {});\n if ((!rpc || !closeFailure) && !(error instanceof AgentError && error.code === \"CANCELLATION_FAILED\")) await state.cleanup();\n if (closeFailure instanceof AgentError) throw closeFailure;\n if (error instanceof AgentError) throw error;\n throw new AgentError(\"HARNESS_UNAVAILABLE\", \"Cursor subscription access could not start.\");\n }\n}\n\nfunction validateOptions(options: AdapterOptions): void {\n const harness = options.harness;\n if (harness.kind !== \"cursor\") throw new AgentError(\"INVALID_CONFIG\", \"Cursor received configuration for a different harness.\");\n if (typeof harness.model !== \"string\" || !harness.model.trim()) throw new AgentError(\"INVALID_CONFIG\", \"Cursor requires an explicit nonempty model.\");\n if (options.access.type !== \"subscription\") throw new AgentError(\"INVALID_CONFIG\", \"Cursor CLI access requires an explicit subscription connection.\");\n if (harness.sandboxMode !== undefined) throw new AgentError(\"UNSUPPORTED_OPTION\", \"Cursor subscription access does not expose a verified sandbox control.\");\n if (process.platform === \"win32\") throw new AgentError(\"UNSUPPORTED_OPTION\", \"Cursor subscription access is supported only on macOS and Linux.\");\n}\n\nfunction rejectOverrides(env: NodeJS.ProcessEnv): void {\n for (const key of Object.keys(env)) {\n if ((FIXED_OVERRIDES.includes(key as any) || key.startsWith(\"CURSOR_BEDROCK_\")) && env[key]?.trim()) {\n throw new AgentError(\"UNSUPPORTED_OPTION\", \"Cursor endpoint and alternate-provider overrides are unsupported for subscription access.\");\n }\n }\n}\n\nasync function privateState(source: NodeJS.ProcessEnv): Promise<PrivateState> {\n const root = await mkdtemp(join(tmpdir(), \"subharness-cursor-\"));\n await chmod(root, 0o700);\n const config = join(root, \"config\");\n const data = join(root, \"data\");\n await mkdir(config, { mode: 0o700 });\n await mkdir(data, { mode: 0o700 });\n try {\n const policy = await nativePolicy(source);\n if (Object.keys(policy).length) await writeFile(join(config, \"cli-config.json\"), `${JSON.stringify(policy, null, 2)}\\n`, { mode: 0o600 });\n } catch (error) {\n await rm(root, { recursive: true, force: true });\n if (error instanceof AgentError) throw error;\n throw new AgentError(\"INVALID_CONFIG\", \"Cursor native permission and network configuration could not be isolated.\");\n }\n const env: NodeJS.ProcessEnv = { ...source, CURSOR_CONFIG_DIR: config, CURSOR_DATA_DIR: data };\n delete env.CURSOR_API_KEY;\n delete env.CURSOR_AUTH_TOKEN;\n return { env, cleanup: async () => { await rm(root, { recursive: true, force: true }); } };\n}\n\nasync function nativePolicy(env: NodeJS.ProcessEnv): Promise<Record<string, unknown>> {\n const configured = env.CURSOR_CONFIG_DIR?.trim();\n const home = env.HOME?.trim() || homedir();\n const base = configured || (env.XDG_CONFIG_HOME?.trim() ? join(env.XDG_CONFIG_HOME, \"cursor\") : join(home, \".cursor\"));\n const path = join(base, \"cli-config.json\");\n let raw: string;\n try {\n const info = await stat(path);\n if (info.size > 1024 * 1024) throw new AgentError(\"INVALID_CONFIG\", \"Cursor native configuration is too large to isolate safely.\");\n raw = await readFile(path, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return {};\n throw error;\n }\n let value: unknown;\n try { value = JSON.parse(raw); } catch { throw new AgentError(\"INVALID_CONFIG\", \"Cursor native configuration is malformed.\"); }\n if (!value || typeof value !== \"object\" || Array.isArray(value)) throw new AgentError(\"INVALID_CONFIG\", \"Cursor native configuration is malformed.\");\n const source = value as Record<string, unknown>;\n const retained: Record<string, unknown> = {};\n for (const key of POLICY_KEYS) if (source[key] !== undefined) retained[key] = structuredClone(source[key]);\n return retained;\n}\n\nfunction verifyStatus(stdout: string): void {\n let value: unknown;\n try { value = JSON.parse(stdout); } catch { throw new AgentError(\"PROTOCOL_ERROR\", \"Cursor returned invalid native authentication status.\"); }\n const status = record(value, \"Cursor returned invalid native authentication status.\");\n const authenticated = status.status === \"authenticated\" && status.isAuthenticated === true\n && status.hasAccessToken === true && status.hasRefreshToken === true;\n const unauthenticated = (status.status === \"unauthenticated\" && status.isAuthenticated === false\n && status.hasAccessToken === false && status.hasRefreshToken === false)\n || (status.status === \"partially-authenticated\" && status.isAuthenticated === false\n && status.hasAccessToken === true && status.hasRefreshToken === false);\n if (authenticated) return;\n if (unauthenticated) throw new AgentError(\"ACCESS_UNAVAILABLE\", \"Cursor native login is unavailable. Run cursor-agent login outside Subharness.\");\n throw new AgentError(\"PROTOCOL_ERROR\", \"Cursor returned invalid native authentication status.\");\n}\n\nfunction record(value: unknown, message: string): Record<string, any> {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) throw new AgentError(\"PROTOCOL_ERROR\", message);\n return value as Record<string, any>;\n}\n\nfunction runControl(executable: string, args: string[], cwd: string, env: NodeJS.ProcessEnv): Promise<string> {\n return new Promise((resolve, reject) => {\n const child = spawn(executable, args, { cwd, env, detached: true, stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n const chunks: Buffer[] = [];\n let bytes = 0;\n let failure: AgentError | undefined;\n let spawnFailure: NodeJS.ErrnoException | undefined;\n let closed = false;\n let exitCode: number | null = null;\n let settleExit!: () => void;\n let forceRetirement!: () => void;\n const exited = new Promise<void>(accept => { settleExit = accept; });\n const forced = new Promise<void>(accept => { forceRetirement = accept; });\n const timer = setTimeout(() => {\n failure ??= new AgentError(\"HARNESS_FAILED\", \"Cursor native readiness check timed out.\");\n forceRetirement();\n }, CONTROL_TIMEOUT_MS);\n timer.unref();\n child.stdout.on(\"data\", chunk => {\n bytes += chunk.length;\n if (bytes > 1024 * 1024) {\n failure = new AgentError(\"PROTOCOL_ERROR\", \"Cursor returned oversized native control output.\");\n forceRetirement();\n } else chunks.push(chunk);\n });\n child.stderr.resume();\n child.once(\"error\", error => {\n spawnFailure = error as NodeJS.ErrnoException;\n settleExit();\n });\n child.once(\"close\", code => {\n closed = true;\n exitCode = code;\n settleExit();\n });\n void (async () => {\n const winner = await Promise.race([exited.then(() => \"exit\" as const), forced.then(() => \"force\" as const)]);\n clearTimeout(timer);\n if (winner === \"force\" || !groupGone(child.pid)) {\n try { if (child.pid !== undefined) process.kill(-child.pid, \"SIGTERM\"); } catch {}\n if (!await waitForControlExit(() => closed && groupGone(child.pid), 250)) {\n try { if (child.pid !== undefined) process.kill(-child.pid, \"SIGKILL\"); } catch {}\n if (!await waitForControlExit(() => closed && groupGone(child.pid), 1_000)) {\n return reject(new AgentError(\"CANCELLATION_FAILED\", \"Cursor native readiness process termination could not be confirmed.\"));\n }\n }\n }\n if (spawnFailure) {\n return reject(new AgentError(spawnFailure.code === \"ENOENT\" ? \"HARNESS_UNAVAILABLE\" : \"HARNESS_FAILED\", \"Cannot start the Cursor native executable.\"));\n }\n if (failure) return reject(failure);\n if (exitCode !== 0) return reject(new AgentError(\"HARNESS_FAILED\", \"Cursor native readiness check failed.\"));\n resolve(Buffer.concat(chunks).toString(\"utf8\"));\n })().catch(() => reject(new AgentError(\"HARNESS_FAILED\", \"Cursor native readiness check failed.\")));\n });\n}\n\nfunction groupGone(pid: number | undefined): boolean {\n if (pid === undefined) return true;\n try { process.kill(-pid, 0); return false; }\n catch (error) { return (error as NodeJS.ErrnoException).code === \"ESRCH\"; }\n}\n\nasync function waitForControlExit(retired: () => boolean, milliseconds: number): Promise<boolean> {\n const deadline = Date.now() + milliseconds;\n while (Date.now() < deadline) {\n if (retired()) return true;\n await new Promise(resolve => setTimeout(resolve, 10));\n }\n return retired();\n}\n\nasync function boundedControl<T>(promise: Promise<T>, message: string): Promise<T> {\n let timer: NodeJS.Timeout | undefined;\n try {\n return await Promise.race([promise, new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => reject(new AgentError(\"HARNESS_FAILED\", message)), CONTROL_TIMEOUT_MS);\n timer.unref();\n })]);\n } finally { clearTimeout(timer); }\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { RunResult, RunStatus, SDKModel, SDKUser } from "@cursor/sdk";
|
|
2
|
+
export declare function validateCursorAccount(value: unknown): asserts value is SDKUser;
|
|
3
|
+
export declare function validateCursorCatalog(value: unknown): asserts value is SDKModel[];
|
|
4
|
+
export declare function resolveCursorModel(catalog: SDKModel[], requested: string): SDKModel;
|
|
5
|
+
export declare function isCursorTerminalStatus(status: unknown): status is Exclude<RunStatus, "running">;
|
|
6
|
+
export declare function validateCursorRunResult(value: unknown): asserts value is RunResult;
|
|
7
|
+
export declare function cursorTerminalText(result: RunResult, selected: SDKModel): string;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { AgentError } from "../errors.js";
|
|
2
|
+
export function validateCursorAccount(value) {
|
|
3
|
+
if (!plainObject(value) || typeof value.apiKeyName !== "string" || typeof value.createdAt !== "string"
|
|
4
|
+
|| (value.userId !== undefined && typeof value.userId !== "number")
|
|
5
|
+
|| (value.userEmail !== undefined && typeof value.userEmail !== "string")
|
|
6
|
+
|| (value.userFirstName !== undefined && typeof value.userFirstName !== "string")
|
|
7
|
+
|| (value.userLastName !== undefined && typeof value.userLastName !== "string")) {
|
|
8
|
+
throw new AgentError("PROTOCOL_ERROR", "Cursor returned malformed account metadata.");
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export function validateCursorCatalog(value) {
|
|
12
|
+
if (!Array.isArray(value) || value.some(model => !plainObject(model)
|
|
13
|
+
|| typeof model.id !== "string" || !model.id
|
|
14
|
+
|| typeof model.displayName !== "string"
|
|
15
|
+
|| (model.aliases !== undefined && (!Array.isArray(model.aliases) || model.aliases.some(alias => typeof alias !== "string"))))) {
|
|
16
|
+
throw new AgentError("PROTOCOL_ERROR", "Cursor returned a malformed model catalog.");
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function resolveCursorModel(catalog, requested) {
|
|
20
|
+
if (AUTO_MODEL_IDS.has(requested)) {
|
|
21
|
+
throw new AgentError("UNSUPPORTED_OPTION", "Cursor Auto model routing does not retain a concrete model.");
|
|
22
|
+
}
|
|
23
|
+
const matches = catalog.filter(model => model.id === requested || model.aliases?.includes(requested));
|
|
24
|
+
if (matches.length !== 1)
|
|
25
|
+
throw new AgentError("INVALID_CONFIG", "The selected Cursor model is not available in the account catalog.");
|
|
26
|
+
const selected = matches[0];
|
|
27
|
+
if (AUTO_MODEL_IDS.has(selected.id)) {
|
|
28
|
+
throw new AgentError("UNSUPPORTED_OPTION", "Cursor Auto model routing does not retain a concrete model.");
|
|
29
|
+
}
|
|
30
|
+
return selected;
|
|
31
|
+
}
|
|
32
|
+
const AUTO_MODEL_IDS = new Set(["auto", "auto-smart"]);
|
|
33
|
+
export function isCursorTerminalStatus(status) {
|
|
34
|
+
return status === "finished" || status === "error" || status === "cancelled";
|
|
35
|
+
}
|
|
36
|
+
export function validateCursorRunResult(value) {
|
|
37
|
+
if (!plainObject(value) || typeof value.id !== "string" || !isCursorTerminalStatus(value.status)
|
|
38
|
+
|| (value.requestId !== undefined && typeof value.requestId !== "string")
|
|
39
|
+
|| (value.result !== undefined && typeof value.result !== "string")
|
|
40
|
+
|| (value.error !== undefined && (!plainObject(value.error) || typeof value.error.message !== "string"
|
|
41
|
+
|| (value.error.code !== undefined && typeof value.error.code !== "string")))
|
|
42
|
+
|| (value.model !== undefined && (!plainObject(value.model) || typeof value.model.id !== "string"))) {
|
|
43
|
+
throw new AgentError("PROTOCOL_ERROR", "Cursor returned a malformed native result.");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export function cursorTerminalText(result, selected) {
|
|
47
|
+
const expected = new Set([selected.id, ...(selected.aliases ?? [])]);
|
|
48
|
+
if (result.model && !expected.has(result.model.id)) {
|
|
49
|
+
throw new AgentError("INVALID_CONFIG", "Cursor selected a different model than requested.");
|
|
50
|
+
}
|
|
51
|
+
if (result.status === "finished") {
|
|
52
|
+
const text = result.result ?? "";
|
|
53
|
+
if (Buffer.byteLength(text, "utf8") > 1024 * 1024)
|
|
54
|
+
throw new AgentError("RESPONSE_TOO_LARGE", "The Cursor response exceeds 1 MiB.");
|
|
55
|
+
return text;
|
|
56
|
+
}
|
|
57
|
+
if (result.status === "cancelled")
|
|
58
|
+
throw new AgentError("INTERRUPTED", "The Cursor turn was interrupted.");
|
|
59
|
+
throw new AgentError("HARNESS_ERROR", "Cursor could not complete the turn.");
|
|
60
|
+
}
|
|
61
|
+
function plainObject(value) {
|
|
62
|
+
if (typeof value !== "object" || value === null)
|
|
63
|
+
return false;
|
|
64
|
+
const prototype = Object.getPrototypeOf(value);
|
|
65
|
+
return prototype === Object.prototype || prototype === null;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=cursor-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-model.js","sourceRoot":"","sources":["../../src/adapters/cursor-model.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RunResult, RunStatus, SDKModel, SDKUser } from \"@cursor/sdk\";\nimport { AgentError } from \"../errors.js\";\n\nexport function validateCursorAccount(value: unknown): asserts value is SDKUser {\n if (!plainObject(value) || typeof value.apiKeyName !== \"string\" || typeof value.createdAt !== \"string\"\n || (value.userId !== undefined && typeof value.userId !== \"number\")\n || (value.userEmail !== undefined && typeof value.userEmail !== \"string\")\n || (value.userFirstName !== undefined && typeof value.userFirstName !== \"string\")\n || (value.userLastName !== undefined && typeof value.userLastName !== \"string\")) {\n throw new AgentError(\"PROTOCOL_ERROR\", \"Cursor returned malformed account metadata.\");\n }\n}\n\nexport function validateCursorCatalog(value: unknown): asserts value is SDKModel[] {\n if (!Array.isArray(value) || value.some(model => !plainObject(model)\n || typeof model.id !== \"string\" || !model.id\n || typeof model.displayName !== \"string\"\n || (model.aliases !== undefined && (!Array.isArray(model.aliases) || model.aliases.some(alias => typeof alias !== \"string\"))))) {\n throw new AgentError(\"PROTOCOL_ERROR\", \"Cursor returned a malformed model catalog.\");\n }\n}\n\nexport function resolveCursorModel(catalog: SDKModel[], requested: string): SDKModel {\n if (AUTO_MODEL_IDS.has(requested)) {\n throw new AgentError(\"UNSUPPORTED_OPTION\", \"Cursor Auto model routing does not retain a concrete model.\");\n }\n const matches = catalog.filter(model => model.id === requested || model.aliases?.includes(requested));\n if (matches.length !== 1) throw new AgentError(\"INVALID_CONFIG\", \"The selected Cursor model is not available in the account catalog.\");\n const selected = matches[0]!;\n if (AUTO_MODEL_IDS.has(selected.id)) {\n throw new AgentError(\"UNSUPPORTED_OPTION\", \"Cursor Auto model routing does not retain a concrete model.\");\n }\n return selected;\n}\n\nconst AUTO_MODEL_IDS = new Set([\"auto\", \"auto-smart\"]);\n\nexport function isCursorTerminalStatus(status: unknown): status is Exclude<RunStatus, \"running\"> {\n return status === \"finished\" || status === \"error\" || status === \"cancelled\";\n}\n\nexport function validateCursorRunResult(value: unknown): asserts value is RunResult {\n if (!plainObject(value) || typeof value.id !== \"string\" || !isCursorTerminalStatus(value.status)\n || (value.requestId !== undefined && typeof value.requestId !== \"string\")\n || (value.result !== undefined && typeof value.result !== \"string\")\n || (value.error !== undefined && (!plainObject(value.error) || typeof value.error.message !== \"string\"\n || (value.error.code !== undefined && typeof value.error.code !== \"string\")))\n || (value.model !== undefined && (!plainObject(value.model) || typeof value.model.id !== \"string\"))) {\n throw new AgentError(\"PROTOCOL_ERROR\", \"Cursor returned a malformed native result.\");\n }\n}\n\nexport function cursorTerminalText(result: RunResult, selected: SDKModel): string {\n const expected = new Set([selected.id, ...(selected.aliases ?? [])]);\n if (result.model && !expected.has(result.model.id)) {\n throw new AgentError(\"INVALID_CONFIG\", \"Cursor selected a different model than requested.\");\n }\n if (result.status === \"finished\") {\n const text = result.result ?? \"\";\n if (Buffer.byteLength(text, \"utf8\") > 1024 * 1024) throw new AgentError(\"RESPONSE_TOO_LARGE\", \"The Cursor response exceeds 1 MiB.\");\n return text;\n }\n if (result.status === \"cancelled\") throw new AgentError(\"INTERRUPTED\", \"The Cursor turn was interrupted.\");\n throw new AgentError(\"HARNESS_ERROR\", \"Cursor could not complete the turn.\");\n}\n\nfunction plainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null) return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n"]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { AgentError } from "../errors.js";
|
|
2
|
+
export type CursorRpcEnvelope = {
|
|
3
|
+
jsonrpc?: "2.0";
|
|
4
|
+
id?: string | number;
|
|
5
|
+
method?: string;
|
|
6
|
+
params?: unknown;
|
|
7
|
+
result?: unknown;
|
|
8
|
+
error?: unknown;
|
|
9
|
+
};
|
|
10
|
+
export declare class CursorRpcNativeError extends AgentError {
|
|
11
|
+
readonly nativeCode: number;
|
|
12
|
+
constructor(nativeCode: number);
|
|
13
|
+
}
|
|
14
|
+
/** Newline-delimited JSON-RPC 2.0 transport for Cursor's native ACP process. */
|
|
15
|
+
export declare class CursorRpc {
|
|
16
|
+
private readonly child;
|
|
17
|
+
private readonly pending;
|
|
18
|
+
private sequence;
|
|
19
|
+
private buffer;
|
|
20
|
+
private started;
|
|
21
|
+
private closing;
|
|
22
|
+
private closed;
|
|
23
|
+
private closePromise?;
|
|
24
|
+
private failure?;
|
|
25
|
+
private failureHandler;
|
|
26
|
+
onMessage: (message: CursorRpcEnvelope) => void;
|
|
27
|
+
constructor(executable: string, args: string[], cwd: string, env: NodeJS.ProcessEnv);
|
|
28
|
+
request(method: string, params: unknown, timeoutMs?: number): Promise<unknown>;
|
|
29
|
+
send(envelope: CursorRpcEnvelope): void;
|
|
30
|
+
setFailureHandler(handler: (error: AgentError) => void): void;
|
|
31
|
+
close(): Promise<void>;
|
|
32
|
+
private closeOwnedProcess;
|
|
33
|
+
private signal;
|
|
34
|
+
private waitForRetirement;
|
|
35
|
+
private retired;
|
|
36
|
+
private read;
|
|
37
|
+
private invalid;
|
|
38
|
+
private handleInputFailure;
|
|
39
|
+
private handleExit;
|
|
40
|
+
private rejectPending;
|
|
41
|
+
private fail;
|
|
42
|
+
}
|