@hasna/skills 0.1.36 → 0.1.38

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/bin/mcp.js CHANGED
@@ -6934,6 +6934,7 @@ var init_pricing = __esm(() => {
6934
6934
  init_skill_aliases();
6935
6935
  MUSIC_ALBUM_SONG_COUNTS = [7, 14, 21];
6936
6936
  PREMIUM_SKILLS = [
6937
+ { slug: "icon-pack", displayName: "Icon Pack", tier: "premium", costCents: 200, providers: ["hosted"], description: "Hosted coordinated icon pack with SVGs, transparent PNGs, size variants, and manifest" },
6937
6938
  { slug: "logo-design", displayName: "Logo Design", tier: "premium", costCents: 50, providers: ["hosted"], description: "Hosted multi-variant logo package with transparent PNGs, vector-style SVGs, usage notes, and manifest" },
6938
6939
  { slug: "deepresearch", displayName: "Deep Research", tier: "premium", costCents: 20, providers: ["exa"], description: "Agentic web research with semantic search and synthesis" },
6939
6940
  { slug: "playlist-maker", displayName: "Playlist Maker", tier: "premium", costCents: 30, providers: ["exa", "gemini-3-pro"], description: "Curated playlist with research, track selection, and album art" },
@@ -7207,6 +7208,8 @@ function clearAuthConfig() {
7207
7208
  function getApiKey() {
7208
7209
  if (process.env.SKILLS_API_KEY)
7209
7210
  return process.env.SKILLS_API_KEY;
7211
+ if (process.env.SKILL_API_KEY)
7212
+ return process.env.SKILL_API_KEY;
7210
7213
  return getAuthConfig()?.apiKey || null;
7211
7214
  }
7212
7215
  function normalizeSkillsApiOrigin(apiUrl) {
@@ -21793,7 +21796,7 @@ class StdioServerTransport {
21793
21796
  // package.json
21794
21797
  var package_default = {
21795
21798
  name: "@hasna/skills",
21796
- version: "0.1.36",
21799
+ version: "0.1.38",
21797
21800
  description: "Skills library for AI coding agents",
21798
21801
  type: "module",
21799
21802
  bin: {
@@ -31785,7 +31788,8 @@ function getSkillRequirements(name) {
31785
31788
  envVars.delete(envVar);
31786
31789
  }
31787
31790
  }
31788
- envVars.add("SKILL_API_KEY");
31791
+ envVars.delete("SKILL_API_KEY");
31792
+ envVars.add("SKILLS_API_KEY");
31789
31793
  }
31790
31794
  const systemDeps = new Set;
31791
31795
  const depPatterns = [
@@ -32032,6 +32036,10 @@ var runArgsSchema = {
32032
32036
  default: [],
32033
32037
  description: "CLI-style string arguments passed to the skill."
32034
32038
  };
32039
+ var paidRunApprovalSchema = {
32040
+ type: "boolean",
32041
+ description: "Set true only after the user has approved the quoted cost for a paid hosted run."
32042
+ };
32035
32043
  var errorSchema = objectSchema({
32036
32044
  code: stringSchema("Stable error code."),
32037
32045
  message: stringSchema("Human-readable error message."),
@@ -32259,11 +32267,16 @@ var toolContracts = [
32259
32267
  name: "run_skill",
32260
32268
  title: "Run Skill",
32261
32269
  description: "Run a skill locally or through a configured remote runner.",
32262
- params: ["name", "input?", "args?"],
32270
+ params: ["name", "input?", "args?", "approved?"],
32263
32271
  category: "execution",
32264
32272
  sideEffects: "local-process-or-remote-run",
32265
32273
  stable: true,
32266
- inputSchema: objectSchema({ name: skillNameInput, input: runInputSchema, args: runArgsSchema }, ["name"]),
32274
+ inputSchema: objectSchema({
32275
+ name: skillNameInput,
32276
+ input: runInputSchema,
32277
+ args: runArgsSchema,
32278
+ approved: paidRunApprovalSchema
32279
+ }, ["name"]),
32267
32280
  outputSchema: runOutputSchema
32268
32281
  },
32269
32282
  {
@@ -32722,8 +32735,8 @@ function sanitizePublicDiscoveryText(text) {
32722
32735
  function publicDiscoveryEnvVars(skillName, envVars) {
32723
32736
  if (!isPremiumSkill(skillName))
32724
32737
  return envVars;
32725
- const filtered = envVars.filter((envVar) => !VENDOR_ENV_PREFIXES.some((prefix) => envVar.startsWith(prefix)));
32726
- return filtered.includes("SKILL_API_KEY") ? filtered : ["SKILL_API_KEY", ...filtered];
32738
+ const filtered = envVars.filter((envVar) => envVar !== "SKILL_API_KEY" && !VENDOR_ENV_PREFIXES.some((prefix) => envVar.startsWith(prefix)));
32739
+ return filtered.includes("SKILLS_API_KEY") ? filtered : ["SKILLS_API_KEY", ...filtered];
32727
32740
  }
32728
32741
  function publicDiscoveryDependencies(skillName, dependencies) {
32729
32742
  if (!isPremiumSkill(skillName))
@@ -32739,7 +32752,7 @@ function publicDiscoveryDocumentation(skill, documentation) {
32739
32752
  `# ${skill.displayName || skill.name}`,
32740
32753
  sanitizePublicDiscoveryText(skill.description),
32741
32754
  `Pricing: ${getPublicSkillPricing(skill.name).formattedCost}.`,
32742
- "Set `SKILL_API_KEY` for hosted runtime execution. Runtime routing and model selection are managed by the hosted Skills runtime."
32755
+ "Set `SKILLS_API_KEY` or run `skills auth login` for hosted runtime execution. Runtime routing and model selection are managed by the hosted Skills runtime."
32743
32756
  ].join(`
32744
32757
 
32745
32758
  `);
@@ -33262,9 +33275,10 @@ function registerOperationTools(server) {
33262
33275
  inputSchema: {
33263
33276
  name: exports_external.string(),
33264
33277
  input: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
33265
- args: exports_external.array(exports_external.string()).optional()
33278
+ args: exports_external.array(exports_external.string()).optional(),
33279
+ approved: exports_external.boolean().optional()
33266
33280
  }
33267
- }, async ({ name, input, args }) => {
33281
+ }, async ({ name, input, args, approved }) => {
33268
33282
  const skill = getSkill(name);
33269
33283
  if (!skill) {
33270
33284
  return mcpError("SKILL_NOT_FOUND", `Skill '${name}' not found`, findSimilarSkills(name));
@@ -33302,6 +33316,17 @@ function registerOperationTools(server) {
33302
33316
  const run = completeSkillRun(runContext, { status: "failed", error: error48, costCents });
33303
33317
  return mcpError("AUTH_REQUIRED", `${error48}. Local run metadata: ${run.paths.runDir}/run.json`, ["skills auth login"]);
33304
33318
  }
33319
+ if (isPremiumSkill2(skillName) && apiKey && approved !== true) {
33320
+ const cost = formatCost2(costCents ?? 0);
33321
+ const error48 = `${skillName} is a paid hosted skill (${cost}). Call quote_skill first, then call run_skill with approved: true after user approval.`;
33322
+ writeRunLogs(runContext, "", error48 + `
33323
+ `);
33324
+ const run = completeSkillRun(runContext, { status: "failed", error: error48, costCents });
33325
+ return mcpError("APPROVAL_REQUIRED", `${error48}. Local run metadata: ${run.paths.runDir}/run.json`, [
33326
+ "quote_skill",
33327
+ "run_skill approved=true"
33328
+ ]);
33329
+ }
33305
33330
  if (isPremiumSkill2(skillName) && apiKey) {
33306
33331
  try {
33307
33332
  const { RemoteSkillsClient: RemoteSkillsClient2 } = await Promise.resolve().then(() => (init_remote_client(), exports_remote_client));
package/dist/index.js CHANGED
@@ -2658,6 +2658,7 @@ var MUSIC_ALBUM_SLUG = "music-album";
2658
2658
  var MUSIC_ALBUM_SONG_COUNTS = [7, 14, 21];
2659
2659
  var MUSIC_ALBUM_COST_CENTS_PER_SONG = 150;
2660
2660
  var PREMIUM_SKILLS = [
2661
+ { slug: "icon-pack", displayName: "Icon Pack", tier: "premium", costCents: 200, providers: ["hosted"], description: "Hosted coordinated icon pack with SVGs, transparent PNGs, size variants, and manifest" },
2661
2662
  { slug: "logo-design", displayName: "Logo Design", tier: "premium", costCents: 50, providers: ["hosted"], description: "Hosted multi-variant logo package with transparent PNGs, vector-style SVGs, usage notes, and manifest" },
2662
2663
  { slug: "deepresearch", displayName: "Deep Research", tier: "premium", costCents: 20, providers: ["exa"], description: "Agentic web research with semantic search and synthesis" },
2663
2664
  { slug: "playlist-maker", displayName: "Playlist Maker", tier: "premium", costCents: 30, providers: ["exa", "gemini-3-pro"], description: "Curated playlist with research, track selection, and album art" },
@@ -3157,7 +3158,8 @@ function getSkillRequirements(name) {
3157
3158
  envVars.delete(envVar);
3158
3159
  }
3159
3160
  }
3160
- envVars.add("SKILL_API_KEY");
3161
+ envVars.delete("SKILL_API_KEY");
3162
+ envVars.add("SKILLS_API_KEY");
3161
3163
  }
3162
3164
  const systemDeps = new Set;
3163
3165
  const depPatterns = [
@@ -17076,6 +17078,8 @@ function getAuthConfig() {
17076
17078
  function getApiKey() {
17077
17079
  if (process.env.SKILLS_API_KEY)
17078
17080
  return process.env.SKILLS_API_KEY;
17081
+ if (process.env.SKILL_API_KEY)
17082
+ return process.env.SKILL_API_KEY;
17079
17083
  return getAuthConfig()?.apiKey || null;
17080
17084
  }
17081
17085
  function normalizeSkillsApiOrigin(apiUrl) {
@@ -17331,8 +17335,8 @@ function sanitizePublicDiscoveryText(text) {
17331
17335
  function publicDiscoveryEnvVars(skillName, envVars) {
17332
17336
  if (!isPremiumSkill(skillName))
17333
17337
  return envVars;
17334
- const filtered = envVars.filter((envVar) => !VENDOR_ENV_PREFIXES.some((prefix) => envVar.startsWith(prefix)));
17335
- return filtered.includes("SKILL_API_KEY") ? filtered : ["SKILL_API_KEY", ...filtered];
17338
+ const filtered = envVars.filter((envVar) => envVar !== "SKILL_API_KEY" && !VENDOR_ENV_PREFIXES.some((prefix) => envVar.startsWith(prefix)));
17339
+ return filtered.includes("SKILLS_API_KEY") ? filtered : ["SKILLS_API_KEY", ...filtered];
17336
17340
  }
17337
17341
  function publicDiscoveryDependencies(skillName, dependencies) {
17338
17342
  if (!isPremiumSkill(skillName))
@@ -17348,7 +17352,7 @@ function publicDiscoveryDocumentation(skill, documentation) {
17348
17352
  `# ${skill.displayName || skill.name}`,
17349
17353
  sanitizePublicDiscoveryText(skill.description),
17350
17354
  `Pricing: ${getPublicSkillPricing(skill.name).formattedCost}.`,
17351
- "Set `SKILL_API_KEY` for hosted runtime execution. Runtime routing and model selection are managed by the hosted Skills runtime."
17355
+ "Set `SKILLS_API_KEY` or run `skills auth login` for hosted runtime execution. Runtime routing and model selection are managed by the hosted Skills runtime."
17352
17356
  ].join(`
17353
17357
 
17354
17358
  `);
@@ -18031,7 +18035,7 @@ import { dirname as dirname3, relative as relative2 } from "path";
18031
18035
  // package.json
18032
18036
  var package_default = {
18033
18037
  name: "@hasna/skills",
18034
- version: "0.1.36",
18038
+ version: "0.1.38",
18035
18039
  description: "Skills library for AI coding agents",
18036
18040
  type: "module",
18037
18041
  bin: {
@@ -18230,6 +18234,10 @@ var runArgsSchema = {
18230
18234
  default: [],
18231
18235
  description: "CLI-style string arguments passed to the skill."
18232
18236
  };
18237
+ var paidRunApprovalSchema = {
18238
+ type: "boolean",
18239
+ description: "Set true only after the user has approved the quoted cost for a paid hosted run."
18240
+ };
18233
18241
  var errorSchema = objectSchema({
18234
18242
  code: stringSchema("Stable error code."),
18235
18243
  message: stringSchema("Human-readable error message."),
@@ -18457,11 +18465,16 @@ var toolContracts = [
18457
18465
  name: "run_skill",
18458
18466
  title: "Run Skill",
18459
18467
  description: "Run a skill locally or through a configured remote runner.",
18460
- params: ["name", "input?", "args?"],
18468
+ params: ["name", "input?", "args?", "approved?"],
18461
18469
  category: "execution",
18462
18470
  sideEffects: "local-process-or-remote-run",
18463
18471
  stable: true,
18464
- inputSchema: objectSchema({ name: skillNameInput, input: runInputSchema, args: runArgsSchema }, ["name"]),
18472
+ inputSchema: objectSchema({
18473
+ name: skillNameInput,
18474
+ input: runInputSchema,
18475
+ args: runArgsSchema,
18476
+ approved: paidRunApprovalSchema
18477
+ }, ["name"]),
18465
18478
  outputSchema: runOutputSchema
18466
18479
  },
18467
18480
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/skills",
3
- "version": "0.1.36",
3
+ "version": "0.1.38",
4
4
  "description": "Skills library for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -4,28 +4,24 @@
4
4
  */
5
5
 
6
6
  export function checkSkillAuth(): void {
7
- const SKILL_API_KEY = process.env.SKILL_API_KEY;
7
+ const skillsApiKey = process.env.SKILLS_API_KEY || process.env.SKILL_API_KEY;
8
8
 
9
- // Check if SKILL_API_KEY is set
10
- if (!SKILL_API_KEY) {
11
- console.error('❌ Error: SKILL_API_KEY environment variable not set');
9
+ if (!skillsApiKey) {
10
+ console.error('Error: SKILLS_API_KEY environment variable not set');
12
11
  console.error('');
13
- console.error('To use this skill, you must set your SKILL_API_KEY:');
12
+ console.error('To use hosted execution, set your SKILLS_API_KEY:');
14
13
  console.error('');
15
- console.error(' export SKILL_API_KEY=your-api-key-here');
14
+ console.error(' export SKILLS_API_KEY=your-api-key-here');
16
15
  console.error('');
17
- console.error('Contact your administrator to get your API key.');
16
+ console.error('You can also use the root `skills auth login` command.');
18
17
  process.exit(1);
19
18
  }
20
19
 
21
- // Validate key format
22
- if (!SKILL_API_KEY.startsWith('sk-skill-')) {
23
- console.error('❌ Error: Invalid SKILL_API_KEY format');
20
+ if (!skillsApiKey.startsWith('sk-skill-')) {
21
+ console.error('Error: Invalid SKILLS_API_KEY format');
24
22
  console.error('Expected format: sk-skill-xxxxxxxxxxxx');
25
23
  process.exit(1);
26
24
  }
27
-
28
- // Key is valid - skill can proceed
29
25
  }
30
26
 
31
27
  /**
@@ -5,7 +5,7 @@
5
5
  * Usage: import and call executeSkill() from your skill CLI
6
6
  */
7
7
 
8
- const SKILL_API_URL = process.env.SKILL_API_URL || "https://skill.hasnaxyz.com";
8
+ const SKILL_API_URL = process.env.SKILLS_API_URL || process.env.SKILL_API_URL || "https://skills.md/api/v1";
9
9
 
10
10
  export interface SkillRequest {
11
11
  skill: string;
@@ -33,12 +33,12 @@ export async function executeSkill(request: SkillRequest): Promise<SkillResponse
33
33
  const url = `${SKILL_API_URL}/${skill}/`;
34
34
 
35
35
  // Get API key from environment
36
- const apiKey = process.env.SKILL_API_KEY;
36
+ const apiKey = process.env.SKILLS_API_KEY || process.env.SKILL_API_KEY;
37
37
  if (!apiKey) {
38
38
  return {
39
39
  success: false,
40
- error: "Missing SKILL_API_KEY",
41
- details: "Set SKILL_API_KEY environment variable"
40
+ error: "Missing SKILLS_API_KEY",
41
+ details: "Set SKILLS_API_KEY environment variable or run `skills auth login`"
42
42
  };
43
43
  }
44
44
 
@@ -32,4 +32,4 @@ audio generate --provider gemini --text "Studio announcement" --output ./voice.w
32
32
 
33
33
  ## Environment
34
34
 
35
- - `SKILL_API_KEY`: required for hosted runtime execution
35
+ - `SKILLS_API_KEY`: required for hosted runtime execution
@@ -3,13 +3,13 @@
3
3
  "version": "1.0.0",
4
4
  "description": "Code quality CLI for auto-linting, formatting, and fixing code issues",
5
5
  "type": "module",
6
- "main": "src/index.ts",
6
+ "main": "src/index-local.ts",
7
7
  "bin": {
8
- "codefix": "src/index.ts"
8
+ "codefix": "src/index-local.ts"
9
9
  },
10
10
  "scripts": {
11
- "start": "bun run src/index.ts",
12
- "dev": "bun run --watch src/index.ts"
11
+ "start": "bun run src/index-local.ts",
12
+ "dev": "bun run --watch src/index-local.ts"
13
13
  },
14
14
  "dependencies": {},
15
15
  "devDependencies": {
@@ -13,7 +13,7 @@ const SKILL_META = {
13
13
  description: 'Code quality CLI for auto-linting, formatting, and fixing code issues',
14
14
  version: '1.0.0',
15
15
  commands: `Use: codefix --help`,
16
- requiredEnvVars: ['SKILL_API_KEY'],
16
+ requiredEnvVars: [],
17
17
  };
18
18
 
19
19
  if (await handleInstallCommand(SKILL_META, process.argv.slice(2))) {
@@ -49,6 +49,7 @@ function parseArgs(): {
49
49
  verbose?: boolean;
50
50
  } {
51
51
  const args = process.argv.slice(2);
52
+ if (args[0] === '--help' || args[0] === '-h') args[0] = 'help';
52
53
  const parsed: Record<string, unknown> = { command: args[0] || 'help' };
53
54
 
54
55
  for (let i = 1; i < args.length; i++) {
@@ -1,110 +1,4 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
- /**
4
- * Skill Codefix (HTTP Client)
5
- * Calls the remote skill API server
6
- */
7
-
8
- import { executeAndSave, executeSkill, handleInstallCommand } from '../../_common';
9
-
10
- // Skill metadata for install command
11
- const SKILL_META = {
12
- name: 'codefix',
13
- description: 'Codefix skill - calls remote API',
14
- version: '1.0.0',
15
- commands: `codefix <command> [options]`,
16
- requiredEnvVars: ['SKILL_API_KEY'],
17
- };
18
-
19
- // Handle install/uninstall commands
20
- if (await handleInstallCommand(SKILL_META, process.argv.slice(2))) {
21
- process.exit(0);
22
- }
23
-
24
- // Parse command line arguments
25
- function parseArgs(): Record<string, string | boolean> {
26
- const args = process.argv.slice(2);
27
- const parsed: Record<string, string | boolean> = {};
28
-
29
- for (let i = 0; i < args.length; i++) {
30
- if (args[i].startsWith('--')) {
31
- const key = args[i].slice(2);
32
- const value = args[i + 1];
33
- if (value && !value.startsWith('--')) {
34
- parsed[key] = value;
35
- i++;
36
- } else {
37
- parsed[key] = true;
38
- }
39
- } else if (!parsed.command) {
40
- parsed.command = args[i];
41
- }
42
- }
43
-
44
- return parsed;
45
- }
46
-
47
- // Main logic
48
- async function main() {
49
- const args = parseArgs();
50
- const command = (args.command as string) || 'help';
51
-
52
- if (command === 'help' || args.help) {
53
- console.log(`Skill Codefix CLI
54
-
55
- USAGE:
56
- codefix <command> [options]
57
-
58
- COMMANDS:
59
- Call with any command and it will be forwarded to the remote API server
60
-
61
- EXAMPLES:
62
- codefix generate --provider <provider> [options]`);
63
- return;
64
- }
65
-
66
- // Extract all parameters
67
- const { command: cmd, ...params } = args;
68
-
69
- // Check if output file is expected (for file-generating skills)
70
- const fileSkills = ['audio', 'image', 'video', 'emoji'];
71
- const isFileSkill = fileSkills.includes('codefix');
72
-
73
- if (isFileSkill && params.output) {
74
- // Skill that generates files
75
- const success = await executeAndSave({
76
- skill: 'codefix',
77
- command: cmd,
78
- ...params,
79
- });
80
- process.exit(success ? 0 : 1);
81
- } else {
82
- // Skill that returns JSON/text
83
- const result = await executeSkill({
84
- skill: 'codefix',
85
- command: cmd,
86
- ...params,
87
- });
88
-
89
- if (result instanceof Blob) {
90
- console.error('❌ Unexpected binary response');
91
- process.exit(1);
92
- }
93
-
94
- if (result.success && result.output) {
95
- console.log(result.output);
96
- } else {
97
- console.error(`❌ Error: ${result.error}`);
98
- if (result.details) {
99
- console.error(` ${result.details}`);
100
- }
101
- process.exit(1);
102
- }
103
- }
104
- }
105
-
106
- // Run main
107
- main().catch((error) => {
108
- console.error('❌ Fatal error:', error.message);
109
- process.exit(1);
110
- });
3
+ // Keep the package root on the local implementation; hosted execution goes through the root Skills CLI.
4
+ import "./index-local";
@@ -9,7 +9,7 @@ description: File format conversion and transformation CLI between images, PDFs,
9
9
 
10
10
  File format conversion skill with AI-powered extraction capabilities. Converts between images, PDFs, documents, and data formats with optional quality control and AI cleanup.
11
11
 
12
- This CLI is API-backed. Set `SKILL_API_KEY` when routing through the hosted skills/connectors runtime; provider-specific keys are managed by that runtime.
12
+ This CLI is API-backed. Set `SKILLS_API_KEY` when routing through the hosted skills/connectors runtime; provider-specific keys are managed by that runtime.
13
13
 
14
14
  ## Category
15
15
 
@@ -65,7 +65,7 @@ bun run src/index.ts formats
65
65
  - `openai` - GPT-4o AI
66
66
 
67
67
  ### API Key
68
- - `SKILL_API_KEY` - Hosted runtime access. Provider credentials for AI features are managed remotely.
68
+ - `SKILLS_API_KEY` - Hosted runtime access. Provider credentials for AI features are managed remotely.
69
69
 
70
70
  ## Conversion Categories
71
71
 
@@ -3,13 +3,13 @@
3
3
  "version": "1.0.0",
4
4
  "description": "File format conversion CLI - convert between images, PDFs, documents, and data formats with AI-powered extraction",
5
5
  "type": "module",
6
- "main": "src/index.ts",
6
+ "main": "src/index-local.ts",
7
7
  "bin": {
8
- "convert": "src/index.ts"
8
+ "convert": "src/index-local.ts"
9
9
  },
10
10
  "scripts": {
11
- "start": "bun run src/index.ts",
12
- "dev": "bun run --watch src/index.ts"
11
+ "start": "bun run src/index-local.ts",
12
+ "dev": "bun run --watch src/index-local.ts"
13
13
  },
14
14
  "dependencies": {
15
15
  "@anthropic-ai/sdk": "^0.36.3",
@@ -13,7 +13,7 @@ const SKILL_META = {
13
13
  description: 'File format conversion CLI - convert between images, PDFs, documents, and data formats with AI-powered extraction',
14
14
  version: '1.0.0',
15
15
  commands: `Use: convert --help`,
16
- requiredEnvVars: ['SKILL_API_KEY'],
16
+ requiredEnvVars: [],
17
17
  };
18
18
 
19
19
  if (await handleInstallCommand(SKILL_META, process.argv.slice(2))) {
@@ -68,6 +68,7 @@ function parseArgs(): {
68
68
  recursive?: boolean;
69
69
  } {
70
70
  const args = process.argv.slice(2);
71
+ if (args[0] === '--help' || args[0] === '-h') args[0] = 'help';
71
72
  const parsed: Record<string, unknown> = { command: args[0] || 'help' };
72
73
 
73
74
  for (let i = 1; i < args.length; i++) {
@@ -1,110 +1,4 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
- /**
4
- * Skill Convert (HTTP Client)
5
- * Calls the remote skill API server
6
- */
7
-
8
- import { executeAndSave, executeSkill, handleInstallCommand } from '../../_common';
9
-
10
- // Skill metadata for install command
11
- const SKILL_META = {
12
- name: 'convert',
13
- description: 'Convert skill - calls remote API',
14
- version: '1.0.0',
15
- commands: `convert <command> [options]`,
16
- requiredEnvVars: ['SKILL_API_KEY'],
17
- };
18
-
19
- // Handle install/uninstall commands
20
- if (await handleInstallCommand(SKILL_META, process.argv.slice(2))) {
21
- process.exit(0);
22
- }
23
-
24
- // Parse command line arguments
25
- function parseArgs(): Record<string, string | boolean> {
26
- const args = process.argv.slice(2);
27
- const parsed: Record<string, string | boolean> = {};
28
-
29
- for (let i = 0; i < args.length; i++) {
30
- if (args[i].startsWith('--')) {
31
- const key = args[i].slice(2);
32
- const value = args[i + 1];
33
- if (value && !value.startsWith('--')) {
34
- parsed[key] = value;
35
- i++;
36
- } else {
37
- parsed[key] = true;
38
- }
39
- } else if (!parsed.command) {
40
- parsed.command = args[i];
41
- }
42
- }
43
-
44
- return parsed;
45
- }
46
-
47
- // Main logic
48
- async function main() {
49
- const args = parseArgs();
50
- const command = (args.command as string) || 'help';
51
-
52
- if (command === 'help' || args.help) {
53
- console.log(`Skill Convert CLI
54
-
55
- USAGE:
56
- convert <command> [options]
57
-
58
- COMMANDS:
59
- Call with any command and it will be forwarded to the remote API server
60
-
61
- EXAMPLES:
62
- convert generate --provider <provider> [options]`);
63
- return;
64
- }
65
-
66
- // Extract all parameters
67
- const { command: cmd, ...params } = args;
68
-
69
- // Check if output file is expected (for file-generating skills)
70
- const fileSkills = ['audio', 'image', 'video', 'emoji'];
71
- const isFileSkill = fileSkills.includes('convert');
72
-
73
- if (isFileSkill && params.output) {
74
- // Skill that generates files
75
- const success = await executeAndSave({
76
- skill: 'convert',
77
- command: cmd,
78
- ...params,
79
- });
80
- process.exit(success ? 0 : 1);
81
- } else {
82
- // Skill that returns JSON/text
83
- const result = await executeSkill({
84
- skill: 'convert',
85
- command: cmd,
86
- ...params,
87
- });
88
-
89
- if (result instanceof Blob) {
90
- console.error('❌ Unexpected binary response');
91
- process.exit(1);
92
- }
93
-
94
- if (result.success && result.output) {
95
- console.log(result.output);
96
- } else {
97
- console.error(`❌ Error: ${result.error}`);
98
- if (result.details) {
99
- console.error(` ${result.details}`);
100
- }
101
- process.exit(1);
102
- }
103
- }
104
- }
105
-
106
- // Run main
107
- main().catch((error) => {
108
- console.error('❌ Fatal error:', error.message);
109
- process.exit(1);
110
- });
3
+ // Keep the package root on the local implementation; hosted execution goes through the root Skills CLI.
4
+ import "./index-local";
@@ -3,13 +3,13 @@
3
3
  "version": "1.0.0",
4
4
  "description": "Deployment CLI for managing EC2 deployments with automated health checks",
5
5
  "type": "module",
6
- "main": "src/index.ts",
6
+ "main": "src/index-local.ts",
7
7
  "bin": {
8
8
  "deploy": "src/index-local.ts"
9
9
  },
10
10
  "scripts": {
11
- "start": "bun run src/index.ts",
12
- "dev": "bun run --watch src/index.ts"
11
+ "start": "bun run src/index-local.ts",
12
+ "dev": "bun run --watch src/index-local.ts"
13
13
  },
14
14
  "dependencies": {},
15
15
  "devDependencies": {
@@ -5,7 +5,7 @@
5
5
  * Usage: import and call executeSkill() from your skill CLI
6
6
  */
7
7
 
8
- const SKILL_API_URL = process.env.SKILL_API_URL || "http://localhost:3000";
8
+ const SKILL_API_URL = process.env.SKILLS_API_URL || process.env.SKILL_API_URL || "https://skills.md/api/v1";
9
9
 
10
10
  export interface SkillRequest {
11
11
  skill: string;
@@ -33,12 +33,12 @@ export async function executeSkill(request: SkillRequest): Promise<SkillResponse
33
33
  const url = `${SKILL_API_URL}/${skill}/`;
34
34
 
35
35
  // Get API key from environment
36
- const apiKey = process.env.SKILL_API_KEY;
36
+ const apiKey = process.env.SKILLS_API_KEY || process.env.SKILL_API_KEY;
37
37
  if (!apiKey) {
38
38
  return {
39
39
  success: false,
40
- error: "Missing SKILL_API_KEY",
41
- details: "Set SKILL_API_KEY environment variable"
40
+ error: "Missing SKILLS_API_KEY",
41
+ details: "Set SKILLS_API_KEY environment variable or run `skills auth login`"
42
42
  };
43
43
  }
44
44
 
@@ -13,7 +13,7 @@ const SKILL_META = {
13
13
  description: 'Deployment CLI for managing EC2 deployments with automated health checks',
14
14
  version: '1.0.0',
15
15
  commands: `Use: deploy --help`,
16
- requiredEnvVars: ['SKILL_API_KEY'],
16
+ requiredEnvVars: [],
17
17
  };
18
18
 
19
19
  if (await handleInstallCommand(SKILL_META, process.argv.slice(2))) {
@@ -38,6 +38,7 @@ function parseArgs(): {
38
38
  parallel?: boolean;
39
39
  } {
40
40
  const args = process.argv.slice(2);
41
+ if (args[0] === '--help' || args[0] === '-h') args[0] = 'help';
41
42
  const parsed: Record<string, any> = {
42
43
  command: args[0] || 'help',
43
44
  hosts: [],