@code-yeongyu/senpi 2026.8.17 → 2026.8.18
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/CHANGELOG.md +23 -0
- package/dist/core/extensions/builtin/cursor-cli-oauth/account-command.d.ts +4 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/account-command.d.ts.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/account-command.js +27 -7
- package/dist/core/extensions/builtin/cursor-cli-oauth/account-command.js.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/index.js +3 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/index.js.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/oauth-login.d.ts +4 -0
- package/dist/core/extensions/builtin/cursor-cli-oauth/oauth-login.d.ts.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/oauth-login.js +33 -2
- package/dist/core/extensions/builtin/cursor-cli-oauth/oauth-login.js.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/settings.d.ts +2 -0
- package/dist/core/extensions/builtin/cursor-cli-oauth/settings.d.ts.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/settings.js +19 -9
- package/dist/core/extensions/builtin/cursor-cli-oauth/settings.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +11 -5
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/providers.md +7 -5
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +12 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/baseten.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-workers-ai.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/xai.json +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -16,6 +16,29 @@
|
|
|
16
16
|
|
|
17
17
|
### Removed
|
|
18
18
|
|
|
19
|
+
## [2026.8.18] - 2026-08-18
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- Extension widgets no longer change stacking order when their content updates: `setWidget` now replaces the
|
|
26
|
+
component in place, so two live widgets with independent refresh timers (for example omo-senpi's `omo-task` and
|
|
27
|
+
`omo-dag` status widgets) stay in a fixed vertical order instead of bouncing on every refresh
|
|
28
|
+
([#929](https://github.com/code-yeongyu/senpi/pull/929)).
|
|
29
|
+
|
|
30
|
+
- Cursor model catalogs now become available immediately after authentication: dynamic providers perform their scoped network refresh after login, while explicit Cursor CLI fallback login/import enables the lane, `/cursor-account import native` safely copies the primary OAuth credential into managed accounts, and imported accounts refresh model availability in the current session ([#928](https://github.com/code-yeongyu/senpi/pull/928)).
|
|
31
|
+
|
|
32
|
+
### New Features
|
|
33
|
+
|
|
34
|
+
### Breaking Changes
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
|
|
40
|
+
### Removed
|
|
41
|
+
|
|
19
42
|
## [2026.8.17] - 2026-08-17
|
|
20
43
|
|
|
21
44
|
### Added
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Credential } from "@earendil-works/pi-ai";
|
|
2
2
|
import type { ExtensionAPI } from "../../types.ts";
|
|
3
3
|
import { type CursorCliGenerationGuard } from "./diagnostics.ts";
|
|
4
|
-
import { importLocalCursorCredential, type LocalCursorImportDeps } from "./oauth-login.ts";
|
|
4
|
+
import { importLocalCursorCredential, importNativeCursorCredential, type LocalCursorImportDeps } from "./oauth-login.ts";
|
|
5
5
|
import { type CursorCliSessionRouter } from "./session-router.ts";
|
|
6
6
|
import { type CursorCliOauthProviderSettings } from "./settings.ts";
|
|
7
7
|
/** Injectable seams; every default resolves real on-disk state at invocation time. */
|
|
@@ -12,9 +12,12 @@ export type CursorCliAccountCommandDeps = {
|
|
|
12
12
|
readonly probeVersion?: (executable: string) => Promise<string>;
|
|
13
13
|
readonly readNativeCredential?: () => Credential | undefined | Promise<Credential | undefined>;
|
|
14
14
|
readonly importCredential?: typeof importLocalCursorCredential;
|
|
15
|
+
readonly importNativeCredential?: typeof importNativeCursorCredential;
|
|
15
16
|
readonly importDeps?: LocalCursorImportDeps;
|
|
16
17
|
/** Acknowledgement persistence seam; the default read-modify-writes the global settings file. */
|
|
17
18
|
readonly persistAcknowledgement?: (cwd: string, acknowledgedAt: string) => void;
|
|
19
|
+
/** Enablement persistence seam; explicit login/import actions activate the fallback lane. */
|
|
20
|
+
readonly persistEnabled?: (cwd: string, enabled: boolean) => void;
|
|
18
21
|
readonly now?: () => number;
|
|
19
22
|
readonly generation?: CursorCliGenerationGuard;
|
|
20
23
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-command.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/cursor-cli-oauth/account-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAA2B,MAAM,gBAAgB,CAAC;AAW5E,OAAO,EACN,KAAK,wBAAwB,EAK7B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAGN,2BAA2B,EAC3B,KAAK,qBAAqB,EAC1B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,KAAK,sBAAsB,EAA0B,MAAM,qBAAqB,CAAC;AAC1F,OAAO,EACN,KAAK,8BAA8B,
|
|
1
|
+
{"version":3,"file":"account-command.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/cursor-cli-oauth/account-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAA2B,MAAM,gBAAgB,CAAC;AAW5E,OAAO,EACN,KAAK,wBAAwB,EAK7B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAGN,2BAA2B,EAC3B,4BAA4B,EAC5B,KAAK,qBAAqB,EAC1B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,KAAK,sBAAsB,EAA0B,MAAM,qBAAqB,CAAC;AAC1F,OAAO,EACN,KAAK,8BAA8B,EAInC,MAAM,eAAe,CAAC;AAEvB,sFAAsF;AACtF,MAAM,MAAM,2BAA2B,GAAG;IACzC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,8BAA8B,CAAC;IACxE,QAAQ,CAAC,MAAM,CAAC,EAAE,sBAAsB,CAAC;IACzC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE,8BAA8B,KAAK,MAAM,CAAC;IAClF,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAChE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IAC/F,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,2BAA2B,CAAC;IAC/D,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,4BAA4B,CAAC;IACtE,QAAQ,CAAC,UAAU,CAAC,EAAE,qBAAqB,CAAC;IAC5C,iGAAiG;IACjG,QAAQ,CAAC,sBAAsB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IAChF,6FAA6F;IAC7F,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAClE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,CAAC,EAAE,wBAAwB,CAAC;CAC/C,CAAC;AAiCF;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,GAAE,2BAAgC,GAAG,IAAI,CAyD9G"}
|
|
@@ -2,10 +2,10 @@ import { emitProviderAccountsChanged } from "../claude-sdk-oauth/account-events.
|
|
|
2
2
|
import { emptyCredential, listAccounts, pinAccount, removeAccount, } from "./accounts.js";
|
|
3
3
|
import { selectAccount } from "./affinity.js";
|
|
4
4
|
import { collectCursorCliStatus, NATIVE_CURSOR_PROVIDER_ID, registerCursorCliShutdownSafety, renderCursorCliStatus, } from "./diagnostics.js";
|
|
5
|
-
import { CURSOR_CLI_OAUTH_PROVIDER_ID, confirmCursorCliNoApprovalAcknowledgement, importLocalCursorCredential, } from "./oauth-login.js";
|
|
5
|
+
import { CURSOR_CLI_OAUTH_PROVIDER_ID, confirmCursorCliNoApprovalAcknowledgement, importLocalCursorCredential, importNativeCursorCredential, } from "./oauth-login.js";
|
|
6
6
|
import { cursorCliSessionRouter } from "./session-router.js";
|
|
7
|
-
import { loadCursorCliOauthProviderSettingsFromDisk, persistCursorCliNoApprovalAcknowledgement, } from "./settings.js";
|
|
8
|
-
const USAGE = "Usage: /cursor-account [list | add | remove <name> | pin <name> | unpin | import | acknowledge | status]";
|
|
7
|
+
import { loadCursorCliOauthProviderSettingsFromDisk, persistCursorCliNoApprovalAcknowledgement, persistCursorCliOauthEnabled, } from "./settings.js";
|
|
8
|
+
const USAGE = "Usage: /cursor-account [list | add | remove <name> | pin <name> | unpin | import [local | native] | acknowledge | status]";
|
|
9
9
|
function asCursorCredential(value) {
|
|
10
10
|
return value !== undefined && value.type === "oauth" ? value : emptyCredential();
|
|
11
11
|
}
|
|
@@ -72,7 +72,12 @@ export function registerCursorCliAccountCommand(pi, deps = {}) {
|
|
|
72
72
|
return;
|
|
73
73
|
}
|
|
74
74
|
if (action === "import") {
|
|
75
|
-
|
|
75
|
+
const source = args[1] ?? "local";
|
|
76
|
+
if (source !== "local" && source !== "native") {
|
|
77
|
+
ctx.ui.notify(USAGE, "error");
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
await importAccount(ctx, deps, source);
|
|
76
81
|
return;
|
|
77
82
|
}
|
|
78
83
|
if (action === "acknowledge") {
|
|
@@ -217,8 +222,9 @@ async function unpinAccount(ctx) {
|
|
|
217
222
|
emitProviderAccountsChanged(CURSOR_CLI_OAUTH_PROVIDER_ID);
|
|
218
223
|
ctx.ui.notify("Unpinned Cursor CLI (OAuth) account.", "info");
|
|
219
224
|
}
|
|
220
|
-
async function importAccount(ctx, deps) {
|
|
225
|
+
async function importAccount(ctx, deps, source) {
|
|
221
226
|
const importCredential = deps.importCredential ?? importLocalCursorCredential;
|
|
227
|
+
const importNativeCredential = deps.importNativeCredential ?? importNativeCursorCredential;
|
|
222
228
|
const importDeps = { ...deps.importDeps };
|
|
223
229
|
if (importDeps.onPrompt === undefined && ctx.hasUI) {
|
|
224
230
|
importDeps.onPrompt = async (prompt) => {
|
|
@@ -232,7 +238,9 @@ async function importAccount(ctx, deps) {
|
|
|
232
238
|
try {
|
|
233
239
|
await ctx.modelRegistry.authStorage.modify(CURSOR_CLI_OAUTH_PROVIDER_ID, async (current) => {
|
|
234
240
|
const before = asCursorCredential(current);
|
|
235
|
-
const updated =
|
|
241
|
+
const updated = source === "native"
|
|
242
|
+
? await importNativeCredential(before, deps.readNativeCredential ?? (() => ctx.modelRegistry.authStorage.get(NATIVE_CURSOR_PROVIDER_ID)))
|
|
243
|
+
: await importCredential(before, importDeps);
|
|
236
244
|
const existing = new Set(listAccounts(before).map((account) => account.name));
|
|
237
245
|
importedName = listAccounts(updated).find((account) => !existing.has(account.name))?.name;
|
|
238
246
|
return updated;
|
|
@@ -242,8 +250,20 @@ async function importAccount(ctx, deps) {
|
|
|
242
250
|
ctx.ui.notify(`Failed to import local Cursor credential: ${error instanceof Error ? error.message : String(error)}`, "error");
|
|
243
251
|
return;
|
|
244
252
|
}
|
|
253
|
+
const persistEnabled = deps.persistEnabled ?? persistCursorCliOauthEnabled;
|
|
254
|
+
try {
|
|
255
|
+
persistEnabled(ctx.cwd, true);
|
|
256
|
+
await ctx.modelRegistry.modelRuntime.refresh({
|
|
257
|
+
allowNetwork: false,
|
|
258
|
+
providers: [CURSOR_CLI_OAUTH_PROVIDER_ID],
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
ctx.ui.notify(`Imported ${source === "native" ? "native " : ""}Cursor credential, but provider activation failed: ${error instanceof Error ? error.message : String(error)}`, "warning");
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
245
265
|
emitProviderAccountsChanged(CURSOR_CLI_OAUTH_PROVIDER_ID);
|
|
246
|
-
ctx.ui.notify(`Imported local Cursor credential as '${importedName ?? "a new account"}' (copied into this provider's store).`, "info");
|
|
266
|
+
ctx.ui.notify(`Imported ${source === "native" ? "native " : "local "}Cursor credential as '${importedName ?? "a new account"}' (copied into this provider's store).`, "info");
|
|
247
267
|
}
|
|
248
268
|
async function acknowledgeNoApproval(ctx, deps, generation) {
|
|
249
269
|
if (!ctx.hasUI) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-command.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/cursor-cli-oauth/account-command.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Credential } from \"@earendil-works/pi-ai\";\nimport type { ExtensionAPI, ExtensionCommandContext } from \"../../types.ts\";\nimport { emitProviderAccountsChanged } from \"../claude-sdk-oauth/account-events.ts\";\nimport {\n\ttype CursorCliAccountSlot,\n\ttype CursorCliOauthCredential,\n\temptyCredential,\n\tlistAccounts,\n\tpinAccount,\n\tremoveAccount,\n} from \"./accounts.ts\";\nimport { selectAccount } from \"./affinity.ts\";\nimport {\n\ttype CursorCliGenerationGuard,\n\tcollectCursorCliStatus,\n\tNATIVE_CURSOR_PROVIDER_ID,\n\tregisterCursorCliShutdownSafety,\n\trenderCursorCliStatus,\n} from \"./diagnostics.ts\";\nimport {\n\tCURSOR_CLI_OAUTH_PROVIDER_ID,\n\tconfirmCursorCliNoApprovalAcknowledgement,\n\timportLocalCursorCredential,\n\ttype LocalCursorImportDeps,\n} from \"./oauth-login.ts\";\nimport { type CursorCliSessionRouter, cursorCliSessionRouter } from \"./session-router.ts\";\nimport {\n\ttype CursorCliOauthProviderSettings,\n\tloadCursorCliOauthProviderSettingsFromDisk,\n\tpersistCursorCliNoApprovalAcknowledgement,\n} from \"./settings.ts\";\n\n/** Injectable seams; every default resolves real on-disk state at invocation time. */\nexport type CursorCliAccountCommandDeps = {\n\treadonly loadSettings?: (cwd: string) => CursorCliOauthProviderSettings;\n\treadonly router?: CursorCliSessionRouter;\n\treadonly resolveExecutable?: (settings: CursorCliOauthProviderSettings) => string;\n\treadonly probeVersion?: (executable: string) => Promise<string>;\n\treadonly readNativeCredential?: () => Credential | undefined | Promise<Credential | undefined>;\n\treadonly importCredential?: typeof importLocalCursorCredential;\n\treadonly importDeps?: LocalCursorImportDeps;\n\t/** Acknowledgement persistence seam; the default read-modify-writes the global settings file. */\n\treadonly persistAcknowledgement?: (cwd: string, acknowledgedAt: string) => void;\n\treadonly now?: () => number;\n\treadonly generation?: CursorCliGenerationGuard;\n};\n\nconst USAGE =\n\t\"Usage: /cursor-account [list | add | remove <name> | pin <name> | unpin | import | acknowledge | status]\";\n\nfunction asCursorCredential(value: Credential | undefined): CursorCliOauthCredential {\n\treturn value !== undefined && value.type === \"oauth\" ? (value as CursorCliOauthCredential) : emptyCredential();\n}\n\nfunction parseArgs(rawArgs: string): string[] {\n\treturn rawArgs.trim().split(/\\s+/).filter(Boolean);\n}\n\nfunction slotStatus(slot: CursorCliAccountSlot, now: number): string {\n\tif (slot.blockReason === \"auth_error\") return \"blocked until re-login\";\n\tif (slot.blockedUntil !== undefined && slot.blockedUntil > now) {\n\t\treturn `blocked until ${new Date(slot.blockedUntil).toISOString()} (${slot.blockReason ?? \"rate_limit\"})`;\n\t}\n\treturn \"available\";\n}\n\nfunction authEventMessage(event: unknown): string {\n\tif (event === null || typeof event !== \"object\") return \"Cursor CLI (OAuth) authentication update.\";\n\tconst value = event as Record<string, unknown>;\n\tif (value.type === \"auth_url\" && typeof value.url === \"string\") {\n\t\treturn `Open this URL to authorize Cursor CLI (OAuth):\\n${value.url}`;\n\t}\n\tif (value.type === \"device_code\" && typeof value.verificationUri === \"string\") {\n\t\treturn `Open this URL to authorize Cursor CLI (OAuth):\\n${value.verificationUri}`;\n\t}\n\treturn typeof value.message === \"string\" ? value.message : \"Cursor CLI (OAuth) authentication update.\";\n}\n\n/**\n * Registers `/cursor-account` plus the reload/shutdown teardown for this\n * extension generation: the command reads account state fresh from the\n * credential store on every invocation, and every deferred continuation is\n * fenced so a retired generation is never touched after a reload.\n */\nexport function registerCursorCliAccountCommand(pi: ExtensionAPI, deps: CursorCliAccountCommandDeps = {}): void {\n\tconst loadSettings = deps.loadSettings ?? ((cwd: string) => loadCursorCliOauthProviderSettingsFromDisk(cwd));\n\tconst now = deps.now ?? Date.now;\n\t// One guard per registration: a reload rebuilds the extension and gets a\n\t// fresh fence, while the child registry stays process-wide.\n\tconst generation = registerCursorCliShutdownSafety(pi, { generation: deps.generation });\n\n\tpi.registerCommand(\"cursor-account\", {\n\t\tdescription: \"List and manage Cursor CLI (OAuth) accounts.\",\n\t\targumentHint: \"[list | add | remove <name> | pin <name> | unpin | import | acknowledge | status]\",\n\t\thandler: async (rawArgs: string, ctx: ExtensionCommandContext): Promise<void> => {\n\t\t\ttry {\n\t\t\t\tconst args = parseArgs(rawArgs);\n\t\t\t\tconst action = args[0] ?? \"list\";\n\t\t\t\tif (action === \"list\") {\n\t\t\t\t\tshowAccounts(ctx, loadSettings(ctx.cwd), generation, now);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (action === \"add\") {\n\t\t\t\t\tawait addAccount(ctx);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (action === \"remove\") {\n\t\t\t\t\tawait removeNamedAccount(ctx, args[1]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (action === \"pin\" && args[1] !== undefined) {\n\t\t\t\t\tawait pinNamedAccount(ctx, args[1]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (action === \"unpin\") {\n\t\t\t\t\tawait unpinAccount(ctx);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (action === \"import\") {\n\t\t\t\t\tawait importAccount(ctx, deps);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (action === \"acknowledge\") {\n\t\t\t\t\tawait acknowledgeNoApproval(ctx, deps, generation);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (action === \"status\") {\n\t\t\t\t\tawait showStatus(ctx, deps, { loadSettings, generation, now });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tctx.ui.notify(USAGE, \"error\");\n\t\t\t} catch (error) {\n\t\t\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t\t\t}\n\t\t},\n\t});\n}\n\nfunction showAccounts(\n\tctx: ExtensionCommandContext,\n\tsettings: CursorCliOauthProviderSettings,\n\tgeneration: CursorCliGenerationGuard,\n\tnow: () => number,\n): void {\n\tconst credential = asCursorCredential(ctx.modelRegistry.authStorage.get(CURSOR_CLI_OAUTH_PROVIDER_ID));\n\tconst accounts = listAccounts(credential);\n\tconst pinned = settings.pinnedAccount ?? credential.pinned;\n\tconst pinSource = settings.pinnedAccount !== undefined ? \"settings\" : \"stored\";\n\tlet affinityPick: string | undefined;\n\tlet affinityError: string | undefined;\n\tif (accounts.length > 0) {\n\t\ttry {\n\t\t\taffinityPick = selectAccount(accounts, {\n\t\t\t\tsessionId: ctx.sessionManager.getSessionId(),\n\t\t\t\tpinnedAccount: pinned,\n\t\t\t\tnow: now(),\n\t\t\t}).name;\n\t\t} catch (error) {\n\t\t\taffinityError = error instanceof Error ? error.message : String(error);\n\t\t}\n\t}\n\tconst lines = [\"Cursor CLI (OAuth) accounts:\"];\n\tif (accounts.length === 0) lines.push(\" (none)\");\n\tfor (const account of accounts) {\n\t\tconst states = [account.name, account.source, slotStatus(account, now())];\n\t\tif (account.name === pinned) states.push(\"pinned\");\n\t\tif (account.name === affinityPick) states.push(\"affinity pick\");\n\t\tlines.push(` ${states.join(\" | \")}`);\n\t}\n\tlines.push(`Pinned account: ${pinned === undefined ? \"none\" : `${pinned} (${pinSource})`}`);\n\tlines.push(`Affinity pick: ${affinityPick ?? (affinityError ? `unavailable - ${affinityError}` : \"none\")}`);\n\tgeneration.runFencedSync(ctx, () => ctx.ui.notify(lines.join(\"\\n\"), \"info\"));\n}\n\nasync function addAccount(ctx: ExtensionCommandContext): Promise<void> {\n\tif (!ctx.hasUI) {\n\t\tctx.ui.notify(\"/cursor-account add requires an interactive UI.\", \"error\");\n\t\treturn;\n\t}\n\ttry {\n\t\tawait ctx.modelRegistry.modelRuntime.login(CURSOR_CLI_OAUTH_PROVIDER_ID, \"oauth\", {\n\t\t\tsignal: ctx.signal,\n\t\t\tprompt: async (prompt: { message: string }) => {\n\t\t\t\tconst answer = await ctx.ui.input(prompt.message);\n\t\t\t\tif (answer === undefined) throw new Error(\"Login cancelled\");\n\t\t\t\treturn answer;\n\t\t\t},\n\t\t\tnotify: (event: unknown) => ctx.ui.notify(authEventMessage(event), \"info\"),\n\t\t});\n\t\temitProviderAccountsChanged(CURSOR_CLI_OAUTH_PROVIDER_ID);\n\t\tctx.ui.notify(\"Cursor CLI (OAuth) account added.\", \"info\");\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tif (message !== \"Login cancelled\") {\n\t\t\tctx.ui.notify(`Failed to add Cursor CLI (OAuth) account: ${message}`, \"error\");\n\t\t}\n\t}\n}\n\nasync function removeNamedAccount(ctx: ExtensionCommandContext, name: string | undefined): Promise<void> {\n\tif (!name) {\n\t\tctx.ui.notify(\"Usage: /cursor-account remove <name>\", \"error\");\n\t\treturn;\n\t}\n\tlet removed = false;\n\ttry {\n\t\tawait ctx.modelRegistry.authStorage.modify(CURSOR_CLI_OAUTH_PROVIDER_ID, async (current) => {\n\t\t\tconst credential = asCursorCredential(current);\n\t\t\tif (!listAccounts(credential).some((account) => account.name === name)) return current;\n\t\t\tremoved = true;\n\t\t\treturn removeAccount(credential, name);\n\t\t});\n\t} catch (error) {\n\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t\treturn;\n\t}\n\tif (!removed) {\n\t\tctx.ui.notify(`Cursor CLI (OAuth) account '${name}' does not exist.`, \"error\");\n\t\treturn;\n\t}\n\temitProviderAccountsChanged(CURSOR_CLI_OAUTH_PROVIDER_ID);\n\tctx.ui.notify(`Removed Cursor CLI (OAuth) account: ${name}.`, \"info\");\n}\n\nasync function pinNamedAccount(ctx: ExtensionCommandContext, name: string): Promise<void> {\n\ttry {\n\t\tawait ctx.modelRegistry.authStorage.modify(CURSOR_CLI_OAUTH_PROVIDER_ID, async (current) => {\n\t\t\tconst credential = asCursorCredential(current);\n\t\t\tif (!listAccounts(credential).some((account) => account.name === name)) {\n\t\t\t\tthrow new Error(`Cursor CLI (OAuth) account '${name}' does not exist.`);\n\t\t\t}\n\t\t\treturn pinAccount(credential, name);\n\t\t});\n\t} catch (error) {\n\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t\treturn;\n\t}\n\temitProviderAccountsChanged(CURSOR_CLI_OAUTH_PROVIDER_ID);\n\tctx.ui.notify(`Pinned Cursor CLI (OAuth) account: ${name}.`, \"info\");\n}\n\nasync function unpinAccount(ctx: ExtensionCommandContext): Promise<void> {\n\tlet hadPin = false;\n\ttry {\n\t\tawait ctx.modelRegistry.authStorage.modify(CURSOR_CLI_OAUTH_PROVIDER_ID, async (current) => {\n\t\t\tconst credential = asCursorCredential(current);\n\t\t\tif (credential.pinned === undefined) return current;\n\t\t\thadPin = true;\n\t\t\tconst { pinned: _pinned, ...unpinned } = credential;\n\t\t\treturn unpinned;\n\t\t});\n\t} catch (error) {\n\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t\treturn;\n\t}\n\tif (!hadPin) {\n\t\tctx.ui.notify(\"No stored Cursor CLI (OAuth) account pin is set.\", \"info\");\n\t\treturn;\n\t}\n\temitProviderAccountsChanged(CURSOR_CLI_OAUTH_PROVIDER_ID);\n\tctx.ui.notify(\"Unpinned Cursor CLI (OAuth) account.\", \"info\");\n}\n\nasync function importAccount(ctx: ExtensionCommandContext, deps: CursorCliAccountCommandDeps): Promise<void> {\n\tconst importCredential = deps.importCredential ?? importLocalCursorCredential;\n\tconst importDeps: LocalCursorImportDeps = { ...deps.importDeps };\n\tif (importDeps.onPrompt === undefined && ctx.hasUI) {\n\t\timportDeps.onPrompt = async (prompt: { message: string }) => {\n\t\t\tconst answer = await ctx.ui.input(prompt.message);\n\t\t\tif (answer === undefined) throw new Error(\"Import cancelled\");\n\t\t\treturn answer;\n\t\t};\n\t}\n\tlet importedName: string | undefined;\n\ttry {\n\t\tawait ctx.modelRegistry.authStorage.modify(CURSOR_CLI_OAUTH_PROVIDER_ID, async (current) => {\n\t\t\tconst before = asCursorCredential(current);\n\t\t\tconst updated = await importCredential(before, importDeps);\n\t\t\tconst existing = new Set(listAccounts(before).map((account) => account.name));\n\t\t\timportedName = listAccounts(updated).find((account) => !existing.has(account.name))?.name;\n\t\t\treturn updated;\n\t\t});\n\t} catch (error) {\n\t\tctx.ui.notify(\n\t\t\t`Failed to import local Cursor credential: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\"error\",\n\t\t);\n\t\treturn;\n\t}\n\temitProviderAccountsChanged(CURSOR_CLI_OAUTH_PROVIDER_ID);\n\tctx.ui.notify(\n\t\t`Imported local Cursor credential as '${importedName ?? \"a new account\"}' (copied into this provider's store).`,\n\t\t\"info\",\n\t);\n}\n\nasync function acknowledgeNoApproval(\n\tctx: ExtensionCommandContext,\n\tdeps: CursorCliAccountCommandDeps,\n\tgeneration: CursorCliGenerationGuard,\n): Promise<void> {\n\tif (!ctx.hasUI) {\n\t\tctx.ui.notify(\"/cursor-account acknowledge requires an interactive UI.\", \"error\");\n\t\treturn;\n\t}\n\tconst persist = deps.persistAcknowledgement ?? persistCursorCliNoApprovalAcknowledgement;\n\tconst acknowledgedAt = await confirmCursorCliNoApprovalAcknowledgement(\n\t\tasync (ask) => (await ctx.ui.input(ask.message)) ?? \"\",\n\t\t() => new Date((deps.now ?? Date.now)()),\n\t);\n\tif (acknowledgedAt === undefined) {\n\t\tgeneration.runFencedSync(ctx, () =>\n\t\t\tctx.ui.notify(\n\t\t\t\t\"No acknowledgement written: unattended Cursor CLI execution stays off until you acknowledge.\",\n\t\t\t\t\"info\",\n\t\t\t),\n\t\t);\n\t\treturn;\n\t}\n\tpersist(ctx.cwd, acknowledgedAt);\n\tgeneration.runFencedSync(ctx, () =>\n\t\tctx.ui.notify(`Acknowledged unattended Cursor CLI tool execution at ${acknowledgedAt}.`, \"info\"),\n\t);\n}\n\nasync function showStatus(\n\tctx: ExtensionCommandContext,\n\tdeps: CursorCliAccountCommandDeps,\n\tbound: {\n\t\tloadSettings: (cwd: string) => CursorCliOauthProviderSettings;\n\t\tgeneration: CursorCliGenerationGuard;\n\t\tnow: () => number;\n\t},\n): Promise<void> {\n\t// Context reads happen before any await; the render continuation is fenced\n\t// so a reload during the version probe can never touch a retired context.\n\tconst sessionId = ctx.sessionManager.getSessionId();\n\tconst report = await collectCursorCliStatus({\n\t\tsessionId,\n\t\tsettings: bound.loadSettings(ctx.cwd),\n\t\treadCredential: () => ctx.modelRegistry.authStorage.get(CURSOR_CLI_OAUTH_PROVIDER_ID),\n\t\treadNativeCredential:\n\t\t\tdeps.readNativeCredential ?? (() => ctx.modelRegistry.authStorage.get(NATIVE_CURSOR_PROVIDER_ID)),\n\t\trouter: deps.router ?? cursorCliSessionRouter,\n\t\tresolveExecutable: deps.resolveExecutable,\n\t\tprobeVersion: deps.probeVersion,\n\t\tnow: bound.now,\n\t});\n\tbound.generation.runFencedSync(ctx, () => ctx.ui.notify(renderCursorCliStatus(report), \"info\"));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"account-command.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/cursor-cli-oauth/account-command.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Credential } from \"@earendil-works/pi-ai\";\nimport type { ExtensionAPI, ExtensionCommandContext } from \"../../types.ts\";\nimport { emitProviderAccountsChanged } from \"../claude-sdk-oauth/account-events.ts\";\nimport {\n\ttype CursorCliAccountSlot,\n\ttype CursorCliOauthCredential,\n\temptyCredential,\n\tlistAccounts,\n\tpinAccount,\n\tremoveAccount,\n} from \"./accounts.ts\";\nimport { selectAccount } from \"./affinity.ts\";\nimport {\n\ttype CursorCliGenerationGuard,\n\tcollectCursorCliStatus,\n\tNATIVE_CURSOR_PROVIDER_ID,\n\tregisterCursorCliShutdownSafety,\n\trenderCursorCliStatus,\n} from \"./diagnostics.ts\";\nimport {\n\tCURSOR_CLI_OAUTH_PROVIDER_ID,\n\tconfirmCursorCliNoApprovalAcknowledgement,\n\timportLocalCursorCredential,\n\timportNativeCursorCredential,\n\ttype LocalCursorImportDeps,\n} from \"./oauth-login.ts\";\nimport { type CursorCliSessionRouter, cursorCliSessionRouter } from \"./session-router.ts\";\nimport {\n\ttype CursorCliOauthProviderSettings,\n\tloadCursorCliOauthProviderSettingsFromDisk,\n\tpersistCursorCliNoApprovalAcknowledgement,\n\tpersistCursorCliOauthEnabled,\n} from \"./settings.ts\";\n\n/** Injectable seams; every default resolves real on-disk state at invocation time. */\nexport type CursorCliAccountCommandDeps = {\n\treadonly loadSettings?: (cwd: string) => CursorCliOauthProviderSettings;\n\treadonly router?: CursorCliSessionRouter;\n\treadonly resolveExecutable?: (settings: CursorCliOauthProviderSettings) => string;\n\treadonly probeVersion?: (executable: string) => Promise<string>;\n\treadonly readNativeCredential?: () => Credential | undefined | Promise<Credential | undefined>;\n\treadonly importCredential?: typeof importLocalCursorCredential;\n\treadonly importNativeCredential?: typeof importNativeCursorCredential;\n\treadonly importDeps?: LocalCursorImportDeps;\n\t/** Acknowledgement persistence seam; the default read-modify-writes the global settings file. */\n\treadonly persistAcknowledgement?: (cwd: string, acknowledgedAt: string) => void;\n\t/** Enablement persistence seam; explicit login/import actions activate the fallback lane. */\n\treadonly persistEnabled?: (cwd: string, enabled: boolean) => void;\n\treadonly now?: () => number;\n\treadonly generation?: CursorCliGenerationGuard;\n};\n\nconst USAGE =\n\t\"Usage: /cursor-account [list | add | remove <name> | pin <name> | unpin | import [local | native] | acknowledge | status]\";\n\nfunction asCursorCredential(value: Credential | undefined): CursorCliOauthCredential {\n\treturn value !== undefined && value.type === \"oauth\" ? (value as CursorCliOauthCredential) : emptyCredential();\n}\n\nfunction parseArgs(rawArgs: string): string[] {\n\treturn rawArgs.trim().split(/\\s+/).filter(Boolean);\n}\n\nfunction slotStatus(slot: CursorCliAccountSlot, now: number): string {\n\tif (slot.blockReason === \"auth_error\") return \"blocked until re-login\";\n\tif (slot.blockedUntil !== undefined && slot.blockedUntil > now) {\n\t\treturn `blocked until ${new Date(slot.blockedUntil).toISOString()} (${slot.blockReason ?? \"rate_limit\"})`;\n\t}\n\treturn \"available\";\n}\n\nfunction authEventMessage(event: unknown): string {\n\tif (event === null || typeof event !== \"object\") return \"Cursor CLI (OAuth) authentication update.\";\n\tconst value = event as Record<string, unknown>;\n\tif (value.type === \"auth_url\" && typeof value.url === \"string\") {\n\t\treturn `Open this URL to authorize Cursor CLI (OAuth):\\n${value.url}`;\n\t}\n\tif (value.type === \"device_code\" && typeof value.verificationUri === \"string\") {\n\t\treturn `Open this URL to authorize Cursor CLI (OAuth):\\n${value.verificationUri}`;\n\t}\n\treturn typeof value.message === \"string\" ? value.message : \"Cursor CLI (OAuth) authentication update.\";\n}\n\n/**\n * Registers `/cursor-account` plus the reload/shutdown teardown for this\n * extension generation: the command reads account state fresh from the\n * credential store on every invocation, and every deferred continuation is\n * fenced so a retired generation is never touched after a reload.\n */\nexport function registerCursorCliAccountCommand(pi: ExtensionAPI, deps: CursorCliAccountCommandDeps = {}): void {\n\tconst loadSettings = deps.loadSettings ?? ((cwd: string) => loadCursorCliOauthProviderSettingsFromDisk(cwd));\n\tconst now = deps.now ?? Date.now;\n\t// One guard per registration: a reload rebuilds the extension and gets a\n\t// fresh fence, while the child registry stays process-wide.\n\tconst generation = registerCursorCliShutdownSafety(pi, { generation: deps.generation });\n\n\tpi.registerCommand(\"cursor-account\", {\n\t\tdescription: \"List and manage Cursor CLI (OAuth) accounts.\",\n\t\targumentHint: \"[list | add | remove <name> | pin <name> | unpin | import | acknowledge | status]\",\n\t\thandler: async (rawArgs: string, ctx: ExtensionCommandContext): Promise<void> => {\n\t\t\ttry {\n\t\t\t\tconst args = parseArgs(rawArgs);\n\t\t\t\tconst action = args[0] ?? \"list\";\n\t\t\t\tif (action === \"list\") {\n\t\t\t\t\tshowAccounts(ctx, loadSettings(ctx.cwd), generation, now);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (action === \"add\") {\n\t\t\t\t\tawait addAccount(ctx);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (action === \"remove\") {\n\t\t\t\t\tawait removeNamedAccount(ctx, args[1]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (action === \"pin\" && args[1] !== undefined) {\n\t\t\t\t\tawait pinNamedAccount(ctx, args[1]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (action === \"unpin\") {\n\t\t\t\t\tawait unpinAccount(ctx);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (action === \"import\") {\n\t\t\t\t\tconst source = args[1] ?? \"local\";\n\t\t\t\t\tif (source !== \"local\" && source !== \"native\") {\n\t\t\t\t\t\tctx.ui.notify(USAGE, \"error\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tawait importAccount(ctx, deps, source);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (action === \"acknowledge\") {\n\t\t\t\t\tawait acknowledgeNoApproval(ctx, deps, generation);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (action === \"status\") {\n\t\t\t\t\tawait showStatus(ctx, deps, { loadSettings, generation, now });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tctx.ui.notify(USAGE, \"error\");\n\t\t\t} catch (error) {\n\t\t\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t\t\t}\n\t\t},\n\t});\n}\n\nfunction showAccounts(\n\tctx: ExtensionCommandContext,\n\tsettings: CursorCliOauthProviderSettings,\n\tgeneration: CursorCliGenerationGuard,\n\tnow: () => number,\n): void {\n\tconst credential = asCursorCredential(ctx.modelRegistry.authStorage.get(CURSOR_CLI_OAUTH_PROVIDER_ID));\n\tconst accounts = listAccounts(credential);\n\tconst pinned = settings.pinnedAccount ?? credential.pinned;\n\tconst pinSource = settings.pinnedAccount !== undefined ? \"settings\" : \"stored\";\n\tlet affinityPick: string | undefined;\n\tlet affinityError: string | undefined;\n\tif (accounts.length > 0) {\n\t\ttry {\n\t\t\taffinityPick = selectAccount(accounts, {\n\t\t\t\tsessionId: ctx.sessionManager.getSessionId(),\n\t\t\t\tpinnedAccount: pinned,\n\t\t\t\tnow: now(),\n\t\t\t}).name;\n\t\t} catch (error) {\n\t\t\taffinityError = error instanceof Error ? error.message : String(error);\n\t\t}\n\t}\n\tconst lines = [\"Cursor CLI (OAuth) accounts:\"];\n\tif (accounts.length === 0) lines.push(\" (none)\");\n\tfor (const account of accounts) {\n\t\tconst states = [account.name, account.source, slotStatus(account, now())];\n\t\tif (account.name === pinned) states.push(\"pinned\");\n\t\tif (account.name === affinityPick) states.push(\"affinity pick\");\n\t\tlines.push(` ${states.join(\" | \")}`);\n\t}\n\tlines.push(`Pinned account: ${pinned === undefined ? \"none\" : `${pinned} (${pinSource})`}`);\n\tlines.push(`Affinity pick: ${affinityPick ?? (affinityError ? `unavailable - ${affinityError}` : \"none\")}`);\n\tgeneration.runFencedSync(ctx, () => ctx.ui.notify(lines.join(\"\\n\"), \"info\"));\n}\n\nasync function addAccount(ctx: ExtensionCommandContext): Promise<void> {\n\tif (!ctx.hasUI) {\n\t\tctx.ui.notify(\"/cursor-account add requires an interactive UI.\", \"error\");\n\t\treturn;\n\t}\n\ttry {\n\t\tawait ctx.modelRegistry.modelRuntime.login(CURSOR_CLI_OAUTH_PROVIDER_ID, \"oauth\", {\n\t\t\tsignal: ctx.signal,\n\t\t\tprompt: async (prompt: { message: string }) => {\n\t\t\t\tconst answer = await ctx.ui.input(prompt.message);\n\t\t\t\tif (answer === undefined) throw new Error(\"Login cancelled\");\n\t\t\t\treturn answer;\n\t\t\t},\n\t\t\tnotify: (event: unknown) => ctx.ui.notify(authEventMessage(event), \"info\"),\n\t\t});\n\t\temitProviderAccountsChanged(CURSOR_CLI_OAUTH_PROVIDER_ID);\n\t\tctx.ui.notify(\"Cursor CLI (OAuth) account added.\", \"info\");\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tif (message !== \"Login cancelled\") {\n\t\t\tctx.ui.notify(`Failed to add Cursor CLI (OAuth) account: ${message}`, \"error\");\n\t\t}\n\t}\n}\n\nasync function removeNamedAccount(ctx: ExtensionCommandContext, name: string | undefined): Promise<void> {\n\tif (!name) {\n\t\tctx.ui.notify(\"Usage: /cursor-account remove <name>\", \"error\");\n\t\treturn;\n\t}\n\tlet removed = false;\n\ttry {\n\t\tawait ctx.modelRegistry.authStorage.modify(CURSOR_CLI_OAUTH_PROVIDER_ID, async (current) => {\n\t\t\tconst credential = asCursorCredential(current);\n\t\t\tif (!listAccounts(credential).some((account) => account.name === name)) return current;\n\t\t\tremoved = true;\n\t\t\treturn removeAccount(credential, name);\n\t\t});\n\t} catch (error) {\n\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t\treturn;\n\t}\n\tif (!removed) {\n\t\tctx.ui.notify(`Cursor CLI (OAuth) account '${name}' does not exist.`, \"error\");\n\t\treturn;\n\t}\n\temitProviderAccountsChanged(CURSOR_CLI_OAUTH_PROVIDER_ID);\n\tctx.ui.notify(`Removed Cursor CLI (OAuth) account: ${name}.`, \"info\");\n}\n\nasync function pinNamedAccount(ctx: ExtensionCommandContext, name: string): Promise<void> {\n\ttry {\n\t\tawait ctx.modelRegistry.authStorage.modify(CURSOR_CLI_OAUTH_PROVIDER_ID, async (current) => {\n\t\t\tconst credential = asCursorCredential(current);\n\t\t\tif (!listAccounts(credential).some((account) => account.name === name)) {\n\t\t\t\tthrow new Error(`Cursor CLI (OAuth) account '${name}' does not exist.`);\n\t\t\t}\n\t\t\treturn pinAccount(credential, name);\n\t\t});\n\t} catch (error) {\n\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t\treturn;\n\t}\n\temitProviderAccountsChanged(CURSOR_CLI_OAUTH_PROVIDER_ID);\n\tctx.ui.notify(`Pinned Cursor CLI (OAuth) account: ${name}.`, \"info\");\n}\n\nasync function unpinAccount(ctx: ExtensionCommandContext): Promise<void> {\n\tlet hadPin = false;\n\ttry {\n\t\tawait ctx.modelRegistry.authStorage.modify(CURSOR_CLI_OAUTH_PROVIDER_ID, async (current) => {\n\t\t\tconst credential = asCursorCredential(current);\n\t\t\tif (credential.pinned === undefined) return current;\n\t\t\thadPin = true;\n\t\t\tconst { pinned: _pinned, ...unpinned } = credential;\n\t\t\treturn unpinned;\n\t\t});\n\t} catch (error) {\n\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t\treturn;\n\t}\n\tif (!hadPin) {\n\t\tctx.ui.notify(\"No stored Cursor CLI (OAuth) account pin is set.\", \"info\");\n\t\treturn;\n\t}\n\temitProviderAccountsChanged(CURSOR_CLI_OAUTH_PROVIDER_ID);\n\tctx.ui.notify(\"Unpinned Cursor CLI (OAuth) account.\", \"info\");\n}\n\nasync function importAccount(\n\tctx: ExtensionCommandContext,\n\tdeps: CursorCliAccountCommandDeps,\n\tsource: \"local\" | \"native\",\n): Promise<void> {\n\tconst importCredential = deps.importCredential ?? importLocalCursorCredential;\n\tconst importNativeCredential = deps.importNativeCredential ?? importNativeCursorCredential;\n\tconst importDeps: LocalCursorImportDeps = { ...deps.importDeps };\n\tif (importDeps.onPrompt === undefined && ctx.hasUI) {\n\t\timportDeps.onPrompt = async (prompt: { message: string }) => {\n\t\t\tconst answer = await ctx.ui.input(prompt.message);\n\t\t\tif (answer === undefined) throw new Error(\"Import cancelled\");\n\t\t\treturn answer;\n\t\t};\n\t}\n\tlet importedName: string | undefined;\n\ttry {\n\t\tawait ctx.modelRegistry.authStorage.modify(CURSOR_CLI_OAUTH_PROVIDER_ID, async (current) => {\n\t\t\tconst before = asCursorCredential(current);\n\t\t\tconst updated =\n\t\t\t\tsource === \"native\"\n\t\t\t\t\t? await importNativeCredential(\n\t\t\t\t\t\t\tbefore,\n\t\t\t\t\t\t\tdeps.readNativeCredential ?? (() => ctx.modelRegistry.authStorage.get(NATIVE_CURSOR_PROVIDER_ID)),\n\t\t\t\t\t\t)\n\t\t\t\t\t: await importCredential(before, importDeps);\n\t\t\tconst existing = new Set(listAccounts(before).map((account) => account.name));\n\t\t\timportedName = listAccounts(updated).find((account) => !existing.has(account.name))?.name;\n\t\t\treturn updated;\n\t\t});\n\t} catch (error) {\n\t\tctx.ui.notify(\n\t\t\t`Failed to import local Cursor credential: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\"error\",\n\t\t);\n\t\treturn;\n\t}\n\tconst persistEnabled = deps.persistEnabled ?? persistCursorCliOauthEnabled;\n\ttry {\n\t\tpersistEnabled(ctx.cwd, true);\n\t\tawait ctx.modelRegistry.modelRuntime.refresh({\n\t\t\tallowNetwork: false,\n\t\t\tproviders: [CURSOR_CLI_OAUTH_PROVIDER_ID],\n\t\t});\n\t} catch (error) {\n\t\tctx.ui.notify(\n\t\t\t`Imported ${source === \"native\" ? \"native \" : \"\"}Cursor credential, but provider activation failed: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\"warning\",\n\t\t);\n\t\treturn;\n\t}\n\temitProviderAccountsChanged(CURSOR_CLI_OAUTH_PROVIDER_ID);\n\tctx.ui.notify(\n\t\t`Imported ${source === \"native\" ? \"native \" : \"local \"}Cursor credential as '${importedName ?? \"a new account\"}' (copied into this provider's store).`,\n\t\t\"info\",\n\t);\n}\n\nasync function acknowledgeNoApproval(\n\tctx: ExtensionCommandContext,\n\tdeps: CursorCliAccountCommandDeps,\n\tgeneration: CursorCliGenerationGuard,\n): Promise<void> {\n\tif (!ctx.hasUI) {\n\t\tctx.ui.notify(\"/cursor-account acknowledge requires an interactive UI.\", \"error\");\n\t\treturn;\n\t}\n\tconst persist = deps.persistAcknowledgement ?? persistCursorCliNoApprovalAcknowledgement;\n\tconst acknowledgedAt = await confirmCursorCliNoApprovalAcknowledgement(\n\t\tasync (ask) => (await ctx.ui.input(ask.message)) ?? \"\",\n\t\t() => new Date((deps.now ?? Date.now)()),\n\t);\n\tif (acknowledgedAt === undefined) {\n\t\tgeneration.runFencedSync(ctx, () =>\n\t\t\tctx.ui.notify(\n\t\t\t\t\"No acknowledgement written: unattended Cursor CLI execution stays off until you acknowledge.\",\n\t\t\t\t\"info\",\n\t\t\t),\n\t\t);\n\t\treturn;\n\t}\n\tpersist(ctx.cwd, acknowledgedAt);\n\tgeneration.runFencedSync(ctx, () =>\n\t\tctx.ui.notify(`Acknowledged unattended Cursor CLI tool execution at ${acknowledgedAt}.`, \"info\"),\n\t);\n}\n\nasync function showStatus(\n\tctx: ExtensionCommandContext,\n\tdeps: CursorCliAccountCommandDeps,\n\tbound: {\n\t\tloadSettings: (cwd: string) => CursorCliOauthProviderSettings;\n\t\tgeneration: CursorCliGenerationGuard;\n\t\tnow: () => number;\n\t},\n): Promise<void> {\n\t// Context reads happen before any await; the render continuation is fenced\n\t// so a reload during the version probe can never touch a retired context.\n\tconst sessionId = ctx.sessionManager.getSessionId();\n\tconst report = await collectCursorCliStatus({\n\t\tsessionId,\n\t\tsettings: bound.loadSettings(ctx.cwd),\n\t\treadCredential: () => ctx.modelRegistry.authStorage.get(CURSOR_CLI_OAUTH_PROVIDER_ID),\n\t\treadNativeCredential:\n\t\t\tdeps.readNativeCredential ?? (() => ctx.modelRegistry.authStorage.get(NATIVE_CURSOR_PROVIDER_ID)),\n\t\trouter: deps.router ?? cursorCliSessionRouter,\n\t\tresolveExecutable: deps.resolveExecutable,\n\t\tprobeVersion: deps.probeVersion,\n\t\tnow: bound.now,\n\t});\n\tbound.generation.runFencedSync(ctx, () => ctx.ui.notify(renderCursorCliStatus(report), \"info\"));\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/cursor-cli-oauth/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGzE,OAAO,KAAK,EAAE,YAAY,EAAuB,MAAM,gBAAgB,CAAC;AAKxE,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/cursor-cli-oauth/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGzE,OAAO,KAAK,EAAE,YAAY,EAAuB,MAAM,gBAAgB,CAAC;AAKxE,OAAO,EACN,KAAK,8BAA8B,EAInC,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AAChE,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,mEAAmE;AACnE,MAAM,MAAM,2BAA2B,GAAG;IACzC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IAC7D,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,8BAA8B,CAAC;IACxE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM,CAAC;CAC/E,CAAC;AAKF;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,GAAE,2BAAgC,GAAG,IAAI,CAmD9G;AAED,MAAM,CAAC,OAAO,UAAU,uBAAuB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAEtE"}
|
|
@@ -4,7 +4,7 @@ import { registerCursorCliAccountCommand } from "./account-command.js";
|
|
|
4
4
|
import { defaultCursorAgentExecutableDeps, resolveCursorAgentExecutable } from "./executable.js";
|
|
5
5
|
import { resolveCursorCliModelCatalog, STATIC_CURSOR_CLI_MODELS } from "./models.js";
|
|
6
6
|
import { CURSOR_CLI_OAUTH_PROVIDER_ID, createCursorCliOauthConfig } from "./oauth-login.js";
|
|
7
|
-
import { loadCursorCliOauthProviderSettingsFromDisk } from "./settings.js";
|
|
7
|
+
import { loadCursorCliOauthProviderSettingsFromDisk, persistCursorCliNoApprovalAcknowledgement, persistCursorCliOauthEnabled, } from "./settings.js";
|
|
8
8
|
import { streamCursorCliOauth } from "./stream.js";
|
|
9
9
|
export { CURSOR_CLI_OAUTH_PROVIDER_ID } from "./oauth-login.js";
|
|
10
10
|
const defaultResolveExecutable = (settings) => resolveCursorAgentExecutable({ ...defaultCursorAgentExecutableDeps(), settings });
|
|
@@ -36,6 +36,8 @@ export function registerCursorCliOauthExtension(pi, deps = {}) {
|
|
|
36
36
|
readCurrent,
|
|
37
37
|
readSettings: () => loadSettings(cwd),
|
|
38
38
|
resolveExecutable,
|
|
39
|
+
persistAcknowledgement: (acknowledgedAt) => persistCursorCliNoApprovalAcknowledgement(cwd, acknowledgedAt),
|
|
40
|
+
persistEnabled: (enabled) => persistCursorCliOauthEnabled(cwd, enabled),
|
|
39
41
|
}),
|
|
40
42
|
});
|
|
41
43
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/cursor-cli-oauth/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,EAAE,+BAA+B,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,gCAAgC,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AACjG,OAAO,EAAE,4BAA4B,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACrF,OAAO,EAAE,4BAA4B,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAC5F,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/cursor-cli-oauth/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Credential, CredentialStore } from \"@earendil-works/pi-ai\";\nimport { getAgentDir } from \"../../../../config.ts\";\nimport { AuthStorage } from \"../../../auth-storage.ts\";\nimport type { ExtensionAPI, ProviderModelConfig } from \"../../types.ts\";\nimport { registerCursorCliAccountCommand } from \"./account-command.ts\";\nimport { defaultCursorAgentExecutableDeps, resolveCursorAgentExecutable } from \"./executable.ts\";\nimport { resolveCursorCliModelCatalog, STATIC_CURSOR_CLI_MODELS } from \"./models.ts\";\nimport { CURSOR_CLI_OAUTH_PROVIDER_ID, createCursorCliOauthConfig } from \"./oauth-login.ts\";\nimport {\n\ttype CursorCliOauthProviderSettings,\n\tloadCursorCliOauthProviderSettingsFromDisk,\n\tpersistCursorCliNoApprovalAcknowledgement,\n\tpersistCursorCliOauthEnabled,\n} from \"./settings.ts\";\nimport { streamCursorCliOauth } from \"./stream.ts\";\n\nexport { CURSOR_CLI_OAUTH_PROVIDER_ID } from \"./oauth-login.ts\";\nexport type { CursorCliStreamDeps } from \"./stream.ts\";\n\n/** Injectable seams; every default resolves real on-disk state. */\nexport type CursorCliOauthExtensionDeps = {\n\treadonly cwd?: string;\n\treadonly agentDir?: string;\n\treadonly store?: CredentialStore;\n\treadonly readCurrent?: () => Promise<Credential | undefined>;\n\treadonly loadSettings?: (cwd: string) => CursorCliOauthProviderSettings;\n\treadonly resolveExecutable?: (settings: { executablePath?: string }) => string;\n};\n\nconst defaultResolveExecutable = (settings: { executablePath?: string }): string =>\n\tresolveCursorAgentExecutable({ ...defaultCursorAgentExecutableDeps(), settings });\n\n/**\n * Registers the cursor-cli-oauth provider lane. Registration is unconditional:\n * the provider ships with the offline model fallback and reports availability\n * through the oauth `check`, so a missing cursor-agent binary never hides the\n * lane - it only makes `check` name the install guidance.\n */\nexport function registerCursorCliOauthExtension(pi: ExtensionAPI, deps: CursorCliOauthExtensionDeps = {}): void {\n\tconst cwd = deps.cwd ?? process.cwd();\n\tconst agentDir = deps.agentDir ?? getAgentDir();\n\tconst store = deps.store ?? AuthStorage.create();\n\tconst readCurrent = deps.readCurrent ?? (async () => store.read(CURSOR_CLI_OAUTH_PROVIDER_ID));\n\tconst loadSettings = deps.loadSettings ?? loadCursorCliOauthProviderSettingsFromDisk;\n\tconst resolveExecutable = deps.resolveExecutable ?? defaultResolveExecutable;\n\n\t// Todo 21: /cursor-account command plus the reload/shutdown teardown for\n\t// this extension generation (minimal additive wiring).\n\tregisterCursorCliAccountCommand(pi);\n\n\tconst register = (models: readonly ProviderModelConfig[]): void => {\n\t\tpi.registerProvider(CURSOR_CLI_OAUTH_PROVIDER_ID, {\n\t\t\tbaseUrl: CURSOR_CLI_OAUTH_PROVIDER_ID,\n\t\t\tapi: CURSOR_CLI_OAUTH_PROVIDER_ID,\n\t\t\tmodels: models.map((entry) => ({ ...entry })),\n\t\t\t// Settings, accounts, and the executable are re-resolved inside every\n\t\t\t// turn; nothing captured here outlives a settings or credential change.\n\t\t\tstreamSimple: (model, context, options) =>\n\t\t\t\tstreamCursorCliOauth(model, context, options, { cwd, agentDir, store }),\n\t\t\toauth: createCursorCliOauthConfig({\n\t\t\t\treadCurrent,\n\t\t\t\treadSettings: () => loadSettings(cwd),\n\t\t\t\tresolveExecutable,\n\t\t\t\tpersistAcknowledgement: (acknowledgedAt) => persistCursorCliNoApprovalAcknowledgement(cwd, acknowledgedAt),\n\t\t\t\tpersistEnabled: (enabled) => persistCursorCliOauthEnabled(cwd, enabled),\n\t\t\t}),\n\t\t});\n\t};\n\n\t// Register immediately with the offline fallback so a missing, hanging, or\n\t// broken cursor-agent can never delay or block provider registration; the\n\t// probe-backed catalog replaces it once resolved.\n\tregister(STATIC_CURSOR_CLI_MODELS);\n\tconst settings = loadSettings(cwd);\n\tvoid resolveCursorCliModelCatalog({\n\t\tagentDir,\n\t\tsettings: {\n\t\t\tmodelCatalogTtlHours: settings.modelCatalogTtlHours,\n\t\t\texecutablePath: settings.executablePath,\n\t\t},\n\t\tdeps: { resolveExecutable: () => resolveExecutable({ executablePath: settings.executablePath }) },\n\t})\n\t\t.then((models) => {\n\t\t\tconst resolved = models.map((entry) => entry.id).join(\"\\n\");\n\t\t\tif (resolved !== STATIC_CURSOR_CLI_MODELS.map((entry) => entry.id).join(\"\\n\")) register(models);\n\t\t})\n\t\t.catch(() => {\n\t\t\t// The loader degrades to the static fallback itself; keep the registered fallback.\n\t\t});\n}\n\nexport default function cursorCliOauthExtension(pi: ExtensionAPI): void {\n\tregisterCursorCliOauthExtension(pi);\n}\n"]}
|
|
@@ -21,6 +21,8 @@ export type CursorCliOauthConfigDeps = {
|
|
|
21
21
|
now?: () => Date;
|
|
22
22
|
/** Persists the no-approval acknowledgement; the disk default is wired in defaultCursorCliOauthConfig. */
|
|
23
23
|
persistAcknowledgement?: (acknowledgedAt: string) => void;
|
|
24
|
+
/** Persists explicit provider activation after a successful login. */
|
|
25
|
+
persistEnabled?: (enabled: boolean) => void;
|
|
24
26
|
};
|
|
25
27
|
export type CursorCliOauthLaneResolution = {
|
|
26
28
|
lane: typeof FILE_STORE_LANE;
|
|
@@ -68,6 +70,8 @@ export declare function confirmCursorCliNoApprovalAcknowledgement(onPrompt: ((pr
|
|
|
68
70
|
export declare function createCursorCliOauthConfig(deps: CursorCliOauthConfigDeps): CursorCliOauthConfig;
|
|
69
71
|
/** Explicitly copy the user's local Cursor credential into this provider's managed account slots. */
|
|
70
72
|
export declare function importLocalCursorCredential(current: CursorCliOauthCredential, deps?: LocalCursorImportDeps): Promise<CursorCliOauthCredential>;
|
|
73
|
+
/** Explicitly copy Senpi's native `cursor` OAuth credential into a managed CLI account slot. */
|
|
74
|
+
export declare function importNativeCursorCredential(current: CursorCliOauthCredential, readNativeCredential: () => Credential | undefined | Promise<Credential | undefined>): Promise<CursorCliOauthCredential>;
|
|
71
75
|
export declare function defaultCursorCliOauthConfig(cwd: string, readCurrent: () => Promise<Credential | undefined>): CursorCliOauthConfig;
|
|
72
76
|
export {};
|
|
73
77
|
//# sourceMappingURL=oauth-login.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-login.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/cursor-cli-oauth/oauth-login.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACX,SAAS,EACT,WAAW,EACX,UAAU,EACV,SAAS,EACT,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EAEnB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAEN,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAI7B,MAAM,eAAe,CAAC;AAOvB,OAAO,EACN,KAAK,8BAA8B,
|
|
1
|
+
{"version":3,"file":"oauth-login.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/cursor-cli-oauth/oauth-login.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@ import { cursorProvider } from "@earendil-works/pi-ai/providers/cursor";
|
|
|
6
6
|
import { addAccount, emptyCredential, listAccounts, SENTINEL_OAUTH_FIELDS, } from "./accounts.js";
|
|
7
7
|
import { defaultCursorAgentExecutableDeps, resolveCursorAgentExecutable, } from "./executable.js";
|
|
8
8
|
import { CURSOR_CLI_OAUTH_NO_APPROVAL_EXPLANATION } from "./guardrails.js";
|
|
9
|
-
import { loadCursorCliOauthProviderSettingsFromDisk, persistCursorCliNoApprovalAcknowledgement, } from "./settings.js";
|
|
9
|
+
import { loadCursorCliOauthProviderSettingsFromDisk, persistCursorCliNoApprovalAcknowledgement, persistCursorCliOauthEnabled, } from "./settings.js";
|
|
10
10
|
export const CURSOR_CLI_OAUTH_PROVIDER_ID = "cursor-cli-oauth";
|
|
11
11
|
export const CURSOR_CLI_OAUTH_NAME = "Cursor CLI (OAuth)";
|
|
12
12
|
const NO_ACCOUNTS_MESSAGE = "no accounts: run /login cursor-cli-oauth";
|
|
@@ -209,7 +209,9 @@ export function createCursorCliOauthConfig(deps) {
|
|
|
209
209
|
const acknowledgedAt = await confirmCursorCliNoApprovalAcknowledgement(callbacks.onPrompt, deps.now ?? (() => new Date()));
|
|
210
210
|
if (acknowledgedAt !== undefined)
|
|
211
211
|
deps.persistAcknowledgement?.(acknowledgedAt);
|
|
212
|
-
|
|
212
|
+
const credential = addAccount(current, slotFromCredential(loggedIn, name, "login"));
|
|
213
|
+
deps.persistEnabled?.(true);
|
|
214
|
+
return credential;
|
|
213
215
|
},
|
|
214
216
|
async refreshToken(credentials, signal) {
|
|
215
217
|
if (!isCursorCliOauthCredential(credentials))
|
|
@@ -312,6 +314,34 @@ export async function importLocalCursorCredential(current, deps = {}) {
|
|
|
312
314
|
expires: imported.expires ?? Date.now() + DEFAULT_IMPORTED_EXPIRY_MS,
|
|
313
315
|
}, name, "import"));
|
|
314
316
|
}
|
|
317
|
+
function isUsableFlatOAuthCredential(value) {
|
|
318
|
+
return (value?.type === "oauth" &&
|
|
319
|
+
typeof value.access === "string" &&
|
|
320
|
+
value.access.length > 0 &&
|
|
321
|
+
typeof value.refresh === "string" &&
|
|
322
|
+
value.refresh.length > 0 &&
|
|
323
|
+
typeof value.expires === "number" &&
|
|
324
|
+
Number.isFinite(value.expires));
|
|
325
|
+
}
|
|
326
|
+
function nativeAccountName(existing) {
|
|
327
|
+
const names = new Set(existing.map((account) => account.name));
|
|
328
|
+
if (!names.has("native"))
|
|
329
|
+
return "native";
|
|
330
|
+
for (let index = 2; index <= 10_000; index++) {
|
|
331
|
+
const candidate = `native-${index}`;
|
|
332
|
+
if (!names.has(candidate))
|
|
333
|
+
return candidate;
|
|
334
|
+
}
|
|
335
|
+
throw new Error("Could not allocate a Cursor CLI OAuth native account name");
|
|
336
|
+
}
|
|
337
|
+
/** Explicitly copy Senpi's native `cursor` OAuth credential into a managed CLI account slot. */
|
|
338
|
+
export async function importNativeCursorCredential(current, readNativeCredential) {
|
|
339
|
+
const native = await readNativeCredential();
|
|
340
|
+
if (!isUsableFlatOAuthCredential(native)) {
|
|
341
|
+
throw new Error("No stored native Cursor OAuth credential found");
|
|
342
|
+
}
|
|
343
|
+
return addAccount(current, slotFromCredential(native, nativeAccountName(listAccounts(current)), "import"));
|
|
344
|
+
}
|
|
315
345
|
export function defaultCursorCliOauthConfig(cwd, readCurrent) {
|
|
316
346
|
return createCursorCliOauthConfig({
|
|
317
347
|
readCurrent,
|
|
@@ -325,6 +355,7 @@ export function defaultCursorCliOauthConfig(cwd, readCurrent) {
|
|
|
325
355
|
},
|
|
326
356
|
now: () => new Date(),
|
|
327
357
|
persistAcknowledgement: (acknowledgedAt) => persistCursorCliNoApprovalAcknowledgement(cwd, acknowledgedAt),
|
|
358
|
+
persistEnabled: (enabled) => persistCursorCliOauthEnabled(cwd, enabled),
|
|
328
359
|
});
|
|
329
360
|
}
|
|
330
361
|
//# sourceMappingURL=oauth-login.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-login.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/cursor-cli-oauth/oauth-login.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile as nodeExecFile } from \"node:child_process\";\nimport { readFile as nodeReadFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type {\n\tAuthCheck,\n\tAuthContext,\n\tCredential,\n\tOAuthAuth,\n\tOAuthCredential,\n\tOAuthCredentials,\n\tOAuthLoginCallbacks,\n\tProviderAuthInteraction,\n} from \"@earendil-works/pi-ai\";\nimport { cursorProvider } from \"@earendil-works/pi-ai/providers/cursor\";\nimport {\n\taddAccount,\n\ttype CursorCliAccountSlot,\n\ttype CursorCliOauthCredential,\n\temptyCredential,\n\tlistAccounts,\n\tSENTINEL_OAUTH_FIELDS,\n} from \"./accounts.ts\";\nimport {\n\ttype CursorAgentExecutableDeps,\n\tdefaultCursorAgentExecutableDeps,\n\tresolveCursorAgentExecutable,\n} from \"./executable.ts\";\nimport { CURSOR_CLI_OAUTH_NO_APPROVAL_EXPLANATION } from \"./guardrails.ts\";\nimport {\n\ttype CursorCliOauthProviderSettings,\n\tloadCursorCliOauthProviderSettingsFromDisk,\n\tpersistCursorCliNoApprovalAcknowledgement,\n} from \"./settings.ts\";\n\nexport const CURSOR_CLI_OAUTH_PROVIDER_ID = \"cursor-cli-oauth\";\nexport const CURSOR_CLI_OAUTH_NAME = \"Cursor CLI (OAuth)\";\n\nconst NO_ACCOUNTS_MESSAGE = \"no accounts: run /login cursor-cli-oauth\";\nconst DISABLED_MESSAGE = \"disabled by settings\";\nconst FILE_STORE_LANE = \"file-store\" as const;\nconst DEFAULT_IMPORTED_EXPIRY_MS = 60 * 60 * 1000;\n\ntype CursorCliOauthSettings = Pick<CursorCliOauthProviderSettings, \"enabled\" | \"executablePath\">;\n\ntype ImportedCursorCredential = {\n\taccess: string;\n\trefresh: string;\n\texpires?: number;\n};\n\nexport type CursorCliOauthConfigDeps = {\n\treadCurrent: () => Promise<Credential | undefined>;\n\treadSettings: () => CursorCliOauthSettings;\n\tresolveExecutable: (settings: CursorCliOauthSettings) => string;\n\tloadOAuth?: () => Promise<OAuthAuth>;\n\treadCursorFile?: () => Promise<ImportedCursorCredential | undefined>;\n\treadCursorKeychain?: () => Promise<ImportedCursorCredential | undefined>;\n\t/** Clock for acknowledgement timestamps; injectable so tests stay deterministic. */\n\tnow?: () => Date;\n\t/** Persists the no-approval acknowledgement; the disk default is wired in defaultCursorCliOauthConfig. */\n\tpersistAcknowledgement?: (acknowledgedAt: string) => void;\n};\n\nexport type CursorCliOauthLaneResolution = {\n\tlane: typeof FILE_STORE_LANE;\n\taccount: CursorCliAccountSlot;\n\taccounts: CursorCliAccountSlot[];\n};\n\nexport type CursorCliOauthConfig = {\n\tname: string;\n\tisSubscription: true;\n\tcheck(input: {\n\t\tctx: AuthContext;\n\t\tcredential?: OAuthCredential;\n\t\tsignal?: AbortSignal;\n\t}): Promise<AuthCheck | undefined>;\n\tlogin(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials>;\n\trefreshToken(credentials: OAuthCredentials, signal: AbortSignal): Promise<OAuthCredentials>;\n\tgetApiKey(credentials: OAuthCredentials): string;\n};\n\nexport type LocalCursorImportDeps = {\n\tplatform?: NodeJS.Platform;\n\treadCursorFile?: () => Promise<ImportedCursorCredential | undefined>;\n\treadCursorKeychain?: () => Promise<ImportedCursorCredential | undefined>;\n\tonPrompt?: OAuthLoginCallbacks[\"onPrompt\"];\n};\n\ntype ConfigurationAssessment = {\n\taccounts: CursorCliAccountSlot[];\n\tmessage: string;\n};\n\n/** The single condition evaluation behind both the tolerant `check` and the throwing turn-time resolution. */\ntype ConfigurationOutcome =\n\t| { status: \"disabled\" }\n\t| { status: \"not-installed\"; error: unknown }\n\t| { status: \"no-accounts\" }\n\t| { status: \"configured\"; assessment: ConfigurationAssessment };\n\n/**\n * One predicate so availability and resolution cannot disagree: evaluates the\n * same conditions for every caller and reports why the lane is unusable\n * instead of deciding per call-site whether that is fatal.\n */\nasync function assessConfiguration(deps: CursorCliOauthConfigDeps): Promise<ConfigurationOutcome> {\n\tconst settings = deps.readSettings();\n\tif (!settings.enabled) return { status: \"disabled\" };\n\ttry {\n\t\tdeps.resolveExecutable(settings);\n\t} catch (error) {\n\t\treturn { status: \"not-installed\", error };\n\t}\n\n\tconst accounts = usableAccounts(await deps.readCurrent());\n\tif (accounts.length === 0) return { status: \"no-accounts\" };\n\treturn {\n\t\tstatus: \"configured\",\n\t\tassessment: { accounts, message: `configured (file-store, ${accounts.length} accounts)` },\n\t};\n}\n\n/** The throwing view used by turn-time resolution; a turn attempted on an unusable lane must still error clearly. */\nasync function configuredFor(deps: CursorCliOauthConfigDeps): Promise<ConfigurationAssessment> {\n\tconst outcome = await assessConfiguration(deps);\n\tswitch (outcome.status) {\n\t\tcase \"disabled\":\n\t\t\tthrow new Error(DISABLED_MESSAGE);\n\t\tcase \"not-installed\":\n\t\t\tthrow cursorAgentNotInstalledError(outcome.error);\n\t\tcase \"no-accounts\":\n\t\t\tthrow new Error(NO_ACCOUNTS_MESSAGE);\n\t\tdefault:\n\t\t\treturn outcome.assessment;\n\t}\n}\n\nfunction isCursorCliOauthCredential(\n\tvalue: Credential | OAuthCredentials | undefined,\n): value is CursorCliOauthCredential {\n\tif (typeof value !== \"object\" || value === null) return false;\n\tconst candidate = value as Partial<CursorCliOauthCredential>;\n\treturn candidate.type === \"oauth\" && Array.isArray(candidate.accounts);\n}\n\nfunction usableAccounts(value: Credential | OAuthCredentials | undefined): CursorCliAccountSlot[] {\n\tif (!isCursorCliOauthCredential(value)) return [];\n\treturn listAccounts(value).filter(\n\t\t(slot) =>\n\t\t\ttypeof slot.name === \"string\" &&\n\t\t\ttypeof slot.access === \"string\" &&\n\t\t\tslot.access.trim().length > 0 &&\n\t\t\ttypeof slot.refresh === \"string\" &&\n\t\t\tslot.refresh.trim().length > 0 &&\n\t\t\ttypeof slot.expires === \"number\" &&\n\t\t\tNumber.isFinite(slot.expires),\n\t);\n}\n\nfunction installationMessage(error: unknown): string {\n\tconst detail = error instanceof Error ? error.message : String(error);\n\treturn `cursor-agent not installed: ${detail.replace(/^Cursor CLI is not installed\\.\\s*/, \"\")}`;\n}\n\n/**\n * The typed turn-path error for a missing cursor-agent binary: carries the\n * `cursor-agent not installed` marker plus the install guidance verbatim, with\n * the underlying resolution failure preserved as `cause`.\n */\nexport function cursorAgentNotInstalledError(cause: unknown): Error {\n\tconst error = new Error(installationMessage(cause));\n\terror.name = \"CursorAgentNotInstalledError\";\n\terror.cause = cause;\n\treturn error;\n}\n\n/** Resolve credentials immediately before execution so a concurrent refresh cannot leave a stale token in memory. */\nexport async function resolveCursorCliOauthLane(deps: CursorCliOauthConfigDeps): Promise<CursorCliOauthLaneResolution> {\n\tconst assessment = await configuredFor(deps);\n\tconst account = assessment.accounts[0];\n\tif (!account) throw new Error(NO_ACCOUNTS_MESSAGE);\n\treturn { lane: FILE_STORE_LANE, account, accounts: assessment.accounts };\n}\n\nasync function loadCursorOAuthFlow(): Promise<OAuthAuth> {\n\tconst flow = cursorProvider().auth.oauth;\n\tif (!flow) throw new Error(\"Cursor OAuth flow is unavailable\");\n\treturn flow;\n}\n\nfunction providerInteraction(callbacks: OAuthLoginCallbacks): ProviderAuthInteraction {\n\treturn {\n\t\tsignal: callbacks.signal ?? new AbortController().signal,\n\t\tprompt: async (prompt) => {\n\t\t\tswitch (prompt.type) {\n\t\t\t\tcase \"select\":\n\t\t\t\t\treturn (await callbacks.onSelect(prompt)) ?? \"\";\n\t\t\t\tcase \"manual_code\":\n\t\t\t\t\treturn callbacks.onManualCodeInput?.() ?? callbacks.onPrompt(prompt);\n\t\t\t\tdefault:\n\t\t\t\t\treturn callbacks.onPrompt(prompt);\n\t\t\t}\n\t\t},\n\t\tnotify: (event) => {\n\t\t\tswitch (event.type) {\n\t\t\t\tcase \"auth_url\":\n\t\t\t\t\tcallbacks.onAuth({ url: event.url, instructions: event.instructions });\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"device_code\":\n\t\t\t\t\tcallbacks.onDeviceCode(event);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"progress\":\n\t\t\t\t\tcallbacks.onProgress?.(event.message);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"info\":\n\t\t\t\t\tcallbacks.onProgress?.(event.message);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t},\n\t};\n}\n\nasync function accountName(\n\texisting: CursorCliAccountSlot[],\n\tonPrompt: OAuthLoginCallbacks[\"onPrompt\"] | undefined,\n): Promise<string> {\n\tif (existing.length === 0) return \"default\";\n\tconst fallback = `account-${existing.length + 1}`;\n\tif (!onPrompt) return fallback;\n\tconst answer = (\n\t\tawait onPrompt({\n\t\t\tmessage: `Name for this account (existing: ${existing.map((slot) => slot.name).join(\", \")})`,\n\t\t\tplaceholder: fallback,\n\t\t})\n\t).trim();\n\treturn answer || fallback;\n}\n\nfunction slotFromCredential(\n\tcredential: Pick<OAuthCredentials, \"access\" | \"refresh\" | \"expires\">,\n\tname: string,\n\tsource: CursorCliAccountSlot[\"source\"],\n): CursorCliAccountSlot {\n\treturn {\n\t\tname,\n\t\taccess: credential.access,\n\t\trefresh: credential.refresh,\n\t\texpires: credential.expires,\n\t\tsource,\n\t};\n}\n\n/** The one-screen login explanation: what unattended Cursor CLI execution gives up, and the plan-mode alternative. */\nexport const CURSOR_CLI_OAUTH_LOGIN_ACKNOWLEDGEMENT_EXPLANATION = `${CURSOR_CLI_OAUTH_NO_APPROVAL_EXPLANATION} Plan mode (planning only, no tool execution) is available via the executionMode setting.`;\n\nconst ACKNOWLEDGEMENT_ACCEPTANCE = new Set([\"yes\", \"y\"]);\n\n/**\n * Present the no-approval explanation exactly once and return the ISO\n * acknowledgement timestamp on explicit confirmation, undefined otherwise.\n * Shared by the login flow and the /cursor-account acknowledge subcommand so\n * both surfaces present the identical explanation and persist identically.\n */\nexport async function confirmCursorCliNoApprovalAcknowledgement(\n\tonPrompt: ((prompt: { message: string; placeholder?: string }) => Promise<string>) | undefined,\n\tnow: () => Date,\n): Promise<string | undefined> {\n\tif (!onPrompt) return undefined;\n\tconst answer = (\n\t\tawait onPrompt({\n\t\t\tmessage: `${CURSOR_CLI_OAUTH_LOGIN_ACKNOWLEDGEMENT_EXPLANATION}\\nType \"yes\" to acknowledge and allow unattended Cursor CLI tool execution; anything else leaves it off.`,\n\t\t})\n\t)\n\t\t.trim()\n\t\t.toLowerCase();\n\treturn ACKNOWLEDGEMENT_ACCEPTANCE.has(answer) ? now().toISOString() : undefined;\n}\n\nexport function createCursorCliOauthConfig(deps: CursorCliOauthConfigDeps): CursorCliOauthConfig {\n\treturn {\n\t\tname: CURSOR_CLI_OAUTH_NAME,\n\t\tisSubscription: true,\n\n\t\tasync check(input) {\n\t\t\t// Tolerant by contract: ModelsImpl.getAvailable runs every provider's\n\t\t\t// check under Promise.all (packages/ai/src/models.ts:544-548) and turns a\n\t\t\t// throw into a rejecting ModelsError, so one throwing check would reject\n\t\t\t// all model listing. Not usable (disabled / not installed / no accounts)\n\t\t\t// reports undefined here - as claude-sdk-oauth's check does - while\n\t\t\t// turn-time resolution keeps throwing via configuredFor.\n\t\t\t//\n\t\t\t// One nuance: the auth-resolution path (checkAuth, resolveStoredOAuth)\n\t\t\t// always passes the stored credential, while bare model listing does not.\n\t\t\t// A credential-backed lane whose executable is missing stays selectable\n\t\t\t// with the install guidance as its source, so a TURN reaches\n\t\t\t// streamCursorCliOauth, which throws the typed not-installed error;\n\t\t\t// without a credential the lane hides exactly as before.\n\t\t\tconst outcome = await assessConfiguration(deps);\n\t\t\tif (outcome.status === \"disabled\" || outcome.status === \"no-accounts\") return undefined;\n\t\t\tif (outcome.status === \"not-installed\") {\n\t\t\t\treturn input.credential === undefined\n\t\t\t\t\t? undefined\n\t\t\t\t\t: { type: \"oauth\", source: installationMessage(outcome.error) };\n\t\t\t}\n\t\t\treturn { type: \"oauth\", source: outcome.assessment.message };\n\t\t},\n\n\t\tasync login(callbacks) {\n\t\t\tconst stored = await deps.readCurrent();\n\t\t\tconst current = isCursorCliOauthCredential(stored) ? stored : emptyCredential();\n\t\t\tconst existing = listAccounts(current);\n\t\t\tconst flow = await (deps.loadOAuth ?? loadCursorOAuthFlow)();\n\t\t\tconst loggedIn = await flow.login(providerInteraction(callbacks));\n\t\t\tconst name = await accountName(existing, callbacks.onPrompt);\n\t\t\t// After the PKCE flow succeeds and before the slot is stored: the\n\t\t\t// one-screen no-approval explanation, confirmed once. Declining still\n\t\t\t// stores the slot; only the acknowledgement stays unset, so force turns\n\t\t\t// refuse until the user acknowledges later.\n\t\t\tconst acknowledgedAt = await confirmCursorCliNoApprovalAcknowledgement(\n\t\t\t\tcallbacks.onPrompt,\n\t\t\t\tdeps.now ?? (() => new Date()),\n\t\t\t);\n\t\t\tif (acknowledgedAt !== undefined) deps.persistAcknowledgement?.(acknowledgedAt);\n\t\t\treturn addAccount(current, slotFromCredential(loggedIn, name, \"login\"));\n\t\t},\n\n\t\tasync refreshToken(credentials, signal) {\n\t\t\tif (!isCursorCliOauthCredential(credentials)) return credentials;\n\t\t\tconst flow = await (deps.loadOAuth ?? loadCursorOAuthFlow)();\n\t\t\tconst accounts: CursorCliAccountSlot[] = [];\n\t\t\tfor (const slot of listAccounts(credentials)) {\n\t\t\t\tif (Date.now() < slot.expires) {\n\t\t\t\t\taccounts.push(slot);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst refreshed = await flow.refresh(\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"oauth\",\n\t\t\t\t\t\taccess: slot.access,\n\t\t\t\t\t\trefresh: slot.refresh,\n\t\t\t\t\t\texpires: slot.expires,\n\t\t\t\t\t},\n\t\t\t\t\tsignal,\n\t\t\t\t);\n\t\t\t\taccounts.push({\n\t\t\t\t\t...slot,\n\t\t\t\t\taccess: refreshed.access,\n\t\t\t\t\trefresh: refreshed.refresh,\n\t\t\t\t\texpires: refreshed.expires,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn { ...credentials, ...SENTINEL_OAUTH_FIELDS, accounts };\n\t\t},\n\n\t\tgetApiKey() {\n\t\t\treturn SENTINEL_OAUTH_FIELDS.access;\n\t\t},\n\t};\n}\n\nfunction execFileOutput(file: string, args: string[]): Promise<string | undefined> {\n\treturn new Promise((resolve) => {\n\t\tnodeExecFile(file, args, { encoding: \"utf8\" }, (error, stdout) => {\n\t\t\tif (error) {\n\t\t\t\tresolve(undefined);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst value = stdout.trim();\n\t\t\tresolve(value.length > 0 ? value : undefined);\n\t\t});\n\t});\n}\n\nasync function defaultKeychainCredential(): Promise<ImportedCursorCredential | undefined> {\n\tif (process.platform !== \"darwin\") return undefined;\n\tconst [access, refresh] = await Promise.all([\n\t\texecFileOutput(\"security\", [\"find-generic-password\", \"-a\", \"cursor-user\", \"-s\", \"cursor-access-token\", \"-w\"]),\n\t\texecFileOutput(\"security\", [\"find-generic-password\", \"-a\", \"cursor-user\", \"-s\", \"cursor-refresh-token\", \"-w\"]),\n\t]);\n\treturn access && refresh ? { access, refresh } : undefined;\n}\n\nfunction localCursorAuthPath(platform: NodeJS.Platform): string | undefined {\n\tswitch (platform) {\n\t\tcase \"darwin\":\n\t\t\treturn join(homedir(), \".cursor\", \"auth.json\");\n\t\tcase \"linux\":\n\t\t\treturn join(process.env.XDG_CONFIG_HOME ?? join(homedir(), \".config\"), \"cursor\", \"auth.json\");\n\t\tcase \"win32\": {\n\t\t\tconst appData = process.env.APPDATA;\n\t\t\treturn appData ? join(appData, \"Cursor\", \"auth.json\") : undefined;\n\t\t}\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\nasync function defaultFileCredential(platform: NodeJS.Platform): Promise<ImportedCursorCredential | undefined> {\n\tconst path = localCursorAuthPath(platform);\n\tif (!path) return undefined;\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(await nodeReadFile(path, \"utf8\"));\n\t\tif (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) return undefined;\n\t\tconst record = parsed as Record<string, unknown>;\n\t\tconst access = record.accessToken;\n\t\tconst refresh = record.refreshToken;\n\t\tif (typeof access !== \"string\" || access.length === 0 || typeof refresh !== \"string\" || refresh.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn { access, refresh };\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/** Explicitly copy the user's local Cursor credential into this provider's managed account slots. */\nexport async function importLocalCursorCredential(\n\tcurrent: CursorCliOauthCredential,\n\tdeps: LocalCursorImportDeps = {},\n): Promise<CursorCliOauthCredential> {\n\tconst platform = deps.platform ?? process.platform;\n\tconst readKeychain = deps.readCursorKeychain ?? defaultKeychainCredential;\n\tconst readFile = deps.readCursorFile ?? (() => defaultFileCredential(platform));\n\tconst imported = platform === \"darwin\" ? ((await readKeychain()) ?? (await readFile())) : await readFile();\n\tif (!imported) throw new Error(\"No local Cursor OAuth credential found\");\n\tconst existing = listAccounts(current);\n\tconst name = await accountName(existing, deps.onPrompt);\n\treturn addAccount(\n\t\tcurrent,\n\t\tslotFromCredential(\n\t\t\t{\n\t\t\t\taccess: imported.access,\n\t\t\t\trefresh: imported.refresh,\n\t\t\t\texpires: imported.expires ?? Date.now() + DEFAULT_IMPORTED_EXPIRY_MS,\n\t\t\t},\n\t\t\tname,\n\t\t\t\"import\",\n\t\t),\n\t);\n}\n\nexport function defaultCursorCliOauthConfig(\n\tcwd: string,\n\treadCurrent: () => Promise<Credential | undefined>,\n): CursorCliOauthConfig {\n\treturn createCursorCliOauthConfig({\n\t\treadCurrent,\n\t\treadSettings: () => loadCursorCliOauthProviderSettingsFromDisk(cwd),\n\t\tresolveExecutable: (settings) => {\n\t\t\tconst executableDeps: CursorAgentExecutableDeps = {\n\t\t\t\t...defaultCursorAgentExecutableDeps(),\n\t\t\t\tsettings,\n\t\t\t};\n\t\t\treturn resolveCursorAgentExecutable(executableDeps);\n\t\t},\n\t\tnow: () => new Date(),\n\t\tpersistAcknowledgement: (acknowledgedAt: string) =>\n\t\t\tpersistCursorCliNoApprovalAcknowledgement(cwd, acknowledgedAt),\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"oauth-login.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/cursor-cli-oauth/oauth-login.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile as nodeExecFile } from \"node:child_process\";\nimport { readFile as nodeReadFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type {\n\tAuthCheck,\n\tAuthContext,\n\tCredential,\n\tOAuthAuth,\n\tOAuthCredential,\n\tOAuthCredentials,\n\tOAuthLoginCallbacks,\n\tProviderAuthInteraction,\n} from \"@earendil-works/pi-ai\";\nimport { cursorProvider } from \"@earendil-works/pi-ai/providers/cursor\";\nimport {\n\taddAccount,\n\ttype CursorCliAccountSlot,\n\ttype CursorCliOauthCredential,\n\temptyCredential,\n\tlistAccounts,\n\tSENTINEL_OAUTH_FIELDS,\n} from \"./accounts.ts\";\nimport {\n\ttype CursorAgentExecutableDeps,\n\tdefaultCursorAgentExecutableDeps,\n\tresolveCursorAgentExecutable,\n} from \"./executable.ts\";\nimport { CURSOR_CLI_OAUTH_NO_APPROVAL_EXPLANATION } from \"./guardrails.ts\";\nimport {\n\ttype CursorCliOauthProviderSettings,\n\tloadCursorCliOauthProviderSettingsFromDisk,\n\tpersistCursorCliNoApprovalAcknowledgement,\n\tpersistCursorCliOauthEnabled,\n} from \"./settings.ts\";\n\nexport const CURSOR_CLI_OAUTH_PROVIDER_ID = \"cursor-cli-oauth\";\nexport const CURSOR_CLI_OAUTH_NAME = \"Cursor CLI (OAuth)\";\n\nconst NO_ACCOUNTS_MESSAGE = \"no accounts: run /login cursor-cli-oauth\";\nconst DISABLED_MESSAGE = \"disabled by settings\";\nconst FILE_STORE_LANE = \"file-store\" as const;\nconst DEFAULT_IMPORTED_EXPIRY_MS = 60 * 60 * 1000;\n\ntype CursorCliOauthSettings = Pick<CursorCliOauthProviderSettings, \"enabled\" | \"executablePath\">;\n\ntype ImportedCursorCredential = {\n\taccess: string;\n\trefresh: string;\n\texpires?: number;\n};\n\nexport type CursorCliOauthConfigDeps = {\n\treadCurrent: () => Promise<Credential | undefined>;\n\treadSettings: () => CursorCliOauthSettings;\n\tresolveExecutable: (settings: CursorCliOauthSettings) => string;\n\tloadOAuth?: () => Promise<OAuthAuth>;\n\treadCursorFile?: () => Promise<ImportedCursorCredential | undefined>;\n\treadCursorKeychain?: () => Promise<ImportedCursorCredential | undefined>;\n\t/** Clock for acknowledgement timestamps; injectable so tests stay deterministic. */\n\tnow?: () => Date;\n\t/** Persists the no-approval acknowledgement; the disk default is wired in defaultCursorCliOauthConfig. */\n\tpersistAcknowledgement?: (acknowledgedAt: string) => void;\n\t/** Persists explicit provider activation after a successful login. */\n\tpersistEnabled?: (enabled: boolean) => void;\n};\n\nexport type CursorCliOauthLaneResolution = {\n\tlane: typeof FILE_STORE_LANE;\n\taccount: CursorCliAccountSlot;\n\taccounts: CursorCliAccountSlot[];\n};\n\nexport type CursorCliOauthConfig = {\n\tname: string;\n\tisSubscription: true;\n\tcheck(input: {\n\t\tctx: AuthContext;\n\t\tcredential?: OAuthCredential;\n\t\tsignal?: AbortSignal;\n\t}): Promise<AuthCheck | undefined>;\n\tlogin(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials>;\n\trefreshToken(credentials: OAuthCredentials, signal: AbortSignal): Promise<OAuthCredentials>;\n\tgetApiKey(credentials: OAuthCredentials): string;\n};\n\nexport type LocalCursorImportDeps = {\n\tplatform?: NodeJS.Platform;\n\treadCursorFile?: () => Promise<ImportedCursorCredential | undefined>;\n\treadCursorKeychain?: () => Promise<ImportedCursorCredential | undefined>;\n\tonPrompt?: OAuthLoginCallbacks[\"onPrompt\"];\n};\n\ntype ConfigurationAssessment = {\n\taccounts: CursorCliAccountSlot[];\n\tmessage: string;\n};\n\n/** The single condition evaluation behind both the tolerant `check` and the throwing turn-time resolution. */\ntype ConfigurationOutcome =\n\t| { status: \"disabled\" }\n\t| { status: \"not-installed\"; error: unknown }\n\t| { status: \"no-accounts\" }\n\t| { status: \"configured\"; assessment: ConfigurationAssessment };\n\n/**\n * One predicate so availability and resolution cannot disagree: evaluates the\n * same conditions for every caller and reports why the lane is unusable\n * instead of deciding per call-site whether that is fatal.\n */\nasync function assessConfiguration(deps: CursorCliOauthConfigDeps): Promise<ConfigurationOutcome> {\n\tconst settings = deps.readSettings();\n\tif (!settings.enabled) return { status: \"disabled\" };\n\ttry {\n\t\tdeps.resolveExecutable(settings);\n\t} catch (error) {\n\t\treturn { status: \"not-installed\", error };\n\t}\n\n\tconst accounts = usableAccounts(await deps.readCurrent());\n\tif (accounts.length === 0) return { status: \"no-accounts\" };\n\treturn {\n\t\tstatus: \"configured\",\n\t\tassessment: { accounts, message: `configured (file-store, ${accounts.length} accounts)` },\n\t};\n}\n\n/** The throwing view used by turn-time resolution; a turn attempted on an unusable lane must still error clearly. */\nasync function configuredFor(deps: CursorCliOauthConfigDeps): Promise<ConfigurationAssessment> {\n\tconst outcome = await assessConfiguration(deps);\n\tswitch (outcome.status) {\n\t\tcase \"disabled\":\n\t\t\tthrow new Error(DISABLED_MESSAGE);\n\t\tcase \"not-installed\":\n\t\t\tthrow cursorAgentNotInstalledError(outcome.error);\n\t\tcase \"no-accounts\":\n\t\t\tthrow new Error(NO_ACCOUNTS_MESSAGE);\n\t\tdefault:\n\t\t\treturn outcome.assessment;\n\t}\n}\n\nfunction isCursorCliOauthCredential(\n\tvalue: Credential | OAuthCredentials | undefined,\n): value is CursorCliOauthCredential {\n\tif (typeof value !== \"object\" || value === null) return false;\n\tconst candidate = value as Partial<CursorCliOauthCredential>;\n\treturn candidate.type === \"oauth\" && Array.isArray(candidate.accounts);\n}\n\nfunction usableAccounts(value: Credential | OAuthCredentials | undefined): CursorCliAccountSlot[] {\n\tif (!isCursorCliOauthCredential(value)) return [];\n\treturn listAccounts(value).filter(\n\t\t(slot) =>\n\t\t\ttypeof slot.name === \"string\" &&\n\t\t\ttypeof slot.access === \"string\" &&\n\t\t\tslot.access.trim().length > 0 &&\n\t\t\ttypeof slot.refresh === \"string\" &&\n\t\t\tslot.refresh.trim().length > 0 &&\n\t\t\ttypeof slot.expires === \"number\" &&\n\t\t\tNumber.isFinite(slot.expires),\n\t);\n}\n\nfunction installationMessage(error: unknown): string {\n\tconst detail = error instanceof Error ? error.message : String(error);\n\treturn `cursor-agent not installed: ${detail.replace(/^Cursor CLI is not installed\\.\\s*/, \"\")}`;\n}\n\n/**\n * The typed turn-path error for a missing cursor-agent binary: carries the\n * `cursor-agent not installed` marker plus the install guidance verbatim, with\n * the underlying resolution failure preserved as `cause`.\n */\nexport function cursorAgentNotInstalledError(cause: unknown): Error {\n\tconst error = new Error(installationMessage(cause));\n\terror.name = \"CursorAgentNotInstalledError\";\n\terror.cause = cause;\n\treturn error;\n}\n\n/** Resolve credentials immediately before execution so a concurrent refresh cannot leave a stale token in memory. */\nexport async function resolveCursorCliOauthLane(deps: CursorCliOauthConfigDeps): Promise<CursorCliOauthLaneResolution> {\n\tconst assessment = await configuredFor(deps);\n\tconst account = assessment.accounts[0];\n\tif (!account) throw new Error(NO_ACCOUNTS_MESSAGE);\n\treturn { lane: FILE_STORE_LANE, account, accounts: assessment.accounts };\n}\n\nasync function loadCursorOAuthFlow(): Promise<OAuthAuth> {\n\tconst flow = cursorProvider().auth.oauth;\n\tif (!flow) throw new Error(\"Cursor OAuth flow is unavailable\");\n\treturn flow;\n}\n\nfunction providerInteraction(callbacks: OAuthLoginCallbacks): ProviderAuthInteraction {\n\treturn {\n\t\tsignal: callbacks.signal ?? new AbortController().signal,\n\t\tprompt: async (prompt) => {\n\t\t\tswitch (prompt.type) {\n\t\t\t\tcase \"select\":\n\t\t\t\t\treturn (await callbacks.onSelect(prompt)) ?? \"\";\n\t\t\t\tcase \"manual_code\":\n\t\t\t\t\treturn callbacks.onManualCodeInput?.() ?? callbacks.onPrompt(prompt);\n\t\t\t\tdefault:\n\t\t\t\t\treturn callbacks.onPrompt(prompt);\n\t\t\t}\n\t\t},\n\t\tnotify: (event) => {\n\t\t\tswitch (event.type) {\n\t\t\t\tcase \"auth_url\":\n\t\t\t\t\tcallbacks.onAuth({ url: event.url, instructions: event.instructions });\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"device_code\":\n\t\t\t\t\tcallbacks.onDeviceCode(event);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"progress\":\n\t\t\t\t\tcallbacks.onProgress?.(event.message);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"info\":\n\t\t\t\t\tcallbacks.onProgress?.(event.message);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t},\n\t};\n}\n\nasync function accountName(\n\texisting: CursorCliAccountSlot[],\n\tonPrompt: OAuthLoginCallbacks[\"onPrompt\"] | undefined,\n): Promise<string> {\n\tif (existing.length === 0) return \"default\";\n\tconst fallback = `account-${existing.length + 1}`;\n\tif (!onPrompt) return fallback;\n\tconst answer = (\n\t\tawait onPrompt({\n\t\t\tmessage: `Name for this account (existing: ${existing.map((slot) => slot.name).join(\", \")})`,\n\t\t\tplaceholder: fallback,\n\t\t})\n\t).trim();\n\treturn answer || fallback;\n}\n\nfunction slotFromCredential(\n\tcredential: Pick<OAuthCredentials, \"access\" | \"refresh\" | \"expires\">,\n\tname: string,\n\tsource: CursorCliAccountSlot[\"source\"],\n): CursorCliAccountSlot {\n\treturn {\n\t\tname,\n\t\taccess: credential.access,\n\t\trefresh: credential.refresh,\n\t\texpires: credential.expires,\n\t\tsource,\n\t};\n}\n\n/** The one-screen login explanation: what unattended Cursor CLI execution gives up, and the plan-mode alternative. */\nexport const CURSOR_CLI_OAUTH_LOGIN_ACKNOWLEDGEMENT_EXPLANATION = `${CURSOR_CLI_OAUTH_NO_APPROVAL_EXPLANATION} Plan mode (planning only, no tool execution) is available via the executionMode setting.`;\n\nconst ACKNOWLEDGEMENT_ACCEPTANCE = new Set([\"yes\", \"y\"]);\n\n/**\n * Present the no-approval explanation exactly once and return the ISO\n * acknowledgement timestamp on explicit confirmation, undefined otherwise.\n * Shared by the login flow and the /cursor-account acknowledge subcommand so\n * both surfaces present the identical explanation and persist identically.\n */\nexport async function confirmCursorCliNoApprovalAcknowledgement(\n\tonPrompt: ((prompt: { message: string; placeholder?: string }) => Promise<string>) | undefined,\n\tnow: () => Date,\n): Promise<string | undefined> {\n\tif (!onPrompt) return undefined;\n\tconst answer = (\n\t\tawait onPrompt({\n\t\t\tmessage: `${CURSOR_CLI_OAUTH_LOGIN_ACKNOWLEDGEMENT_EXPLANATION}\\nType \"yes\" to acknowledge and allow unattended Cursor CLI tool execution; anything else leaves it off.`,\n\t\t})\n\t)\n\t\t.trim()\n\t\t.toLowerCase();\n\treturn ACKNOWLEDGEMENT_ACCEPTANCE.has(answer) ? now().toISOString() : undefined;\n}\n\nexport function createCursorCliOauthConfig(deps: CursorCliOauthConfigDeps): CursorCliOauthConfig {\n\treturn {\n\t\tname: CURSOR_CLI_OAUTH_NAME,\n\t\tisSubscription: true,\n\n\t\tasync check(input) {\n\t\t\t// Tolerant by contract: ModelsImpl.getAvailable runs every provider's\n\t\t\t// check under Promise.all (packages/ai/src/models.ts:544-548) and turns a\n\t\t\t// throw into a rejecting ModelsError, so one throwing check would reject\n\t\t\t// all model listing. Not usable (disabled / not installed / no accounts)\n\t\t\t// reports undefined here - as claude-sdk-oauth's check does - while\n\t\t\t// turn-time resolution keeps throwing via configuredFor.\n\t\t\t//\n\t\t\t// One nuance: the auth-resolution path (checkAuth, resolveStoredOAuth)\n\t\t\t// always passes the stored credential, while bare model listing does not.\n\t\t\t// A credential-backed lane whose executable is missing stays selectable\n\t\t\t// with the install guidance as its source, so a TURN reaches\n\t\t\t// streamCursorCliOauth, which throws the typed not-installed error;\n\t\t\t// without a credential the lane hides exactly as before.\n\t\t\tconst outcome = await assessConfiguration(deps);\n\t\t\tif (outcome.status === \"disabled\" || outcome.status === \"no-accounts\") return undefined;\n\t\t\tif (outcome.status === \"not-installed\") {\n\t\t\t\treturn input.credential === undefined\n\t\t\t\t\t? undefined\n\t\t\t\t\t: { type: \"oauth\", source: installationMessage(outcome.error) };\n\t\t\t}\n\t\t\treturn { type: \"oauth\", source: outcome.assessment.message };\n\t\t},\n\n\t\tasync login(callbacks) {\n\t\t\tconst stored = await deps.readCurrent();\n\t\t\tconst current = isCursorCliOauthCredential(stored) ? stored : emptyCredential();\n\t\t\tconst existing = listAccounts(current);\n\t\t\tconst flow = await (deps.loadOAuth ?? loadCursorOAuthFlow)();\n\t\t\tconst loggedIn = await flow.login(providerInteraction(callbacks));\n\t\t\tconst name = await accountName(existing, callbacks.onPrompt);\n\t\t\t// After the PKCE flow succeeds and before the slot is stored: the\n\t\t\t// one-screen no-approval explanation, confirmed once. Declining still\n\t\t\t// stores the slot; only the acknowledgement stays unset, so force turns\n\t\t\t// refuse until the user acknowledges later.\n\t\t\tconst acknowledgedAt = await confirmCursorCliNoApprovalAcknowledgement(\n\t\t\t\tcallbacks.onPrompt,\n\t\t\t\tdeps.now ?? (() => new Date()),\n\t\t\t);\n\t\t\tif (acknowledgedAt !== undefined) deps.persistAcknowledgement?.(acknowledgedAt);\n\t\t\tconst credential = addAccount(current, slotFromCredential(loggedIn, name, \"login\"));\n\t\t\tdeps.persistEnabled?.(true);\n\t\t\treturn credential;\n\t\t},\n\n\t\tasync refreshToken(credentials, signal) {\n\t\t\tif (!isCursorCliOauthCredential(credentials)) return credentials;\n\t\t\tconst flow = await (deps.loadOAuth ?? loadCursorOAuthFlow)();\n\t\t\tconst accounts: CursorCliAccountSlot[] = [];\n\t\t\tfor (const slot of listAccounts(credentials)) {\n\t\t\t\tif (Date.now() < slot.expires) {\n\t\t\t\t\taccounts.push(slot);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst refreshed = await flow.refresh(\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"oauth\",\n\t\t\t\t\t\taccess: slot.access,\n\t\t\t\t\t\trefresh: slot.refresh,\n\t\t\t\t\t\texpires: slot.expires,\n\t\t\t\t\t},\n\t\t\t\t\tsignal,\n\t\t\t\t);\n\t\t\t\taccounts.push({\n\t\t\t\t\t...slot,\n\t\t\t\t\taccess: refreshed.access,\n\t\t\t\t\trefresh: refreshed.refresh,\n\t\t\t\t\texpires: refreshed.expires,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn { ...credentials, ...SENTINEL_OAUTH_FIELDS, accounts };\n\t\t},\n\n\t\tgetApiKey() {\n\t\t\treturn SENTINEL_OAUTH_FIELDS.access;\n\t\t},\n\t};\n}\n\nfunction execFileOutput(file: string, args: string[]): Promise<string | undefined> {\n\treturn new Promise((resolve) => {\n\t\tnodeExecFile(file, args, { encoding: \"utf8\" }, (error, stdout) => {\n\t\t\tif (error) {\n\t\t\t\tresolve(undefined);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst value = stdout.trim();\n\t\t\tresolve(value.length > 0 ? value : undefined);\n\t\t});\n\t});\n}\n\nasync function defaultKeychainCredential(): Promise<ImportedCursorCredential | undefined> {\n\tif (process.platform !== \"darwin\") return undefined;\n\tconst [access, refresh] = await Promise.all([\n\t\texecFileOutput(\"security\", [\"find-generic-password\", \"-a\", \"cursor-user\", \"-s\", \"cursor-access-token\", \"-w\"]),\n\t\texecFileOutput(\"security\", [\"find-generic-password\", \"-a\", \"cursor-user\", \"-s\", \"cursor-refresh-token\", \"-w\"]),\n\t]);\n\treturn access && refresh ? { access, refresh } : undefined;\n}\n\nfunction localCursorAuthPath(platform: NodeJS.Platform): string | undefined {\n\tswitch (platform) {\n\t\tcase \"darwin\":\n\t\t\treturn join(homedir(), \".cursor\", \"auth.json\");\n\t\tcase \"linux\":\n\t\t\treturn join(process.env.XDG_CONFIG_HOME ?? join(homedir(), \".config\"), \"cursor\", \"auth.json\");\n\t\tcase \"win32\": {\n\t\t\tconst appData = process.env.APPDATA;\n\t\t\treturn appData ? join(appData, \"Cursor\", \"auth.json\") : undefined;\n\t\t}\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\nasync function defaultFileCredential(platform: NodeJS.Platform): Promise<ImportedCursorCredential | undefined> {\n\tconst path = localCursorAuthPath(platform);\n\tif (!path) return undefined;\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(await nodeReadFile(path, \"utf8\"));\n\t\tif (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) return undefined;\n\t\tconst record = parsed as Record<string, unknown>;\n\t\tconst access = record.accessToken;\n\t\tconst refresh = record.refreshToken;\n\t\tif (typeof access !== \"string\" || access.length === 0 || typeof refresh !== \"string\" || refresh.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn { access, refresh };\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/** Explicitly copy the user's local Cursor credential into this provider's managed account slots. */\nexport async function importLocalCursorCredential(\n\tcurrent: CursorCliOauthCredential,\n\tdeps: LocalCursorImportDeps = {},\n): Promise<CursorCliOauthCredential> {\n\tconst platform = deps.platform ?? process.platform;\n\tconst readKeychain = deps.readCursorKeychain ?? defaultKeychainCredential;\n\tconst readFile = deps.readCursorFile ?? (() => defaultFileCredential(platform));\n\tconst imported = platform === \"darwin\" ? ((await readKeychain()) ?? (await readFile())) : await readFile();\n\tif (!imported) throw new Error(\"No local Cursor OAuth credential found\");\n\tconst existing = listAccounts(current);\n\tconst name = await accountName(existing, deps.onPrompt);\n\treturn addAccount(\n\t\tcurrent,\n\t\tslotFromCredential(\n\t\t\t{\n\t\t\t\taccess: imported.access,\n\t\t\t\trefresh: imported.refresh,\n\t\t\t\texpires: imported.expires ?? Date.now() + DEFAULT_IMPORTED_EXPIRY_MS,\n\t\t\t},\n\t\t\tname,\n\t\t\t\"import\",\n\t\t),\n\t);\n}\n\nfunction isUsableFlatOAuthCredential(value: Credential | undefined): value is OAuthCredential {\n\treturn (\n\t\tvalue?.type === \"oauth\" &&\n\t\ttypeof value.access === \"string\" &&\n\t\tvalue.access.length > 0 &&\n\t\ttypeof value.refresh === \"string\" &&\n\t\tvalue.refresh.length > 0 &&\n\t\ttypeof value.expires === \"number\" &&\n\t\tNumber.isFinite(value.expires)\n\t);\n}\n\nfunction nativeAccountName(existing: readonly CursorCliAccountSlot[]): string {\n\tconst names = new Set(existing.map((account) => account.name));\n\tif (!names.has(\"native\")) return \"native\";\n\tfor (let index = 2; index <= 10_000; index++) {\n\t\tconst candidate = `native-${index}`;\n\t\tif (!names.has(candidate)) return candidate;\n\t}\n\tthrow new Error(\"Could not allocate a Cursor CLI OAuth native account name\");\n}\n\n/** Explicitly copy Senpi's native `cursor` OAuth credential into a managed CLI account slot. */\nexport async function importNativeCursorCredential(\n\tcurrent: CursorCliOauthCredential,\n\treadNativeCredential: () => Credential | undefined | Promise<Credential | undefined>,\n): Promise<CursorCliOauthCredential> {\n\tconst native = await readNativeCredential();\n\tif (!isUsableFlatOAuthCredential(native)) {\n\t\tthrow new Error(\"No stored native Cursor OAuth credential found\");\n\t}\n\treturn addAccount(current, slotFromCredential(native, nativeAccountName(listAccounts(current)), \"import\"));\n}\n\nexport function defaultCursorCliOauthConfig(\n\tcwd: string,\n\treadCurrent: () => Promise<Credential | undefined>,\n): CursorCliOauthConfig {\n\treturn createCursorCliOauthConfig({\n\t\treadCurrent,\n\t\treadSettings: () => loadCursorCliOauthProviderSettingsFromDisk(cwd),\n\t\tresolveExecutable: (settings) => {\n\t\t\tconst executableDeps: CursorAgentExecutableDeps = {\n\t\t\t\t...defaultCursorAgentExecutableDeps(),\n\t\t\t\tsettings,\n\t\t\t};\n\t\t\treturn resolveCursorAgentExecutable(executableDeps);\n\t\t},\n\t\tnow: () => new Date(),\n\t\tpersistAcknowledgement: (acknowledgedAt: string) =>\n\t\t\tpersistCursorCliNoApprovalAcknowledgement(cwd, acknowledgedAt),\n\t\tpersistEnabled: (enabled: boolean) => persistCursorCliOauthEnabled(cwd, enabled),\n\t});\n}\n"]}
|
|
@@ -24,6 +24,8 @@ export declare function parseCursorCliOauthProviderSettings(value: unknown, envi
|
|
|
24
24
|
export declare function createCursorCliOauthSandboxModeValidator(acceptedModes: ReadonlySet<string>, onWarning: (message: string) => void): (value: string | undefined) => string | undefined;
|
|
25
25
|
/** Load global and project settings afresh, with env values taking final precedence. */
|
|
26
26
|
export declare function loadCursorCliOauthProviderSettingsFromDisk(cwd: string): CursorCliOauthProviderSettings;
|
|
27
|
+
/** Persist explicit provider activation while preserving every sibling setting. */
|
|
28
|
+
export declare function persistCursorCliOauthEnabled(cwd: string, enabled: boolean): void;
|
|
27
29
|
/**
|
|
28
30
|
* Read-modify-write `noApprovalAcknowledgedAt` into the provider block of the
|
|
29
31
|
* global settings file, preserving every other key. An unparseable file is
|