subagents-sh 0.1.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 +57 -0
- package/dist/commands/add.d.ts +6 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +35 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/list.d.ts +7 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +77 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/remove.d.ts +6 -0
- package/dist/commands/remove.d.ts.map +1 -0
- package/dist/commands/remove.js +25 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/commands/update.d.ts +7 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +83 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +125 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +41 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/fetch.d.ts +23 -0
- package/dist/utils/fetch.d.ts.map +1 -0
- package/dist/utils/fetch.js +124 -0
- package/dist/utils/fetch.js.map +1 -0
- package/dist/utils/fetch.test.d.ts +2 -0
- package/dist/utils/fetch.test.d.ts.map +1 -0
- package/dist/utils/fetch.test.js +246 -0
- package/dist/utils/fetch.test.js.map +1 -0
- package/dist/utils/install.d.ts +68 -0
- package/dist/utils/install.d.ts.map +1 -0
- package/dist/utils/install.js +140 -0
- package/dist/utils/install.js.map +1 -0
- package/dist/utils/install.test.d.ts +2 -0
- package/dist/utils/install.test.d.ts.map +1 -0
- package/dist/utils/install.test.js +565 -0
- package/dist/utils/install.test.js.map +1 -0
- package/dist/utils/manifest.d.ts +37 -0
- package/dist/utils/manifest.d.ts.map +1 -0
- package/dist/utils/manifest.js +74 -0
- package/dist/utils/manifest.js.map +1 -0
- package/dist/utils/manifest.test.d.ts +2 -0
- package/dist/utils/manifest.test.d.ts.map +1 -0
- package/dist/utils/manifest.test.js +278 -0
- package/dist/utils/manifest.test.js.map +1 -0
- package/dist/utils/paths.d.ts +49 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +98 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/paths.test.d.ts +2 -0
- package/dist/utils/paths.test.d.ts.map +1 -0
- package/dist/utils/paths.test.js +255 -0
- package/dist/utils/paths.test.js.map +1 -0
- package/dist/utils/telemetry.d.ts +5 -0
- package/dist/utils/telemetry.d.ts.map +1 -0
- package/dist/utils/telemetry.js +30 -0
- package/dist/utils/telemetry.js.map +1 -0
- package/dist/utils/telemetry.test.d.ts +2 -0
- package/dist/utils/telemetry.test.d.ts.map +1 -0
- package/dist/utils/telemetry.test.js +113 -0
- package/dist/utils/telemetry.test.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
const GITHUB_RAW_BASE = 'https://raw.githubusercontent.com';
|
|
2
|
+
const GITHUB_API_BASE = 'https://api.github.com';
|
|
3
|
+
// Common paths where subagents might be located
|
|
4
|
+
const SEARCH_PATHS = ['.claude/agents', 'agents', '.claude', ''];
|
|
5
|
+
/**
|
|
6
|
+
* Parse a subagent identifier (owner/repo/name or full GitHub URL)
|
|
7
|
+
*/
|
|
8
|
+
export function parseIdentifier(identifier) {
|
|
9
|
+
// Handle full GitHub URLs
|
|
10
|
+
if (identifier.startsWith('https://github.com/')) {
|
|
11
|
+
const url = new URL(identifier);
|
|
12
|
+
const parts = url.pathname.split('/').filter(Boolean);
|
|
13
|
+
if (parts.length >= 2) {
|
|
14
|
+
const owner = parts[0];
|
|
15
|
+
const repo = parts[1];
|
|
16
|
+
// If there's a blob/tree path, extract the file name
|
|
17
|
+
let name = repo;
|
|
18
|
+
if (parts.length > 4 && (parts[2] === 'blob' || parts[2] === 'tree')) {
|
|
19
|
+
// e.g., /owner/repo/blob/main/.claude/agents/agent-name.md
|
|
20
|
+
const filePath = parts.slice(4).join('/');
|
|
21
|
+
name = filePath.replace(/\.md$/, '').split('/').pop() || repo;
|
|
22
|
+
}
|
|
23
|
+
else if (parts.length > 2) {
|
|
24
|
+
name = parts[parts.length - 1].replace(/\.md$/, '');
|
|
25
|
+
}
|
|
26
|
+
return { owner, repo, name };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// Handle owner/repo/name format
|
|
30
|
+
const parts = identifier.split('/');
|
|
31
|
+
if (parts.length === 3) {
|
|
32
|
+
return {
|
|
33
|
+
owner: parts[0],
|
|
34
|
+
repo: parts[1],
|
|
35
|
+
name: parts[2].replace(/\.md$/, ''),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (parts.length === 2) {
|
|
39
|
+
// Assume owner/repo, and name is the repo
|
|
40
|
+
return {
|
|
41
|
+
owner: parts[0],
|
|
42
|
+
repo: parts[1],
|
|
43
|
+
name: parts[1],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
throw new Error(`Invalid identifier format: "${identifier}". Expected owner/repo/name or GitHub URL.`);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Fetch subagent content from GitHub
|
|
50
|
+
* Tries multiple paths to find the agent file
|
|
51
|
+
*/
|
|
52
|
+
export async function fetchFromGitHub(owner, repo, name, branch = 'main') {
|
|
53
|
+
const errors = [];
|
|
54
|
+
// Try each search path
|
|
55
|
+
for (const basePath of SEARCH_PATHS) {
|
|
56
|
+
const filePath = basePath ? `${basePath}/${name}.md` : `${name}.md`;
|
|
57
|
+
const url = `${GITHUB_RAW_BASE}/${owner}/${repo}/${branch}/${filePath}`;
|
|
58
|
+
try {
|
|
59
|
+
const response = await fetch(url);
|
|
60
|
+
if (response.ok) {
|
|
61
|
+
const content = await response.text();
|
|
62
|
+
return {
|
|
63
|
+
content,
|
|
64
|
+
source: {
|
|
65
|
+
owner,
|
|
66
|
+
repo,
|
|
67
|
+
name,
|
|
68
|
+
branch,
|
|
69
|
+
path: filePath,
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (response.status !== 404) {
|
|
74
|
+
errors.push(`${filePath}: HTTP ${response.status}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
errors.push(`${filePath}: ${err instanceof Error ? err.message : 'Unknown error'}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Try with 'master' branch if 'main' didn't work
|
|
82
|
+
if (branch === 'main') {
|
|
83
|
+
try {
|
|
84
|
+
return await fetchFromGitHub(owner, repo, name, 'master');
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
// Fall through to error
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
throw new Error(`Could not find subagent "${name}" in ${owner}/${repo}.\n` +
|
|
91
|
+
`Searched in: ${SEARCH_PATHS.map((p) => p || '(root)').join(', ')}\n` +
|
|
92
|
+
`Make sure the file exists at one of these locations.`);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Check if a GitHub repo exists and is accessible
|
|
96
|
+
*/
|
|
97
|
+
export async function checkRepoExists(owner, repo) {
|
|
98
|
+
const url = `${GITHUB_API_BASE}/repos/${owner}/${repo}`;
|
|
99
|
+
try {
|
|
100
|
+
const response = await fetch(url);
|
|
101
|
+
return response.ok;
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get the default branch for a repository
|
|
109
|
+
*/
|
|
110
|
+
export async function getDefaultBranch(owner, repo) {
|
|
111
|
+
const url = `${GITHUB_API_BASE}/repos/${owner}/${repo}`;
|
|
112
|
+
try {
|
|
113
|
+
const response = await fetch(url);
|
|
114
|
+
if (response.ok) {
|
|
115
|
+
const data = (await response.json());
|
|
116
|
+
return data.default_branch || 'main';
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// Fall through
|
|
121
|
+
}
|
|
122
|
+
return 'main';
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/utils/fetch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.test.d.ts","sourceRoot":"","sources":["../../src/utils/fetch.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { parseIdentifier, fetchFromGitHub, checkRepoExists, getDefaultBranch } from './fetch.js';
|
|
3
|
+
describe('parseIdentifier', () => {
|
|
4
|
+
it('parses owner/repo/name format', () => {
|
|
5
|
+
const result = parseIdentifier('owner/repo/agent-name');
|
|
6
|
+
expect(result).toEqual({
|
|
7
|
+
owner: 'owner',
|
|
8
|
+
repo: 'repo',
|
|
9
|
+
name: 'agent-name',
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
it('parses owner/repo format (name defaults to repo)', () => {
|
|
13
|
+
const result = parseIdentifier('owner/repo');
|
|
14
|
+
expect(result).toEqual({
|
|
15
|
+
owner: 'owner',
|
|
16
|
+
repo: 'repo',
|
|
17
|
+
name: 'repo',
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
it('strips .md extension from name', () => {
|
|
21
|
+
const result = parseIdentifier('owner/repo/agent-name.md');
|
|
22
|
+
expect(result).toEqual({
|
|
23
|
+
owner: 'owner',
|
|
24
|
+
repo: 'repo',
|
|
25
|
+
name: 'agent-name',
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
it('parses full GitHub URL', () => {
|
|
29
|
+
const result = parseIdentifier('https://github.com/owner/repo');
|
|
30
|
+
expect(result).toEqual({
|
|
31
|
+
owner: 'owner',
|
|
32
|
+
repo: 'repo',
|
|
33
|
+
name: 'repo',
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
it('parses GitHub URL with blob path', () => {
|
|
37
|
+
const result = parseIdentifier('https://github.com/owner/repo/blob/main/.claude/agents/my-agent.md');
|
|
38
|
+
expect(result).toEqual({
|
|
39
|
+
owner: 'owner',
|
|
40
|
+
repo: 'repo',
|
|
41
|
+
name: 'my-agent',
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
it('parses GitHub URL with tree path', () => {
|
|
45
|
+
const result = parseIdentifier('https://github.com/owner/repo/tree/main/agents/my-agent.md');
|
|
46
|
+
expect(result).toEqual({
|
|
47
|
+
owner: 'owner',
|
|
48
|
+
repo: 'repo',
|
|
49
|
+
name: 'my-agent',
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
it('parses GitHub URL with path but no blob/tree', () => {
|
|
53
|
+
const result = parseIdentifier('https://github.com/owner/repo/my-agent');
|
|
54
|
+
expect(result).toEqual({
|
|
55
|
+
owner: 'owner',
|
|
56
|
+
repo: 'repo',
|
|
57
|
+
name: 'my-agent',
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
it('throws on invalid format (single part)', () => {
|
|
61
|
+
expect(() => parseIdentifier('invalid')).toThrow('Invalid identifier format: "invalid"');
|
|
62
|
+
});
|
|
63
|
+
it('throws on empty string', () => {
|
|
64
|
+
expect(() => parseIdentifier('')).toThrow('Invalid identifier format');
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
describe('fetchFromGitHub', () => {
|
|
68
|
+
let mockFetch;
|
|
69
|
+
beforeEach(() => {
|
|
70
|
+
mockFetch = vi.fn();
|
|
71
|
+
vi.stubGlobal('fetch', mockFetch);
|
|
72
|
+
});
|
|
73
|
+
afterEach(() => {
|
|
74
|
+
vi.unstubAllGlobals();
|
|
75
|
+
});
|
|
76
|
+
it('tries .claude/agents path first', async () => {
|
|
77
|
+
mockFetch.mockResolvedValueOnce({
|
|
78
|
+
ok: true,
|
|
79
|
+
text: () => Promise.resolve('# Agent content'),
|
|
80
|
+
});
|
|
81
|
+
const result = await fetchFromGitHub('owner', 'repo', 'test-agent', 'main');
|
|
82
|
+
expect(mockFetch).toHaveBeenCalledTimes(1);
|
|
83
|
+
expect(mockFetch).toHaveBeenCalledWith('https://raw.githubusercontent.com/owner/repo/main/.claude/agents/test-agent.md');
|
|
84
|
+
expect(result.content).toBe('# Agent content');
|
|
85
|
+
expect(result.source).toEqual({
|
|
86
|
+
owner: 'owner',
|
|
87
|
+
repo: 'repo',
|
|
88
|
+
name: 'test-agent',
|
|
89
|
+
branch: 'main',
|
|
90
|
+
path: '.claude/agents/test-agent.md',
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
it('falls back to agents/ path on 404', async () => {
|
|
94
|
+
mockFetch
|
|
95
|
+
.mockResolvedValueOnce({ ok: false, status: 404 }) // .claude/agents
|
|
96
|
+
.mockResolvedValueOnce({
|
|
97
|
+
ok: true,
|
|
98
|
+
text: () => Promise.resolve('# From agents/'),
|
|
99
|
+
}); // agents/
|
|
100
|
+
const result = await fetchFromGitHub('owner', 'repo', 'test-agent', 'main');
|
|
101
|
+
expect(mockFetch).toHaveBeenCalledTimes(2);
|
|
102
|
+
expect(mockFetch).toHaveBeenNthCalledWith(2, 'https://raw.githubusercontent.com/owner/repo/main/agents/test-agent.md');
|
|
103
|
+
expect(result.source.path).toBe('agents/test-agent.md');
|
|
104
|
+
});
|
|
105
|
+
it('falls back to .claude/ path', async () => {
|
|
106
|
+
mockFetch
|
|
107
|
+
.mockResolvedValueOnce({ ok: false, status: 404 }) // .claude/agents
|
|
108
|
+
.mockResolvedValueOnce({ ok: false, status: 404 }) // agents/
|
|
109
|
+
.mockResolvedValueOnce({
|
|
110
|
+
ok: true,
|
|
111
|
+
text: () => Promise.resolve('# From .claude/'),
|
|
112
|
+
}); // .claude/
|
|
113
|
+
const result = await fetchFromGitHub('owner', 'repo', 'test-agent', 'main');
|
|
114
|
+
expect(mockFetch).toHaveBeenCalledTimes(3);
|
|
115
|
+
expect(result.source.path).toBe('.claude/test-agent.md');
|
|
116
|
+
});
|
|
117
|
+
it('falls back to root path', async () => {
|
|
118
|
+
mockFetch
|
|
119
|
+
.mockResolvedValueOnce({ ok: false, status: 404 }) // .claude/agents
|
|
120
|
+
.mockResolvedValueOnce({ ok: false, status: 404 }) // agents/
|
|
121
|
+
.mockResolvedValueOnce({ ok: false, status: 404 }) // .claude/
|
|
122
|
+
.mockResolvedValueOnce({
|
|
123
|
+
ok: true,
|
|
124
|
+
text: () => Promise.resolve('# From root'),
|
|
125
|
+
}); // root
|
|
126
|
+
const result = await fetchFromGitHub('owner', 'repo', 'test-agent', 'main');
|
|
127
|
+
expect(mockFetch).toHaveBeenCalledTimes(4);
|
|
128
|
+
expect(result.source.path).toBe('test-agent.md');
|
|
129
|
+
});
|
|
130
|
+
it('tries master branch if main fails', async () => {
|
|
131
|
+
// All 4 paths fail for main branch
|
|
132
|
+
mockFetch
|
|
133
|
+
.mockResolvedValueOnce({ ok: false, status: 404 })
|
|
134
|
+
.mockResolvedValueOnce({ ok: false, status: 404 })
|
|
135
|
+
.mockResolvedValueOnce({ ok: false, status: 404 })
|
|
136
|
+
.mockResolvedValueOnce({ ok: false, status: 404 })
|
|
137
|
+
// Then succeeds on master
|
|
138
|
+
.mockResolvedValueOnce({
|
|
139
|
+
ok: true,
|
|
140
|
+
text: () => Promise.resolve('# From master'),
|
|
141
|
+
});
|
|
142
|
+
const result = await fetchFromGitHub('owner', 'repo', 'test-agent', 'main');
|
|
143
|
+
expect(mockFetch).toHaveBeenCalledTimes(5);
|
|
144
|
+
expect(mockFetch).toHaveBeenLastCalledWith('https://raw.githubusercontent.com/owner/repo/master/.claude/agents/test-agent.md');
|
|
145
|
+
expect(result.source.branch).toBe('master');
|
|
146
|
+
});
|
|
147
|
+
it('returns content and source metadata', async () => {
|
|
148
|
+
const content = '---\nname: Test\n---\n# Content';
|
|
149
|
+
mockFetch.mockResolvedValueOnce({
|
|
150
|
+
ok: true,
|
|
151
|
+
text: () => Promise.resolve(content),
|
|
152
|
+
});
|
|
153
|
+
const result = await fetchFromGitHub('myorg', 'myrepo', 'myagent', 'develop');
|
|
154
|
+
expect(result).toEqual({
|
|
155
|
+
content,
|
|
156
|
+
source: {
|
|
157
|
+
owner: 'myorg',
|
|
158
|
+
repo: 'myrepo',
|
|
159
|
+
name: 'myagent',
|
|
160
|
+
branch: 'develop',
|
|
161
|
+
path: '.claude/agents/myagent.md',
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
it('throws descriptive error when not found anywhere', async () => {
|
|
166
|
+
// Fail all paths for both main and master
|
|
167
|
+
mockFetch.mockResolvedValue({ ok: false, status: 404 });
|
|
168
|
+
await expect(fetchFromGitHub('owner', 'repo', 'missing', 'main')).rejects.toThrow('Could not find subagent "missing" in owner/repo');
|
|
169
|
+
});
|
|
170
|
+
it('collects non-404 HTTP errors', async () => {
|
|
171
|
+
mockFetch
|
|
172
|
+
.mockResolvedValueOnce({ ok: false, status: 500 }) // Server error on first path
|
|
173
|
+
.mockResolvedValueOnce({ ok: false, status: 404 })
|
|
174
|
+
.mockResolvedValueOnce({ ok: false, status: 404 })
|
|
175
|
+
.mockResolvedValueOnce({ ok: false, status: 404 })
|
|
176
|
+
.mockResolvedValue({ ok: false, status: 404 }); // master fallback
|
|
177
|
+
await expect(fetchFromGitHub('owner', 'repo', 'agent', 'main')).rejects.toThrow();
|
|
178
|
+
});
|
|
179
|
+
it('handles network errors gracefully', async () => {
|
|
180
|
+
mockFetch.mockRejectedValue(new Error('Network error'));
|
|
181
|
+
await expect(fetchFromGitHub('owner', 'repo', 'agent', 'main')).rejects.toThrow();
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
describe('checkRepoExists', () => {
|
|
185
|
+
let mockFetch;
|
|
186
|
+
beforeEach(() => {
|
|
187
|
+
mockFetch = vi.fn();
|
|
188
|
+
vi.stubGlobal('fetch', mockFetch);
|
|
189
|
+
});
|
|
190
|
+
afterEach(() => {
|
|
191
|
+
vi.unstubAllGlobals();
|
|
192
|
+
});
|
|
193
|
+
it('returns true for existing repo', async () => {
|
|
194
|
+
mockFetch.mockResolvedValueOnce({ ok: true });
|
|
195
|
+
const result = await checkRepoExists('owner', 'repo');
|
|
196
|
+
expect(result).toBe(true);
|
|
197
|
+
expect(mockFetch).toHaveBeenCalledWith('https://api.github.com/repos/owner/repo');
|
|
198
|
+
});
|
|
199
|
+
it('returns false for non-existing repo', async () => {
|
|
200
|
+
mockFetch.mockResolvedValueOnce({ ok: false, status: 404 });
|
|
201
|
+
const result = await checkRepoExists('owner', 'nonexistent');
|
|
202
|
+
expect(result).toBe(false);
|
|
203
|
+
});
|
|
204
|
+
it('returns false on network error', async () => {
|
|
205
|
+
mockFetch.mockRejectedValueOnce(new Error('Network error'));
|
|
206
|
+
const result = await checkRepoExists('owner', 'repo');
|
|
207
|
+
expect(result).toBe(false);
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
describe('getDefaultBranch', () => {
|
|
211
|
+
let mockFetch;
|
|
212
|
+
beforeEach(() => {
|
|
213
|
+
mockFetch = vi.fn();
|
|
214
|
+
vi.stubGlobal('fetch', mockFetch);
|
|
215
|
+
});
|
|
216
|
+
afterEach(() => {
|
|
217
|
+
vi.unstubAllGlobals();
|
|
218
|
+
});
|
|
219
|
+
it('returns default_branch from API response', async () => {
|
|
220
|
+
mockFetch.mockResolvedValueOnce({
|
|
221
|
+
ok: true,
|
|
222
|
+
json: () => Promise.resolve({ default_branch: 'develop' }),
|
|
223
|
+
});
|
|
224
|
+
const result = await getDefaultBranch('owner', 'repo');
|
|
225
|
+
expect(result).toBe('develop');
|
|
226
|
+
});
|
|
227
|
+
it('returns main when API response has no default_branch', async () => {
|
|
228
|
+
mockFetch.mockResolvedValueOnce({
|
|
229
|
+
ok: true,
|
|
230
|
+
json: () => Promise.resolve({}),
|
|
231
|
+
});
|
|
232
|
+
const result = await getDefaultBranch('owner', 'repo');
|
|
233
|
+
expect(result).toBe('main');
|
|
234
|
+
});
|
|
235
|
+
it('returns main on API error', async () => {
|
|
236
|
+
mockFetch.mockResolvedValueOnce({ ok: false, status: 404 });
|
|
237
|
+
const result = await getDefaultBranch('owner', 'repo');
|
|
238
|
+
expect(result).toBe('main');
|
|
239
|
+
});
|
|
240
|
+
it('returns main on network error', async () => {
|
|
241
|
+
mockFetch.mockRejectedValueOnce(new Error('Network error'));
|
|
242
|
+
const result = await getDefaultBranch('owner', 'repo');
|
|
243
|
+
expect(result).toBe('main');
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
//# sourceMappingURL=fetch.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.test.js","sourceRoot":"","sources":["../../src/utils/fetch.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { ParsedSubagent, StorageScope } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parse a subagent markdown file content
|
|
4
|
+
*/
|
|
5
|
+
export declare function parseSubagent(content: string): ParsedSubagent;
|
|
6
|
+
export interface InstallOptions {
|
|
7
|
+
force?: boolean;
|
|
8
|
+
scope?: StorageScope;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Install a subagent from an identifier (owner/repo/name or GitHub URL)
|
|
12
|
+
* @param identifier - The subagent identifier
|
|
13
|
+
* @param options - Installation options including scope ('global' or 'local')
|
|
14
|
+
*/
|
|
15
|
+
export declare function installSubagent(identifier: string, options?: InstallOptions): Promise<{
|
|
16
|
+
name: string;
|
|
17
|
+
path: string;
|
|
18
|
+
isUpdate: boolean;
|
|
19
|
+
scope: StorageScope;
|
|
20
|
+
}>;
|
|
21
|
+
export interface UninstallOptions {
|
|
22
|
+
scope?: StorageScope;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Uninstall a subagent
|
|
26
|
+
* @param name - Subagent name
|
|
27
|
+
* @param options - Uninstall options including scope ('global' or 'local')
|
|
28
|
+
* If scope is not specified, auto-detects the location
|
|
29
|
+
*/
|
|
30
|
+
export declare function uninstallSubagent(name: string, options?: UninstallOptions): {
|
|
31
|
+
path: string;
|
|
32
|
+
scope: StorageScope;
|
|
33
|
+
};
|
|
34
|
+
export interface UpdateOptions {
|
|
35
|
+
scope?: StorageScope;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Update all installed subagents in a given scope
|
|
39
|
+
* @param options - Update options including scope ('global' or 'local')
|
|
40
|
+
* @param onProgress - Progress callback
|
|
41
|
+
*/
|
|
42
|
+
export declare function updateAllSubagents(options?: UpdateOptions, onProgress?: (name: string, status: 'updating' | 'updated' | 'error', error?: string) => void): Promise<{
|
|
43
|
+
updated: string[];
|
|
44
|
+
errors: Array<{
|
|
45
|
+
name: string;
|
|
46
|
+
error: string;
|
|
47
|
+
}>;
|
|
48
|
+
}>;
|
|
49
|
+
/**
|
|
50
|
+
* Update all subagents in both scopes
|
|
51
|
+
*/
|
|
52
|
+
export declare function updateAllScopesSubagents(onProgress?: (name: string, scope: StorageScope, status: 'updating' | 'updated' | 'error', error?: string) => void): Promise<{
|
|
53
|
+
global: {
|
|
54
|
+
updated: string[];
|
|
55
|
+
errors: Array<{
|
|
56
|
+
name: string;
|
|
57
|
+
error: string;
|
|
58
|
+
}>;
|
|
59
|
+
};
|
|
60
|
+
local: {
|
|
61
|
+
updated: string[];
|
|
62
|
+
errors: Array<{
|
|
63
|
+
name: string;
|
|
64
|
+
error: string;
|
|
65
|
+
}>;
|
|
66
|
+
};
|
|
67
|
+
}>;
|
|
68
|
+
//# sourceMappingURL=install.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/utils/install.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAA0C,YAAY,EAAE,MAAM,aAAa,CAAC;AAExG;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAa7D;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,CAAC,CA2DjF;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,gBAAqB,GAC7B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,CA6BvC;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,GAAE,aAAkB,EAC3B,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,GAC5F,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAsBhF;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,GACjH,OAAO,CAAC;IACT,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;IAC9E,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;CAC9E,CAAC,CAeD"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import matter from 'gray-matter';
|
|
3
|
+
import { getSubagentPath, subagentExists, findSubagentScope } from './paths.js';
|
|
4
|
+
import { addToManifest, getFromManifest, removeFromManifest, listManifestSubagents } from './manifest.js';
|
|
5
|
+
import { fetchFromGitHub, parseIdentifier, getDefaultBranch } from './fetch.js';
|
|
6
|
+
import { sendTelemetry } from './telemetry.js';
|
|
7
|
+
/**
|
|
8
|
+
* Parse a subagent markdown file content
|
|
9
|
+
*/
|
|
10
|
+
export function parseSubagent(content) {
|
|
11
|
+
const { data, content: body } = matter(content);
|
|
12
|
+
const frontmatter = data;
|
|
13
|
+
if (!frontmatter.name) {
|
|
14
|
+
throw new Error('Subagent is missing required "name" field in frontmatter');
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
frontmatter,
|
|
18
|
+
content: body.trim(),
|
|
19
|
+
raw: content,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Install a subagent from an identifier (owner/repo/name or GitHub URL)
|
|
24
|
+
* @param identifier - The subagent identifier
|
|
25
|
+
* @param options - Installation options including scope ('global' or 'local')
|
|
26
|
+
*/
|
|
27
|
+
export async function installSubagent(identifier, options = {}) {
|
|
28
|
+
const { owner, repo, name } = parseIdentifier(identifier);
|
|
29
|
+
const scope = options.scope ?? 'global';
|
|
30
|
+
// Check if already installed in the target scope
|
|
31
|
+
const existing = getFromManifest(name, scope);
|
|
32
|
+
const fileExists = subagentExists(name, scope);
|
|
33
|
+
if ((existing || fileExists) && !options.force) {
|
|
34
|
+
throw new Error(`Subagent "${name}" is already installed in ${scope} scope. Use --force to overwrite.`);
|
|
35
|
+
}
|
|
36
|
+
const isUpdate = !!existing;
|
|
37
|
+
// Get default branch
|
|
38
|
+
const branch = await getDefaultBranch(owner, repo);
|
|
39
|
+
// Fetch the subagent content
|
|
40
|
+
const result = await fetchFromGitHub(owner, repo, name, branch);
|
|
41
|
+
// Parse and validate the content
|
|
42
|
+
const parsed = parseSubagent(result.content);
|
|
43
|
+
// Write the file
|
|
44
|
+
const filePath = getSubagentPath(name, scope);
|
|
45
|
+
fs.writeFileSync(filePath, result.content);
|
|
46
|
+
// Update manifest
|
|
47
|
+
const now = new Date().toISOString();
|
|
48
|
+
const subagentInfo = {
|
|
49
|
+
name: parsed.frontmatter.name,
|
|
50
|
+
path: filePath,
|
|
51
|
+
source: `${owner}/${repo}/${name}`,
|
|
52
|
+
description: parsed.frontmatter.description,
|
|
53
|
+
tools: parsed.frontmatter.tools,
|
|
54
|
+
installedAt: existing?.installedAt || now,
|
|
55
|
+
updatedAt: now,
|
|
56
|
+
};
|
|
57
|
+
addToManifest(name, subagentInfo, scope);
|
|
58
|
+
// Send telemetry (fire and forget)
|
|
59
|
+
const subagentId = `${owner}/${repo}/${name}`;
|
|
60
|
+
sendTelemetry(subagentId, 'download', {
|
|
61
|
+
owner,
|
|
62
|
+
repo,
|
|
63
|
+
name,
|
|
64
|
+
isUpdate,
|
|
65
|
+
scope,
|
|
66
|
+
});
|
|
67
|
+
return {
|
|
68
|
+
name,
|
|
69
|
+
path: filePath,
|
|
70
|
+
isUpdate,
|
|
71
|
+
scope,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Uninstall a subagent
|
|
76
|
+
* @param name - Subagent name
|
|
77
|
+
* @param options - Uninstall options including scope ('global' or 'local')
|
|
78
|
+
* If scope is not specified, auto-detects the location
|
|
79
|
+
*/
|
|
80
|
+
export function uninstallSubagent(name, options = {}) {
|
|
81
|
+
// Auto-detect scope if not specified
|
|
82
|
+
let scope = options.scope;
|
|
83
|
+
if (!scope) {
|
|
84
|
+
const foundScope = findSubagentScope(name);
|
|
85
|
+
if (!foundScope) {
|
|
86
|
+
throw new Error(`Subagent "${name}" is not installed.`);
|
|
87
|
+
}
|
|
88
|
+
scope = foundScope;
|
|
89
|
+
}
|
|
90
|
+
const filePath = getSubagentPath(name, scope);
|
|
91
|
+
const existing = getFromManifest(name, scope);
|
|
92
|
+
const fileExists = subagentExists(name, scope);
|
|
93
|
+
if (!existing && !fileExists) {
|
|
94
|
+
throw new Error(`Subagent "${name}" is not installed in ${scope} scope.`);
|
|
95
|
+
}
|
|
96
|
+
// Remove file if it exists
|
|
97
|
+
if (fileExists) {
|
|
98
|
+
fs.unlinkSync(filePath);
|
|
99
|
+
}
|
|
100
|
+
// Remove from manifest
|
|
101
|
+
removeFromManifest(name, scope);
|
|
102
|
+
return { path: filePath, scope };
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Update all installed subagents in a given scope
|
|
106
|
+
* @param options - Update options including scope ('global' or 'local')
|
|
107
|
+
* @param onProgress - Progress callback
|
|
108
|
+
*/
|
|
109
|
+
export async function updateAllSubagents(options = {}, onProgress) {
|
|
110
|
+
const scope = options.scope ?? 'global';
|
|
111
|
+
const installed = listManifestSubagents(scope);
|
|
112
|
+
const updated = [];
|
|
113
|
+
const errors = [];
|
|
114
|
+
for (const subagent of installed) {
|
|
115
|
+
onProgress?.(subagent.name, 'updating');
|
|
116
|
+
try {
|
|
117
|
+
await installSubagent(subagent.source, { force: true, scope });
|
|
118
|
+
updated.push(subagent.name);
|
|
119
|
+
onProgress?.(subagent.name, 'updated');
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
const errorMessage = err instanceof Error ? err.message : 'Unknown error';
|
|
123
|
+
errors.push({ name: subagent.name, error: errorMessage });
|
|
124
|
+
onProgress?.(subagent.name, 'error', errorMessage);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return { updated, errors };
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Update all subagents in both scopes
|
|
131
|
+
*/
|
|
132
|
+
export async function updateAllScopesSubagents(onProgress) {
|
|
133
|
+
const globalResult = await updateAllSubagents({ scope: 'global' }, onProgress ? (name, status, error) => onProgress(name, 'global', status, error) : undefined);
|
|
134
|
+
const localResult = await updateAllSubagents({ scope: 'local' }, onProgress ? (name, status, error) => onProgress(name, 'local', status, error) : undefined);
|
|
135
|
+
return {
|
|
136
|
+
global: globalResult,
|
|
137
|
+
local: localResult,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/utils/install.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC1G,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG/C;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,WAAW,GAAG,IAA2B,CAAC;IAEhD,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IAED,OAAO;QACL,WAAW;QACX,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE;QACpB,GAAG,EAAE,OAAO;KACb,CAAC;AACJ,CAAC;AAOD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,UAAkB,EAClB,UAA0B,EAAE;IAE5B,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAC1D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,QAAQ,CAAC;IAExC,iDAAiD;IACjD,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAE/C,IAAI,CAAC,QAAQ,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CACb,aAAa,IAAI,6BAA6B,KAAK,mCAAmC,CACvF,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;IAE5B,qBAAqB;IACrB,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAEnD,6BAA6B;IAC7B,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAEhE,iCAAiC;IACjC,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAE7C,iBAAiB;IACjB,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC9C,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAE3C,kBAAkB;IAClB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,YAAY,GAAsB;QACtC,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI;QAC7B,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,GAAG,KAAK,IAAI,IAAI,IAAI,IAAI,EAAE;QAClC,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,WAAW;QAC3C,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK;QAC/B,WAAW,EAAE,QAAQ,EAAE,WAAW,IAAI,GAAG;QACzC,SAAS,EAAE,GAAG;KACf,CAAC;IAEF,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;IAEzC,mCAAmC;IACnC,MAAM,UAAU,GAAG,GAAG,KAAK,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;IAC9C,aAAa,CAAC,UAAU,EAAE,UAAU,EAAE;QACpC,KAAK;QACL,IAAI;QACJ,IAAI;QACJ,QAAQ;QACR,KAAK;KACN,CAAC,CAAC;IAEH,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,QAAQ;QACd,QAAQ;QACR,KAAK;KACN,CAAC;AACJ,CAAC;AAMD;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAY,EACZ,UAA4B,EAAE;IAE9B,qCAAqC;IACrC,IAAI,KAAK,GAA6B,OAAO,CAAC,KAAK,CAAC;IAEpD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,qBAAqB,CAAC,CAAC;QAC1D,CAAC;QACD,KAAK,GAAG,UAAU,CAAC;IACrB,CAAC;IAED,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAE/C,IAAI,CAAC,QAAQ,IAAI,CAAC,UAAU,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,yBAAyB,KAAK,SAAS,CAAC,CAAC;IAC5E,CAAC;IAED,2BAA2B;IAC3B,IAAI,UAAU,EAAE,CAAC;QACf,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC;IAED,uBAAuB;IACvB,kBAAkB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAEhC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AACnC,CAAC;AAMD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,UAAyB,EAAE,EAC3B,UAA6F;IAE7F,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,QAAQ,CAAC;IACxC,MAAM,SAAS,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;IAE/C,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,MAAM,GAA2C,EAAE,CAAC;IAE1D,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,UAAU,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAExC,IAAI,CAAC;YACH,MAAM,eAAe,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YAC/D,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC5B,UAAU,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,YAAY,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YAC1E,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;YAC1D,UAAU,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,UAAkH;IAKlH,MAAM,YAAY,GAAG,MAAM,kBAAkB,CAC3C,EAAE,KAAK,EAAE,QAAQ,EAAE,EACnB,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAC5F,CAAC;IAEF,MAAM,WAAW,GAAG,MAAM,kBAAkB,CAC1C,EAAE,KAAK,EAAE,OAAO,EAAE,EAClB,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAC3F,CAAC;IAEF,OAAO;QACL,MAAM,EAAE,YAAY;QACpB,KAAK,EAAE,WAAW;KACnB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.test.d.ts","sourceRoot":"","sources":["../../src/utils/install.test.ts"],"names":[],"mappings":""}
|