agents-pkg 0.6.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -20
- package/dist/add-plugin.d.ts +2 -2
- package/dist/add-plugin.d.ts.map +1 -1
- package/dist/add-plugin.js +36 -11
- package/dist/add-plugin.js.map +1 -1
- package/dist/del-marketplace.d.ts +1 -1
- package/dist/del-marketplace.d.ts.map +1 -1
- package/dist/del-marketplace.js +15 -27
- package/dist/del-marketplace.js.map +1 -1
- package/dist/del-plugin.d.ts +0 -1
- package/dist/del-plugin.d.ts.map +1 -1
- package/dist/del-plugin.js +8 -26
- package/dist/del-plugin.js.map +1 -1
- package/dist/lib/plugin-local.d.ts +10 -0
- package/dist/lib/plugin-local.d.ts.map +1 -0
- package/dist/lib/plugin-local.js +27 -0
- package/dist/lib/plugin-local.js.map +1 -0
- package/dist/lib/source-dir.d.ts +8 -0
- package/dist/lib/source-dir.d.ts.map +1 -1
- package/dist/lib/source-dir.js +58 -74
- package/dist/lib/source-dir.js.map +1 -1
- package/dist/lib/source-parser.d.ts +37 -0
- package/dist/lib/source-parser.d.ts.map +1 -0
- package/dist/lib/source-parser.js +214 -0
- package/dist/lib/source-parser.js.map +1 -0
- package/dist/lib/types.d.ts +1 -1
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/uninstall-plugin.d.ts +14 -0
- package/dist/lib/uninstall-plugin.d.ts.map +1 -0
- package/dist/lib/uninstall-plugin.js +33 -0
- package/dist/lib/uninstall-plugin.js.map +1 -0
- package/dist/update.d.ts.map +1 -1
- package/dist/update.js +31 -44
- package/dist/update.js.map +1 -1
- package/package.json +1 -1
package/dist/lib/source-dir.js
CHANGED
|
@@ -1,64 +1,68 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Resolve a source (GitHub owner/repo, git URL, or local path) to a local directory path.
|
|
3
3
|
* For remote sources, clones to a temp directory; caller must call cleanup() when done.
|
|
4
|
+
*
|
|
5
|
+
* Parsing of `source` (local vs. git, ref extraction) lives in `source-parser.ts`; this
|
|
6
|
+
* module only does filesystem/network work (stat a local path, or clone a git remote).
|
|
4
7
|
*/
|
|
5
|
-
import { resolve } from 'path';
|
|
6
8
|
import { mkdtemp, rm, stat } from 'fs/promises';
|
|
7
9
|
import { join } from 'path';
|
|
8
10
|
import { tmpdir } from 'os';
|
|
9
11
|
import { spawnSync } from 'child_process';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
import { parseSource } from './source-parser.js';
|
|
13
|
+
const DEFAULT_CLONE_TIMEOUT_MS = 300_000;
|
|
14
|
+
function getCloneTimeoutMs() {
|
|
15
|
+
const raw = process.env.AGENTS_PKG_CLONE_TIMEOUT_MS;
|
|
16
|
+
if (!raw)
|
|
17
|
+
return DEFAULT_CLONE_TIMEOUT_MS;
|
|
18
|
+
const parsed = Number(raw);
|
|
19
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_CLONE_TIMEOUT_MS;
|
|
18
20
|
}
|
|
19
21
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
+
* Clone `url` (optionally at `ref`) into a fresh temp directory and return its path.
|
|
23
|
+
* Caller owns the returned directory and should remove it when done.
|
|
22
24
|
*/
|
|
23
|
-
function
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
25
|
+
export async function cloneRepo(url, ref) {
|
|
26
|
+
const tempDir = await mkdtemp(join(tmpdir(), 'agents-pkg-'));
|
|
27
|
+
const cloneArgs = [
|
|
28
|
+
// Never smudge git-lfs content on checkout: avoids hard failures when git-lfs isn't installed.
|
|
29
|
+
'-c',
|
|
30
|
+
'filter.lfs.required=false',
|
|
31
|
+
'-c',
|
|
32
|
+
'filter.lfs.smudge=',
|
|
33
|
+
'-c',
|
|
34
|
+
'filter.lfs.clean=',
|
|
35
|
+
'-c',
|
|
36
|
+
'filter.lfs.process=',
|
|
37
|
+
'clone',
|
|
38
|
+
'--depth',
|
|
39
|
+
'1',
|
|
40
|
+
...(ref ? ['--branch', ref] : []),
|
|
41
|
+
url,
|
|
42
|
+
tempDir,
|
|
43
|
+
];
|
|
44
|
+
const result = spawnSync('git', cloneArgs, {
|
|
45
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
46
|
+
encoding: 'utf-8',
|
|
47
|
+
timeout: getCloneTimeoutMs(),
|
|
48
|
+
env: {
|
|
49
|
+
...process.env,
|
|
50
|
+
// Never hang on an auth prompt; fail fast instead.
|
|
51
|
+
GIT_TERMINAL_PROMPT: '0',
|
|
52
|
+
GIT_LFS_SKIP_SMUDGE: '1',
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
const target = ref ? `${url} (ref: ${ref})` : url;
|
|
56
|
+
if (result.error && result.error.code === 'ETIMEDOUT') {
|
|
57
|
+
await rm(tempDir, { recursive: true, force: true }).catch(() => { });
|
|
58
|
+
throw new Error(`Timed out cloning ${target} after ${getCloneTimeoutMs()}ms`);
|
|
56
59
|
}
|
|
57
|
-
if (
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
if (result.status !== 0) {
|
|
61
|
+
await rm(tempDir, { recursive: true, force: true }).catch(() => { });
|
|
62
|
+
const stderr = (result.stderr || '').trim();
|
|
63
|
+
throw new Error(`Failed to clone ${target}: ${stderr || result.error?.message || 'unknown error'}`);
|
|
60
64
|
}
|
|
61
|
-
return
|
|
65
|
+
return tempDir;
|
|
62
66
|
}
|
|
63
67
|
/**
|
|
64
68
|
* Resolve source to a local directory. For remote sources, clones to a temp dir.
|
|
@@ -69,9 +73,9 @@ export async function resolveSourceToDir(source) {
|
|
|
69
73
|
if (!trimmed) {
|
|
70
74
|
throw new Error('Source is required');
|
|
71
75
|
}
|
|
72
|
-
|
|
73
|
-
if (
|
|
74
|
-
const abs =
|
|
76
|
+
const parsed = parseSource(trimmed);
|
|
77
|
+
if (parsed.type === 'local') {
|
|
78
|
+
const abs = parsed.localPath ?? parsed.url;
|
|
75
79
|
try {
|
|
76
80
|
const st = await stat(abs);
|
|
77
81
|
if (!st.isDirectory()) {
|
|
@@ -85,31 +89,11 @@ export async function resolveSourceToDir(source) {
|
|
|
85
89
|
}
|
|
86
90
|
return { path: abs };
|
|
87
91
|
}
|
|
88
|
-
|
|
89
|
-
let cloneUrl;
|
|
90
|
-
if (isGitUrl(trimmed)) {
|
|
91
|
-
cloneUrl = trimmed;
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
cloneUrl = ownerRepoToUrl(trimmed);
|
|
95
|
-
if (!cloneUrl) {
|
|
96
|
-
throw new Error(`Invalid source: ${trimmed}. Use a local path, owner/repo, or a git URL.`);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
const tempDir = await mkdtemp(join(tmpdir(), 'agents-pkg-'));
|
|
100
|
-
const result = spawnSync('git', ['clone', '--depth', '1', cloneUrl, tempDir], {
|
|
101
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
102
|
-
encoding: 'utf-8',
|
|
103
|
-
});
|
|
104
|
-
if (result.status !== 0) {
|
|
105
|
-
await rm(tempDir, { recursive: true, force: true }).catch(() => { });
|
|
106
|
-
const stderr = (result.stderr || '').trim();
|
|
107
|
-
throw new Error(`Failed to clone ${cloneUrl}: ${stderr || result.error?.message || 'unknown error'}`);
|
|
108
|
-
}
|
|
92
|
+
const path = await cloneRepo(parsed.url, parsed.ref);
|
|
109
93
|
return {
|
|
110
|
-
path
|
|
94
|
+
path,
|
|
111
95
|
cleanup: async () => {
|
|
112
|
-
await rm(
|
|
96
|
+
await rm(path, { recursive: true, force: true });
|
|
113
97
|
},
|
|
114
98
|
};
|
|
115
99
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-dir.js","sourceRoot":"","sources":["../../src/lib/source-dir.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"source-dir.js","sourceRoot":"","sources":["../../src/lib/source-dir.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure parsing of a `source` string (as passed to `add-plugin` / stored in the lock file)
|
|
3
|
+
* into a structured description of where to get the code from: a local directory, or a
|
|
4
|
+
* git remote (with an optional ref) to clone.
|
|
5
|
+
*
|
|
6
|
+
* No filesystem or network access happens here; see `source-dir.ts` for resolution.
|
|
7
|
+
*
|
|
8
|
+
* Modeled after vercel-labs/skills' `parseSource`, with two deliberate deviations for
|
|
9
|
+
* agents-pkg (documented at their point of divergence below):
|
|
10
|
+
* - No skill-filter support (`#ref@skill` / `owner/repo@skill`); we select plugins via
|
|
11
|
+
* separate CLI args, so anything after `@` in a fragment is ignored.
|
|
12
|
+
* - No subpath support; a `tree/<ref>/<subpath>` (or gitlab `-/tree/<ref>/<subpath>`) only
|
|
13
|
+
* ever yields a ref, the subpath is dropped, since our installer always reads
|
|
14
|
+
* `.cursor-plugin/marketplace.json` at the repo root.
|
|
15
|
+
*/
|
|
16
|
+
export interface ParsedSource {
|
|
17
|
+
type: 'local' | 'github' | 'gitlab' | 'git';
|
|
18
|
+
url: string;
|
|
19
|
+
ref?: string;
|
|
20
|
+
localPath?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Whether `input` (the base, with any `#ref` already stripped) "looks like" a git source,
|
|
24
|
+
* i.e. the `#` fragment (if present) should be treated as a git ref rather than left as
|
|
25
|
+
* part of an opaque string.
|
|
26
|
+
*
|
|
27
|
+
* DEVIATION from vercel-labs/skills: they only treat http(s) URLs as git-like when they
|
|
28
|
+
* are github.com/gitlab.com or end in `.git`. agents-pkg only ever resolves git remotes
|
|
29
|
+
* (there's no other kind of http(s) source), so we additionally treat any plain
|
|
30
|
+
* `https?://<host>/<path>` (with at least one path segment) as git-like. This is what
|
|
31
|
+
* makes our primary internal use case (self-hosted GitLab URLs without a `.git` suffix,
|
|
32
|
+
* e.g. `https://git.example.com/group/subgroup/repo#branch/name`) parse the `#ref`
|
|
33
|
+
* fragment correctly.
|
|
34
|
+
*/
|
|
35
|
+
export declare function looksLikeGitSource(input: string): boolean;
|
|
36
|
+
export declare function parseSource(input: string): ParsedSource;
|
|
37
|
+
//# sourceMappingURL=source-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-parser.d.ts","sourceRoot":"","sources":["../../src/lib/source-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,CAAC;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAiCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAyBzD;AA4CD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAmFvD"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure parsing of a `source` string (as passed to `add-plugin` / stored in the lock file)
|
|
3
|
+
* into a structured description of where to get the code from: a local directory, or a
|
|
4
|
+
* git remote (with an optional ref) to clone.
|
|
5
|
+
*
|
|
6
|
+
* No filesystem or network access happens here; see `source-dir.ts` for resolution.
|
|
7
|
+
*
|
|
8
|
+
* Modeled after vercel-labs/skills' `parseSource`, with two deliberate deviations for
|
|
9
|
+
* agents-pkg (documented at their point of divergence below):
|
|
10
|
+
* - No skill-filter support (`#ref@skill` / `owner/repo@skill`); we select plugins via
|
|
11
|
+
* separate CLI args, so anything after `@` in a fragment is ignored.
|
|
12
|
+
* - No subpath support; a `tree/<ref>/<subpath>` (or gitlab `-/tree/<ref>/<subpath>`) only
|
|
13
|
+
* ever yields a ref, the subpath is dropped, since our installer always reads
|
|
14
|
+
* `.cursor-plugin/marketplace.json` at the repo root.
|
|
15
|
+
*/
|
|
16
|
+
import { resolve } from 'path';
|
|
17
|
+
function isLocalPath(input) {
|
|
18
|
+
const t = input.trim();
|
|
19
|
+
return (t.startsWith('./') ||
|
|
20
|
+
t.startsWith('../') ||
|
|
21
|
+
t === '.' ||
|
|
22
|
+
t === '..' ||
|
|
23
|
+
t.startsWith('/') ||
|
|
24
|
+
/^[a-zA-Z]:[/\\]/.test(t));
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* SSH-style URL without git@ prefix: host:path (e.g. git.example.com:owner/repo.git).
|
|
28
|
+
* Single colon, host-like left part, path-like right part.
|
|
29
|
+
*/
|
|
30
|
+
function isSshStyleUrl(input) {
|
|
31
|
+
const colonIdx = input.indexOf(':');
|
|
32
|
+
if (colonIdx <= 0 || colonIdx !== input.lastIndexOf(':'))
|
|
33
|
+
return false;
|
|
34
|
+
const host = input.slice(0, colonIdx);
|
|
35
|
+
const path = input.slice(colonIdx + 1);
|
|
36
|
+
const hostLooksValid = host.includes('.') || host === 'github' || host === 'gitlab';
|
|
37
|
+
const pathLooksValid = path.length > 0 && (path.includes('/') || path.endsWith('.git'));
|
|
38
|
+
return hostLooksValid && pathLooksValid;
|
|
39
|
+
}
|
|
40
|
+
const GITHUB_TREE_RE = /^https?:\/\/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)$/;
|
|
41
|
+
const GITHUB_TREE_SUBPATH_RE = /^https?:\/\/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)\/(.+)$/;
|
|
42
|
+
const GITLAB_TREE_RE = /^(https?):\/\/([^/]+)\/(.+?)\/-\/tree\/([^/]+)$/;
|
|
43
|
+
const GITLAB_TREE_SUBPATH_RE = /^(https?):\/\/([^/]+)\/(.+?)\/-\/tree\/([^/]+)\/(.+)$/;
|
|
44
|
+
/**
|
|
45
|
+
* Whether `input` (the base, with any `#ref` already stripped) "looks like" a git source,
|
|
46
|
+
* i.e. the `#` fragment (if present) should be treated as a git ref rather than left as
|
|
47
|
+
* part of an opaque string.
|
|
48
|
+
*
|
|
49
|
+
* DEVIATION from vercel-labs/skills: they only treat http(s) URLs as git-like when they
|
|
50
|
+
* are github.com/gitlab.com or end in `.git`. agents-pkg only ever resolves git remotes
|
|
51
|
+
* (there's no other kind of http(s) source), so we additionally treat any plain
|
|
52
|
+
* `https?://<host>/<path>` (with at least one path segment) as git-like. This is what
|
|
53
|
+
* makes our primary internal use case (self-hosted GitLab URLs without a `.git` suffix,
|
|
54
|
+
* e.g. `https://git.example.com/group/subgroup/repo#branch/name`) parse the `#ref`
|
|
55
|
+
* fragment correctly.
|
|
56
|
+
*/
|
|
57
|
+
export function looksLikeGitSource(input) {
|
|
58
|
+
const t = input.trim();
|
|
59
|
+
if (isLocalPath(t))
|
|
60
|
+
return false;
|
|
61
|
+
if (t.startsWith('github:') || t.startsWith('gitlab:') || t.startsWith('git@'))
|
|
62
|
+
return true;
|
|
63
|
+
// file:// URLs are a git-clonable remote (used for local git repos in tests/CI), not a plain local path.
|
|
64
|
+
if (t.startsWith('file://'))
|
|
65
|
+
return true;
|
|
66
|
+
if (/^ssh:\/\/.+\.git$/.test(t))
|
|
67
|
+
return true;
|
|
68
|
+
if (GITHUB_TREE_RE.test(t) || GITHUB_TREE_SUBPATH_RE.test(t))
|
|
69
|
+
return true;
|
|
70
|
+
if (GITLAB_TREE_RE.test(t) || GITLAB_TREE_SUBPATH_RE.test(t))
|
|
71
|
+
return true;
|
|
72
|
+
if (/^https?:\/\/.+\.git$/.test(t))
|
|
73
|
+
return true;
|
|
74
|
+
if (t.startsWith('http://') || t.startsWith('https://')) {
|
|
75
|
+
// Extended beyond vercel-labs/skills: see doc comment above.
|
|
76
|
+
try {
|
|
77
|
+
const u = new URL(t);
|
|
78
|
+
return u.pathname.replace(/^\/+/, '').length > 0;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (isSshStyleUrl(t))
|
|
85
|
+
return true;
|
|
86
|
+
// Bare owner/repo shorthand: no colon, not starting with `.` or `/`.
|
|
87
|
+
if (!t.includes(':') && !t.startsWith('.') && !t.startsWith('/') && /^[^/]+\/[^/]+$/.test(t)) {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
/** Split an optional `#ref` (or `#ref@skillFilter`, skillFilter ignored) fragment off a source string. */
|
|
93
|
+
function splitFragmentRef(input) {
|
|
94
|
+
const hashIdx = input.indexOf('#');
|
|
95
|
+
if (hashIdx === -1)
|
|
96
|
+
return { base: input };
|
|
97
|
+
const base = input.slice(0, hashIdx);
|
|
98
|
+
let fragment = input.slice(hashIdx + 1).trim();
|
|
99
|
+
if (fragment.length === 0)
|
|
100
|
+
return { base };
|
|
101
|
+
const atIdx = fragment.indexOf('@');
|
|
102
|
+
if (atIdx !== -1)
|
|
103
|
+
fragment = fragment.slice(0, atIdx);
|
|
104
|
+
if (fragment.length === 0)
|
|
105
|
+
return { base };
|
|
106
|
+
let decoded = fragment;
|
|
107
|
+
try {
|
|
108
|
+
decoded = decodeURIComponent(fragment);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
decoded = fragment;
|
|
112
|
+
}
|
|
113
|
+
return { base, fragmentRef: decoded };
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Convert bare shorthand to an HTTPS clone URL.
|
|
117
|
+
* owner/repo -> https://github.com/owner/repo.git
|
|
118
|
+
* github.com/owner/repo, gitlab.com/owner/repo -> https://<host>/owner/repo.git
|
|
119
|
+
*/
|
|
120
|
+
function ownerRepoToUrl(ownerRepo) {
|
|
121
|
+
const trimmed = ownerRepo.trim();
|
|
122
|
+
if (trimmed.includes(':'))
|
|
123
|
+
return undefined;
|
|
124
|
+
const parts = trimmed.split('/').filter(Boolean);
|
|
125
|
+
if (parts.length === 2) {
|
|
126
|
+
const [owner, repo] = parts;
|
|
127
|
+
if (owner.includes('.'))
|
|
128
|
+
return undefined;
|
|
129
|
+
return { type: 'github', url: `https://github.com/${owner}/${(repo ?? '').replace(/\.git$/, '')}.git` };
|
|
130
|
+
}
|
|
131
|
+
if (parts.length >= 3 && (parts[0] === 'github.com' || parts[0] === 'gitlab.com')) {
|
|
132
|
+
const host = parts[0];
|
|
133
|
+
const rest = parts.slice(1);
|
|
134
|
+
const repo = rest.pop().replace(/\.git$/, '');
|
|
135
|
+
return { type: host === 'github.com' ? 'github' : 'gitlab', url: `https://${host}/${rest.join('/')}/${repo}.git` };
|
|
136
|
+
}
|
|
137
|
+
return undefined;
|
|
138
|
+
}
|
|
139
|
+
export function parseSource(input) {
|
|
140
|
+
const trimmed = input.trim();
|
|
141
|
+
if (isLocalPath(trimmed)) {
|
|
142
|
+
const abs = resolve(trimmed);
|
|
143
|
+
return { type: 'local', url: abs, localPath: abs };
|
|
144
|
+
}
|
|
145
|
+
// github:owner/repo / gitlab:group/sub/repo prefix shorthand, optionally with #ref.
|
|
146
|
+
if (trimmed.startsWith('github:') || trimmed.startsWith('gitlab:')) {
|
|
147
|
+
const isGithub = trimmed.startsWith('github:');
|
|
148
|
+
const rest = trimmed.slice(isGithub ? 'github:'.length : 'gitlab:'.length);
|
|
149
|
+
const { base, fragmentRef } = splitFragmentRef(rest);
|
|
150
|
+
const parts = base.split('/').filter(Boolean);
|
|
151
|
+
const repo = (parts.pop() ?? '').replace(/\.git$/, '');
|
|
152
|
+
const url = isGithub
|
|
153
|
+
? `https://github.com/${parts.join('/')}/${repo}.git`
|
|
154
|
+
: `https://gitlab.com/${parts.join('/')}/${repo}.git`;
|
|
155
|
+
return { type: isGithub ? 'github' : 'gitlab', url, ref: fragmentRef };
|
|
156
|
+
}
|
|
157
|
+
const { base, fragmentRef } = splitFragmentRef(trimmed);
|
|
158
|
+
// Browse-URL ref extraction takes precedence over a `#ref` fragment.
|
|
159
|
+
const ghSubpath = base.match(GITHUB_TREE_SUBPATH_RE);
|
|
160
|
+
const ghBranchOnly = base.match(GITHUB_TREE_RE);
|
|
161
|
+
if (ghBranchOnly) {
|
|
162
|
+
const [, owner, repo, ref] = ghBranchOnly;
|
|
163
|
+
return { type: 'github', url: `https://github.com/${owner}/${repo}.git`, ref };
|
|
164
|
+
}
|
|
165
|
+
if (ghSubpath) {
|
|
166
|
+
const [, owner, repo, ref] = ghSubpath;
|
|
167
|
+
return { type: 'github', url: `https://github.com/${owner}/${repo}.git`, ref };
|
|
168
|
+
}
|
|
169
|
+
const glSubpath = base.match(GITLAB_TREE_SUBPATH_RE);
|
|
170
|
+
const glBranchOnly = base.match(GITLAB_TREE_RE);
|
|
171
|
+
if (glBranchOnly) {
|
|
172
|
+
const [, proto, host, repoPath, ref] = glBranchOnly;
|
|
173
|
+
return { type: 'gitlab', url: `${proto}://${host}/${repoPath}.git`, ref };
|
|
174
|
+
}
|
|
175
|
+
if (glSubpath) {
|
|
176
|
+
const [, proto, host, repoPath, ref] = glSubpath;
|
|
177
|
+
return { type: 'gitlab', url: `${proto}://${host}/${repoPath}.git`, ref };
|
|
178
|
+
}
|
|
179
|
+
// Bare owner/repo shorthand, or owner/repo prefixed with a bare github.com/gitlab.com
|
|
180
|
+
// host (no scheme). Tried before the looksLikeGitSource guard below since these forms
|
|
181
|
+
// are unambiguously our own shorthand, not a generic opaque string.
|
|
182
|
+
const shorthand = ownerRepoToUrl(base);
|
|
183
|
+
if (shorthand) {
|
|
184
|
+
return { type: shorthand.type, url: shorthand.url, ref: fragmentRef };
|
|
185
|
+
}
|
|
186
|
+
if (!looksLikeGitSource(base)) {
|
|
187
|
+
// Base doesn't look git-like: leave the `#` as part of the string (not a ref).
|
|
188
|
+
return { type: 'git', url: trimmed };
|
|
189
|
+
}
|
|
190
|
+
if (base.startsWith('git@') || isSshStyleUrl(base) || base.startsWith('ssh://') || base.startsWith('file://')) {
|
|
191
|
+
return { type: 'git', url: base, ref: fragmentRef };
|
|
192
|
+
}
|
|
193
|
+
if (base.startsWith('http://') || base.startsWith('https://')) {
|
|
194
|
+
let host = '';
|
|
195
|
+
try {
|
|
196
|
+
host = new URL(base).hostname;
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
host = '';
|
|
200
|
+
}
|
|
201
|
+
if (host === 'github.com') {
|
|
202
|
+
const withGit = base.endsWith('.git') ? base : `${base.replace(/\/$/, '')}.git`;
|
|
203
|
+
return { type: 'github', url: withGit, ref: fragmentRef };
|
|
204
|
+
}
|
|
205
|
+
if (host === 'gitlab.com') {
|
|
206
|
+
const withGit = base.endsWith('.git') ? base : `${base.replace(/\/$/, '')}.git`;
|
|
207
|
+
return { type: 'gitlab', url: withGit, ref: fragmentRef };
|
|
208
|
+
}
|
|
209
|
+
// Generic git host (our extension): keep URL as-is, don't force a `.git` suffix.
|
|
210
|
+
return { type: 'git', url: base, ref: fragmentRef };
|
|
211
|
+
}
|
|
212
|
+
return { type: 'git', url: base, ref: fragmentRef };
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=source-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-parser.js","sourceRoot":"","sources":["../../src/lib/source-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAS/B,SAAS,WAAW,CAAC,KAAa;IAChC,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IACvB,OAAO,CACL,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;QAClB,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC;QACnB,CAAC,KAAK,GAAG;QACT,CAAC,KAAK,IAAI;QACV,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;QACjB,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAC1B,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CAAC,KAAa;IAClC,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,QAAQ,IAAI,CAAC,IAAI,QAAQ,KAAK,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACvE,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACtC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;IACvC,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,QAAQ,CAAC;IACpF,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IACxF,OAAO,cAAc,IAAI,cAAc,CAAC;AAC1C,CAAC;AAED,MAAM,cAAc,GAAG,2DAA2D,CAAC;AACnF,MAAM,sBAAsB,GAAG,iEAAiE,CAAC;AACjG,MAAM,cAAc,GAAG,iDAAiD,CAAC;AACzE,MAAM,sBAAsB,GAAG,uDAAuD,CAAC;AAEvF;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IACvB,IAAI,WAAW,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACjC,IAAI,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5F,yGAAyG;IACzG,IAAI,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,IAAI,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7C,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1E,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1E,IAAI,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAChD,IAAI,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACxD,6DAA6D;QAC7D,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;YACrB,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,IAAI,aAAa,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,qEAAqE;IACrE,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7F,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,0GAA0G;AAC1G,SAAS,gBAAgB,CAAC,KAAa;IACrC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,OAAO,KAAK,CAAC,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACrC,IAAI,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3C,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,KAAK,KAAK,CAAC,CAAC;QAAE,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACtD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3C,IAAI,OAAO,GAAG,QAAQ,CAAC;IACvB,IAAI,CAAC;QACH,OAAO,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,QAAQ,CAAC;IACrB,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;AACxC,CAAC;AAED;;;;GAIG;AACH,SAAS,cAAc,CAAC,SAAiB;IACvC,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IACjC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACjD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC;QAC5B,IAAI,KAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,SAAS,CAAC;QAC3C,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,sBAAsB,KAAK,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC;IAC1G,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,YAAY,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,YAAY,CAAC,EAAE,CAAC;QAClF,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACvB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC/C,OAAO,EAAE,IAAI,EAAE,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAE,WAAW,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,EAAE,CAAC;IACrH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAE7B,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;IACrD,CAAC;IAED,oFAAoF;IACpF,IAAI,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QACnE,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC3E,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG,QAAQ;YAClB,CAAC,CAAC,sBAAsB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM;YACrD,CAAC,CAAC,sBAAsB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC;QACxD,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC;IACzE,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAExD,qEAAqE;IACrE,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACrD,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAChD,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,GAAG,YAAY,CAAC;QAC1C,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,sBAAsB,KAAK,IAAI,IAAI,MAAM,EAAE,GAAG,EAAE,CAAC;IACjF,CAAC;IACD,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,GAAG,SAAS,CAAC;QACvC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,sBAAsB,KAAK,IAAI,IAAI,MAAM,EAAE,GAAG,EAAE,CAAC;IACjF,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACrD,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAChD,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,GAAG,YAAY,CAAC;QACpD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,KAAK,MAAM,IAAI,IAAI,QAAQ,MAAM,EAAE,GAAG,EAAE,CAAC;IAC5E,CAAC;IACD,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,GAAG,SAAS,CAAC;QACjD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,KAAK,MAAM,IAAI,IAAI,QAAQ,MAAM,EAAE,GAAG,EAAE,CAAC;IAC5E,CAAC;IAED,sFAAsF;IACtF,sFAAsF;IACtF,oEAAoE;IACpE,MAAM,SAAS,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC;IACxE,CAAC;IAED,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,+EAA+E;QAC/E,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;IACvC,CAAC;IAED,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9G,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC;IACtD,CAAC;IAED,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9D,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,IAAI,CAAC;YACH,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,GAAG,EAAE,CAAC;QACZ,CAAC;QACD,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC;YAChF,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC;QAC5D,CAAC;QACD,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC;YAChF,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC;QAC5D,CAAC;QACD,iFAAiF;QACjF,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC;IACtD,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC;AACtD,CAAC"}
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export interface MarketplaceEntry {
|
|
|
8
8
|
version: string;
|
|
9
9
|
pluginNames: string[];
|
|
10
10
|
updatedAt: string;
|
|
11
|
-
/** If true (default),
|
|
11
|
+
/** If true (default), plugins sync to ~/.cursor/plugins/local/; if false, flatten into project .cursor/*. */
|
|
12
12
|
global?: boolean;
|
|
13
13
|
/** Hook entries we merged per plugin (for removal on uninstall). */
|
|
14
14
|
pluginHooks?: Record<string, Array<{
|
package/dist/lib/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,kIAAkI;AAClI,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,kIAAkI;AAClI,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,6GAA6G;IAC7G,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC3E,2DAA2D;IAC3D,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,2HAA2H;IAC3H,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAChD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remove a plugin from Cursor — global installs use plugins/local; project installs use flattened symlinks + store.
|
|
3
|
+
*/
|
|
4
|
+
export declare function uninstallPluginFromCursor(options: {
|
|
5
|
+
marketplaceName: string;
|
|
6
|
+
pluginName: string;
|
|
7
|
+
global: boolean;
|
|
8
|
+
cwd: string;
|
|
9
|
+
pluginHooks?: Array<{
|
|
10
|
+
hookName: string;
|
|
11
|
+
command: string;
|
|
12
|
+
}>;
|
|
13
|
+
}): Promise<void>;
|
|
14
|
+
//# sourceMappingURL=uninstall-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uninstall-plugin.d.ts","sourceRoot":"","sources":["../../src/lib/uninstall-plugin.ts"],"names":[],"mappings":"AAAA;;GAEG;AAeH,wBAAsB,yBAAyB,CAAC,OAAO,EAAE;IACvD,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5D,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BhB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remove a plugin from Cursor — global installs use plugins/local; project installs use flattened symlinks + store.
|
|
3
|
+
*/
|
|
4
|
+
import { rm } from 'fs/promises';
|
|
5
|
+
import { getPluginStorePath } from './marketplace.js';
|
|
6
|
+
import { getCursorAgentsDir, getCursorCommandsDir, getCursorSkillsDir, getCursorRulesDir, } from './paths.js';
|
|
7
|
+
import { removeLocalPlugin } from './plugin-local.js';
|
|
8
|
+
import { removeSymlinksInDirPointingUnder } from './symlink.js';
|
|
9
|
+
import { removeCopiedAgentsForPlugin } from './agents-copy.js';
|
|
10
|
+
import { removeHookEntries } from './hooks.js';
|
|
11
|
+
export async function uninstallPluginFromCursor(options) {
|
|
12
|
+
const { marketplaceName, pluginName, global, cwd, pluginHooks } = options;
|
|
13
|
+
if (global) {
|
|
14
|
+
await removeLocalPlugin(pluginName);
|
|
15
|
+
// Also remove leftovers from agents-pkg versions that installed global plugins
|
|
16
|
+
// by flattening them into ~/.cursor/* from the marketplace store.
|
|
17
|
+
}
|
|
18
|
+
const pluginStorePath = getPluginStorePath(marketplaceName, pluginName);
|
|
19
|
+
if (pluginHooks?.length) {
|
|
20
|
+
await removeHookEntries(pluginHooks, global, cwd);
|
|
21
|
+
}
|
|
22
|
+
const cursorAgentsDir = getCursorAgentsDir(global, cwd);
|
|
23
|
+
const cursorCommandsDir = getCursorCommandsDir(global, cwd);
|
|
24
|
+
const cursorSkillsDir = getCursorSkillsDir(global, cwd);
|
|
25
|
+
const cursorRulesDir = getCursorRulesDir(global, cwd);
|
|
26
|
+
await removeCopiedAgentsForPlugin(pluginStorePath, cursorAgentsDir);
|
|
27
|
+
await removeSymlinksInDirPointingUnder(cursorAgentsDir, pluginStorePath);
|
|
28
|
+
await removeSymlinksInDirPointingUnder(cursorCommandsDir, pluginStorePath);
|
|
29
|
+
await removeSymlinksInDirPointingUnder(cursorSkillsDir, pluginStorePath);
|
|
30
|
+
await removeSymlinksInDirPointingUnder(cursorRulesDir, pluginStorePath);
|
|
31
|
+
await rm(pluginStorePath, { recursive: true, force: true }).catch(() => { });
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=uninstall-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uninstall-plugin.js","sourceRoot":"","sources":["../../src/lib/uninstall-plugin.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,gCAAgC,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,OAM/C;IACC,MAAM,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAE1E,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,iBAAiB,CAAC,UAAU,CAAC,CAAC;QACpC,+EAA+E;QAC/E,kEAAkE;IACpE,CAAC;IAED,MAAM,eAAe,GAAG,kBAAkB,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;IACxE,IAAI,WAAW,EAAE,MAAM,EAAE,CAAC;QACxB,MAAM,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,eAAe,GAAG,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACxD,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5D,MAAM,eAAe,GAAG,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACxD,MAAM,cAAc,GAAG,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAEtD,MAAM,2BAA2B,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;IACpE,MAAM,gCAAgC,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;IACzE,MAAM,gCAAgC,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC;IAC3E,MAAM,gCAAgC,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;IACzE,MAAM,gCAAgC,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;IAExE,MAAM,EAAE,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AAC9E,CAAC"}
|
package/dist/update.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../src/update.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../src/update.ts"],"names":[],"mappings":"AAAA;;GAEG;AAiCH,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAkK/C"}
|