@tankpkg/mcp-server 0.4.2 → 0.5.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 +41 -33
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/api-client.d.ts +6 -5
- package/dist/lib/api-client.d.ts.map +1 -1
- package/dist/lib/api-client.js +6 -6
- package/dist/lib/api-client.js.map +1 -1
- package/dist/lib/packer.d.ts +20 -0
- package/dist/lib/packer.d.ts.map +1 -1
- package/dist/lib/packer.js +85 -0
- package/dist/lib/packer.js.map +1 -1
- package/dist/tools/audit-skill.d.ts +3 -0
- package/dist/tools/audit-skill.d.ts.map +1 -0
- package/dist/tools/audit-skill.js +213 -0
- package/dist/tools/audit-skill.js.map +1 -0
- package/dist/tools/doctor.d.ts +3 -0
- package/dist/tools/doctor.d.ts.map +1 -0
- package/dist/tools/doctor.js +158 -0
- package/dist/tools/doctor.js.map +1 -0
- package/dist/tools/init-skill.d.ts +3 -0
- package/dist/tools/init-skill.d.ts.map +1 -0
- package/dist/tools/init-skill.js +72 -0
- package/dist/tools/init-skill.js.map +1 -0
- package/dist/tools/install-skill.d.ts +3 -0
- package/dist/tools/install-skill.d.ts.map +1 -0
- package/dist/tools/install-skill.js +206 -0
- package/dist/tools/install-skill.js.map +1 -0
- package/dist/tools/link-skill.d.ts +3 -0
- package/dist/tools/link-skill.d.ts.map +1 -0
- package/dist/tools/link-skill.js +81 -0
- package/dist/tools/link-skill.js.map +1 -0
- package/dist/tools/logout.d.ts +3 -0
- package/dist/tools/logout.d.ts.map +1 -0
- package/dist/tools/logout.js +19 -0
- package/dist/tools/logout.js.map +1 -0
- package/dist/tools/remove-skill.d.ts +3 -0
- package/dist/tools/remove-skill.d.ts.map +1 -0
- package/dist/tools/remove-skill.js +110 -0
- package/dist/tools/remove-skill.js.map +1 -0
- package/dist/tools/scan-skill.d.ts.map +1 -1
- package/dist/tools/scan-skill.js +41 -18
- package/dist/tools/scan-skill.js.map +1 -1
- package/dist/tools/skill-permissions.d.ts +3 -0
- package/dist/tools/skill-permissions.d.ts.map +1 -0
- package/dist/tools/skill-permissions.js +311 -0
- package/dist/tools/skill-permissions.js.map +1 -0
- package/dist/tools/unlink-skill.d.ts +3 -0
- package/dist/tools/unlink-skill.d.ts.map +1 -0
- package/dist/tools/unlink-skill.js +72 -0
- package/dist/tools/unlink-skill.js.map +1 -0
- package/dist/tools/update-skill.d.ts +3 -0
- package/dist/tools/update-skill.d.ts.map +1 -0
- package/dist/tools/update-skill.js +317 -0
- package/dist/tools/update-skill.js.map +1 -0
- package/dist/tools/verify-skills.d.ts +3 -0
- package/dist/tools/verify-skills.d.ts.map +1 -0
- package/dist/tools/verify-skills.js +121 -0
- package/dist/tools/verify-skills.js.map +1 -0
- package/dist/tools/whoami.d.ts +3 -0
- package/dist/tools/whoami.d.ts.map +1 -0
- package/dist/tools/whoami.js +29 -0
- package/dist/tools/whoami.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unlink-skill.js","sourceRoot":"","sources":["../../src/tools/unlink-skill.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-skill.d.ts","sourceRoot":"","sources":["../../src/tools/update-skill.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA0BzE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA6U/D"}
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { resolve } from '@tank/shared';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { TankApiClient } from '../lib/api-client.js';
|
|
6
|
+
const SCOPED_NAME_PATTERN = /^@[a-z0-9-]+\/[a-z0-9][a-z0-9-]*$/;
|
|
7
|
+
function parseLockKey(key) {
|
|
8
|
+
const lastAt = key.lastIndexOf('@');
|
|
9
|
+
if (lastAt <= 0)
|
|
10
|
+
return null;
|
|
11
|
+
return { name: key.slice(0, lastAt), version: key.slice(lastAt + 1) };
|
|
12
|
+
}
|
|
13
|
+
export function registerUpdateSkillTool(server) {
|
|
14
|
+
server.tool('update-skill', 'Update an installed skill to the latest compatible version within its declared semver range.', {
|
|
15
|
+
name: z.string().describe('Skill name in @org/name format'),
|
|
16
|
+
directory: z.string().optional().describe('Project directory (defaults to current working directory)'),
|
|
17
|
+
}, async ({ name, directory }) => {
|
|
18
|
+
if (!SCOPED_NAME_PATTERN.test(name)) {
|
|
19
|
+
return {
|
|
20
|
+
content: [{
|
|
21
|
+
type: 'text',
|
|
22
|
+
text: `Validation error: Skill name "${name}" must use the @org/name format (e.g. @acme/my-skill).`,
|
|
23
|
+
}],
|
|
24
|
+
isError: true,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const dir = directory ? path.resolve(directory) : process.cwd();
|
|
28
|
+
const skillsJsonPath = path.join(dir, 'skills.json');
|
|
29
|
+
if (!fs.existsSync(skillsJsonPath)) {
|
|
30
|
+
return {
|
|
31
|
+
content: [{
|
|
32
|
+
type: 'text',
|
|
33
|
+
text: `No skills.json found in ${dir}. Run the "init-skill" tool first.`,
|
|
34
|
+
}],
|
|
35
|
+
isError: true,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
let skillsJson;
|
|
39
|
+
try {
|
|
40
|
+
const raw = fs.readFileSync(skillsJsonPath, 'utf-8');
|
|
41
|
+
skillsJson = JSON.parse(raw);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return {
|
|
45
|
+
content: [{
|
|
46
|
+
type: 'text',
|
|
47
|
+
text: 'Failed to read or parse skills.json.',
|
|
48
|
+
}],
|
|
49
|
+
isError: true,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
const skills = (skillsJson.skills ?? {});
|
|
53
|
+
const versionRange = skills[name];
|
|
54
|
+
if (!versionRange) {
|
|
55
|
+
return {
|
|
56
|
+
content: [{
|
|
57
|
+
type: 'text',
|
|
58
|
+
text: `Skill "${name}" is not installed (not found in skills.json). Install it first with the install-skill tool.`,
|
|
59
|
+
}],
|
|
60
|
+
isError: true,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
const lockPath = path.join(dir, 'skills.lock');
|
|
64
|
+
let currentVersion = null;
|
|
65
|
+
if (fs.existsSync(lockPath)) {
|
|
66
|
+
try {
|
|
67
|
+
const raw = fs.readFileSync(lockPath, 'utf-8');
|
|
68
|
+
const lock = JSON.parse(raw);
|
|
69
|
+
for (const key of Object.keys(lock.skills)) {
|
|
70
|
+
const parsed = parseLockKey(key);
|
|
71
|
+
if (!parsed)
|
|
72
|
+
continue;
|
|
73
|
+
if (parsed.name === name) {
|
|
74
|
+
currentVersion = parsed.version;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// Lockfile unreadable — treat as no current version
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (!currentVersion) {
|
|
84
|
+
return {
|
|
85
|
+
content: [{
|
|
86
|
+
type: 'text',
|
|
87
|
+
text: `Skill "${name}" is not installed (not found in skills.lock). Install it first with the install-skill tool.`,
|
|
88
|
+
}],
|
|
89
|
+
isError: true,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
const client = new TankApiClient();
|
|
93
|
+
if (!client.isAuthenticated) {
|
|
94
|
+
return {
|
|
95
|
+
content: [{
|
|
96
|
+
type: 'text',
|
|
97
|
+
text: 'Authentication required. Please run the "login" tool first to authenticate with Tank.',
|
|
98
|
+
}],
|
|
99
|
+
isError: true,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
// Fetch available versions from registry
|
|
103
|
+
const encodedName = encodeURIComponent(name);
|
|
104
|
+
const versionsResult = await client.fetch(`/api/v1/skills/${encodedName}/versions`);
|
|
105
|
+
if (!versionsResult.ok) {
|
|
106
|
+
if (versionsResult.status === 0) {
|
|
107
|
+
return {
|
|
108
|
+
content: [{
|
|
109
|
+
type: 'text',
|
|
110
|
+
text: `Unable to connect to the Tank registry. Check your network connection and try again.`,
|
|
111
|
+
}],
|
|
112
|
+
isError: true,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
if (versionsResult.status === 404) {
|
|
116
|
+
return {
|
|
117
|
+
content: [{
|
|
118
|
+
type: 'text',
|
|
119
|
+
text: `Skill "${name}" not found in the registry.`,
|
|
120
|
+
}],
|
|
121
|
+
isError: true,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
content: [{
|
|
126
|
+
type: 'text',
|
|
127
|
+
text: `Failed to fetch versions for ${name}: ${versionsResult.error}`,
|
|
128
|
+
}],
|
|
129
|
+
isError: true,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
const availableVersions = versionsResult.data.versions.map((v) => v.version);
|
|
133
|
+
// 6. Resolve best version within declared range
|
|
134
|
+
const resolved = resolve(versionRange, availableVersions);
|
|
135
|
+
if (!resolved) {
|
|
136
|
+
return {
|
|
137
|
+
content: [{
|
|
138
|
+
type: 'text',
|
|
139
|
+
text: `No version of ${name} satisfies range "${versionRange}". Available: ${availableVersions.join(', ')}`,
|
|
140
|
+
}],
|
|
141
|
+
isError: true,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
// 7. Check for newer major versions outside range
|
|
145
|
+
const allMajors = availableVersions
|
|
146
|
+
.map((v) => {
|
|
147
|
+
const major = v.split('.')[0];
|
|
148
|
+
return { version: v, major: parseInt(major, 10) };
|
|
149
|
+
})
|
|
150
|
+
.filter((v) => !isNaN(v.major));
|
|
151
|
+
const currentMajor = parseInt(currentVersion.split('.')[0], 10);
|
|
152
|
+
const newerMajors = allMajors
|
|
153
|
+
.filter((v) => v.major > currentMajor)
|
|
154
|
+
.map((v) => v.version);
|
|
155
|
+
const highestOutOfRange = newerMajors.length > 0
|
|
156
|
+
? newerMajors.sort((a, b) => {
|
|
157
|
+
const [aMaj, aMin, aPat] = a.split('.').map(Number);
|
|
158
|
+
const [bMaj, bMin, bPat] = b.split('.').map(Number);
|
|
159
|
+
return bMaj - aMaj || bMin - aMin || bPat - aPat;
|
|
160
|
+
})[0]
|
|
161
|
+
: null;
|
|
162
|
+
// 8. If resolved === current, already at latest
|
|
163
|
+
if (resolved === currentVersion) {
|
|
164
|
+
const lines = [`Already at latest compatible version: ${name}@${resolved}`];
|
|
165
|
+
if (highestOutOfRange) {
|
|
166
|
+
lines.push(`\nNote: Version ${highestOutOfRange} is available but outside the declared range "${versionRange}". Update skills.json to use it.`);
|
|
167
|
+
}
|
|
168
|
+
return {
|
|
169
|
+
content: [{
|
|
170
|
+
type: 'text',
|
|
171
|
+
text: lines.join(''),
|
|
172
|
+
}],
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
// 9. Fetch the resolved version details for download
|
|
176
|
+
const versionResult = await client.fetch(`/api/v1/skills/${encodedName}/${resolved}`);
|
|
177
|
+
if (!versionResult.ok) {
|
|
178
|
+
return {
|
|
179
|
+
content: [{
|
|
180
|
+
type: 'text',
|
|
181
|
+
text: `Failed to fetch version details for ${name}@${resolved}: ${versionResult.error}`,
|
|
182
|
+
}],
|
|
183
|
+
isError: true,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
const versionData = versionResult.data;
|
|
187
|
+
// 10. Download tarball
|
|
188
|
+
let tarballBuffer;
|
|
189
|
+
try {
|
|
190
|
+
const tarballRes = await fetch(versionData.downloadUrl, {
|
|
191
|
+
headers: client.token ? { Authorization: `Bearer ${client.token}` } : {},
|
|
192
|
+
});
|
|
193
|
+
if (!tarballRes.ok) {
|
|
194
|
+
return {
|
|
195
|
+
content: [{
|
|
196
|
+
type: 'text',
|
|
197
|
+
text: `Failed to download tarball for ${name}@${resolved}: ${tarballRes.statusText}`,
|
|
198
|
+
}],
|
|
199
|
+
isError: true,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
tarballBuffer = await tarballRes.arrayBuffer();
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
return {
|
|
206
|
+
content: [{
|
|
207
|
+
type: 'text',
|
|
208
|
+
text: `Network error downloading ${name}@${resolved}: ${err instanceof Error ? err.message : String(err)}`,
|
|
209
|
+
}],
|
|
210
|
+
isError: true,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
// 11. Verify SHA-512
|
|
214
|
+
const { createHash } = await import('node:crypto');
|
|
215
|
+
const hash = createHash('sha512').update(Buffer.from(tarballBuffer)).digest('base64');
|
|
216
|
+
const computedIntegrity = `sha512-${hash}`;
|
|
217
|
+
if (computedIntegrity !== versionData.integrity) {
|
|
218
|
+
return {
|
|
219
|
+
content: [{
|
|
220
|
+
type: 'text',
|
|
221
|
+
text: `Integrity check failed for ${name}@${resolved}. The tarball has been tampered with or is corrupted.\nExpected: ${versionData.integrity}\nGot: ${computedIntegrity}`,
|
|
222
|
+
}],
|
|
223
|
+
isError: true,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
// 12. Extract tarball to skill directory
|
|
227
|
+
const { execSync } = await import('node:child_process');
|
|
228
|
+
const skillDir = getSkillDir(dir, name);
|
|
229
|
+
// Remove old version files if they exist
|
|
230
|
+
if (fs.existsSync(skillDir)) {
|
|
231
|
+
fs.rmSync(skillDir, { recursive: true, force: true });
|
|
232
|
+
}
|
|
233
|
+
fs.mkdirSync(skillDir, { recursive: true });
|
|
234
|
+
const tarballPath = path.join(skillDir, '__temp_tarball.tgz');
|
|
235
|
+
fs.writeFileSync(tarballPath, Buffer.from(tarballBuffer));
|
|
236
|
+
try {
|
|
237
|
+
execSync(`tar xzf "${tarballPath}" -C "${skillDir}" --strip-components=1`, {
|
|
238
|
+
stdio: 'pipe',
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
catch (err) {
|
|
242
|
+
return {
|
|
243
|
+
content: [{
|
|
244
|
+
type: 'text',
|
|
245
|
+
text: `Failed to extract tarball for ${name}@${resolved}: ${err instanceof Error ? err.message : String(err)}`,
|
|
246
|
+
}],
|
|
247
|
+
isError: true,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
finally {
|
|
251
|
+
// Clean up temp tarball
|
|
252
|
+
try {
|
|
253
|
+
fs.unlinkSync(tarballPath);
|
|
254
|
+
}
|
|
255
|
+
catch { /* ignore */ }
|
|
256
|
+
}
|
|
257
|
+
// 13. Update lockfile
|
|
258
|
+
let lock;
|
|
259
|
+
if (fs.existsSync(lockPath)) {
|
|
260
|
+
try {
|
|
261
|
+
const raw = fs.readFileSync(lockPath, 'utf-8');
|
|
262
|
+
lock = JSON.parse(raw);
|
|
263
|
+
}
|
|
264
|
+
catch {
|
|
265
|
+
lock = { lockfileVersion: 1, skills: {} };
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
lock = { lockfileVersion: 1, skills: {} };
|
|
270
|
+
}
|
|
271
|
+
// Remove old lock entry for this skill
|
|
272
|
+
for (const key of Object.keys(lock.skills)) {
|
|
273
|
+
const parsed = parseLockKey(key);
|
|
274
|
+
if (parsed && parsed.name === name) {
|
|
275
|
+
delete lock.skills[key];
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
// Add new lock entry
|
|
279
|
+
const newLockKey = `${name}@${resolved}`;
|
|
280
|
+
lock.skills[newLockKey] = {
|
|
281
|
+
resolved: versionData.downloadUrl,
|
|
282
|
+
integrity: versionData.integrity,
|
|
283
|
+
permissions: versionData.permissions,
|
|
284
|
+
audit_score: versionData.auditScore,
|
|
285
|
+
};
|
|
286
|
+
// Sort keys for deterministic output
|
|
287
|
+
const sortedSkills = {};
|
|
288
|
+
for (const key of Object.keys(lock.skills).sort()) {
|
|
289
|
+
sortedSkills[key] = lock.skills[key];
|
|
290
|
+
}
|
|
291
|
+
lock.skills = sortedSkills;
|
|
292
|
+
fs.writeFileSync(lockPath, JSON.stringify(lock, null, 2) + '\n');
|
|
293
|
+
// 14. Build response
|
|
294
|
+
const lines = [
|
|
295
|
+
`Updated ${name} from ${currentVersion} to ${resolved}.`,
|
|
296
|
+
`Integrity verified (SHA-512).`,
|
|
297
|
+
`Lockfile updated.`,
|
|
298
|
+
];
|
|
299
|
+
if (highestOutOfRange) {
|
|
300
|
+
lines.push(`\nNote: Version ${highestOutOfRange} is available but outside the declared range "${versionRange}". Update skills.json to use it.`);
|
|
301
|
+
}
|
|
302
|
+
return {
|
|
303
|
+
content: [{
|
|
304
|
+
type: 'text',
|
|
305
|
+
text: lines.join('\n'),
|
|
306
|
+
}],
|
|
307
|
+
};
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
function getSkillDir(projectDir, skillName) {
|
|
311
|
+
if (skillName.startsWith('@')) {
|
|
312
|
+
const [scope, name] = skillName.split('/');
|
|
313
|
+
return path.join(projectDir, '.tank', 'skills', scope, name);
|
|
314
|
+
}
|
|
315
|
+
return path.join(projectDir, '.tank', 'skills', skillName);
|
|
316
|
+
}
|
|
317
|
+
//# sourceMappingURL=update-skill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-skill.js","sourceRoot":"","sources":["../../src/tools/update-skill.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-skills.d.ts","sourceRoot":"","sources":["../../src/tools/verify-skills.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyHhE"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
export function registerVerifySkillsTool(server) {
|
|
5
|
+
server.tool('verify-skills', 'Verify that installed skills match their lockfile entries. Checks that skill directories exist and are not empty.', {
|
|
6
|
+
name: z.string().optional().describe('Specific skill name to verify (verifies all if omitted)'),
|
|
7
|
+
directory: z.string().optional().describe('Project directory (defaults to current working directory)'),
|
|
8
|
+
}, async ({ name, directory }) => {
|
|
9
|
+
const dir = directory ? path.resolve(directory) : process.cwd();
|
|
10
|
+
const lockPath = path.join(dir, 'skills.lock');
|
|
11
|
+
if (!fs.existsSync(lockPath)) {
|
|
12
|
+
return {
|
|
13
|
+
content: [{
|
|
14
|
+
type: 'text',
|
|
15
|
+
text: 'No skills.lock found. Run "install-skill" to install skills and generate a lockfile.',
|
|
16
|
+
}],
|
|
17
|
+
isError: true,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
let lock;
|
|
21
|
+
try {
|
|
22
|
+
const raw = fs.readFileSync(lockPath, 'utf-8');
|
|
23
|
+
lock = JSON.parse(raw);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return {
|
|
27
|
+
content: [{
|
|
28
|
+
type: 'text',
|
|
29
|
+
text: 'Failed to parse skills.lock. The file may be corrupted.',
|
|
30
|
+
}],
|
|
31
|
+
isError: true,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
let entries = Object.entries(lock.skills);
|
|
35
|
+
if (entries.length === 0) {
|
|
36
|
+
return {
|
|
37
|
+
content: [{
|
|
38
|
+
type: 'text',
|
|
39
|
+
text: 'No skills to verify. The lockfile is empty.',
|
|
40
|
+
}],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
if (name) {
|
|
44
|
+
entries = entries.filter(([key]) => {
|
|
45
|
+
const lastAt = key.lastIndexOf('@');
|
|
46
|
+
if (lastAt <= 0)
|
|
47
|
+
return false;
|
|
48
|
+
return key.slice(0, lastAt) === name;
|
|
49
|
+
});
|
|
50
|
+
if (entries.length === 0) {
|
|
51
|
+
return {
|
|
52
|
+
content: [{
|
|
53
|
+
type: 'text',
|
|
54
|
+
text: `Skill "${name}" not found in lockfile.`,
|
|
55
|
+
}],
|
|
56
|
+
isError: true,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const results = [];
|
|
61
|
+
for (const [key, entry] of entries) {
|
|
62
|
+
const skillName = parseLockKey(key);
|
|
63
|
+
const skillDir = getExtractDir(dir, skillName);
|
|
64
|
+
if (!fs.existsSync(skillDir)) {
|
|
65
|
+
results.push({
|
|
66
|
+
key,
|
|
67
|
+
status: 'MISSING',
|
|
68
|
+
detail: `Directory missing at ${skillDir}. Reinstall with "install-skill".`,
|
|
69
|
+
});
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
const contents = fs.readdirSync(skillDir);
|
|
73
|
+
if (contents.length === 0) {
|
|
74
|
+
results.push({
|
|
75
|
+
key,
|
|
76
|
+
status: 'FAIL',
|
|
77
|
+
detail: `Directory exists but is empty. Expected integrity: ${entry.integrity}. SHA-512 mismatch detected.`,
|
|
78
|
+
});
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
results.push({
|
|
82
|
+
key,
|
|
83
|
+
status: 'PASS',
|
|
84
|
+
detail: `Verified (integrity: ${entry.integrity})`,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
const passing = results.filter((r) => r.status === 'PASS');
|
|
88
|
+
const failing = results.filter((r) => r.status !== 'PASS');
|
|
89
|
+
const lines = [];
|
|
90
|
+
for (const r of results) {
|
|
91
|
+
lines.push(`${r.status} ${r.key}: ${r.detail}`);
|
|
92
|
+
}
|
|
93
|
+
if (failing.length > 0) {
|
|
94
|
+
lines.push('');
|
|
95
|
+
lines.push(`Verification failed: ${failing.length} issue(s) found, ${passing.length} passed.`);
|
|
96
|
+
return {
|
|
97
|
+
content: [{ type: 'text', text: lines.join('\n') }],
|
|
98
|
+
isError: true,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
lines.push('');
|
|
102
|
+
lines.push(`All ${passing.length} skill(s) passed verification.`);
|
|
103
|
+
return {
|
|
104
|
+
content: [{ type: 'text', text: lines.join('\n') }],
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
function parseLockKey(key) {
|
|
109
|
+
const lastAt = key.lastIndexOf('@');
|
|
110
|
+
if (lastAt <= 0)
|
|
111
|
+
return key;
|
|
112
|
+
return key.slice(0, lastAt);
|
|
113
|
+
}
|
|
114
|
+
function getExtractDir(projectDir, skillName) {
|
|
115
|
+
if (skillName.startsWith('@')) {
|
|
116
|
+
const [scope, name] = skillName.split('/');
|
|
117
|
+
return path.join(projectDir, '.tank', 'skills', scope, name);
|
|
118
|
+
}
|
|
119
|
+
return path.join(projectDir, '.tank', 'skills', skillName);
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=verify-skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-skills.js","sourceRoot":"","sources":["../../src/tools/verify-skills.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/tools/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAoC1D"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { TankApiClient } from '../lib/api-client.js';
|
|
2
|
+
export function registerWhoamiTool(server) {
|
|
3
|
+
server.tool('whoami', 'Show the authenticated Tank user for the current local session.', {}, async () => {
|
|
4
|
+
const client = new TankApiClient();
|
|
5
|
+
if (!client.isAuthenticated) {
|
|
6
|
+
return {
|
|
7
|
+
content: [{ type: 'text', text: 'Not logged in. Use the login tool to authenticate.' }],
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
const authCheck = await client.verifyAuth();
|
|
11
|
+
if (authCheck.valid) {
|
|
12
|
+
const name = authCheck.user.name ?? 'unknown';
|
|
13
|
+
const email = authCheck.user.email ?? 'unknown';
|
|
14
|
+
return {
|
|
15
|
+
content: [{ type: 'text', text: `Logged in as ${name}\nEmail: ${email}` }],
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
if (authCheck.reason === 'network-error') {
|
|
19
|
+
return {
|
|
20
|
+
content: [{ type: 'text', text: `Failed to connect to the registry. Check your network connection.\nError: ${authCheck.error ?? 'unknown'}` }],
|
|
21
|
+
isError: true,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
content: [{ type: 'text', text: 'Session expired or invalid. Use the login tool to re-authenticate.' }],
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=whoami.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/tools/whoami.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,UAAU,kBAAkB,CAAC,MAAiB;IAClD,MAAM,CAAC,IAAI,CACT,QAAQ,EACR,iEAAiE,EACjE,EAAE,EACF,KAAK,IAAI,EAAE;QACT,MAAM,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAEnC,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;YAC5B,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,oDAAoD,EAAE,CAAC;aACjG,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;QAE5C,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;YACpB,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,SAAS,CAAC;YAC9C,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC;YAChD,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,gBAAgB,IAAI,YAAY,KAAK,EAAE,EAAE,CAAC;aACpF,CAAC;QACJ,CAAC;QAED,IAAI,SAAS,CAAC,MAAM,KAAK,eAAe,EAAE,CAAC;YACzC,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,6EAA6E,SAAS,CAAC,KAAK,IAAI,SAAS,EAAE,EAAE,CAAC;gBACvJ,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,oEAAoE,EAAE,CAAC;SACjH,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|