toolshedtech 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.
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/index.js ADDED
@@ -0,0 +1,613 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import path2 from "path";
5
+ import { Command } from "commander";
6
+
7
+ // src/commands/add.ts
8
+ import { spawn } from "child_process";
9
+ import { cp, mkdir, mkdtemp, readFile, rm, stat } from "fs/promises";
10
+ import os from "os";
11
+ import path from "path";
12
+ import kleur from "kleur";
13
+ import { z as z3 } from "zod";
14
+
15
+ // ../shared/src/index.ts
16
+ import { z as z2 } from "zod";
17
+
18
+ // ../shared/src/tool-release-map.ts
19
+ import { z } from "zod";
20
+ var toolReleaseMapEntrySchema = z.object({
21
+ toolName: z.string().regex(/^[a-z0-9-]+$/),
22
+ sourcePath: z.string().min(1),
23
+ publicRepo: z.string().url().regex(/^https:\/\/github\.com\/[^/]+\/[^/]+(?:\.git)?$/),
24
+ publicDefaultBranch: z.string().min(1).default("main")
25
+ });
26
+ var toolReleaseMapSchema = z.object({
27
+ tools: z.array(toolReleaseMapEntrySchema)
28
+ });
29
+
30
+ // ../shared/src/index.ts
31
+ var TOOLSHED_MANIFEST_FILENAME = "toolshed.tool.json";
32
+ var AI_SDK_PACKAGE_NAME = "ai";
33
+ var AI_SDK_REQUIRED_MAJOR = 6;
34
+ var AI_SDK_REQUIRED_RANGE = ">=6 <7";
35
+ var MCP_MANIFEST_VARIANT = "mcp";
36
+ function stripVersionProtocol(value) {
37
+ let normalized = value.trim();
38
+ const protocols = ["workspace:", "npm:", "pnpm:", "yarn:", "catalog:"];
39
+ for (const protocol of protocols) {
40
+ if (normalized.startsWith(protocol)) {
41
+ normalized = normalized.slice(protocol.length).trim();
42
+ }
43
+ }
44
+ return normalized;
45
+ }
46
+ function extractDependencyNameAndRange(specifier) {
47
+ const normalized = stripVersionProtocol(specifier);
48
+ const scopedMatch = normalized.match(/^(@[^/@\s]+\/[^@\s]+)(?:@(.+))?$/);
49
+ if (scopedMatch) {
50
+ return {
51
+ name: scopedMatch[1] ?? normalized,
52
+ range: scopedMatch[2]?.trim() || null
53
+ };
54
+ }
55
+ const plainMatch = normalized.match(/^([^@\s]+)(?:@(.+))?$/);
56
+ if (plainMatch) {
57
+ return {
58
+ name: plainMatch[1] ?? normalized,
59
+ range: plainMatch[2]?.trim() || null
60
+ };
61
+ }
62
+ return {
63
+ name: normalized,
64
+ range: null
65
+ };
66
+ }
67
+ function isAiSdk6Range(range) {
68
+ const normalized = stripVersionProtocol(range).replace(/\s+/g, "");
69
+ if (!normalized) return false;
70
+ const disjunctive = normalized.split("||");
71
+ return disjunctive.some((candidate) => {
72
+ if (/^[~^]?6(?:\.|$)/.test(candidate)) return true;
73
+ if (/^6(?:\.x)?(?:\.x)?$/.test(candidate)) return true;
74
+ if (/^>=6(?:\.0\.0)?<7(?:\.0\.0)?$/.test(candidate)) return true;
75
+ return false;
76
+ });
77
+ }
78
+ function findAiSdkDependencySpecifier(entries) {
79
+ return entries.find((entry) => {
80
+ const parsed = extractDependencyNameAndRange(entry);
81
+ return parsed.name === AI_SDK_PACKAGE_NAME;
82
+ });
83
+ }
84
+ function isAiSdkSpecifierCompatible(specifier) {
85
+ const parsed = extractDependencyNameAndRange(specifier);
86
+ if (parsed.name !== AI_SDK_PACKAGE_NAME || !parsed.range) return false;
87
+ return isAiSdk6Range(parsed.range);
88
+ }
89
+ function isAiSdkRangeCompatible(range) {
90
+ return isAiSdk6Range(range);
91
+ }
92
+ var aiSdkRequirementSchema = z2.object({
93
+ package: z2.literal(AI_SDK_PACKAGE_NAME).default(AI_SDK_PACKAGE_NAME),
94
+ major: z2.literal(AI_SDK_REQUIRED_MAJOR).default(AI_SDK_REQUIRED_MAJOR),
95
+ range: z2.string().min(1).default(AI_SDK_REQUIRED_RANGE)
96
+ });
97
+ var toolProviderSchema = z2.enum(["github", "gmail", "spotify", "generic"]);
98
+ var toolOperationSchema = z2.enum(["read", "write", "mixed"]);
99
+ var toolGuardrailSchema = z2.enum(["confirm_true", "none"]);
100
+ var manifestFileVariantSchema = z2.enum(["core", MCP_MANIFEST_VARIANT]);
101
+ var toolManifestFileSchema = z2.object({
102
+ source: z2.string().min(1),
103
+ target: z2.string().min(1),
104
+ variant: manifestFileVariantSchema.default("core")
105
+ });
106
+ var toolManifestSchema = z2.object({
107
+ name: z2.string().min(2),
108
+ version: z2.string().min(1),
109
+ description: z2.string().min(10),
110
+ aiSdk: aiSdkRequirementSchema.default({
111
+ package: AI_SDK_PACKAGE_NAME,
112
+ major: AI_SDK_REQUIRED_MAJOR,
113
+ range: AI_SDK_REQUIRED_RANGE
114
+ }),
115
+ entry: z2.string().min(1),
116
+ files: z2.array(toolManifestFileSchema),
117
+ dependencies: z2.array(z2.string()).default([]),
118
+ devDependencies: z2.array(z2.string()).default([]),
119
+ envVars: z2.record(z2.string(), z2.string()).optional(),
120
+ provider: toolProviderSchema.default("generic"),
121
+ operation: toolOperationSchema.default("read"),
122
+ guardrail: toolGuardrailSchema.default("none"),
123
+ mcpAdapterAvailable: z2.boolean().default(false),
124
+ keywords: z2.array(z2.string()).default([])
125
+ }).superRefine((manifest, ctx) => {
126
+ const dependencyEntries = [...manifest.dependencies, ...manifest.devDependencies];
127
+ const aiSpecifier = findAiSdkDependencySpecifier(dependencyEntries);
128
+ if (!aiSpecifier) {
129
+ ctx.addIssue({
130
+ code: z2.ZodIssueCode.custom,
131
+ message: `Manifest must include ${AI_SDK_PACKAGE_NAME} with an explicit ${AI_SDK_REQUIRED_RANGE} range in dependencies or devDependencies.`,
132
+ path: ["dependencies"]
133
+ });
134
+ return;
135
+ }
136
+ if (!isAiSdkSpecifierCompatible(aiSpecifier)) {
137
+ ctx.addIssue({
138
+ code: z2.ZodIssueCode.custom,
139
+ message: `${AI_SDK_PACKAGE_NAME} dependency must be compatible with ${AI_SDK_REQUIRED_RANGE}; received "${aiSpecifier}".`,
140
+ path: ["dependencies"]
141
+ });
142
+ }
143
+ const hasMcpFiles = manifest.files.some((entry) => entry.variant === MCP_MANIFEST_VARIANT);
144
+ if (manifest.mcpAdapterAvailable && !hasMcpFiles) {
145
+ ctx.addIssue({
146
+ code: z2.ZodIssueCode.custom,
147
+ message: 'mcpAdapterAvailable=true requires at least one files entry with variant="mcp".',
148
+ path: ["files"]
149
+ });
150
+ }
151
+ if (!manifest.mcpAdapterAvailable && hasMcpFiles) {
152
+ ctx.addIssue({
153
+ code: z2.ZodIssueCode.custom,
154
+ message: 'files entries with variant="mcp" require mcpAdapterAvailable=true.',
155
+ path: ["mcpAdapterAvailable"]
156
+ });
157
+ }
158
+ if ((manifest.operation === "write" || manifest.operation === "mixed") && manifest.guardrail !== "confirm_true") {
159
+ ctx.addIssue({
160
+ code: z2.ZodIssueCode.custom,
161
+ message: 'Write-capable tools must set guardrail to "confirm_true".',
162
+ path: ["guardrail"]
163
+ });
164
+ }
165
+ });
166
+ var toolCoordinateSchema = z2.object({
167
+ owner: z2.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9-]{0,38}$/),
168
+ tool: z2.string().regex(/^[a-z0-9-]+$/),
169
+ version: z2.string().optional()
170
+ });
171
+ var releaseVersionSchema = z2.string().regex(/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/);
172
+ var commitShaSchema = z2.string().regex(/^[a-f0-9]{40}$/i);
173
+ var manifestHashSchema = z2.string().regex(/^[a-f0-9]{64}$/i);
174
+ var publishReleaseSchema = z2.object({
175
+ owner: toolCoordinateSchema.shape.owner,
176
+ name: toolCoordinateSchema.shape.tool,
177
+ description: z2.string().min(10),
178
+ version: releaseVersionSchema,
179
+ repoUrl: z2.string().url(),
180
+ commitSha: commitShaSchema,
181
+ manifestHash: manifestHashSchema,
182
+ isVerifiedOwner: z2.boolean(),
183
+ isFork: z2.boolean().default(false),
184
+ upstreamOwner: z2.string().optional(),
185
+ upstreamRepo: z2.string().optional(),
186
+ upstreamUrl: z2.string().url().optional(),
187
+ aiSdkMajor: z2.literal(AI_SDK_REQUIRED_MAJOR).default(AI_SDK_REQUIRED_MAJOR),
188
+ aiSdkRange: z2.string().min(1).default(AI_SDK_REQUIRED_RANGE)
189
+ });
190
+
191
+ // src/utils/tool-spec.ts
192
+ function parseToolSpecifier(input, options = {}) {
193
+ const allowVersion = options.allowVersion ?? true;
194
+ const trimmed = input.trim();
195
+ const withoutPrefix = trimmed.replace(/^@/, "");
196
+ const slashIndex = withoutPrefix.indexOf("/");
197
+ if (slashIndex < 1) {
198
+ throw new Error("Tool must be in the format @owner/name[@version]");
199
+ }
200
+ const owner = withoutPrefix.slice(0, slashIndex);
201
+ const remainder = withoutPrefix.slice(slashIndex + 1);
202
+ if (!remainder || remainder.includes("/")) {
203
+ throw new Error("Tool must be in the format @owner/name[@version]");
204
+ }
205
+ let name = remainder;
206
+ let version;
207
+ const atIndex = remainder.lastIndexOf("@");
208
+ if (atIndex > 0) {
209
+ if (!allowVersion) {
210
+ throw new Error("Tool must be in the format @owner/name");
211
+ }
212
+ name = remainder.slice(0, atIndex);
213
+ version = remainder.slice(atIndex + 1);
214
+ }
215
+ const parsed = toolCoordinateSchema.safeParse({
216
+ owner,
217
+ tool: name,
218
+ version
219
+ });
220
+ if (!parsed.success) {
221
+ throw new Error("Tool must be in the format @owner/name[@version]");
222
+ }
223
+ return {
224
+ owner: parsed.data.owner.toLowerCase(),
225
+ name: parsed.data.tool,
226
+ version: parsed.data.version
227
+ };
228
+ }
229
+
230
+ // src/commands/add.ts
231
+ var resolveResponseSchema = z3.object({
232
+ tool: z3.object({
233
+ owner: z3.string(),
234
+ name: z3.string(),
235
+ slug: z3.string(),
236
+ description: z3.string(),
237
+ isVerifiedOwner: z3.boolean(),
238
+ isFork: z3.boolean()
239
+ }),
240
+ version: z3.object({
241
+ version: z3.string(),
242
+ manifestHash: z3.string(),
243
+ aiSdk: z3.object({
244
+ major: z3.number(),
245
+ range: z3.string()
246
+ }),
247
+ repo: z3.object({
248
+ owner: z3.string(),
249
+ name: z3.string(),
250
+ url: z3.string(),
251
+ commitSha: z3.string()
252
+ })
253
+ }),
254
+ installCommand: z3.string()
255
+ });
256
+ var packageJsonSchema = z3.object({
257
+ dependencies: z3.record(z3.string(), z3.string()).optional(),
258
+ devDependencies: z3.record(z3.string(), z3.string()).optional(),
259
+ peerDependencies: z3.record(z3.string(), z3.string()).optional(),
260
+ optionalDependencies: z3.record(z3.string(), z3.string()).optional()
261
+ });
262
+ function resolveWithin(root, relativePath, label) {
263
+ const absoluteRoot = path.resolve(root);
264
+ const candidate = path.resolve(absoluteRoot, relativePath);
265
+ if (candidate !== absoluteRoot && !candidate.startsWith(`${absoluteRoot}${path.sep}`)) {
266
+ throw new Error(`Invalid ${label} path in manifest: ${relativePath}`);
267
+ }
268
+ return candidate;
269
+ }
270
+ function runCommand(command, args, cwd) {
271
+ return new Promise((resolve, reject) => {
272
+ const child = spawn(command, args, {
273
+ cwd,
274
+ stdio: "inherit",
275
+ env: process.env
276
+ });
277
+ child.on("error", reject);
278
+ child.on("close", (code) => {
279
+ if (code === 0) {
280
+ resolve();
281
+ return;
282
+ }
283
+ reject(new Error(`${command} ${args.join(" ")} exited with code ${code ?? "unknown"}`));
284
+ });
285
+ });
286
+ }
287
+ async function exists(filePath) {
288
+ try {
289
+ await stat(filePath);
290
+ return true;
291
+ } catch {
292
+ return false;
293
+ }
294
+ }
295
+ async function detectPackageManager(cwd) {
296
+ if (await exists(path.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
297
+ if (await exists(path.join(cwd, "yarn.lock"))) return "yarn";
298
+ if (await exists(path.join(cwd, "bun.lockb"))) return "bun";
299
+ if (await exists(path.join(cwd, "bun.lock"))) return "bun";
300
+ return "npm";
301
+ }
302
+ function normalizeProjectAiRange(value) {
303
+ let normalized = value.trim();
304
+ const prefixes = ["workspace:", "catalog:", "npm:", "pnpm:", "yarn:"];
305
+ for (const prefix of prefixes) {
306
+ if (normalized.startsWith(prefix)) {
307
+ normalized = normalized.slice(prefix.length).trim();
308
+ }
309
+ }
310
+ if (normalized.startsWith("ai@")) {
311
+ normalized = normalized.slice("ai@".length);
312
+ }
313
+ return normalized;
314
+ }
315
+ async function detectProjectAiRange(cwd) {
316
+ const packageJsonPath = path.join(cwd, "package.json");
317
+ if (!await exists(packageJsonPath)) {
318
+ return null;
319
+ }
320
+ try {
321
+ const packageJsonRaw = await readFile(packageJsonPath, "utf8");
322
+ const parsed = packageJsonSchema.parse(JSON.parse(packageJsonRaw));
323
+ const groups = [
324
+ parsed.dependencies,
325
+ parsed.devDependencies,
326
+ parsed.peerDependencies,
327
+ parsed.optionalDependencies
328
+ ];
329
+ for (const group of groups) {
330
+ const aiRange = group?.ai;
331
+ if (aiRange) return normalizeProjectAiRange(aiRange);
332
+ }
333
+ } catch {
334
+ return null;
335
+ }
336
+ return null;
337
+ }
338
+ async function installDependencies(cwd, dependencies, devDependencies) {
339
+ const deps = [...new Set(dependencies)];
340
+ const devDeps = [...new Set(devDependencies)];
341
+ if (!deps.length && !devDeps.length) return;
342
+ const packageManager = await detectPackageManager(cwd);
343
+ console.log(kleur.dim(`Installing dependencies with ${packageManager}...`));
344
+ if (packageManager === "pnpm") {
345
+ if (deps.length) await runCommand("pnpm", ["add", ...deps], cwd);
346
+ if (devDeps.length) await runCommand("pnpm", ["add", "-D", ...devDeps], cwd);
347
+ return;
348
+ }
349
+ if (packageManager === "yarn") {
350
+ if (deps.length) await runCommand("yarn", ["add", ...deps], cwd);
351
+ if (devDeps.length) await runCommand("yarn", ["add", "-D", ...devDeps], cwd);
352
+ return;
353
+ }
354
+ if (packageManager === "bun") {
355
+ if (deps.length) await runCommand("bun", ["add", ...deps], cwd);
356
+ if (devDeps.length) await runCommand("bun", ["add", "-d", ...devDeps], cwd);
357
+ return;
358
+ }
359
+ if (deps.length) await runCommand("npm", ["install", ...deps], cwd);
360
+ if (devDeps.length) await runCommand("npm", ["install", "-D", ...devDeps], cwd);
361
+ }
362
+ async function runAdd(specifier, apiBaseUrl2, options) {
363
+ const coordinate = parseToolSpecifier(specifier, { allowVersion: true });
364
+ const versionSuffix = coordinate.version ? `/${encodeURIComponent(coordinate.version)}` : "";
365
+ const endpoint = `${apiBaseUrl2}/cli/resolve/${coordinate.owner}/${coordinate.name}${versionSuffix}`;
366
+ console.log(kleur.dim(`Resolving @${coordinate.owner}/${coordinate.name}...`));
367
+ const response = await fetch(endpoint);
368
+ if (!response.ok) {
369
+ const errorBody = await response.text();
370
+ throw new Error(`Failed to resolve ${specifier} (${response.status}): ${errorBody}`);
371
+ }
372
+ const payload = resolveResponseSchema.parse(await response.json());
373
+ if (!payload.tool.isVerifiedOwner) {
374
+ console.log(
375
+ kleur.yellow(
376
+ `Warning: @${payload.tool.owner}/${payload.tool.name} is not from a verified owner.`
377
+ )
378
+ );
379
+ }
380
+ const tmpDir = await mkdtemp(path.join(os.tmpdir(), "toolshed-"));
381
+ const repoDir = path.join(tmpDir, "repo");
382
+ try {
383
+ console.log(kleur.dim(`Cloning ${payload.version.repo.url}...`));
384
+ await runCommand("git", ["clone", "--quiet", payload.version.repo.url, repoDir]);
385
+ await runCommand("git", ["-C", repoDir, "checkout", "--quiet", payload.version.repo.commitSha]);
386
+ const toolRootCandidates = [repoDir, path.join(repoDir, "tools", payload.tool.name)];
387
+ const toolRoot = (await Promise.all(
388
+ toolRootCandidates.map(async (candidate) => {
389
+ const candidateManifestPath = path.join(candidate, TOOLSHED_MANIFEST_FILENAME);
390
+ return await exists(candidateManifestPath) ? candidate : null;
391
+ })
392
+ )).find((value) => value !== null);
393
+ if (!toolRoot) {
394
+ throw new Error(
395
+ `Unable to locate ${TOOLSHED_MANIFEST_FILENAME} in repository root or tools/${payload.tool.name}`
396
+ );
397
+ }
398
+ const manifestPath = path.join(toolRoot, TOOLSHED_MANIFEST_FILENAME);
399
+ const manifestRaw = await readFile(manifestPath, "utf8");
400
+ const manifest = toolManifestSchema.parse(JSON.parse(manifestRaw));
401
+ if (payload.version.aiSdk.major !== manifest.aiSdk.major || payload.version.aiSdk.range !== manifest.aiSdk.range) {
402
+ console.log(
403
+ kleur.yellow(
404
+ `Warning: registry metadata reports AI SDK ${payload.version.aiSdk.major} (${payload.version.aiSdk.range}), but manifest requires AI SDK ${manifest.aiSdk.major} (${manifest.aiSdk.range}).`
405
+ )
406
+ );
407
+ }
408
+ const projectAiRange = await detectProjectAiRange(options.cwd);
409
+ if (!projectAiRange) {
410
+ console.log(
411
+ kleur.yellow(
412
+ `Warning: no "ai" dependency found in ${path.join(
413
+ options.cwd,
414
+ "package.json"
415
+ )}. This tool requires AI SDK ${manifest.aiSdk.major} (${manifest.aiSdk.range}).`
416
+ )
417
+ );
418
+ } else if (!isAiSdkRangeCompatible(projectAiRange)) {
419
+ console.log(
420
+ kleur.yellow(
421
+ `Warning: project declares ai@${projectAiRange}, but this tool requires AI SDK ${AI_SDK_REQUIRED_MAJOR} (${manifest.aiSdk.range}).`
422
+ )
423
+ );
424
+ }
425
+ const filesToInstall = manifest.files.filter((entry) => {
426
+ if (entry.variant === MCP_MANIFEST_VARIANT && !options.withMcp) {
427
+ return false;
428
+ }
429
+ return true;
430
+ });
431
+ const mcpFileCount = manifest.files.filter(
432
+ (entry) => entry.variant === MCP_MANIFEST_VARIANT
433
+ ).length;
434
+ const installedMcpFiles = filesToInstall.filter(
435
+ (entry) => entry.variant === MCP_MANIFEST_VARIANT
436
+ ).length;
437
+ for (const entry of filesToInstall) {
438
+ const sourcePath = resolveWithin(toolRoot, entry.source, "source");
439
+ const targetPath = resolveWithin(options.cwd, entry.target, "target");
440
+ await mkdir(path.dirname(targetPath), { recursive: true });
441
+ await cp(sourcePath, targetPath, {
442
+ recursive: true,
443
+ force: options.overwrite,
444
+ errorOnExist: !options.overwrite
445
+ });
446
+ }
447
+ await installDependencies(
448
+ options.cwd,
449
+ manifest.dependencies ?? [],
450
+ manifest.devDependencies ?? []
451
+ );
452
+ console.log(
453
+ kleur.green(
454
+ `Installed @${payload.tool.owner}/${payload.tool.name}@${payload.version.version}`
455
+ )
456
+ );
457
+ console.log(kleur.dim(`Source: ${payload.version.repo.url}#${payload.version.repo.commitSha}`));
458
+ console.log(`Provider: ${manifest.provider}`);
459
+ console.log(`Operation: ${manifest.operation}`);
460
+ if (manifest.operation === "write") {
461
+ console.log(`Write guardrail: ${manifest.guardrail}`);
462
+ }
463
+ const envKeys = Object.keys(manifest.envVars ?? {});
464
+ if (envKeys.length) {
465
+ console.log(kleur.yellow("Required environment variables:"));
466
+ for (const envKey of envKeys) {
467
+ console.log(` - ${envKey}`);
468
+ }
469
+ }
470
+ if (options.withMcp && installedMcpFiles === 0) {
471
+ console.log(kleur.yellow("No MCP adapter files were found in this tool package."));
472
+ } else if (options.withMcp && installedMcpFiles > 0) {
473
+ console.log(kleur.dim(`Included ${installedMcpFiles} MCP adapter file(s).`));
474
+ } else if (!options.withMcp && mcpFileCount > 0) {
475
+ console.log(kleur.dim("Tip: re-run with --with-mcp to install optional MCP adapter files."));
476
+ }
477
+ } finally {
478
+ await rm(tmpDir, { recursive: true, force: true });
479
+ }
480
+ }
481
+
482
+ // src/commands/search.ts
483
+ import kleur2 from "kleur";
484
+ import { z as z4 } from "zod";
485
+ var searchResponseSchema = z4.object({
486
+ items: z4.array(
487
+ z4.object({
488
+ owner: z4.string(),
489
+ name: z4.string(),
490
+ description: z4.string(),
491
+ latestVersion: z4.string().nullable(),
492
+ isVerifiedOwner: z4.boolean(),
493
+ isFork: z4.boolean()
494
+ })
495
+ )
496
+ });
497
+ function parseLimit(input) {
498
+ if (!Number.isFinite(input) || input <= 0) return 20;
499
+ return Math.min(Math.floor(input), 100);
500
+ }
501
+ async function runSearch(query, apiBaseUrl2, options) {
502
+ const url = new URL("/cli/search", apiBaseUrl2);
503
+ if (query.trim()) {
504
+ url.searchParams.set("q", query.trim());
505
+ }
506
+ url.searchParams.set("limit", String(parseLimit(options.limit)));
507
+ const response = await fetch(url);
508
+ if (!response.ok) {
509
+ throw new Error(`Search failed (${response.status})`);
510
+ }
511
+ const payload = searchResponseSchema.parse(await response.json());
512
+ if (!payload.items.length) {
513
+ console.log("No tools found.");
514
+ return;
515
+ }
516
+ for (const item of payload.items) {
517
+ const version = item.latestVersion ?? "n/a";
518
+ const ownerState = item.isVerifiedOwner ? kleur2.green("verified") : item.isFork ? kleur2.yellow("fork") : kleur2.red("unverified");
519
+ console.log(`${kleur2.bold(`@${item.owner}/${item.name}`)} ${kleur2.dim(`v${version}`)} ${ownerState}`);
520
+ console.log(` ${item.description}`);
521
+ }
522
+ }
523
+
524
+ // src/commands/view.ts
525
+ import kleur3 from "kleur";
526
+ import { z as z5 } from "zod";
527
+ var viewResponseSchema = z5.object({
528
+ tool: z5.object({
529
+ owner: z5.string(),
530
+ name: z5.string(),
531
+ description: z5.string(),
532
+ latestVersion: z5.string().nullable(),
533
+ isVerifiedOwner: z5.boolean(),
534
+ isFork: z5.boolean(),
535
+ upstreamOwner: z5.string().nullable(),
536
+ upstreamRepo: z5.string().nullable(),
537
+ upstreamUrl: z5.string().nullable()
538
+ }),
539
+ versions: z5.array(
540
+ z5.object({
541
+ version: z5.string(),
542
+ repoUrl: z5.string(),
543
+ commitSha: z5.string(),
544
+ aiSdkMajor: z5.number(),
545
+ aiSdkRange: z5.string(),
546
+ createdAt: z5.string()
547
+ })
548
+ ),
549
+ installCommand: z5.string()
550
+ });
551
+ async function runView(specifier, apiBaseUrl2) {
552
+ const coordinate = parseToolSpecifier(specifier, { allowVersion: false });
553
+ const response = await fetch(`${apiBaseUrl2}/cli/view/${coordinate.owner}/${coordinate.name}`);
554
+ if (!response.ok) {
555
+ throw new Error(`View failed (${response.status})`);
556
+ }
557
+ const payload = viewResponseSchema.parse(await response.json());
558
+ console.log(kleur3.bold(`@${payload.tool.owner}/${payload.tool.name}`));
559
+ console.log(payload.tool.description);
560
+ console.log(`Latest version: ${payload.tool.latestVersion ?? "n/a"}`);
561
+ console.log(`Owner status: ${payload.tool.isVerifiedOwner ? "verified" : "unverified"}`);
562
+ const latest = payload.versions[0];
563
+ if (latest) {
564
+ console.log(`AI SDK: v${latest.aiSdkMajor} (${latest.aiSdkRange})`);
565
+ }
566
+ if (payload.tool.isFork && payload.tool.upstreamOwner && payload.tool.upstreamRepo) {
567
+ console.log(
568
+ kleur3.yellow(
569
+ `Forked from @${payload.tool.upstreamOwner}/${payload.tool.upstreamRepo}${payload.tool.upstreamUrl ? ` (${payload.tool.upstreamUrl})` : ""}`
570
+ )
571
+ );
572
+ }
573
+ console.log("");
574
+ console.log(kleur3.dim("Install"));
575
+ console.log(payload.installCommand);
576
+ if (payload.versions.length) {
577
+ console.log("");
578
+ console.log(kleur3.dim("Recent versions"));
579
+ for (const version of payload.versions.slice(0, 10)) {
580
+ console.log(`- ${version.version} ${version.commitSha.slice(0, 8)} ${version.repoUrl}`);
581
+ }
582
+ }
583
+ }
584
+
585
+ // src/index.ts
586
+ var program = new Command();
587
+ var apiBaseUrl = "https://api.toolshed.tech";
588
+ program.name("toolshed").description("Add and discover toolshed tools").version("0.1.0");
589
+ program.command("add").description("add a published tool to your project").argument("<tool>", "tool coordinate in the form @owner/name[@version]").option(
590
+ "-c, --cwd <cwd>",
591
+ "the working directory. defaults to the current directory.",
592
+ process.cwd()
593
+ ).option("-o, --overwrite", "overwrite existing files.", false).option("--with-mcp", "install optional MCP adapter files when available.", false).action(async (tool, opts) => {
594
+ await runAdd(tool, apiBaseUrl, {
595
+ cwd: path2.resolve(opts.cwd),
596
+ overwrite: opts.overwrite,
597
+ withMcp: opts.withMcp
598
+ });
599
+ });
600
+ program.command("search").description("search published tools").argument("[query]", "tool search query").option("-l, --limit <limit>", "number of tools to return", "20").action(async (query, opts) => {
601
+ await runSearch(query ?? "", apiBaseUrl, {
602
+ limit: Number.parseInt(opts.limit, 10)
603
+ });
604
+ });
605
+ program.command("view").description("view details for a published tool").argument("<tool>", "tool coordinate in the form @owner/name").action(async (tool) => {
606
+ await runView(tool, apiBaseUrl);
607
+ });
608
+ program.parseAsync().catch((error) => {
609
+ const message = error instanceof Error ? error.message : String(error);
610
+ console.error(message);
611
+ process.exit(1);
612
+ });
613
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/add.ts","../../shared/src/index.ts","../../shared/src/tool-release-map.ts","../src/utils/tool-spec.ts","../src/commands/search.ts","../src/commands/view.ts"],"sourcesContent":["#!/usr/bin/env node\nimport path from \"node:path\"\n\nimport { Command } from \"commander\"\n\nimport { runAdd } from \"./commands/add\"\nimport { runSearch } from \"./commands/search\"\nimport { runView } from \"./commands/view\"\n\nconst program = new Command()\nconst apiBaseUrl = \"https://api.toolshed.tech\"\n\nprogram\n .name(\"toolshed\")\n .description(\"Add and discover toolshed tools\")\n .version(\"0.1.0\")\n\nprogram\n .command(\"add\")\n .description(\"add a published tool to your project\")\n .argument(\"<tool>\", \"tool coordinate in the form @owner/name[@version]\")\n .option(\n \"-c, --cwd <cwd>\",\n \"the working directory. defaults to the current directory.\",\n process.cwd()\n )\n .option(\"-o, --overwrite\", \"overwrite existing files.\", false)\n .option(\"--with-mcp\", \"install optional MCP adapter files when available.\", false)\n .action(async (tool: string, opts: { cwd: string; overwrite: boolean; withMcp: boolean }) => {\n await runAdd(tool, apiBaseUrl, {\n cwd: path.resolve(opts.cwd),\n overwrite: opts.overwrite,\n withMcp: opts.withMcp,\n })\n })\n\nprogram\n .command(\"search\")\n .description(\"search published tools\")\n .argument(\"[query]\", \"tool search query\")\n .option(\"-l, --limit <limit>\", \"number of tools to return\", \"20\")\n .action(async (query: string | undefined, opts: { limit: string }) => {\n await runSearch(query ?? \"\", apiBaseUrl, {\n limit: Number.parseInt(opts.limit, 10),\n })\n })\n\nprogram\n .command(\"view\")\n .description(\"view details for a published tool\")\n .argument(\"<tool>\", \"tool coordinate in the form @owner/name\")\n .action(async (tool: string) => {\n await runView(tool, apiBaseUrl)\n })\n\nprogram.parseAsync().catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error)\n console.error(message)\n process.exit(1)\n})\n","import { spawn } from \"node:child_process\"\nimport { cp, mkdir, mkdtemp, readFile, rm, stat } from \"node:fs/promises\"\nimport os from \"node:os\"\nimport path from \"node:path\"\n\nimport kleur from \"kleur\"\nimport { z } from \"zod\"\n\nimport {\n AI_SDK_REQUIRED_MAJOR,\n MCP_MANIFEST_VARIANT,\n TOOLSHED_MANIFEST_FILENAME,\n isAiSdkRangeCompatible,\n toolManifestSchema,\n} from \"@toolshed/shared\"\n\nimport { parseToolSpecifier } from \"../utils/tool-spec\"\n\nconst resolveResponseSchema = z.object({\n tool: z.object({\n owner: z.string(),\n name: z.string(),\n slug: z.string(),\n description: z.string(),\n isVerifiedOwner: z.boolean(),\n isFork: z.boolean(),\n }),\n version: z.object({\n version: z.string(),\n manifestHash: z.string(),\n aiSdk: z.object({\n major: z.number(),\n range: z.string(),\n }),\n repo: z.object({\n owner: z.string(),\n name: z.string(),\n url: z.string(),\n commitSha: z.string(),\n }),\n }),\n installCommand: z.string(),\n})\n\ntype AddOptions = {\n cwd: string\n overwrite: boolean\n withMcp: boolean\n}\n\nconst packageJsonSchema = z.object({\n dependencies: z.record(z.string(), z.string()).optional(),\n devDependencies: z.record(z.string(), z.string()).optional(),\n peerDependencies: z.record(z.string(), z.string()).optional(),\n optionalDependencies: z.record(z.string(), z.string()).optional(),\n})\n\nexport function resolveWithin(root: string, relativePath: string, label: string) {\n const absoluteRoot = path.resolve(root)\n const candidate = path.resolve(absoluteRoot, relativePath)\n if (candidate !== absoluteRoot && !candidate.startsWith(`${absoluteRoot}${path.sep}`)) {\n throw new Error(`Invalid ${label} path in manifest: ${relativePath}`)\n }\n\n return candidate\n}\n\nfunction runCommand(command: string, args: string[], cwd?: string) {\n return new Promise<void>((resolve, reject) => {\n const child = spawn(command, args, {\n cwd,\n stdio: \"inherit\",\n env: process.env,\n })\n\n child.on(\"error\", reject)\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve()\n return\n }\n\n reject(new Error(`${command} ${args.join(\" \")} exited with code ${code ?? \"unknown\"}`))\n })\n })\n}\n\nasync function exists(filePath: string) {\n try {\n await stat(filePath)\n return true\n } catch {\n return false\n }\n}\n\nasync function detectPackageManager(cwd: string) {\n if (await exists(path.join(cwd, \"pnpm-lock.yaml\"))) return \"pnpm\"\n if (await exists(path.join(cwd, \"yarn.lock\"))) return \"yarn\"\n if (await exists(path.join(cwd, \"bun.lockb\"))) return \"bun\"\n if (await exists(path.join(cwd, \"bun.lock\"))) return \"bun\"\n return \"npm\"\n}\n\nexport function normalizeProjectAiRange(value: string) {\n let normalized = value.trim()\n const prefixes = [\"workspace:\", \"catalog:\", \"npm:\", \"pnpm:\", \"yarn:\"]\n for (const prefix of prefixes) {\n if (normalized.startsWith(prefix)) {\n normalized = normalized.slice(prefix.length).trim()\n }\n }\n\n if (normalized.startsWith(\"ai@\")) {\n normalized = normalized.slice(\"ai@\".length)\n }\n\n return normalized\n}\n\nexport async function detectProjectAiRange(cwd: string) {\n const packageJsonPath = path.join(cwd, \"package.json\")\n if (!(await exists(packageJsonPath))) {\n return null\n }\n\n try {\n const packageJsonRaw = await readFile(packageJsonPath, \"utf8\")\n const parsed = packageJsonSchema.parse(JSON.parse(packageJsonRaw))\n const groups = [\n parsed.dependencies,\n parsed.devDependencies,\n parsed.peerDependencies,\n parsed.optionalDependencies,\n ]\n\n for (const group of groups) {\n const aiRange = group?.ai\n if (aiRange) return normalizeProjectAiRange(aiRange)\n }\n } catch {\n return null\n }\n\n return null\n}\n\nasync function installDependencies(\n cwd: string,\n dependencies: string[],\n devDependencies: string[]\n) {\n const deps = [...new Set(dependencies)]\n const devDeps = [...new Set(devDependencies)]\n if (!deps.length && !devDeps.length) return\n\n const packageManager = await detectPackageManager(cwd)\n console.log(kleur.dim(`Installing dependencies with ${packageManager}...`))\n\n if (packageManager === \"pnpm\") {\n if (deps.length) await runCommand(\"pnpm\", [\"add\", ...deps], cwd)\n if (devDeps.length) await runCommand(\"pnpm\", [\"add\", \"-D\", ...devDeps], cwd)\n return\n }\n\n if (packageManager === \"yarn\") {\n if (deps.length) await runCommand(\"yarn\", [\"add\", ...deps], cwd)\n if (devDeps.length) await runCommand(\"yarn\", [\"add\", \"-D\", ...devDeps], cwd)\n return\n }\n\n if (packageManager === \"bun\") {\n if (deps.length) await runCommand(\"bun\", [\"add\", ...deps], cwd)\n if (devDeps.length) await runCommand(\"bun\", [\"add\", \"-d\", ...devDeps], cwd)\n return\n }\n\n if (deps.length) await runCommand(\"npm\", [\"install\", ...deps], cwd)\n if (devDeps.length) await runCommand(\"npm\", [\"install\", \"-D\", ...devDeps], cwd)\n}\n\nexport async function runAdd(specifier: string, apiBaseUrl: string, options: AddOptions) {\n const coordinate = parseToolSpecifier(specifier, { allowVersion: true })\n const versionSuffix = coordinate.version ? `/${encodeURIComponent(coordinate.version)}` : \"\"\n const endpoint = `${apiBaseUrl}/cli/resolve/${coordinate.owner}/${coordinate.name}${versionSuffix}`\n\n console.log(kleur.dim(`Resolving @${coordinate.owner}/${coordinate.name}...`))\n const response = await fetch(endpoint)\n if (!response.ok) {\n const errorBody = await response.text()\n throw new Error(`Failed to resolve ${specifier} (${response.status}): ${errorBody}`)\n }\n\n const payload = resolveResponseSchema.parse(await response.json())\n if (!payload.tool.isVerifiedOwner) {\n console.log(\n kleur.yellow(\n `Warning: @${payload.tool.owner}/${payload.tool.name} is not from a verified owner.`\n )\n )\n }\n\n const tmpDir = await mkdtemp(path.join(os.tmpdir(), \"toolshed-\"))\n const repoDir = path.join(tmpDir, \"repo\")\n\n try {\n console.log(kleur.dim(`Cloning ${payload.version.repo.url}...`))\n await runCommand(\"git\", [\"clone\", \"--quiet\", payload.version.repo.url, repoDir])\n await runCommand(\"git\", [\"-C\", repoDir, \"checkout\", \"--quiet\", payload.version.repo.commitSha])\n\n const toolRootCandidates = [repoDir, path.join(repoDir, \"tools\", payload.tool.name)]\n const toolRoot = (\n await Promise.all(\n toolRootCandidates.map(async (candidate) => {\n const candidateManifestPath = path.join(candidate, TOOLSHED_MANIFEST_FILENAME)\n return (await exists(candidateManifestPath)) ? candidate : null\n })\n )\n ).find((value): value is string => value !== null)\n\n if (!toolRoot) {\n throw new Error(\n `Unable to locate ${TOOLSHED_MANIFEST_FILENAME} in repository root or tools/${payload.tool.name}`\n )\n }\n\n const manifestPath = path.join(toolRoot, TOOLSHED_MANIFEST_FILENAME)\n const manifestRaw = await readFile(manifestPath, \"utf8\")\n const manifest = toolManifestSchema.parse(JSON.parse(manifestRaw))\n\n if (\n payload.version.aiSdk.major !== manifest.aiSdk.major ||\n payload.version.aiSdk.range !== manifest.aiSdk.range\n ) {\n console.log(\n kleur.yellow(\n `Warning: registry metadata reports AI SDK ${payload.version.aiSdk.major} (${payload.version.aiSdk.range}), but manifest requires AI SDK ${manifest.aiSdk.major} (${manifest.aiSdk.range}).`\n )\n )\n }\n\n const projectAiRange = await detectProjectAiRange(options.cwd)\n if (!projectAiRange) {\n console.log(\n kleur.yellow(\n `Warning: no \"ai\" dependency found in ${path.join(\n options.cwd,\n \"package.json\"\n )}. This tool requires AI SDK ${manifest.aiSdk.major} (${manifest.aiSdk.range}).`\n )\n )\n } else if (!isAiSdkRangeCompatible(projectAiRange)) {\n console.log(\n kleur.yellow(\n `Warning: project declares ai@${projectAiRange}, but this tool requires AI SDK ${AI_SDK_REQUIRED_MAJOR} (${manifest.aiSdk.range}).`\n )\n )\n }\n\n const filesToInstall = manifest.files.filter((entry) => {\n if (entry.variant === MCP_MANIFEST_VARIANT && !options.withMcp) {\n return false\n }\n\n return true\n })\n\n const mcpFileCount = manifest.files.filter(\n (entry) => entry.variant === MCP_MANIFEST_VARIANT\n ).length\n const installedMcpFiles = filesToInstall.filter(\n (entry) => entry.variant === MCP_MANIFEST_VARIANT\n ).length\n\n for (const entry of filesToInstall) {\n const sourcePath = resolveWithin(toolRoot, entry.source, \"source\")\n const targetPath = resolveWithin(options.cwd, entry.target, \"target\")\n\n await mkdir(path.dirname(targetPath), { recursive: true })\n await cp(sourcePath, targetPath, {\n recursive: true,\n force: options.overwrite,\n errorOnExist: !options.overwrite,\n })\n }\n\n await installDependencies(\n options.cwd,\n manifest.dependencies ?? [],\n manifest.devDependencies ?? []\n )\n\n console.log(\n kleur.green(\n `Installed @${payload.tool.owner}/${payload.tool.name}@${payload.version.version}`\n )\n )\n console.log(kleur.dim(`Source: ${payload.version.repo.url}#${payload.version.repo.commitSha}`))\n console.log(`Provider: ${manifest.provider}`)\n console.log(`Operation: ${manifest.operation}`)\n if (manifest.operation === \"write\") {\n console.log(`Write guardrail: ${manifest.guardrail}`)\n }\n\n const envKeys = Object.keys(manifest.envVars ?? {})\n if (envKeys.length) {\n console.log(kleur.yellow(\"Required environment variables:\"))\n for (const envKey of envKeys) {\n console.log(` - ${envKey}`)\n }\n }\n\n if (options.withMcp && installedMcpFiles === 0) {\n console.log(kleur.yellow(\"No MCP adapter files were found in this tool package.\"))\n } else if (options.withMcp && installedMcpFiles > 0) {\n console.log(kleur.dim(`Included ${installedMcpFiles} MCP adapter file(s).`))\n } else if (!options.withMcp && mcpFileCount > 0) {\n console.log(kleur.dim(\"Tip: re-run with --with-mcp to install optional MCP adapter files.\"))\n }\n } finally {\n await rm(tmpDir, { recursive: true, force: true })\n }\n}\n","import { z } from \"zod\"\nexport * from \"./tool-release-map\"\n\nexport const TOOLSHED_MANIFEST_FILENAME = \"toolshed.tool.json\"\nexport const AI_SDK_PACKAGE_NAME = \"ai\"\nexport const AI_SDK_REQUIRED_MAJOR = 6\nexport const AI_SDK_REQUIRED_RANGE = \">=6 <7\"\nexport const MCP_MANIFEST_VARIANT = \"mcp\"\n\nfunction stripVersionProtocol(value: string) {\n let normalized = value.trim()\n const protocols = [\"workspace:\", \"npm:\", \"pnpm:\", \"yarn:\", \"catalog:\"]\n for (const protocol of protocols) {\n if (normalized.startsWith(protocol)) {\n normalized = normalized.slice(protocol.length).trim()\n }\n }\n\n return normalized\n}\n\nfunction extractDependencyNameAndRange(specifier: string): { name: string; range: string | null } {\n const normalized = stripVersionProtocol(specifier)\n const scopedMatch = normalized.match(/^(@[^/@\\s]+\\/[^@\\s]+)(?:@(.+))?$/)\n if (scopedMatch) {\n return {\n name: scopedMatch[1] ?? normalized,\n range: scopedMatch[2]?.trim() || null,\n }\n }\n\n const plainMatch = normalized.match(/^([^@\\s]+)(?:@(.+))?$/)\n if (plainMatch) {\n return {\n name: plainMatch[1] ?? normalized,\n range: plainMatch[2]?.trim() || null,\n }\n }\n\n return {\n name: normalized,\n range: null,\n }\n}\n\nfunction isAiSdk6Range(range: string) {\n const normalized = stripVersionProtocol(range).replace(/\\s+/g, \"\")\n if (!normalized) return false\n\n const disjunctive = normalized.split(\"||\")\n return disjunctive.some((candidate) => {\n if (/^[~^]?6(?:\\.|$)/.test(candidate)) return true\n if (/^6(?:\\.x)?(?:\\.x)?$/.test(candidate)) return true\n if (/^>=6(?:\\.0\\.0)?<7(?:\\.0\\.0)?$/.test(candidate)) return true\n return false\n })\n}\n\nexport function parseDependencySpecifier(specifier: string) {\n return extractDependencyNameAndRange(specifier)\n}\n\nexport function findAiSdkDependencySpecifier(entries: string[]) {\n return entries.find((entry) => {\n const parsed = extractDependencyNameAndRange(entry)\n return parsed.name === AI_SDK_PACKAGE_NAME\n })\n}\n\nexport function isAiSdkSpecifierCompatible(specifier: string) {\n const parsed = extractDependencyNameAndRange(specifier)\n if (parsed.name !== AI_SDK_PACKAGE_NAME || !parsed.range) return false\n return isAiSdk6Range(parsed.range)\n}\n\nexport function isAiSdkRangeCompatible(range: string) {\n return isAiSdk6Range(range)\n}\n\nexport const aiSdkRequirementSchema = z.object({\n package: z.literal(AI_SDK_PACKAGE_NAME).default(AI_SDK_PACKAGE_NAME),\n major: z.literal(AI_SDK_REQUIRED_MAJOR).default(AI_SDK_REQUIRED_MAJOR),\n range: z.string().min(1).default(AI_SDK_REQUIRED_RANGE),\n})\n\nexport const toolProviderSchema = z.enum([\"github\", \"gmail\", \"spotify\", \"generic\"])\nexport const toolOperationSchema = z.enum([\"read\", \"write\", \"mixed\"])\nexport const toolGuardrailSchema = z.enum([\"confirm_true\", \"none\"])\nexport const manifestFileVariantSchema = z.enum([\"core\", MCP_MANIFEST_VARIANT])\n\nexport const toolManifestFileSchema = z.object({\n source: z.string().min(1),\n target: z.string().min(1),\n variant: manifestFileVariantSchema.default(\"core\"),\n})\n\nexport const toolManifestSchema = z.object({\n name: z.string().min(2),\n version: z.string().min(1),\n description: z.string().min(10),\n aiSdk: aiSdkRequirementSchema.default({\n package: AI_SDK_PACKAGE_NAME,\n major: AI_SDK_REQUIRED_MAJOR,\n range: AI_SDK_REQUIRED_RANGE,\n }),\n entry: z.string().min(1),\n files: z.array(toolManifestFileSchema),\n dependencies: z.array(z.string()).default([]),\n devDependencies: z.array(z.string()).default([]),\n envVars: z.record(z.string(), z.string()).optional(),\n provider: toolProviderSchema.default(\"generic\"),\n operation: toolOperationSchema.default(\"read\"),\n guardrail: toolGuardrailSchema.default(\"none\"),\n mcpAdapterAvailable: z.boolean().default(false),\n keywords: z.array(z.string()).default([]),\n}).superRefine((manifest, ctx) => {\n const dependencyEntries = [...manifest.dependencies, ...manifest.devDependencies]\n const aiSpecifier = findAiSdkDependencySpecifier(dependencyEntries)\n\n if (!aiSpecifier) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Manifest must include ${AI_SDK_PACKAGE_NAME} with an explicit ${AI_SDK_REQUIRED_RANGE} range in dependencies or devDependencies.`,\n path: [\"dependencies\"],\n })\n return\n }\n\n if (!isAiSdkSpecifierCompatible(aiSpecifier)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `${AI_SDK_PACKAGE_NAME} dependency must be compatible with ${AI_SDK_REQUIRED_RANGE}; received \"${aiSpecifier}\".`,\n path: [\"dependencies\"],\n })\n }\n\n const hasMcpFiles = manifest.files.some((entry) => entry.variant === MCP_MANIFEST_VARIANT)\n if (manifest.mcpAdapterAvailable && !hasMcpFiles) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"mcpAdapterAvailable=true requires at least one files entry with variant=\\\"mcp\\\".\",\n path: [\"files\"],\n })\n }\n\n if (!manifest.mcpAdapterAvailable && hasMcpFiles) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"files entries with variant=\\\"mcp\\\" require mcpAdapterAvailable=true.\",\n path: [\"mcpAdapterAvailable\"],\n })\n }\n\n if (\n (manifest.operation === \"write\" || manifest.operation === \"mixed\") &&\n manifest.guardrail !== \"confirm_true\"\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Write-capable tools must set guardrail to \\\"confirm_true\\\".\",\n path: [\"guardrail\"],\n })\n }\n})\n\nexport type ToolManifest = z.infer<typeof toolManifestSchema>\n\nexport const toolCoordinateSchema = z.object({\n owner: z.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9-]{0,38}$/),\n tool: z.string().regex(/^[a-z0-9-]+$/),\n version: z.string().optional(),\n})\n\nexport type ToolCoordinate = z.infer<typeof toolCoordinateSchema>\n\nexport const releaseVersionSchema = z.string().regex(/^\\d+\\.\\d+\\.\\d+(?:[-+][0-9A-Za-z.-]+)?$/)\nexport const commitShaSchema = z.string().regex(/^[a-f0-9]{40}$/i)\nexport const manifestHashSchema = z.string().regex(/^[a-f0-9]{64}$/i)\n\nexport const publishReleaseSchema = z.object({\n owner: toolCoordinateSchema.shape.owner,\n name: toolCoordinateSchema.shape.tool,\n description: z.string().min(10),\n version: releaseVersionSchema,\n repoUrl: z.string().url(),\n commitSha: commitShaSchema,\n manifestHash: manifestHashSchema,\n isVerifiedOwner: z.boolean(),\n isFork: z.boolean().default(false),\n upstreamOwner: z.string().optional(),\n upstreamRepo: z.string().optional(),\n upstreamUrl: z.string().url().optional(),\n aiSdkMajor: z.literal(AI_SDK_REQUIRED_MAJOR).default(AI_SDK_REQUIRED_MAJOR),\n aiSdkRange: z.string().min(1).default(AI_SDK_REQUIRED_RANGE),\n})\n\nexport type PublishReleaseInput = z.infer<typeof publishReleaseSchema>\n\nexport const publishReleaseFromCiSchema = publishReleaseSchema\n\nexport type PublishReleaseFromCiInput = z.infer<typeof publishReleaseFromCiSchema>\n","import { z } from \"zod\"\n\nexport const toolReleaseMapEntrySchema = z.object({\n toolName: z.string().regex(/^[a-z0-9-]+$/),\n sourcePath: z.string().min(1),\n publicRepo: z.string().url().regex(/^https:\\/\\/github\\.com\\/[^/]+\\/[^/]+(?:\\.git)?$/),\n publicDefaultBranch: z.string().min(1).default(\"main\"),\n})\n\nexport type ToolReleaseMapEntry = z.infer<typeof toolReleaseMapEntrySchema>\n\nexport const toolReleaseMapSchema = z.object({\n tools: z.array(toolReleaseMapEntrySchema),\n})\n\nexport type ToolReleaseMap = z.infer<typeof toolReleaseMapSchema>\n\n","import { toolCoordinateSchema } from \"@toolshed/shared\"\n\ntype ParseOptions = {\n allowVersion?: boolean\n}\n\nexport function parseToolSpecifier(input: string, options: ParseOptions = {}) {\n const allowVersion = options.allowVersion ?? true\n const trimmed = input.trim()\n const withoutPrefix = trimmed.replace(/^@/, \"\")\n\n const slashIndex = withoutPrefix.indexOf(\"/\")\n if (slashIndex < 1) {\n throw new Error(\"Tool must be in the format @owner/name[@version]\")\n }\n\n const owner = withoutPrefix.slice(0, slashIndex)\n const remainder = withoutPrefix.slice(slashIndex + 1)\n if (!remainder || remainder.includes(\"/\")) {\n throw new Error(\"Tool must be in the format @owner/name[@version]\")\n }\n\n let name = remainder\n let version: string | undefined\n const atIndex = remainder.lastIndexOf(\"@\")\n if (atIndex > 0) {\n if (!allowVersion) {\n throw new Error(\"Tool must be in the format @owner/name\")\n }\n name = remainder.slice(0, atIndex)\n version = remainder.slice(atIndex + 1)\n }\n\n const parsed = toolCoordinateSchema.safeParse({\n owner,\n tool: name,\n version,\n })\n\n if (!parsed.success) {\n throw new Error(\"Tool must be in the format @owner/name[@version]\")\n }\n\n return {\n owner: parsed.data.owner.toLowerCase(),\n name: parsed.data.tool,\n version: parsed.data.version,\n }\n}\n","import kleur from \"kleur\"\nimport { z } from \"zod\"\n\nconst searchResponseSchema = z.object({\n items: z.array(\n z.object({\n owner: z.string(),\n name: z.string(),\n description: z.string(),\n latestVersion: z.string().nullable(),\n isVerifiedOwner: z.boolean(),\n isFork: z.boolean(),\n })\n ),\n})\n\ntype SearchOptions = {\n limit: number\n}\n\nfunction parseLimit(input: number) {\n if (!Number.isFinite(input) || input <= 0) return 20\n return Math.min(Math.floor(input), 100)\n}\n\nexport async function runSearch(query: string, apiBaseUrl: string, options: SearchOptions) {\n const url = new URL(\"/cli/search\", apiBaseUrl)\n if (query.trim()) {\n url.searchParams.set(\"q\", query.trim())\n }\n url.searchParams.set(\"limit\", String(parseLimit(options.limit)))\n\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error(`Search failed (${response.status})`)\n }\n\n const payload = searchResponseSchema.parse(await response.json())\n if (!payload.items.length) {\n console.log(\"No tools found.\")\n return\n }\n\n for (const item of payload.items) {\n const version = item.latestVersion ?? \"n/a\"\n const ownerState = item.isVerifiedOwner\n ? kleur.green(\"verified\")\n : item.isFork\n ? kleur.yellow(\"fork\")\n : kleur.red(\"unverified\")\n\n console.log(`${kleur.bold(`@${item.owner}/${item.name}`)} ${kleur.dim(`v${version}`)} ${ownerState}`)\n console.log(` ${item.description}`)\n }\n}\n","import kleur from \"kleur\"\nimport { z } from \"zod\"\n\nimport { parseToolSpecifier } from \"../utils/tool-spec\"\n\nconst viewResponseSchema = z.object({\n tool: z.object({\n owner: z.string(),\n name: z.string(),\n description: z.string(),\n latestVersion: z.string().nullable(),\n isVerifiedOwner: z.boolean(),\n isFork: z.boolean(),\n upstreamOwner: z.string().nullable(),\n upstreamRepo: z.string().nullable(),\n upstreamUrl: z.string().nullable(),\n }),\n versions: z.array(\n z.object({\n version: z.string(),\n repoUrl: z.string(),\n commitSha: z.string(),\n aiSdkMajor: z.number(),\n aiSdkRange: z.string(),\n createdAt: z.string(),\n })\n ),\n installCommand: z.string(),\n})\n\nexport async function runView(specifier: string, apiBaseUrl: string) {\n const coordinate = parseToolSpecifier(specifier, { allowVersion: false })\n\n const response = await fetch(`${apiBaseUrl}/cli/view/${coordinate.owner}/${coordinate.name}`)\n if (!response.ok) {\n throw new Error(`View failed (${response.status})`)\n }\n\n const payload = viewResponseSchema.parse(await response.json())\n\n console.log(kleur.bold(`@${payload.tool.owner}/${payload.tool.name}`))\n console.log(payload.tool.description)\n console.log(`Latest version: ${payload.tool.latestVersion ?? \"n/a\"}`)\n console.log(`Owner status: ${payload.tool.isVerifiedOwner ? \"verified\" : \"unverified\"}`)\n const latest = payload.versions[0]\n if (latest) {\n console.log(`AI SDK: v${latest.aiSdkMajor} (${latest.aiSdkRange})`)\n }\n\n if (payload.tool.isFork && payload.tool.upstreamOwner && payload.tool.upstreamRepo) {\n console.log(\n kleur.yellow(\n `Forked from @${payload.tool.upstreamOwner}/${payload.tool.upstreamRepo}${\n payload.tool.upstreamUrl ? ` (${payload.tool.upstreamUrl})` : \"\"\n }`\n )\n )\n }\n\n console.log(\"\")\n console.log(kleur.dim(\"Install\"))\n console.log(payload.installCommand)\n\n if (payload.versions.length) {\n console.log(\"\")\n console.log(kleur.dim(\"Recent versions\"))\n for (const version of payload.versions.slice(0, 10)) {\n console.log(`- ${version.version} ${version.commitSha.slice(0, 8)} ${version.repoUrl}`)\n }\n }\n}\n"],"mappings":"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","names":["path","z","z","z","z","apiBaseUrl","kleur","z","apiBaseUrl","kleur","z","z","apiBaseUrl","kleur","path"]}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "toolshedtech",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "CLI for toolshed.tech - discover and install AI tools",
6
+ "license": "MIT",
7
+
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/ToolshedTech/toolshed"
11
+ },
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "bin": {
16
+ "toolshed": "./dist/index.js"
17
+ },
18
+ "scripts": {
19
+ "build": "tsup",
20
+ "dev": "tsup --watch",
21
+ "typecheck": "tsc --noEmit",
22
+ "lint": "eslint src --max-warnings 0"
23
+ },
24
+ "dependencies": {
25
+ "@toolshed/shared": "workspace:*",
26
+ "commander": "^14.0.0",
27
+ "kleur": "^4.1.5",
28
+ "zod": "^3.25.76"
29
+ },
30
+ "devDependencies": {
31
+ "@toolshed/eslint-config": "workspace:*",
32
+ "@toolshed/typescript-config": "workspace:*",
33
+ "@types/node": "^24.10.1",
34
+ "eslint": "^9.39.2",
35
+ "tsx": "^4.20.5",
36
+ "tsup": "^8.5.1",
37
+ "typescript": "^5.9.3"
38
+ }
39
+ }