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,74 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import { getManifestPath } from './paths.js';
|
|
3
|
+
const MANIFEST_VERSION = '1';
|
|
4
|
+
/**
|
|
5
|
+
* Load the manifest file for a given scope
|
|
6
|
+
* @param scope - 'global' (default) or 'local'
|
|
7
|
+
*/
|
|
8
|
+
export function loadManifest(scope = 'global') {
|
|
9
|
+
const manifestPath = getManifestPath(scope);
|
|
10
|
+
if (!fs.existsSync(manifestPath)) {
|
|
11
|
+
return {
|
|
12
|
+
version: MANIFEST_VERSION,
|
|
13
|
+
subagents: {},
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
const content = fs.readFileSync(manifestPath, 'utf-8');
|
|
18
|
+
return JSON.parse(content);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return {
|
|
22
|
+
version: MANIFEST_VERSION,
|
|
23
|
+
subagents: {},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Save the manifest file for a given scope
|
|
29
|
+
* @param manifest - The manifest to save
|
|
30
|
+
* @param scope - 'global' (default) or 'local'
|
|
31
|
+
*/
|
|
32
|
+
export function saveManifest(manifest, scope = 'global') {
|
|
33
|
+
const manifestPath = getManifestPath(scope);
|
|
34
|
+
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Add a subagent to the manifest for a given scope
|
|
38
|
+
* @param name - Subagent name
|
|
39
|
+
* @param subagent - Subagent info
|
|
40
|
+
* @param scope - 'global' (default) or 'local'
|
|
41
|
+
*/
|
|
42
|
+
export function addToManifest(name, subagent, scope = 'global') {
|
|
43
|
+
const manifest = loadManifest(scope);
|
|
44
|
+
manifest.subagents[name] = subagent;
|
|
45
|
+
saveManifest(manifest, scope);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Remove a subagent from the manifest for a given scope
|
|
49
|
+
* @param name - Subagent name
|
|
50
|
+
* @param scope - 'global' (default) or 'local'
|
|
51
|
+
*/
|
|
52
|
+
export function removeFromManifest(name, scope = 'global') {
|
|
53
|
+
const manifest = loadManifest(scope);
|
|
54
|
+
delete manifest.subagents[name];
|
|
55
|
+
saveManifest(manifest, scope);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get a subagent from the manifest for a given scope
|
|
59
|
+
* @param name - Subagent name
|
|
60
|
+
* @param scope - 'global' (default) or 'local'
|
|
61
|
+
*/
|
|
62
|
+
export function getFromManifest(name, scope = 'global') {
|
|
63
|
+
const manifest = loadManifest(scope);
|
|
64
|
+
return manifest.subagents[name];
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* List all subagents in the manifest for a given scope
|
|
68
|
+
* @param scope - 'global' (default) or 'local'
|
|
69
|
+
*/
|
|
70
|
+
export function listManifestSubagents(scope = 'global') {
|
|
71
|
+
const manifest = loadManifest(scope);
|
|
72
|
+
return Object.values(manifest.subagents);
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/utils/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAG7C,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAE7B;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,QAAsB,QAAQ;IACzD,MAAM,YAAY,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IAE5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO;YACL,OAAO,EAAE,gBAAgB;YACzB,SAAS,EAAE,EAAE;SACd,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAa,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,OAAO,EAAE,gBAAgB;YACzB,SAAS,EAAE,EAAE;SACd,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,QAAkB,EAAE,QAAsB,QAAQ;IAC7E,MAAM,YAAY,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IAC5C,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,QAA2B,EAAE,QAAsB,QAAQ;IACrG,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACrC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC;IACpC,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;AAChC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,QAAsB,QAAQ;IAC7E,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACrC,OAAO,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAChC,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;AAChC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,QAAsB,QAAQ;IAC1E,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACrC,OAAO,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAsB,QAAQ;IAClE,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACrC,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.test.d.ts","sourceRoot":"","sources":["../../src/utils/manifest.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import * as paths from './paths.js';
|
|
4
|
+
import { loadManifest, saveManifest, addToManifest, removeFromManifest, getFromManifest, listManifestSubagents, } from './manifest.js';
|
|
5
|
+
vi.mock('node:fs');
|
|
6
|
+
vi.mock('./paths.js');
|
|
7
|
+
describe('loadManifest', () => {
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
vi.mocked(paths.getManifestPath).mockReturnValue('/test/.claude/agents/.subagents.json');
|
|
10
|
+
});
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
vi.resetAllMocks();
|
|
13
|
+
});
|
|
14
|
+
it('returns empty manifest when file missing', () => {
|
|
15
|
+
vi.mocked(fs.existsSync).mockReturnValue(false);
|
|
16
|
+
const manifest = loadManifest();
|
|
17
|
+
expect(manifest).toEqual({
|
|
18
|
+
version: '1',
|
|
19
|
+
subagents: {},
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
it('parses existing manifest JSON', () => {
|
|
23
|
+
const existingManifest = {
|
|
24
|
+
version: '1',
|
|
25
|
+
subagents: {
|
|
26
|
+
'test-agent': {
|
|
27
|
+
name: 'Test Agent',
|
|
28
|
+
path: '/test/.claude/agents/test-agent.md',
|
|
29
|
+
source: 'owner/repo/test-agent',
|
|
30
|
+
installedAt: '2024-01-01T00:00:00.000Z',
|
|
31
|
+
updatedAt: '2024-01-01T00:00:00.000Z',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
36
|
+
vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify(existingManifest));
|
|
37
|
+
const manifest = loadManifest();
|
|
38
|
+
expect(manifest).toEqual(existingManifest);
|
|
39
|
+
});
|
|
40
|
+
it('handles corrupted JSON gracefully', () => {
|
|
41
|
+
vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
42
|
+
vi.mocked(fs.readFileSync).mockReturnValue('{ invalid json');
|
|
43
|
+
const manifest = loadManifest();
|
|
44
|
+
expect(manifest).toEqual({
|
|
45
|
+
version: '1',
|
|
46
|
+
subagents: {},
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
it('handles empty file gracefully', () => {
|
|
50
|
+
vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
51
|
+
vi.mocked(fs.readFileSync).mockReturnValue('');
|
|
52
|
+
const manifest = loadManifest();
|
|
53
|
+
expect(manifest).toEqual({
|
|
54
|
+
version: '1',
|
|
55
|
+
subagents: {},
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe('saveManifest', () => {
|
|
60
|
+
beforeEach(() => {
|
|
61
|
+
vi.mocked(paths.getManifestPath).mockReturnValue('/test/.claude/agents/.subagents.json');
|
|
62
|
+
});
|
|
63
|
+
afterEach(() => {
|
|
64
|
+
vi.resetAllMocks();
|
|
65
|
+
});
|
|
66
|
+
it('writes JSON to correct path', () => {
|
|
67
|
+
const manifest = {
|
|
68
|
+
version: '1',
|
|
69
|
+
subagents: {
|
|
70
|
+
'my-agent': {
|
|
71
|
+
name: 'My Agent',
|
|
72
|
+
path: '/test/.claude/agents/my-agent.md',
|
|
73
|
+
source: 'owner/repo/my-agent',
|
|
74
|
+
installedAt: '2024-01-01T00:00:00.000Z',
|
|
75
|
+
updatedAt: '2024-01-01T00:00:00.000Z',
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
saveManifest(manifest);
|
|
80
|
+
expect(fs.writeFileSync).toHaveBeenCalledWith('/test/.claude/agents/.subagents.json', JSON.stringify(manifest, null, 2));
|
|
81
|
+
});
|
|
82
|
+
it('formats JSON with 2-space indentation', () => {
|
|
83
|
+
const manifest = { version: '1', subagents: {} };
|
|
84
|
+
saveManifest(manifest);
|
|
85
|
+
const writtenContent = vi.mocked(fs.writeFileSync).mock.calls[0][1];
|
|
86
|
+
expect(writtenContent).toBe('{\n "version": "1",\n "subagents": {}\n}');
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
describe('addToManifest', () => {
|
|
90
|
+
beforeEach(() => {
|
|
91
|
+
vi.mocked(paths.getManifestPath).mockReturnValue('/test/.claude/agents/.subagents.json');
|
|
92
|
+
});
|
|
93
|
+
afterEach(() => {
|
|
94
|
+
vi.resetAllMocks();
|
|
95
|
+
});
|
|
96
|
+
it('adds new subagent to empty manifest', () => {
|
|
97
|
+
vi.mocked(fs.existsSync).mockReturnValue(false);
|
|
98
|
+
const subagent = {
|
|
99
|
+
name: 'New Agent',
|
|
100
|
+
path: '/test/.claude/agents/new-agent.md',
|
|
101
|
+
source: 'owner/repo/new-agent',
|
|
102
|
+
installedAt: '2024-01-01T00:00:00.000Z',
|
|
103
|
+
updatedAt: '2024-01-01T00:00:00.000Z',
|
|
104
|
+
};
|
|
105
|
+
addToManifest('new-agent', subagent);
|
|
106
|
+
expect(fs.writeFileSync).toHaveBeenCalled();
|
|
107
|
+
const writtenContent = JSON.parse(vi.mocked(fs.writeFileSync).mock.calls[0][1]);
|
|
108
|
+
expect(writtenContent.subagents['new-agent']).toEqual(subagent);
|
|
109
|
+
});
|
|
110
|
+
it('adds subagent to existing manifest', () => {
|
|
111
|
+
const existingManifest = {
|
|
112
|
+
version: '1',
|
|
113
|
+
subagents: {
|
|
114
|
+
'existing-agent': {
|
|
115
|
+
name: 'Existing Agent',
|
|
116
|
+
path: '/test/.claude/agents/existing-agent.md',
|
|
117
|
+
source: 'owner/repo/existing-agent',
|
|
118
|
+
installedAt: '2024-01-01T00:00:00.000Z',
|
|
119
|
+
updatedAt: '2024-01-01T00:00:00.000Z',
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
124
|
+
vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify(existingManifest));
|
|
125
|
+
const newSubagent = {
|
|
126
|
+
name: 'New Agent',
|
|
127
|
+
path: '/test/.claude/agents/new-agent.md',
|
|
128
|
+
source: 'owner/repo/new-agent',
|
|
129
|
+
installedAt: '2024-01-02T00:00:00.000Z',
|
|
130
|
+
updatedAt: '2024-01-02T00:00:00.000Z',
|
|
131
|
+
};
|
|
132
|
+
addToManifest('new-agent', newSubagent);
|
|
133
|
+
const writtenContent = JSON.parse(vi.mocked(fs.writeFileSync).mock.calls[0][1]);
|
|
134
|
+
expect(Object.keys(writtenContent.subagents)).toHaveLength(2);
|
|
135
|
+
expect(writtenContent.subagents['existing-agent']).toBeDefined();
|
|
136
|
+
expect(writtenContent.subagents['new-agent']).toEqual(newSubagent);
|
|
137
|
+
});
|
|
138
|
+
it('updates existing subagent', () => {
|
|
139
|
+
const existingManifest = {
|
|
140
|
+
version: '1',
|
|
141
|
+
subagents: {
|
|
142
|
+
'my-agent': {
|
|
143
|
+
name: 'My Agent',
|
|
144
|
+
path: '/test/.claude/agents/my-agent.md',
|
|
145
|
+
source: 'owner/repo/my-agent',
|
|
146
|
+
description: 'Old description',
|
|
147
|
+
installedAt: '2024-01-01T00:00:00.000Z',
|
|
148
|
+
updatedAt: '2024-01-01T00:00:00.000Z',
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
153
|
+
vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify(existingManifest));
|
|
154
|
+
const updatedSubagent = {
|
|
155
|
+
name: 'My Agent',
|
|
156
|
+
path: '/test/.claude/agents/my-agent.md',
|
|
157
|
+
source: 'owner/repo/my-agent',
|
|
158
|
+
description: 'New description',
|
|
159
|
+
installedAt: '2024-01-01T00:00:00.000Z',
|
|
160
|
+
updatedAt: '2024-01-02T00:00:00.000Z',
|
|
161
|
+
};
|
|
162
|
+
addToManifest('my-agent', updatedSubagent);
|
|
163
|
+
const writtenContent = JSON.parse(vi.mocked(fs.writeFileSync).mock.calls[0][1]);
|
|
164
|
+
expect(writtenContent.subagents['my-agent'].description).toBe('New description');
|
|
165
|
+
expect(writtenContent.subagents['my-agent'].updatedAt).toBe('2024-01-02T00:00:00.000Z');
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
describe('removeFromManifest', () => {
|
|
169
|
+
beforeEach(() => {
|
|
170
|
+
vi.mocked(paths.getManifestPath).mockReturnValue('/test/.claude/agents/.subagents.json');
|
|
171
|
+
});
|
|
172
|
+
afterEach(() => {
|
|
173
|
+
vi.resetAllMocks();
|
|
174
|
+
});
|
|
175
|
+
it('removes subagent from manifest', () => {
|
|
176
|
+
const existingManifest = {
|
|
177
|
+
version: '1',
|
|
178
|
+
subagents: {
|
|
179
|
+
'agent-a': {
|
|
180
|
+
name: 'Agent A',
|
|
181
|
+
path: '/test/.claude/agents/agent-a.md',
|
|
182
|
+
source: 'owner/repo/agent-a',
|
|
183
|
+
installedAt: '2024-01-01T00:00:00.000Z',
|
|
184
|
+
updatedAt: '2024-01-01T00:00:00.000Z',
|
|
185
|
+
},
|
|
186
|
+
'agent-b': {
|
|
187
|
+
name: 'Agent B',
|
|
188
|
+
path: '/test/.claude/agents/agent-b.md',
|
|
189
|
+
source: 'owner/repo/agent-b',
|
|
190
|
+
installedAt: '2024-01-01T00:00:00.000Z',
|
|
191
|
+
updatedAt: '2024-01-01T00:00:00.000Z',
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
196
|
+
vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify(existingManifest));
|
|
197
|
+
removeFromManifest('agent-a');
|
|
198
|
+
const writtenContent = JSON.parse(vi.mocked(fs.writeFileSync).mock.calls[0][1]);
|
|
199
|
+
expect(writtenContent.subagents['agent-a']).toBeUndefined();
|
|
200
|
+
expect(writtenContent.subagents['agent-b']).toBeDefined();
|
|
201
|
+
});
|
|
202
|
+
it('handles removing non-existent subagent gracefully', () => {
|
|
203
|
+
vi.mocked(fs.existsSync).mockReturnValue(false);
|
|
204
|
+
removeFromManifest('nonexistent');
|
|
205
|
+
const writtenContent = JSON.parse(vi.mocked(fs.writeFileSync).mock.calls[0][1]);
|
|
206
|
+
expect(writtenContent.subagents).toEqual({});
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
describe('getFromManifest', () => {
|
|
210
|
+
beforeEach(() => {
|
|
211
|
+
vi.mocked(paths.getManifestPath).mockReturnValue('/test/.claude/agents/.subagents.json');
|
|
212
|
+
});
|
|
213
|
+
afterEach(() => {
|
|
214
|
+
vi.resetAllMocks();
|
|
215
|
+
});
|
|
216
|
+
it('returns subagent when it exists', () => {
|
|
217
|
+
const subagent = {
|
|
218
|
+
name: 'My Agent',
|
|
219
|
+
path: '/test/.claude/agents/my-agent.md',
|
|
220
|
+
source: 'owner/repo/my-agent',
|
|
221
|
+
installedAt: '2024-01-01T00:00:00.000Z',
|
|
222
|
+
updatedAt: '2024-01-01T00:00:00.000Z',
|
|
223
|
+
};
|
|
224
|
+
const existingManifest = {
|
|
225
|
+
version: '1',
|
|
226
|
+
subagents: { 'my-agent': subagent },
|
|
227
|
+
};
|
|
228
|
+
vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
229
|
+
vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify(existingManifest));
|
|
230
|
+
const result = getFromManifest('my-agent');
|
|
231
|
+
expect(result).toEqual(subagent);
|
|
232
|
+
});
|
|
233
|
+
it('returns undefined when subagent does not exist', () => {
|
|
234
|
+
vi.mocked(fs.existsSync).mockReturnValue(false);
|
|
235
|
+
const result = getFromManifest('nonexistent');
|
|
236
|
+
expect(result).toBeUndefined();
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
describe('listManifestSubagents', () => {
|
|
240
|
+
beforeEach(() => {
|
|
241
|
+
vi.mocked(paths.getManifestPath).mockReturnValue('/test/.claude/agents/.subagents.json');
|
|
242
|
+
});
|
|
243
|
+
afterEach(() => {
|
|
244
|
+
vi.resetAllMocks();
|
|
245
|
+
});
|
|
246
|
+
it('returns array of installed subagents', () => {
|
|
247
|
+
const agentA = {
|
|
248
|
+
name: 'Agent A',
|
|
249
|
+
path: '/test/.claude/agents/agent-a.md',
|
|
250
|
+
source: 'owner/repo/agent-a',
|
|
251
|
+
installedAt: '2024-01-01T00:00:00.000Z',
|
|
252
|
+
updatedAt: '2024-01-01T00:00:00.000Z',
|
|
253
|
+
};
|
|
254
|
+
const agentB = {
|
|
255
|
+
name: 'Agent B',
|
|
256
|
+
path: '/test/.claude/agents/agent-b.md',
|
|
257
|
+
source: 'owner/repo/agent-b',
|
|
258
|
+
installedAt: '2024-01-02T00:00:00.000Z',
|
|
259
|
+
updatedAt: '2024-01-02T00:00:00.000Z',
|
|
260
|
+
};
|
|
261
|
+
const existingManifest = {
|
|
262
|
+
version: '1',
|
|
263
|
+
subagents: { 'agent-a': agentA, 'agent-b': agentB },
|
|
264
|
+
};
|
|
265
|
+
vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
266
|
+
vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify(existingManifest));
|
|
267
|
+
const result = listManifestSubagents();
|
|
268
|
+
expect(result).toHaveLength(2);
|
|
269
|
+
expect(result).toContainEqual(agentA);
|
|
270
|
+
expect(result).toContainEqual(agentB);
|
|
271
|
+
});
|
|
272
|
+
it('returns empty array when no subagents installed', () => {
|
|
273
|
+
vi.mocked(fs.existsSync).mockReturnValue(false);
|
|
274
|
+
const result = listManifestSubagents();
|
|
275
|
+
expect(result).toEqual([]);
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
//# sourceMappingURL=manifest.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.test.js","sourceRoot":"","sources":["../../src/utils/manifest.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { StorageScope } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Get the global agents directory path (~/.claude/agents/)
|
|
4
|
+
* Creates it if it doesn't exist
|
|
5
|
+
*/
|
|
6
|
+
export declare function getGlobalAgentsDir(): string;
|
|
7
|
+
/**
|
|
8
|
+
* Get the local/project agents directory path (./.claude/agents/)
|
|
9
|
+
* Creates it if it doesn't exist
|
|
10
|
+
*/
|
|
11
|
+
export declare function getLocalAgentsDir(): string;
|
|
12
|
+
/**
|
|
13
|
+
* Get the agents directory path for a given scope
|
|
14
|
+
* Creates it if it doesn't exist
|
|
15
|
+
* @param scope - 'global' (default) or 'local'
|
|
16
|
+
*/
|
|
17
|
+
export declare function getAgentsDir(scope?: StorageScope): string;
|
|
18
|
+
/**
|
|
19
|
+
* Get the manifest file path for a given scope
|
|
20
|
+
* @param scope - 'global' (default) or 'local'
|
|
21
|
+
*/
|
|
22
|
+
export declare function getManifestPath(scope?: StorageScope): string;
|
|
23
|
+
/**
|
|
24
|
+
* Check if a subagent file exists in the given scope
|
|
25
|
+
* @param name - Subagent name
|
|
26
|
+
* @param scope - 'global' (default) or 'local'
|
|
27
|
+
*/
|
|
28
|
+
export declare function subagentExists(name: string, scope?: StorageScope): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Check if a subagent exists in either scope and return the scope
|
|
31
|
+
* Returns null if not found in either location
|
|
32
|
+
*/
|
|
33
|
+
export declare function findSubagentScope(name: string): StorageScope | null;
|
|
34
|
+
/**
|
|
35
|
+
* Get the full path for a subagent file
|
|
36
|
+
* @param name - Subagent name
|
|
37
|
+
* @param scope - 'global' (default) or 'local'
|
|
38
|
+
*/
|
|
39
|
+
export declare function getSubagentPath(name: string, scope?: StorageScope): string;
|
|
40
|
+
/**
|
|
41
|
+
* List all .md files in the agents directory for a given scope
|
|
42
|
+
* @param scope - 'global' (default) or 'local'
|
|
43
|
+
*/
|
|
44
|
+
export declare function listSubagentFiles(scope?: StorageScope): string[];
|
|
45
|
+
/**
|
|
46
|
+
* Check if local agents directory exists (without creating it)
|
|
47
|
+
*/
|
|
48
|
+
export declare function localAgentsDirExists(): boolean;
|
|
49
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAS3C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAS1C;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,GAAE,YAAuB,GAAG,MAAM,CAEnE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,GAAE,YAAuB,GAAG,MAAM,CAGtE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,YAAuB,GAAG,OAAO,CAIpF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAQnE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,YAAuB,GAAG,MAAM,CAGpF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,GAAE,YAAuB,GAAG,MAAM,EAAE,CAW1E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAI9C"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import * as os from 'node:os';
|
|
4
|
+
/**
|
|
5
|
+
* Get the global agents directory path (~/.claude/agents/)
|
|
6
|
+
* Creates it if it doesn't exist
|
|
7
|
+
*/
|
|
8
|
+
export function getGlobalAgentsDir() {
|
|
9
|
+
const homeDir = os.homedir();
|
|
10
|
+
const agentsDir = path.join(homeDir, '.claude', 'agents');
|
|
11
|
+
if (!fs.existsSync(agentsDir)) {
|
|
12
|
+
fs.mkdirSync(agentsDir, { recursive: true });
|
|
13
|
+
}
|
|
14
|
+
return agentsDir;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Get the local/project agents directory path (./.claude/agents/)
|
|
18
|
+
* Creates it if it doesn't exist
|
|
19
|
+
*/
|
|
20
|
+
export function getLocalAgentsDir() {
|
|
21
|
+
const cwd = process.cwd();
|
|
22
|
+
const agentsDir = path.join(cwd, '.claude', 'agents');
|
|
23
|
+
if (!fs.existsSync(agentsDir)) {
|
|
24
|
+
fs.mkdirSync(agentsDir, { recursive: true });
|
|
25
|
+
}
|
|
26
|
+
return agentsDir;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get the agents directory path for a given scope
|
|
30
|
+
* Creates it if it doesn't exist
|
|
31
|
+
* @param scope - 'global' (default) or 'local'
|
|
32
|
+
*/
|
|
33
|
+
export function getAgentsDir(scope = 'global') {
|
|
34
|
+
return scope === 'global' ? getGlobalAgentsDir() : getLocalAgentsDir();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get the manifest file path for a given scope
|
|
38
|
+
* @param scope - 'global' (default) or 'local'
|
|
39
|
+
*/
|
|
40
|
+
export function getManifestPath(scope = 'global') {
|
|
41
|
+
const agentsDir = getAgentsDir(scope);
|
|
42
|
+
return path.join(agentsDir, '.subagents.json');
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Check if a subagent file exists in the given scope
|
|
46
|
+
* @param name - Subagent name
|
|
47
|
+
* @param scope - 'global' (default) or 'local'
|
|
48
|
+
*/
|
|
49
|
+
export function subagentExists(name, scope = 'global') {
|
|
50
|
+
const agentsDir = getAgentsDir(scope);
|
|
51
|
+
const filePath = path.join(agentsDir, `${name}.md`);
|
|
52
|
+
return fs.existsSync(filePath);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Check if a subagent exists in either scope and return the scope
|
|
56
|
+
* Returns null if not found in either location
|
|
57
|
+
*/
|
|
58
|
+
export function findSubagentScope(name) {
|
|
59
|
+
if (subagentExists(name, 'local')) {
|
|
60
|
+
return 'local';
|
|
61
|
+
}
|
|
62
|
+
if (subagentExists(name, 'global')) {
|
|
63
|
+
return 'global';
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get the full path for a subagent file
|
|
69
|
+
* @param name - Subagent name
|
|
70
|
+
* @param scope - 'global' (default) or 'local'
|
|
71
|
+
*/
|
|
72
|
+
export function getSubagentPath(name, scope = 'global') {
|
|
73
|
+
const agentsDir = getAgentsDir(scope);
|
|
74
|
+
return path.join(agentsDir, `${name}.md`);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* List all .md files in the agents directory for a given scope
|
|
78
|
+
* @param scope - 'global' (default) or 'local'
|
|
79
|
+
*/
|
|
80
|
+
export function listSubagentFiles(scope = 'global') {
|
|
81
|
+
const agentsDir = getAgentsDir(scope);
|
|
82
|
+
if (!fs.existsSync(agentsDir)) {
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
return fs
|
|
86
|
+
.readdirSync(agentsDir)
|
|
87
|
+
.filter((f) => f.endsWith('.md'))
|
|
88
|
+
.map((f) => f.replace('.md', ''));
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Check if local agents directory exists (without creating it)
|
|
92
|
+
*/
|
|
93
|
+
export function localAgentsDirExists() {
|
|
94
|
+
const cwd = process.cwd();
|
|
95
|
+
const agentsDir = path.join(cwd, '.claude', 'agents');
|
|
96
|
+
return fs.existsSync(agentsDir);
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.test.d.ts","sourceRoot":"","sources":["../../src/utils/paths.test.ts"],"names":[],"mappings":""}
|