@tankpkg/mcp-server 0.6.3 → 0.8.1
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 +11 -4
- package/dist/index.d.ts +1 -3
- package/dist/index.js +2215 -29
- package/dist/index.js.map +1 -1
- package/package.json +20 -14
- package/LICENSE +0 -21
- package/dist/index.d.ts.map +0 -1
- package/dist/lib/api-client.d.ts +0 -45
- package/dist/lib/api-client.d.ts.map +0 -1
- package/dist/lib/api-client.js +0 -78
- package/dist/lib/api-client.js.map +0 -1
- package/dist/lib/config.d.ts +0 -25
- package/dist/lib/config.d.ts.map +0 -1
- package/dist/lib/config.js +0 -59
- package/dist/lib/config.js.map +0 -1
- package/dist/lib/packer.d.ts +0 -34
- package/dist/lib/packer.d.ts.map +0 -1
- package/dist/lib/packer.js +0 -276
- package/dist/lib/packer.js.map +0 -1
- package/dist/tools/audit-skill.d.ts +0 -3
- package/dist/tools/audit-skill.d.ts.map +0 -1
- package/dist/tools/audit-skill.js +0 -213
- package/dist/tools/audit-skill.js.map +0 -1
- package/dist/tools/doctor.d.ts +0 -3
- package/dist/tools/doctor.d.ts.map +0 -1
- package/dist/tools/doctor.js +0 -158
- package/dist/tools/doctor.js.map +0 -1
- package/dist/tools/init-skill.d.ts +0 -3
- package/dist/tools/init-skill.d.ts.map +0 -1
- package/dist/tools/init-skill.js +0 -72
- package/dist/tools/init-skill.js.map +0 -1
- package/dist/tools/install-skill.d.ts +0 -3
- package/dist/tools/install-skill.d.ts.map +0 -1
- package/dist/tools/install-skill.js +0 -206
- package/dist/tools/install-skill.js.map +0 -1
- package/dist/tools/link-skill.d.ts +0 -3
- package/dist/tools/link-skill.d.ts.map +0 -1
- package/dist/tools/link-skill.js +0 -81
- package/dist/tools/link-skill.js.map +0 -1
- package/dist/tools/login.d.ts +0 -3
- package/dist/tools/login.d.ts.map +0 -1
- package/dist/tools/login.js +0 -104
- package/dist/tools/login.js.map +0 -1
- package/dist/tools/logout.d.ts +0 -3
- package/dist/tools/logout.d.ts.map +0 -1
- package/dist/tools/logout.js +0 -19
- package/dist/tools/logout.js.map +0 -1
- package/dist/tools/publish-skill.d.ts +0 -3
- package/dist/tools/publish-skill.d.ts.map +0 -1
- package/dist/tools/publish-skill.js +0 -166
- package/dist/tools/publish-skill.js.map +0 -1
- package/dist/tools/remove-skill.d.ts +0 -3
- package/dist/tools/remove-skill.d.ts.map +0 -1
- package/dist/tools/remove-skill.js +0 -110
- package/dist/tools/remove-skill.js.map +0 -1
- package/dist/tools/scan-skill.d.ts +0 -3
- package/dist/tools/scan-skill.d.ts.map +0 -1
- package/dist/tools/scan-skill.js +0 -200
- package/dist/tools/scan-skill.js.map +0 -1
- package/dist/tools/search-skills.d.ts +0 -3
- package/dist/tools/search-skills.d.ts.map +0 -1
- package/dist/tools/search-skills.js +0 -54
- package/dist/tools/search-skills.js.map +0 -1
- package/dist/tools/skill-info.d.ts +0 -3
- package/dist/tools/skill-info.d.ts.map +0 -1
- package/dist/tools/skill-info.js +0 -88
- package/dist/tools/skill-info.js.map +0 -1
- package/dist/tools/skill-permissions.d.ts +0 -3
- package/dist/tools/skill-permissions.d.ts.map +0 -1
- package/dist/tools/skill-permissions.js +0 -311
- package/dist/tools/skill-permissions.js.map +0 -1
- package/dist/tools/unlink-skill.d.ts +0 -3
- package/dist/tools/unlink-skill.d.ts.map +0 -1
- package/dist/tools/unlink-skill.js +0 -72
- package/dist/tools/unlink-skill.js.map +0 -1
- package/dist/tools/update-skill.d.ts +0 -3
- package/dist/tools/update-skill.d.ts.map +0 -1
- package/dist/tools/update-skill.js +0 -317
- package/dist/tools/update-skill.js.map +0 -1
- package/dist/tools/verify-skills.d.ts +0 -3
- package/dist/tools/verify-skills.d.ts.map +0 -1
- package/dist/tools/verify-skills.js +0 -121
- package/dist/tools/verify-skills.js.map +0 -1
- package/dist/tools/whoami.d.ts +0 -3
- package/dist/tools/whoami.d.ts.map +0 -1
- package/dist/tools/whoami.js +0 -29
- package/dist/tools/whoami.js.map +0 -1
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { z } from 'zod';
|
|
4
|
-
import { TankApiClient } from '../lib/api-client.js';
|
|
5
|
-
const SCOPED_NAME_PATTERN = /^@[a-z0-9-]+\/[a-z0-9][a-z0-9-]*$/;
|
|
6
|
-
function parseLockKey(key) {
|
|
7
|
-
const lastAt = key.lastIndexOf('@');
|
|
8
|
-
if (lastAt <= 0)
|
|
9
|
-
return null;
|
|
10
|
-
return { name: key.slice(0, lastAt), version: key.slice(lastAt + 1) };
|
|
11
|
-
}
|
|
12
|
-
function deriveVerdict(score, status) {
|
|
13
|
-
if (status !== 'completed' || score === null)
|
|
14
|
-
return 'PENDING';
|
|
15
|
-
if (score >= 7)
|
|
16
|
-
return 'PASS';
|
|
17
|
-
if (score >= 4)
|
|
18
|
-
return 'FLAGGED';
|
|
19
|
-
return 'FAIL';
|
|
20
|
-
}
|
|
21
|
-
function formatFindings(findings) {
|
|
22
|
-
if (findings.length === 0)
|
|
23
|
-
return '';
|
|
24
|
-
const bySeverity = {
|
|
25
|
-
critical: [],
|
|
26
|
-
high: [],
|
|
27
|
-
medium: [],
|
|
28
|
-
low: [],
|
|
29
|
-
};
|
|
30
|
-
for (const f of findings) {
|
|
31
|
-
if (bySeverity[f.severity]) {
|
|
32
|
-
bySeverity[f.severity].push(f);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
const lines = ['', `### Findings (${findings.length})`];
|
|
36
|
-
for (const severity of ['critical', 'high', 'medium', 'low']) {
|
|
37
|
-
const group = bySeverity[severity];
|
|
38
|
-
if (group.length === 0)
|
|
39
|
-
continue;
|
|
40
|
-
lines.push(`\n**${severity.toUpperCase()} (${group.length}):**`);
|
|
41
|
-
for (const f of group) {
|
|
42
|
-
lines.push(`- ${f.type}: ${f.description}${f.location ? ` (${f.location})` : ''}`);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return lines.join('\n');
|
|
46
|
-
}
|
|
47
|
-
export function registerAuditSkillTool(server) {
|
|
48
|
-
server.tool('audit-skill', 'Show security audit results for a skill from the Tank registry.', {
|
|
49
|
-
name: z.string().describe('Skill name in @org/name format'),
|
|
50
|
-
version: z.string().optional().describe('Specific version to audit (defaults to installed or latest)'),
|
|
51
|
-
}, async ({ name, version }) => {
|
|
52
|
-
if (!SCOPED_NAME_PATTERN.test(name)) {
|
|
53
|
-
return {
|
|
54
|
-
content: [{
|
|
55
|
-
type: 'text',
|
|
56
|
-
text: `Validation error: Skill name "${name}" must use the @org/name format (e.g. @acme/my-skill).`,
|
|
57
|
-
}],
|
|
58
|
-
isError: true,
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
const client = new TankApiClient();
|
|
62
|
-
if (!client.isAuthenticated) {
|
|
63
|
-
return {
|
|
64
|
-
content: [{
|
|
65
|
-
type: 'text',
|
|
66
|
-
text: 'Authentication required. Please run the "login" tool first to authenticate with Tank.',
|
|
67
|
-
}],
|
|
68
|
-
isError: true,
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
const encodedName = encodeURIComponent(name);
|
|
72
|
-
// If no version specified, try to find installed version from lockfile
|
|
73
|
-
let targetVersion = version;
|
|
74
|
-
if (!targetVersion) {
|
|
75
|
-
const lockPath = path.join(process.cwd(), 'skills.lock');
|
|
76
|
-
if (fs.existsSync(lockPath)) {
|
|
77
|
-
try {
|
|
78
|
-
const raw = fs.readFileSync(lockPath, 'utf-8');
|
|
79
|
-
const lock = JSON.parse(raw);
|
|
80
|
-
for (const key of Object.keys(lock.skills)) {
|
|
81
|
-
const parsed = parseLockKey(key);
|
|
82
|
-
if (parsed && parsed.name === name) {
|
|
83
|
-
targetVersion = parsed.version;
|
|
84
|
-
break;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
catch {
|
|
89
|
-
// Lockfile unreadable — fall through to fetch latest
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
// If still no version, fetch skill metadata to get latest
|
|
94
|
-
if (!targetVersion) {
|
|
95
|
-
const metaResult = await client.fetch(`/api/v1/skills/${encodedName}`);
|
|
96
|
-
if (!metaResult.ok) {
|
|
97
|
-
if (metaResult.status === 0) {
|
|
98
|
-
return {
|
|
99
|
-
content: [{
|
|
100
|
-
type: 'text',
|
|
101
|
-
text: 'Unable to connect to the Tank registry. Check your network connection and try again.',
|
|
102
|
-
}],
|
|
103
|
-
isError: true,
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
if (metaResult.status === 404) {
|
|
107
|
-
return {
|
|
108
|
-
content: [{
|
|
109
|
-
type: 'text',
|
|
110
|
-
text: `Skill "${name}" not found in the Tank registry.`,
|
|
111
|
-
}],
|
|
112
|
-
isError: true,
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
return {
|
|
116
|
-
content: [{
|
|
117
|
-
type: 'text',
|
|
118
|
-
text: `Failed to fetch skill metadata: ${metaResult.error}`,
|
|
119
|
-
}],
|
|
120
|
-
isError: true,
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
targetVersion = metaResult.data.latestVersion;
|
|
124
|
-
}
|
|
125
|
-
// Fetch version details with audit data
|
|
126
|
-
const versionResult = await client.fetch(`/api/v1/skills/${encodedName}/${targetVersion}`);
|
|
127
|
-
if (!versionResult.ok) {
|
|
128
|
-
if (versionResult.status === 0) {
|
|
129
|
-
return {
|
|
130
|
-
content: [{
|
|
131
|
-
type: 'text',
|
|
132
|
-
text: 'Unable to connect to the Tank registry. Check your network connection and try again.',
|
|
133
|
-
}],
|
|
134
|
-
isError: true,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
if (versionResult.status === 404) {
|
|
138
|
-
return {
|
|
139
|
-
content: [{
|
|
140
|
-
type: 'text',
|
|
141
|
-
text: `Skill "${name}" version "${targetVersion}" not found in the Tank registry.`,
|
|
142
|
-
}],
|
|
143
|
-
isError: true,
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
return {
|
|
147
|
-
content: [{
|
|
148
|
-
type: 'text',
|
|
149
|
-
text: `Failed to fetch audit data: ${versionResult.error}`,
|
|
150
|
-
}],
|
|
151
|
-
isError: true,
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
const details = versionResult.data;
|
|
155
|
-
const verdict = deriveVerdict(details.auditScore, details.auditStatus);
|
|
156
|
-
if (details.auditStatus !== 'completed') {
|
|
157
|
-
return {
|
|
158
|
-
content: [{
|
|
159
|
-
type: 'text',
|
|
160
|
-
text: [
|
|
161
|
-
`## Audit: ${name}@${targetVersion}`,
|
|
162
|
-
'',
|
|
163
|
-
`**Status:** Pending security review`,
|
|
164
|
-
`**Scan Status:** ${details.auditStatus}`,
|
|
165
|
-
'',
|
|
166
|
-
'This skill has not yet been through security scanning. Results will be available once the scan completes.',
|
|
167
|
-
].join('\n'),
|
|
168
|
-
}],
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
// Try to fetch detailed scan results
|
|
172
|
-
let findingsText = '';
|
|
173
|
-
const scanResult = await client.fetch(`/api/v1/skills/${encodedName}/${targetVersion}/scan`);
|
|
174
|
-
if (scanResult.ok && scanResult.data.findings) {
|
|
175
|
-
findingsText = formatFindings(scanResult.data.findings);
|
|
176
|
-
}
|
|
177
|
-
const score = details.auditScore !== null ? details.auditScore.toFixed(1) : 'N/A';
|
|
178
|
-
const lines = [
|
|
179
|
-
`## Audit: ${name}@${targetVersion}`,
|
|
180
|
-
'',
|
|
181
|
-
`**Verdict:** ${verdict}`,
|
|
182
|
-
`**Score:** ${score}/10`,
|
|
183
|
-
`**Scanned:** ${details.publishedAt}`,
|
|
184
|
-
`**Version:** ${targetVersion}`,
|
|
185
|
-
];
|
|
186
|
-
if (details.permissions) {
|
|
187
|
-
lines.push('', '**Permissions:**');
|
|
188
|
-
const p = details.permissions;
|
|
189
|
-
if (p.network?.outbound?.length) {
|
|
190
|
-
lines.push(` - Network: ${p.network.outbound.join(', ')}`);
|
|
191
|
-
}
|
|
192
|
-
if (p.filesystem?.read?.length || p.filesystem?.write?.length) {
|
|
193
|
-
const parts = [];
|
|
194
|
-
if (p.filesystem.read?.length)
|
|
195
|
-
parts.push(`read: ${p.filesystem.read.join(', ')}`);
|
|
196
|
-
if (p.filesystem.write?.length)
|
|
197
|
-
parts.push(`write: ${p.filesystem.write.join(', ')}`);
|
|
198
|
-
lines.push(` - Filesystem: ${parts.join('; ')}`);
|
|
199
|
-
}
|
|
200
|
-
lines.push(` - Subprocess: ${p.subprocess ? 'yes' : 'no'}`);
|
|
201
|
-
}
|
|
202
|
-
if (findingsText) {
|
|
203
|
-
lines.push(findingsText);
|
|
204
|
-
}
|
|
205
|
-
return {
|
|
206
|
-
content: [{
|
|
207
|
-
type: 'text',
|
|
208
|
-
text: lines.join('\n'),
|
|
209
|
-
}],
|
|
210
|
-
};
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
//# sourceMappingURL=audit-skill.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"audit-skill.js","sourceRoot":"","sources":["../../src/tools/audit-skill.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/doctor.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/tools/doctor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA0KzE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkB1D"}
|
package/dist/tools/doctor.js
DELETED
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import { getConfigPath, getConfig } from '../lib/config.js';
|
|
3
|
-
import { TankApiClient } from '../lib/api-client.js';
|
|
4
|
-
const MIN_NODE_MAJOR = 24;
|
|
5
|
-
function checkConfigFile() {
|
|
6
|
-
const configPath = getConfigPath();
|
|
7
|
-
if (!fs.existsSync(configPath)) {
|
|
8
|
-
return {
|
|
9
|
-
name: 'Configuration File',
|
|
10
|
-
status: 'FAIL',
|
|
11
|
-
message: `Configuration file not found at ${configPath}. Run the login tool to create it.`,
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
try {
|
|
15
|
-
const raw = fs.readFileSync(configPath, 'utf-8');
|
|
16
|
-
JSON.parse(raw);
|
|
17
|
-
return {
|
|
18
|
-
name: 'Configuration File',
|
|
19
|
-
status: 'PASS',
|
|
20
|
-
message: `Configuration file exists and is valid JSON (${configPath}).`,
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
catch (err) {
|
|
24
|
-
const detail = err instanceof Error ? err.message : String(err);
|
|
25
|
-
return {
|
|
26
|
-
name: 'Configuration File',
|
|
27
|
-
status: 'FAIL',
|
|
28
|
-
message: `Configuration file at ${configPath} is malformed: ${detail}`,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
async function checkAuthentication() {
|
|
33
|
-
const client = new TankApiClient();
|
|
34
|
-
if (!client.isAuthenticated) {
|
|
35
|
-
return {
|
|
36
|
-
name: 'Authentication',
|
|
37
|
-
status: 'FAIL',
|
|
38
|
-
message: 'Not authenticated. Use the login tool to authenticate with Tank.',
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
const authCheck = await client.verifyAuth();
|
|
42
|
-
if (authCheck.valid) {
|
|
43
|
-
const name = authCheck.user.name ?? 'unknown';
|
|
44
|
-
return {
|
|
45
|
-
name: 'Authentication',
|
|
46
|
-
status: 'PASS',
|
|
47
|
-
message: `Authenticated as ${name}.`,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
if (authCheck.reason === 'network-error') {
|
|
51
|
-
return {
|
|
52
|
-
name: 'Authentication',
|
|
53
|
-
status: 'FAIL',
|
|
54
|
-
message: `Could not verify credentials (network error). ${authCheck.error ?? ''}`.trim(),
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
return {
|
|
58
|
-
name: 'Authentication',
|
|
59
|
-
status: 'FAIL',
|
|
60
|
-
message: 'Credentials are expired or invalid. Use the login tool to re-authenticate.',
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
async function checkRegistryConnectivity() {
|
|
64
|
-
const config = getConfig();
|
|
65
|
-
const registryUrl = config.registry;
|
|
66
|
-
try {
|
|
67
|
-
const healthUrl = `${registryUrl}/api/health`;
|
|
68
|
-
const response = await fetch(healthUrl, {
|
|
69
|
-
signal: AbortSignal.timeout(10_000),
|
|
70
|
-
});
|
|
71
|
-
if (response.ok) {
|
|
72
|
-
return {
|
|
73
|
-
name: 'Registry Connectivity',
|
|
74
|
-
status: 'PASS',
|
|
75
|
-
message: `Registry at ${registryUrl} is reachable.`,
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
return {
|
|
79
|
-
name: 'Registry Connectivity',
|
|
80
|
-
status: 'FAIL',
|
|
81
|
-
message: `Registry at ${registryUrl} returned HTTP ${response.status}.`,
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
catch {
|
|
85
|
-
return {
|
|
86
|
-
name: 'Registry Connectivity',
|
|
87
|
-
status: 'FAIL',
|
|
88
|
-
message: `Cannot reach registry at ${registryUrl}. Check your network connection.`,
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
function checkNodeVersion() {
|
|
93
|
-
const raw = process.version;
|
|
94
|
-
const match = raw.match(/^v(\d+)/);
|
|
95
|
-
const major = match ? parseInt(match[1], 10) : 0;
|
|
96
|
-
if (major >= MIN_NODE_MAJOR) {
|
|
97
|
-
return {
|
|
98
|
-
name: 'Node.js Version',
|
|
99
|
-
status: 'PASS',
|
|
100
|
-
message: `Node.js ${raw} meets the minimum requirement (v${MIN_NODE_MAJOR}.0.0).`,
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
return {
|
|
104
|
-
name: 'Node.js Version',
|
|
105
|
-
status: 'FAIL',
|
|
106
|
-
message: `Node.js ${raw} is below the minimum required version v${MIN_NODE_MAJOR}.0.0. Please upgrade Node.js.`,
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
function formatChecks(checks) {
|
|
110
|
-
const lines = [];
|
|
111
|
-
lines.push('Tank Doctor Report');
|
|
112
|
-
lines.push('==================');
|
|
113
|
-
lines.push('');
|
|
114
|
-
for (const check of checks) {
|
|
115
|
-
const icon = check.status === 'PASS' ? 'PASS' : 'FAIL';
|
|
116
|
-
lines.push(`[${icon}] ${check.name}`);
|
|
117
|
-
lines.push(` ${check.message}`);
|
|
118
|
-
}
|
|
119
|
-
lines.push('');
|
|
120
|
-
const failedChecks = checks.filter((c) => c.status === 'FAIL');
|
|
121
|
-
const allPassed = failedChecks.length === 0;
|
|
122
|
-
if (allPassed) {
|
|
123
|
-
lines.push('All checks passed. Your Tank environment is ready to use.');
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
lines.push('Suggestions:');
|
|
127
|
-
for (const check of failedChecks) {
|
|
128
|
-
if (check.name === 'Authentication') {
|
|
129
|
-
lines.push(' - Use the login tool to authenticate with Tank.');
|
|
130
|
-
}
|
|
131
|
-
else if (check.name === 'Registry Connectivity') {
|
|
132
|
-
lines.push(' - Check your network connection and verify the registry URL.');
|
|
133
|
-
}
|
|
134
|
-
else if (check.name === 'Node.js Version') {
|
|
135
|
-
lines.push(` - Upgrade Node.js to v${MIN_NODE_MAJOR}.0.0 or later.`);
|
|
136
|
-
}
|
|
137
|
-
else if (check.name === 'Configuration File') {
|
|
138
|
-
lines.push(' - Use the login tool to create a valid configuration file.');
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
lines.push('');
|
|
142
|
-
lines.push('The environment is not healthy. Please address the issues above.');
|
|
143
|
-
}
|
|
144
|
-
return lines.join('\n');
|
|
145
|
-
}
|
|
146
|
-
export function registerDoctorTool(server) {
|
|
147
|
-
server.tool('doctor', 'Diagnose Tank setup and environment.', {}, async () => {
|
|
148
|
-
const checks = [];
|
|
149
|
-
checks.push(checkConfigFile());
|
|
150
|
-
checks.push(await checkAuthentication());
|
|
151
|
-
checks.push(await checkRegistryConnectivity());
|
|
152
|
-
checks.push(checkNodeVersion());
|
|
153
|
-
return {
|
|
154
|
-
content: [{ type: 'text', text: formatChecks(checks) }],
|
|
155
|
-
};
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
//# sourceMappingURL=doctor.js.map
|
package/dist/tools/doctor.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/tools/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"init-skill.d.ts","sourceRoot":"","sources":["../../src/tools/init-skill.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOzE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA+E7D"}
|
package/dist/tools/init-skill.js
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { skillsJsonSchema } from '@tank/shared';
|
|
4
|
-
import { z } from 'zod';
|
|
5
|
-
const SCOPED_NAME_PATTERN = /^@[a-z0-9-]+\/[a-z0-9][a-z0-9-]*$/;
|
|
6
|
-
const SEMVER_PATTERN = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$/;
|
|
7
|
-
export function registerInitSkillTool(server) {
|
|
8
|
-
server.tool('init-skill', 'Create a new skills.json and SKILL.md template for a Tank skill.', {
|
|
9
|
-
name: z.string().regex(SCOPED_NAME_PATTERN, 'Name must be in @org/name format'),
|
|
10
|
-
version: z.string().regex(SEMVER_PATTERN, 'Version must be valid semver').optional().default('0.1.0'),
|
|
11
|
-
description: z.string().optional().default(''),
|
|
12
|
-
directory: z.string().optional().default('.'),
|
|
13
|
-
}, async ({ name, version = '0.1.0', description = '', directory = '.' }) => {
|
|
14
|
-
const targetDir = path.resolve(directory);
|
|
15
|
-
if (!fs.existsSync(targetDir)) {
|
|
16
|
-
return {
|
|
17
|
-
content: [{ type: 'text', text: `Directory does not exist: ${targetDir}` }],
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
if (!fs.statSync(targetDir).isDirectory()) {
|
|
21
|
-
return {
|
|
22
|
-
content: [{ type: 'text', text: `Path is not a directory: ${targetDir}` }],
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
const skillsJsonPath = path.join(targetDir, 'skills.json');
|
|
26
|
-
if (fs.existsSync(skillsJsonPath)) {
|
|
27
|
-
return {
|
|
28
|
-
content: [{ type: 'text', text: `skills.json already exists at ${skillsJsonPath}. Aborting to avoid overwrite.` }],
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
const manifest = {
|
|
32
|
-
name,
|
|
33
|
-
version,
|
|
34
|
-
description,
|
|
35
|
-
skills: {},
|
|
36
|
-
permissions: {
|
|
37
|
-
network: { outbound: [] },
|
|
38
|
-
filesystem: { read: [], write: [] },
|
|
39
|
-
subprocess: false,
|
|
40
|
-
},
|
|
41
|
-
};
|
|
42
|
-
const parseResult = skillsJsonSchema.safeParse(manifest);
|
|
43
|
-
if (!parseResult.success) {
|
|
44
|
-
const details = parseResult.error.issues
|
|
45
|
-
.map((issue) => `${issue.path.join('.') || 'root'}: ${issue.message}`)
|
|
46
|
-
.join('; ');
|
|
47
|
-
return {
|
|
48
|
-
content: [{ type: 'text', text: `Failed to create skills.json: ${details}` }],
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
fs.writeFileSync(skillsJsonPath, JSON.stringify(manifest, null, 2) + '\n', 'utf-8');
|
|
52
|
-
const skillMdPath = path.join(targetDir, 'SKILL.md');
|
|
53
|
-
let createdSkillMd = false;
|
|
54
|
-
if (!fs.existsSync(skillMdPath)) {
|
|
55
|
-
const skillMd = `# ${name}\n\n${description || 'Description here.'}\n`;
|
|
56
|
-
fs.writeFileSync(skillMdPath, skillMd, 'utf-8');
|
|
57
|
-
createdSkillMd = true;
|
|
58
|
-
}
|
|
59
|
-
const skillMdLine = createdSkillMd
|
|
60
|
-
? `Created: ${skillMdPath}`
|
|
61
|
-
: `Skipped existing: ${skillMdPath}`;
|
|
62
|
-
return {
|
|
63
|
-
content: [
|
|
64
|
-
{
|
|
65
|
-
type: 'text',
|
|
66
|
-
text: `Initialized skill in ${targetDir}\nCreated: ${skillsJsonPath}\n${skillMdLine}`,
|
|
67
|
-
},
|
|
68
|
-
],
|
|
69
|
-
};
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
//# sourceMappingURL=init-skill.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"init-skill.js","sourceRoot":"","sources":["../../src/tools/init-skill.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"install-skill.d.ts","sourceRoot":"","sources":["../../src/tools/install-skill.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA2CzE,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA4NhE"}
|