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.
Files changed (66) hide show
  1. package/README.md +57 -0
  2. package/dist/commands/add.d.ts +6 -0
  3. package/dist/commands/add.d.ts.map +1 -0
  4. package/dist/commands/add.js +35 -0
  5. package/dist/commands/add.js.map +1 -0
  6. package/dist/commands/list.d.ts +7 -0
  7. package/dist/commands/list.d.ts.map +1 -0
  8. package/dist/commands/list.js +77 -0
  9. package/dist/commands/list.js.map +1 -0
  10. package/dist/commands/remove.d.ts +6 -0
  11. package/dist/commands/remove.d.ts.map +1 -0
  12. package/dist/commands/remove.js +25 -0
  13. package/dist/commands/remove.js.map +1 -0
  14. package/dist/commands/update.d.ts +7 -0
  15. package/dist/commands/update.d.ts.map +1 -0
  16. package/dist/commands/update.js +83 -0
  17. package/dist/commands/update.js.map +1 -0
  18. package/dist/index.d.ts +3 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +125 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/types.d.ts +41 -0
  23. package/dist/types.d.ts.map +1 -0
  24. package/dist/types.js +3 -0
  25. package/dist/types.js.map +1 -0
  26. package/dist/utils/fetch.d.ts +23 -0
  27. package/dist/utils/fetch.d.ts.map +1 -0
  28. package/dist/utils/fetch.js +124 -0
  29. package/dist/utils/fetch.js.map +1 -0
  30. package/dist/utils/fetch.test.d.ts +2 -0
  31. package/dist/utils/fetch.test.d.ts.map +1 -0
  32. package/dist/utils/fetch.test.js +246 -0
  33. package/dist/utils/fetch.test.js.map +1 -0
  34. package/dist/utils/install.d.ts +68 -0
  35. package/dist/utils/install.d.ts.map +1 -0
  36. package/dist/utils/install.js +140 -0
  37. package/dist/utils/install.js.map +1 -0
  38. package/dist/utils/install.test.d.ts +2 -0
  39. package/dist/utils/install.test.d.ts.map +1 -0
  40. package/dist/utils/install.test.js +565 -0
  41. package/dist/utils/install.test.js.map +1 -0
  42. package/dist/utils/manifest.d.ts +37 -0
  43. package/dist/utils/manifest.d.ts.map +1 -0
  44. package/dist/utils/manifest.js +74 -0
  45. package/dist/utils/manifest.js.map +1 -0
  46. package/dist/utils/manifest.test.d.ts +2 -0
  47. package/dist/utils/manifest.test.d.ts.map +1 -0
  48. package/dist/utils/manifest.test.js +278 -0
  49. package/dist/utils/manifest.test.js.map +1 -0
  50. package/dist/utils/paths.d.ts +49 -0
  51. package/dist/utils/paths.d.ts.map +1 -0
  52. package/dist/utils/paths.js +98 -0
  53. package/dist/utils/paths.js.map +1 -0
  54. package/dist/utils/paths.test.d.ts +2 -0
  55. package/dist/utils/paths.test.d.ts.map +1 -0
  56. package/dist/utils/paths.test.js +255 -0
  57. package/dist/utils/paths.test.js.map +1 -0
  58. package/dist/utils/telemetry.d.ts +5 -0
  59. package/dist/utils/telemetry.d.ts.map +1 -0
  60. package/dist/utils/telemetry.js +30 -0
  61. package/dist/utils/telemetry.js.map +1 -0
  62. package/dist/utils/telemetry.test.d.ts +2 -0
  63. package/dist/utils/telemetry.test.d.ts.map +1 -0
  64. package/dist/utils/telemetry.test.js +113 -0
  65. package/dist/utils/telemetry.test.js.map +1 -0
  66. 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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=fetch.test.d.ts.map
@@ -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":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=install.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.test.d.ts","sourceRoot":"","sources":["../../src/utils/install.test.ts"],"names":[],"mappings":""}