@hasna/skills 0.1.32 → 0.1.33

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.
Files changed (80) hide show
  1. package/README.md +1 -16
  2. package/bin/index.js +57 -14
  3. package/bin/mcp.js +57 -13
  4. package/dist/cli/commands/runtime.d.ts +1 -1
  5. package/dist/index.js +51 -5
  6. package/dist/lib/skill-validation.d.ts +2 -0
  7. package/package.json +1 -1
  8. package/skills/ad-creative-pack/package.json +4 -7
  9. package/skills/api-docs-portal/package.json +5 -3
  10. package/skills/audio/package.json +4 -22
  11. package/skills/audio-transcript-pack/package.json +3 -2
  12. package/skills/blog-article/package.json +5 -21
  13. package/skills/brand-kit/package.json +4 -7
  14. package/skills/brand-photo-shoot/package.json +3 -2
  15. package/skills/browse/package.json +4 -33
  16. package/skills/contract-review-report/package.json +3 -2
  17. package/skills/customer-feedback-report/package.json +3 -2
  18. package/skills/deepresearch/package.json +4 -37
  19. package/skills/domainpurchase/SKILL.md +14 -31
  20. package/skills/domainpurchase/package.json +3 -8
  21. package/skills/email-sequence/package.json +4 -7
  22. package/skills/generate-book-cover/package.json +5 -23
  23. package/skills/icon-pack/package.json +4 -22
  24. package/skills/image/package.json +4 -22
  25. package/skills/invoice-reconciliation/package.json +3 -2
  26. package/skills/landing-page-pack/package.json +4 -7
  27. package/skills/logo-design/package.json +4 -2
  28. package/skills/managemcp/CLAUDE.md +9 -43
  29. package/skills/managemcp/README.md +12 -198
  30. package/skills/managemcp/package.json +2 -10
  31. package/skills/managemcp/tsconfig.json +1 -3
  32. package/skills/market-research-report/package.json +5 -4
  33. package/skills/meeting-pack/package.json +3 -2
  34. package/skills/migration-plan-pack/package.json +3 -2
  35. package/skills/music/package.json +4 -20
  36. package/skills/music-album/package.json +3 -2
  37. package/skills/one-page-website/package.json +3 -2
  38. package/skills/pdf-read/package.json +5 -23
  39. package/skills/pdf-to-dataset/package.json +5 -4
  40. package/skills/pdf-to-markdown/package.json +5 -4
  41. package/skills/performance-audit-report/package.json +3 -2
  42. package/skills/photo-album/package.json +4 -2
  43. package/skills/pitch-deck/package.json +5 -3
  44. package/skills/playlist-maker/package.json +4 -2
  45. package/skills/product-mockup/package.json +3 -2
  46. package/skills/proposal-pack/package.json +5 -4
  47. package/skills/read-pdf/package.json +4 -29
  48. package/skills/remove-background/package.json +5 -21
  49. package/skills/repo-onboarding-report/package.json +3 -2
  50. package/skills/sdk-generator/package.json +3 -2
  51. package/skills/security-audit-report/package.json +5 -4
  52. package/skills/seo-content-pack/package.json +5 -3
  53. package/skills/short-video-pack/package.json +3 -2
  54. package/skills/slide-deck-generator/package.json +3 -2
  55. package/skills/sms/README.md +18 -56
  56. package/skills/sms/package.json +1 -3
  57. package/skills/sms/tsconfig.json +1 -2
  58. package/skills/social-content-calendar/package.json +4 -7
  59. package/skills/test-suite-generator/package.json +5 -4
  60. package/skills/transcript/package.json +4 -23
  61. package/skills/video/package.json +4 -24
  62. package/skills/video-highlight-pack/package.json +3 -2
  63. package/skills/voiceover-jingle-pack/package.json +3 -2
  64. package/skills/webcrawling/package.json +4 -32
  65. package/skills/domainpurchase/.env.example +0 -7
  66. package/skills/domainpurchase/src/lib/api-client.ts +0 -571
  67. package/skills/domainpurchase/src/lib/config.ts +0 -209
  68. package/skills/domainpurchase/src/lib/installer.ts +0 -165
  69. package/skills/managemcp/.env.example +0 -16
  70. package/skills/managemcp/scripts/migrate.ts +0 -57
  71. package/skills/managemcp/scripts/seed.ts +0 -58
  72. package/skills/managemcp/src/db/index.ts +0 -37
  73. package/skills/managemcp/src/lib/api-client.ts +0 -108
  74. package/skills/managemcp/src/lib/config.ts +0 -34
  75. package/skills/managemcp/src/lib/installer.ts +0 -140
  76. package/skills/managemcp/src/lib/service-dir.ts +0 -119
  77. package/skills/sms/scripts/buy-number.ts +0 -63
  78. package/skills/sms/scripts/test-send.ts +0 -67
  79. package/skills/sms/src/server.ts +0 -351
  80. package/skills/sms/src/sse-server.ts +0 -279
@@ -1,140 +0,0 @@
1
- import { readFile, writeFile, readdir, unlink, mkdir } from 'fs/promises';
2
- import { join } from 'path';
3
- import { homedir } from 'os';
4
- import { getItem } from './api-client';
5
-
6
- export type Target = 'claude' | 'codex';
7
- export type ConflictStrategy = 'skip' | 'overwrite';
8
-
9
- export interface InstallResult {
10
- success: boolean;
11
- message: string;
12
- itemId: string;
13
- }
14
-
15
- export interface InstalledItem {
16
- id: string;
17
- name: string;
18
- target: Target;
19
- installedAt: string;
20
- }
21
-
22
- const CLAUDE_DIR = join(homedir(), '.claude', 'skills');
23
- const CODEX_DIR = join(homedir(), '.codex', 'skills');
24
-
25
- function getTargetDir(target: Target): string {
26
- return target === 'claude' ? CLAUDE_DIR : CODEX_DIR;
27
- }
28
-
29
- async function ensureDir(dir: string): Promise<void> {
30
- await mkdir(dir, { recursive: true });
31
- }
32
-
33
- async function writeItemFile(
34
- target: Target,
35
- itemId: string,
36
- content: string,
37
- strategy: ConflictStrategy
38
- ): Promise<boolean> {
39
- const dir = getTargetDir(target);
40
- await ensureDir(dir);
41
-
42
- const filePath = join(dir, `${itemId}.json`);
43
-
44
- try {
45
- await readFile(filePath);
46
- if (strategy === 'skip') return false;
47
- } catch {
48
- // File doesn't exist, proceed
49
- }
50
-
51
- await writeFile(filePath, content, 'utf-8');
52
- return true;
53
- }
54
-
55
- async function installToTarget(
56
- target: Target,
57
- itemId: string,
58
- strategy: ConflictStrategy = 'skip'
59
- ): Promise<InstallResult> {
60
- try {
61
- const item = await getItem(itemId);
62
- const content = JSON.stringify(item, null, 2);
63
- const written = await writeItemFile(target, itemId, content, strategy);
64
-
65
- const targetName = target.charAt(0).toUpperCase() + target.slice(1);
66
- return {
67
- success: true,
68
- message: written
69
- ? `Installed to ${targetName}: ${item.name}`
70
- : `Skipped (already exists): ${item.name}`,
71
- itemId,
72
- };
73
- } catch (error) {
74
- return {
75
- success: false,
76
- message: `Failed to install to ${target}: ${error instanceof Error ? error.message : 'Unknown error'}`,
77
- itemId,
78
- };
79
- }
80
- }
81
-
82
- export async function install(
83
- itemId: string,
84
- target: Target | 'both' = 'both',
85
- strategy: ConflictStrategy = 'skip'
86
- ): Promise<InstallResult> {
87
- if (target === 'both') {
88
- const claudeResult = await installToTarget('claude', itemId, strategy);
89
- const codexResult = await installToTarget('codex', itemId, strategy);
90
-
91
- return {
92
- success: claudeResult.success && codexResult.success,
93
- message: `${claudeResult.message}\n${codexResult.message}`,
94
- itemId,
95
- };
96
- }
97
-
98
- return await installToTarget(target, itemId, strategy);
99
- }
100
-
101
- export async function clearTarget(target?: Target | 'both'): Promise<void> {
102
- const targets: Target[] = target === 'both' || !target ? ['claude', 'codex'] : [target];
103
-
104
- for (const t of targets) {
105
- const dir = getTargetDir(t);
106
- try {
107
- const files = await readdir(dir);
108
- const jsonFiles = files.filter((f) => f.endsWith('.json')).map((f) => unlink(join(dir, f)));
109
- await Promise.all(jsonFiles);
110
- } catch (error) {
111
- if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;
112
- }
113
- }
114
- }
115
-
116
- export async function listInstalled(target?: Target | 'both'): Promise<InstalledItem[]> {
117
- const targets: Target[] = target === 'both' || !target ? ['claude', 'codex'] : [target];
118
- const items: InstalledItem[] = [];
119
-
120
- for (const t of targets) {
121
- const dir = getTargetDir(t);
122
- try {
123
- const files = await readdir(dir);
124
- for (const file of files.filter((f) => f.endsWith('.json'))) {
125
- const content = await readFile(join(dir, file), 'utf-8');
126
- const item = JSON.parse(content);
127
- items.push({
128
- id: item.id,
129
- name: item.name,
130
- target: t,
131
- installedAt: file,
132
- });
133
- }
134
- } catch (error) {
135
- if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;
136
- }
137
- }
138
-
139
- return items;
140
- }
@@ -1,119 +0,0 @@
1
- import { existsSync, mkdirSync, writeFileSync, appendFileSync } from "fs";
2
- import { join } from "path";
3
- import { homedir } from "os";
4
-
5
- const SERVICE_NAME = "managemcp";
6
- const SERVICE_DIR_NAME = `.${SERVICE_NAME}`;
7
-
8
- export function getServiceDir(): string {
9
- return join(homedir(), SERVICE_DIR_NAME);
10
- }
11
-
12
- export function getLogFilePath(): string {
13
- return join(getServiceDir(), `${SERVICE_NAME}.log`);
14
- }
15
-
16
- export function getReadmePath(): string {
17
- return join(getServiceDir(), "README.md");
18
- }
19
-
20
- export function isServiceDirInstalled(): boolean {
21
- return existsSync(getServiceDir());
22
- }
23
-
24
- export function ensureServiceDir(): void {
25
- if (!isServiceDirInstalled()) {
26
- initServiceDir();
27
- }
28
- }
29
-
30
- export function initServiceDir(force = false): { success: boolean; path: string; message: string } {
31
- const serviceDir = getServiceDir();
32
-
33
- if (existsSync(serviceDir) && !force) {
34
- return {
35
- success: false,
36
- path: serviceDir,
37
- message: "Already installed. Use --force to reinstall.",
38
- };
39
- }
40
-
41
- mkdirSync(serviceDir, { recursive: true });
42
-
43
- const readmeContent = generateReadme();
44
- writeFileSync(getReadmePath(), readmeContent);
45
-
46
- const logHeader = `# ${SERVICE_NAME} log file
47
- # Created: ${new Date().toISOString()}
48
- # This file contains activity history and logs.
49
- # -------------------------------------------------------
50
-
51
- `;
52
- writeFileSync(getLogFilePath(), logHeader);
53
-
54
- return {
55
- success: true,
56
- path: serviceDir,
57
- message: `Installed at ${serviceDir}`,
58
- };
59
- }
60
-
61
- function generateReadme(): string {
62
- return `# .${SERVICE_NAME}
63
-
64
- This directory contains local configuration and logs for \`${SERVICE_NAME}\`.
65
-
66
- ## Files
67
-
68
- | Path | Description |
69
- |------|-------------|
70
- | \`${SERVICE_NAME}.log\` | Activity log |
71
- | \`README.md\` | This file |
72
-
73
- ## What is ${SERVICE_NAME}?
74
-
75
- \`${SERVICE_NAME}\` is a tool for managing MCP server connections.
76
-
77
- ## Log File
78
-
79
- The \`${SERVICE_NAME}.log\` file contains:
80
- - Activity logs
81
- - Error logs
82
- - API activity
83
-
84
- ## More Information
85
-
86
- For full documentation, run:
87
-
88
- \`\`\`bash
89
- ${SERVICE_NAME} --help
90
- \`\`\`
91
- `;
92
- }
93
-
94
- export type LogLevel = "debug" | "info" | "warn" | "error";
95
-
96
- export function logToFile(message: string, level: LogLevel = "info"): void {
97
- ensureServiceDir();
98
-
99
- const timestamp = new Date().toISOString();
100
- const logLine = `[${timestamp}] [${level.toUpperCase()}] ${message}\n`;
101
-
102
- try {
103
- appendFileSync(getLogFilePath(), logLine);
104
- } catch {
105
- // Silently fail
106
- }
107
- }
108
-
109
- export function logInfo(message: string): void {
110
- logToFile(message, "info");
111
- }
112
-
113
- export function logError(message: string): void {
114
- logToFile(message, "error");
115
- }
116
-
117
- export function logWarn(message: string): void {
118
- logToFile(message, "warn");
119
- }
@@ -1,63 +0,0 @@
1
- #!/usr/bin/env bun
2
- /**
3
- * Script to buy a Twilio phone number for an agent
4
- * Usage: bun run scripts/buy-number.ts [agent_name] [area_code]
5
- */
6
-
7
- import twilio from "twilio";
8
-
9
- const CONFIG = {
10
- accountSid: process.env.TWILIO_ACCOUNT_SID || "",
11
- authToken: process.env.TWILIO_AUTH_TOKEN || "",
12
- };
13
-
14
- const twilioClient = twilio(CONFIG.accountSid, CONFIG.authToken);
15
-
16
- function capitalize(str: string): string {
17
- return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
18
- }
19
-
20
- async function buyPhoneNumber() {
21
- const agentName = process.argv[2] || "claude";
22
- const areaCode = process.argv[3] || "302"; // Default to Delaware
23
-
24
- const friendlyName = `${capitalize(agentName)} (AI Agent)`;
25
-
26
- console.log(`Searching for available numbers with area code ${areaCode}...`);
27
-
28
- try {
29
- // Search for available numbers
30
- const availableNumbers = await twilioClient
31
- .availablePhoneNumbers("US")
32
- .local.list({ areaCode: parseInt(areaCode), limit: 5 });
33
-
34
- if (availableNumbers.length === 0) {
35
- console.error(`No available phone numbers found with area code ${areaCode}`);
36
- process.exit(1);
37
- }
38
-
39
- console.log(`Found ${availableNumbers.length} available numbers:`);
40
- availableNumbers.forEach((n, i) => {
41
- console.log(` ${i + 1}. ${n.phoneNumber}`);
42
- });
43
-
44
- // Purchase the first available number
45
- const phoneNumber = availableNumbers[0].phoneNumber;
46
- console.log(`\nPurchasing ${phoneNumber} for ${friendlyName}...`);
47
-
48
- const purchased = await twilioClient.incomingPhoneNumbers.create({
49
- phoneNumber,
50
- friendlyName,
51
- });
52
-
53
- console.log("\nPhone number purchased successfully!");
54
- console.log(` SID: ${purchased.sid}`);
55
- console.log(` Phone Number: ${purchased.phoneNumber}`);
56
- console.log(` Friendly Name: ${purchased.friendlyName}`);
57
- } catch (error: any) {
58
- console.error("Failed to buy phone number:", error.message);
59
- process.exit(1);
60
- }
61
- }
62
-
63
- buyPhoneNumber();
@@ -1,67 +0,0 @@
1
- #!/usr/bin/env bun
2
- /**
3
- * Test script to send SMS via Twilio
4
- * Usage: bun run scripts/test-send.ts [from_number] [to_number] [message]
5
- */
6
-
7
- import twilio from "twilio";
8
-
9
- const CONFIG = {
10
- accountSid: process.env.TWILIO_ACCOUNT_SID || "",
11
- authToken: process.env.TWILIO_AUTH_TOKEN || "",
12
- };
13
-
14
- const twilioClient = twilio(CONFIG.accountSid, CONFIG.authToken);
15
-
16
- function formatPhoneNumber(phone: string): string {
17
- const digits = phone.replace(/\D/g, "");
18
- if (digits.length === 10) {
19
- return `+1${digits}`;
20
- }
21
- if (digits.length === 11 && digits.startsWith("1")) {
22
- return `+${digits}`;
23
- }
24
- if (!phone.startsWith("+")) {
25
- return `+${digits}`;
26
- }
27
- return phone;
28
- }
29
-
30
- async function sendTestSms() {
31
- const fromNumber = process.argv[2];
32
- const toNumber = process.argv[3];
33
- const messageBody =
34
- process.argv[4] ||
35
- `Hello from the SMS agent!\n\nThis is a test SMS sent at ${new Date().toISOString()}.`;
36
-
37
- if (!fromNumber || !toNumber) {
38
- console.error("Usage: bun run scripts/test-send.ts <from_number> <to_number> [message]");
39
- console.error("\nAvailable numbers:");
40
- const numbers = await twilioClient.incomingPhoneNumbers.list();
41
- numbers.forEach((n) => {
42
- console.log(` ${n.phoneNumber} - ${n.friendlyName}`);
43
- });
44
- process.exit(1);
45
- }
46
-
47
- console.log(`Sending test SMS from ${formatPhoneNumber(fromNumber)} to ${formatPhoneNumber(toNumber)}...`);
48
-
49
- try {
50
- const message = await twilioClient.messages.create({
51
- body: messageBody,
52
- from: formatPhoneNumber(fromNumber),
53
- to: formatPhoneNumber(toNumber),
54
- });
55
-
56
- console.log("SMS sent successfully!");
57
- console.log(` Message SID: ${message.sid}`);
58
- console.log(` Status: ${message.status}`);
59
- console.log(` From: ${message.from}`);
60
- console.log(` To: ${message.to}`);
61
- } catch (error: any) {
62
- console.error("Failed to send SMS:", error.message);
63
- process.exit(1);
64
- }
65
- }
66
-
67
- sendTestSms();