@hasna/skills 0.1.32 → 0.1.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -16
- package/bin/index.js +57 -14
- package/bin/mcp.js +57 -13
- package/dist/cli/commands/runtime.d.ts +1 -1
- package/dist/index.js +51 -5
- package/dist/lib/skill-validation.d.ts +2 -0
- package/package.json +1 -1
- package/skills/ad-creative-pack/package.json +4 -7
- package/skills/api-docs-portal/package.json +5 -3
- package/skills/audio/package.json +4 -22
- package/skills/audio-transcript-pack/package.json +3 -2
- package/skills/blog-article/package.json +5 -21
- package/skills/brand-kit/package.json +4 -7
- package/skills/brand-photo-shoot/package.json +3 -2
- package/skills/browse/README.md +13 -256
- package/skills/browse/SKILL.md +24 -45
- package/skills/browse/package.json +4 -33
- package/skills/contract-review-report/package.json +3 -2
- package/skills/customer-feedback-report/package.json +3 -2
- package/skills/deepresearch/CLAUDE.md +6 -39
- package/skills/deepresearch/README.md +15 -150
- package/skills/deepresearch/SKILL.md +23 -32
- package/skills/deepresearch/package.json +4 -37
- package/skills/domainpurchase/SKILL.md +14 -31
- package/skills/domainpurchase/package.json +3 -8
- package/skills/email-sequence/package.json +4 -7
- package/skills/generate-book-cover/package.json +5 -23
- package/skills/icon-pack/package.json +4 -22
- package/skills/image/README.md +13 -183
- package/skills/image/package.json +4 -22
- package/skills/invoice-reconciliation/package.json +3 -2
- package/skills/landing-page-pack/package.json +4 -7
- package/skills/logo-design/package.json +4 -2
- package/skills/managemcp/CLAUDE.md +9 -43
- package/skills/managemcp/README.md +12 -198
- package/skills/managemcp/package.json +2 -10
- package/skills/managemcp/tsconfig.json +1 -3
- package/skills/market-research-report/package.json +5 -4
- package/skills/meeting-pack/package.json +3 -2
- package/skills/migration-plan-pack/package.json +3 -2
- package/skills/music/package.json +4 -20
- package/skills/music-album/package.json +3 -2
- package/skills/one-page-website/package.json +3 -2
- package/skills/pdf-read/package.json +5 -23
- package/skills/pdf-to-dataset/package.json +5 -4
- package/skills/pdf-to-markdown/package.json +5 -4
- package/skills/performance-audit-report/package.json +3 -2
- package/skills/photo-album/package.json +4 -2
- package/skills/pitch-deck/package.json +5 -3
- package/skills/playlist-maker/package.json +4 -2
- package/skills/product-mockup/package.json +3 -2
- package/skills/proposal-pack/package.json +5 -4
- package/skills/read-pdf/package.json +4 -29
- package/skills/remove-background/package.json +5 -21
- package/skills/repo-onboarding-report/package.json +3 -2
- package/skills/sdk-generator/package.json +3 -2
- package/skills/security-audit-report/package.json +5 -4
- package/skills/seo-content-pack/package.json +5 -3
- package/skills/short-video-pack/package.json +3 -2
- package/skills/slide-deck-generator/package.json +3 -2
- package/skills/sms/README.md +18 -56
- package/skills/sms/package.json +1 -3
- package/skills/sms/tsconfig.json +1 -2
- package/skills/social-content-calendar/package.json +4 -7
- package/skills/test-suite-generator/package.json +5 -4
- package/skills/transcript/package.json +4 -23
- package/skills/video/package.json +4 -24
- package/skills/video-highlight-pack/package.json +3 -2
- package/skills/voiceover-jingle-pack/package.json +3 -2
- package/skills/webcrawling/CLAUDE.md +6 -17
- package/skills/webcrawling/README.md +13 -66
- package/skills/webcrawling/package.json +4 -32
- package/skills/browse/.env.example +0 -14
- package/skills/deepresearch/.env.example +0 -9
- package/skills/domainpurchase/.env.example +0 -7
- package/skills/domainpurchase/src/lib/api-client.ts +0 -571
- package/skills/domainpurchase/src/lib/config.ts +0 -209
- package/skills/domainpurchase/src/lib/installer.ts +0 -165
- package/skills/image/.env.example +0 -12
- package/skills/image/PROJECT_OVERVIEW.md +0 -216
- package/skills/image/QUICKSTART.md +0 -111
- package/skills/managemcp/.env.example +0 -16
- package/skills/managemcp/scripts/migrate.ts +0 -57
- package/skills/managemcp/scripts/seed.ts +0 -58
- package/skills/managemcp/src/db/index.ts +0 -37
- package/skills/managemcp/src/lib/api-client.ts +0 -108
- package/skills/managemcp/src/lib/config.ts +0 -34
- package/skills/managemcp/src/lib/installer.ts +0 -140
- package/skills/managemcp/src/lib/service-dir.ts +0 -119
- package/skills/sms/scripts/buy-number.ts +0 -63
- package/skills/sms/scripts/test-send.ts +0 -67
- package/skills/sms/src/server.ts +0 -351
- package/skills/sms/src/sse-server.ts +0 -279
- package/skills/transcript/.env.example +0 -10
- package/skills/webcrawling/.env.example +0 -2
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
2
|
-
import { join } from "path";
|
|
3
|
-
import { homedir } from "os";
|
|
4
|
-
|
|
5
|
-
export interface Config {
|
|
6
|
-
apiKey?: string;
|
|
7
|
-
apiSecret?: string;
|
|
8
|
-
customerId?: string;
|
|
9
|
-
shopperId?: string;
|
|
10
|
-
apiUrl: string;
|
|
11
|
-
// Remote server configuration
|
|
12
|
-
useRemoteServer?: boolean;
|
|
13
|
-
remoteServerUrl: string;
|
|
14
|
-
remoteApiKey?: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const CONFIG_DIR = join(homedir(), ".config", "service-domainpurchase");
|
|
18
|
-
export const CONFIG_FILE = join(CONFIG_DIR, "config.json");
|
|
19
|
-
const AWS_SECRET_NAME = process.env.AWS_SECRET_NAME || "your-org/your-tool/api/live";
|
|
20
|
-
|
|
21
|
-
const DEFAULT_CONFIG: Config = {
|
|
22
|
-
apiUrl: "https://api.godaddy.com",
|
|
23
|
-
remoteServerUrl: process.env.DOMAIN_REMOTE_SERVER_URL || "https://service.example.com/domainpurchase",
|
|
24
|
-
useRemoteServer: false,
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
// Cache for AWS secrets to avoid repeated API calls
|
|
28
|
-
let awsSecretsCache: Partial<Config> | null = null;
|
|
29
|
-
|
|
30
|
-
async function loadAwsSecrets(): Promise<Partial<Config>> {
|
|
31
|
-
if (awsSecretsCache) {
|
|
32
|
-
return awsSecretsCache;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
const { SecretsManagerClient, GetSecretValueCommand } = await import(
|
|
37
|
-
"@aws-sdk/client-secrets-manager"
|
|
38
|
-
);
|
|
39
|
-
const client = new SecretsManagerClient({ region: "us-east-1" });
|
|
40
|
-
const response = await client.send(
|
|
41
|
-
new GetSecretValueCommand({ SecretId: AWS_SECRET_NAME })
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
if (response.SecretString) {
|
|
45
|
-
const secret = JSON.parse(response.SecretString);
|
|
46
|
-
awsSecretsCache = {
|
|
47
|
-
apiKey: secret.api_key,
|
|
48
|
-
apiSecret: secret.api_secret,
|
|
49
|
-
customerId: secret.customer_id,
|
|
50
|
-
shopperId: secret.shopper_id,
|
|
51
|
-
};
|
|
52
|
-
return awsSecretsCache;
|
|
53
|
-
}
|
|
54
|
-
} catch {
|
|
55
|
-
// AWS secrets not available, fall back to other sources
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return {};
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export function loadConfig(): Config {
|
|
62
|
-
// First check environment variables
|
|
63
|
-
const envConfig: Partial<Config> = {
|
|
64
|
-
apiKey: process.env.DOMAIN_API_KEY,
|
|
65
|
-
apiSecret: process.env.DOMAIN_API_SECRET,
|
|
66
|
-
customerId: process.env.DOMAIN_CUSTOMER_ID,
|
|
67
|
-
apiUrl: process.env.DOMAIN_API_URL,
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
// Then load from config file
|
|
71
|
-
let fileConfig: Partial<Config> = {};
|
|
72
|
-
if (existsSync(CONFIG_FILE)) {
|
|
73
|
-
try {
|
|
74
|
-
fileConfig = JSON.parse(readFileSync(CONFIG_FILE, "utf-8"));
|
|
75
|
-
} catch {
|
|
76
|
-
// Ignore parse errors
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Merge with defaults (env vars take priority)
|
|
81
|
-
return {
|
|
82
|
-
...DEFAULT_CONFIG,
|
|
83
|
-
...fileConfig,
|
|
84
|
-
...Object.fromEntries(
|
|
85
|
-
Object.entries(envConfig).filter(([_, v]) => v !== undefined)
|
|
86
|
-
),
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export async function loadConfigAsync(): Promise<Config> {
|
|
91
|
-
// Load AWS secrets first (lowest priority)
|
|
92
|
-
const awsConfig = await loadAwsSecrets();
|
|
93
|
-
|
|
94
|
-
// Then check environment variables
|
|
95
|
-
const envConfig: Partial<Config> = {
|
|
96
|
-
apiKey: process.env.DOMAIN_API_KEY,
|
|
97
|
-
apiSecret: process.env.DOMAIN_API_SECRET,
|
|
98
|
-
customerId: process.env.DOMAIN_CUSTOMER_ID,
|
|
99
|
-
apiUrl: process.env.DOMAIN_API_URL,
|
|
100
|
-
useRemoteServer: process.env.DOMAIN_USE_REMOTE_SERVER === "true",
|
|
101
|
-
remoteServerUrl: process.env.DOMAIN_REMOTE_SERVER_URL,
|
|
102
|
-
remoteApiKey: process.env.DOMAIN_REMOTE_API_KEY,
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
// Then load from config file
|
|
106
|
-
let fileConfig: Partial<Config> = {};
|
|
107
|
-
if (existsSync(CONFIG_FILE)) {
|
|
108
|
-
try {
|
|
109
|
-
fileConfig = JSON.parse(readFileSync(CONFIG_FILE, "utf-8"));
|
|
110
|
-
} catch {
|
|
111
|
-
// Ignore parse errors
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Merge: AWS -> file -> env (env takes highest priority)
|
|
116
|
-
return {
|
|
117
|
-
...DEFAULT_CONFIG,
|
|
118
|
-
...awsConfig,
|
|
119
|
-
...fileConfig,
|
|
120
|
-
...Object.fromEntries(
|
|
121
|
-
Object.entries(envConfig).filter(([_, v]) => v !== undefined)
|
|
122
|
-
),
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
export function saveConfig(config: Partial<Config>): void {
|
|
127
|
-
if (!existsSync(CONFIG_DIR)) {
|
|
128
|
-
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const current = loadConfig();
|
|
132
|
-
const merged = { ...current, ...config };
|
|
133
|
-
writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2));
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
export function getApiKey(): string | undefined {
|
|
137
|
-
return loadConfig().apiKey;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export function getApiSecret(): string | undefined {
|
|
141
|
-
return loadConfig().apiSecret;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
export function getCustomerId(): string | undefined {
|
|
145
|
-
return loadConfig().customerId;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
export function getApiUrl(): string {
|
|
149
|
-
return loadConfig().apiUrl;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Async versions that can load from AWS Secrets Manager
|
|
153
|
-
export async function getApiKeyAsync(): Promise<string | undefined> {
|
|
154
|
-
return (await loadConfigAsync()).apiKey;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
export async function getApiSecretAsync(): Promise<string | undefined> {
|
|
158
|
-
return (await loadConfigAsync()).apiSecret;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export async function getCustomerIdAsync(): Promise<string | undefined> {
|
|
162
|
-
return (await loadConfigAsync()).customerId;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
export async function getShopperIdAsync(): Promise<string | undefined> {
|
|
166
|
-
return (await loadConfigAsync()).shopperId;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
export async function getApiUrlAsync(): Promise<string> {
|
|
170
|
-
return (await loadConfigAsync()).apiUrl;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Remote server configuration getters
|
|
174
|
-
export function useRemoteServer(): boolean {
|
|
175
|
-
return loadConfig().useRemoteServer || false;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
export function getRemoteServerUrl(): string {
|
|
179
|
-
return loadConfig().remoteServerUrl;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
export function getRemoteApiKey(): string | undefined {
|
|
183
|
-
return loadConfig().remoteApiKey;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
export async function getRemoteApiKeyAsync(): Promise<string | undefined> {
|
|
187
|
-
const config = await loadConfigAsync();
|
|
188
|
-
if (config.remoteApiKey) {
|
|
189
|
-
return config.remoteApiKey;
|
|
190
|
-
}
|
|
191
|
-
// Try to load from AWS Secrets Manager
|
|
192
|
-
try {
|
|
193
|
-
const { SecretsManagerClient, GetSecretValueCommand } = await import(
|
|
194
|
-
"@aws-sdk/client-secrets-manager"
|
|
195
|
-
);
|
|
196
|
-
const client = new SecretsManagerClient({ region: "us-east-1" });
|
|
197
|
-
const response = await client.send(
|
|
198
|
-
new GetSecretValueCommand({ SecretId: process.env.DOMAIN_API_KEY_SECRET_ID || "your-org/prod/your-service/api-key" })
|
|
199
|
-
);
|
|
200
|
-
return response.SecretString;
|
|
201
|
-
} catch {
|
|
202
|
-
return undefined;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// Initialize config from AWS on first run
|
|
207
|
-
export async function initConfig(): Promise<void> {
|
|
208
|
-
await loadConfigAsync();
|
|
209
|
-
}
|
|
@@ -1,165 +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 = "service-domainpurchase";
|
|
6
|
-
const SERVICE_DIR_NAME = `.${SERVICE_NAME}`;
|
|
7
|
-
|
|
8
|
-
export interface InstallOptions {
|
|
9
|
-
force?: boolean;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function getServiceDir(): string {
|
|
13
|
-
return join(homedir(), SERVICE_DIR_NAME);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function getLogFilePath(): string {
|
|
17
|
-
return join(getServiceDir(), `${SERVICE_NAME}.log`);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function getReadmePath(): string {
|
|
21
|
-
return join(getServiceDir(), "README.md");
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function isInstalled(): boolean {
|
|
25
|
-
return existsSync(getServiceDir());
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function ensureInstalled(): void {
|
|
29
|
-
if (!isInstalled()) {
|
|
30
|
-
install();
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function install(options: InstallOptions = {}): { success: boolean; path: string; message: string } {
|
|
35
|
-
const serviceDir = getServiceDir();
|
|
36
|
-
|
|
37
|
-
if (existsSync(serviceDir) && !options.force) {
|
|
38
|
-
return {
|
|
39
|
-
success: false,
|
|
40
|
-
path: serviceDir,
|
|
41
|
-
message: "Already installed. Use --force to reinstall.",
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
mkdirSync(serviceDir, { recursive: true });
|
|
46
|
-
|
|
47
|
-
const readmeContent = generateReadme();
|
|
48
|
-
writeFileSync(getReadmePath(), readmeContent);
|
|
49
|
-
|
|
50
|
-
const logHeader = `# ${SERVICE_NAME} log file
|
|
51
|
-
# Created: ${new Date().toISOString()}
|
|
52
|
-
# This file contains activity history and logs.
|
|
53
|
-
# -------------------------------------------------------
|
|
54
|
-
|
|
55
|
-
`;
|
|
56
|
-
writeFileSync(getLogFilePath(), logHeader);
|
|
57
|
-
|
|
58
|
-
return {
|
|
59
|
-
success: true,
|
|
60
|
-
path: serviceDir,
|
|
61
|
-
message: `Installed at ${serviceDir}`,
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export function uninstall(): { success: boolean; message: string } {
|
|
66
|
-
const serviceDir = getServiceDir();
|
|
67
|
-
|
|
68
|
-
if (!existsSync(serviceDir)) {
|
|
69
|
-
return {
|
|
70
|
-
success: false,
|
|
71
|
-
message: "Not installed.",
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const { rmSync } = require("fs");
|
|
76
|
-
rmSync(serviceDir, { recursive: true, force: true });
|
|
77
|
-
|
|
78
|
-
return {
|
|
79
|
-
success: true,
|
|
80
|
-
message: `Uninstalled from ${serviceDir}`,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function generateReadme(): string {
|
|
85
|
-
return `# .${SERVICE_NAME}
|
|
86
|
-
|
|
87
|
-
This directory contains local configuration and logs for \`${SERVICE_NAME}\`.
|
|
88
|
-
|
|
89
|
-
## Files
|
|
90
|
-
|
|
91
|
-
| Path | Description |
|
|
92
|
-
|------|-------------|
|
|
93
|
-
| \`${SERVICE_NAME}.log\` | Activity log |
|
|
94
|
-
| \`README.md\` | This file |
|
|
95
|
-
|
|
96
|
-
## What is ${SERVICE_NAME}?
|
|
97
|
-
|
|
98
|
-
\`${SERVICE_NAME}\` is a domain purchase service that provides:
|
|
99
|
-
|
|
100
|
-
- Domain registration automation
|
|
101
|
-
- Registrar integrations (GoDaddy, Namecheap, etc.)
|
|
102
|
-
- DNS configuration
|
|
103
|
-
- Domain transfer management
|
|
104
|
-
- Renewal tracking
|
|
105
|
-
|
|
106
|
-
## Usage
|
|
107
|
-
|
|
108
|
-
\`\`\`bash
|
|
109
|
-
# Purchase a domain
|
|
110
|
-
service-domainpurchase buy --domain "example.com"
|
|
111
|
-
|
|
112
|
-
# List purchased domains
|
|
113
|
-
service-domainpurchase list
|
|
114
|
-
|
|
115
|
-
# Check purchase status
|
|
116
|
-
service-domainpurchase status --domain "example.com"
|
|
117
|
-
|
|
118
|
-
# Start the server
|
|
119
|
-
service-domainpurchase server
|
|
120
|
-
\`\`\`
|
|
121
|
-
|
|
122
|
-
## Log File
|
|
123
|
-
|
|
124
|
-
The \`${SERVICE_NAME}.log\` file contains:
|
|
125
|
-
- Purchase transactions
|
|
126
|
-
- Registration status
|
|
127
|
-
- DNS changes
|
|
128
|
-
- API activity
|
|
129
|
-
|
|
130
|
-
## More Information
|
|
131
|
-
|
|
132
|
-
For full documentation, run:
|
|
133
|
-
|
|
134
|
-
\`\`\`bash
|
|
135
|
-
service-domainpurchase --help
|
|
136
|
-
\`\`\`
|
|
137
|
-
`;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export type LogLevel = "debug" | "info" | "warn" | "error";
|
|
141
|
-
|
|
142
|
-
export function logToFile(message: string, level: LogLevel = "info"): void {
|
|
143
|
-
ensureInstalled();
|
|
144
|
-
|
|
145
|
-
const timestamp = new Date().toISOString();
|
|
146
|
-
const logLine = `[${timestamp}] [${level.toUpperCase()}] ${message}\n`;
|
|
147
|
-
|
|
148
|
-
try {
|
|
149
|
-
appendFileSync(getLogFilePath(), logLine);
|
|
150
|
-
} catch {
|
|
151
|
-
// Silently fail
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
export function logInfo(message: string): void {
|
|
156
|
-
logToFile(message, "info");
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
export function logError(message: string): void {
|
|
160
|
-
logToFile(message, "error");
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
export function logWarn(message: string): void {
|
|
164
|
-
logToFile(message, "warn");
|
|
165
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
# OpenAI API Key
|
|
2
|
-
# Get your key from: https://platform.openai.com/api-keys
|
|
3
|
-
OPENAI_API_KEY=sk-...
|
|
4
|
-
|
|
5
|
-
# Google Gemini API Key and Project ID
|
|
6
|
-
# Get your key from: https://aistudio.google.com/apikey
|
|
7
|
-
GEMINI_API_KEY=...
|
|
8
|
-
GOOGLE_PROJECT_ID=your-project-id
|
|
9
|
-
|
|
10
|
-
# xAI API Key
|
|
11
|
-
# Get your key from: https://x.ai/api
|
|
12
|
-
XAI_API_KEY=...
|
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
# Image Generation Skill - Project Overview
|
|
2
|
-
|
|
3
|
-
## Summary
|
|
4
|
-
|
|
5
|
-
A complete Claude Code skill for AI-powered image generation supporting three major providers: OpenAI DALL-E 3, Google Imagen 3, and xAI Aurora.
|
|
6
|
-
|
|
7
|
-
## Key Statistics
|
|
8
|
-
|
|
9
|
-
- **Total Lines of Code**: ~993 lines
|
|
10
|
-
- **TypeScript Files**: 5 (457 lines)
|
|
11
|
-
- **Providers**: 3 (OpenAI, Google, xAI)
|
|
12
|
-
- **Documentation Files**: 5
|
|
13
|
-
- **Example Scripts**: 3
|
|
14
|
-
- **Dependencies**: Zero (uses native Bun APIs)
|
|
15
|
-
|
|
16
|
-
## File Structure
|
|
17
|
-
|
|
18
|
-
```
|
|
19
|
-
image/
|
|
20
|
-
├── SKILL.md [56 lines] - Skill metadata with YAML frontmatter
|
|
21
|
-
├── README.md [194 lines] - Comprehensive documentation
|
|
22
|
-
├── QUICKSTART.md [111 lines] - Quick start guide
|
|
23
|
-
├── PROJECT_OVERVIEW.md - This file
|
|
24
|
-
├── package.json [29 lines] - Bun package configuration
|
|
25
|
-
├── tsconfig.json [17 lines] - TypeScript configuration
|
|
26
|
-
├── .env.example [12 lines] - Environment variable template
|
|
27
|
-
├── .gitignore [12 lines] - Git ignore patterns
|
|
28
|
-
├── examples/
|
|
29
|
-
│ ├── openai-examples.sh [35 lines] - OpenAI usage examples
|
|
30
|
-
│ ├── google-examples.sh [37 lines] - Google usage examples
|
|
31
|
-
│ └── xai-examples.sh [33 lines] - xAI usage examples
|
|
32
|
-
└── src/
|
|
33
|
-
├── index.ts [189 lines] - Main CLI entry point
|
|
34
|
-
├── types.ts [37 lines] - TypeScript type definitions
|
|
35
|
-
└── providers/
|
|
36
|
-
├── openai.ts [80 lines] - OpenAI DALL-E provider
|
|
37
|
-
├── google.ts [78 lines] - Google Imagen provider
|
|
38
|
-
└── xai.ts [73 lines] - xAI Aurora provider
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Features Implemented
|
|
42
|
-
|
|
43
|
-
### Core Functionality
|
|
44
|
-
- ✅ Multi-provider image generation (OpenAI, Google, xAI)
|
|
45
|
-
- ✅ Clean CLI interface with argument parsing
|
|
46
|
-
- ✅ Automatic image download and file saving
|
|
47
|
-
- ✅ Support for custom models and sizes
|
|
48
|
-
- ✅ Environment variable configuration
|
|
49
|
-
- ✅ Comprehensive error handling
|
|
50
|
-
|
|
51
|
-
### OpenAI Provider
|
|
52
|
-
- ✅ DALL-E 3 support
|
|
53
|
-
- ✅ GPT-4o image generation (gpt-image-1)
|
|
54
|
-
- ✅ Three size options: 1024x1024, 1792x1024, 1024x1792
|
|
55
|
-
- ✅ Revised prompt display
|
|
56
|
-
- ✅ URL-based image retrieval
|
|
57
|
-
|
|
58
|
-
### Google Imagen Provider
|
|
59
|
-
- ✅ Imagen 3.0 support via Vertex AI REST API
|
|
60
|
-
- ✅ Five aspect ratio options: 1:1, 3:4, 4:3, 9:16, 16:9
|
|
61
|
-
- ✅ Base64 image decoding
|
|
62
|
-
- ✅ Project ID configuration
|
|
63
|
-
|
|
64
|
-
### xAI Aurora Provider
|
|
65
|
-
- ✅ Aurora model support
|
|
66
|
-
- ✅ OpenAI-compatible API format
|
|
67
|
-
- ✅ Support for both URL and base64 responses
|
|
68
|
-
- ✅ Flexible size configuration
|
|
69
|
-
|
|
70
|
-
### Developer Experience
|
|
71
|
-
- ✅ TypeScript with strict type checking
|
|
72
|
-
- ✅ Native Bun runtime (no external dependencies)
|
|
73
|
-
- ✅ Modular provider architecture
|
|
74
|
-
- ✅ Clean separation of concerns
|
|
75
|
-
- ✅ Comprehensive inline documentation
|
|
76
|
-
- ✅ Example scripts for all providers
|
|
77
|
-
|
|
78
|
-
### Error Handling
|
|
79
|
-
- ✅ API key validation
|
|
80
|
-
- ✅ Invalid provider detection
|
|
81
|
-
- ✅ Missing argument detection
|
|
82
|
-
- ✅ HTTP error handling
|
|
83
|
-
- ✅ Network failure handling
|
|
84
|
-
- ✅ Size validation (provider-specific)
|
|
85
|
-
|
|
86
|
-
## Usage Examples
|
|
87
|
-
|
|
88
|
-
### Basic Usage
|
|
89
|
-
```bash
|
|
90
|
-
bun run src/index.ts generate --provider openai --prompt "a cat" --output ./cat.png
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
### With Custom Options
|
|
94
|
-
```bash
|
|
95
|
-
bun run src/index.ts generate \
|
|
96
|
-
--provider openai \
|
|
97
|
-
--prompt "a futuristic city" \
|
|
98
|
-
--output ./city.png \
|
|
99
|
-
--size 1792x1024 \
|
|
100
|
-
--model dall-e-3
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### Short Flags
|
|
104
|
-
```bash
|
|
105
|
-
bun run src/index.ts generate -p google --prompt "a dog" -o ./dog.png -s 16:9
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
## API Integration Details
|
|
109
|
-
|
|
110
|
-
### OpenAI DALL-E 3
|
|
111
|
-
- **Endpoint**: `https://api.openai.com/v1/images/generations`
|
|
112
|
-
- **Authentication**: Bearer token via `Authorization` header
|
|
113
|
-
- **Request Format**: JSON with model, prompt, size, response_format
|
|
114
|
-
- **Response Format**: URL or base64
|
|
115
|
-
- **Environment Variable**: `OPENAI_API_KEY`
|
|
116
|
-
|
|
117
|
-
### Google Imagen 3
|
|
118
|
-
- **Endpoint**: `https://{location}-aiplatform.googleapis.com/v1/projects/{projectId}/locations/{location}/publishers/google/models/{model}:predict`
|
|
119
|
-
- **Authentication**: Bearer token via `Authorization` header
|
|
120
|
-
- **Request Format**: JSON with instances and parameters
|
|
121
|
-
- **Response Format**: Base64 encoded image
|
|
122
|
-
- **Environment Variables**: `GOOGLE_API_KEY`, `GOOGLE_PROJECT_ID`
|
|
123
|
-
|
|
124
|
-
### xAI Aurora
|
|
125
|
-
- **Endpoint**: `https://api.x.ai/v1/images/generations`
|
|
126
|
-
- **Authentication**: Bearer token via `Authorization` header
|
|
127
|
-
- **Request Format**: OpenAI-compatible JSON
|
|
128
|
-
- **Response Format**: URL or base64
|
|
129
|
-
- **Environment Variable**: `XAI_API_KEY`
|
|
130
|
-
|
|
131
|
-
## Architecture Patterns
|
|
132
|
-
|
|
133
|
-
### Provider Interface
|
|
134
|
-
All providers implement the `ImageProvider` interface:
|
|
135
|
-
```typescript
|
|
136
|
-
interface ImageProvider {
|
|
137
|
-
generate(prompt: string, options?: {
|
|
138
|
-
model?: string;
|
|
139
|
-
size?: string;
|
|
140
|
-
}): Promise<Buffer>;
|
|
141
|
-
}
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
### Type Safety
|
|
145
|
-
- Strong typing throughout the codebase
|
|
146
|
-
- Provider-specific response interfaces
|
|
147
|
-
- Validated command-line options
|
|
148
|
-
- Type-safe error handling
|
|
149
|
-
|
|
150
|
-
### Modularity
|
|
151
|
-
- Each provider in separate file
|
|
152
|
-
- Shared types in dedicated module
|
|
153
|
-
- Clean CLI entry point
|
|
154
|
-
- No circular dependencies
|
|
155
|
-
|
|
156
|
-
## Testing Performed
|
|
157
|
-
|
|
158
|
-
✅ Help command display
|
|
159
|
-
✅ Invalid provider detection
|
|
160
|
-
✅ Missing argument validation
|
|
161
|
-
✅ Successful image generation (OpenAI)
|
|
162
|
-
✅ File output and directory creation
|
|
163
|
-
✅ TypeScript compilation
|
|
164
|
-
✅ Bun runtime compatibility
|
|
165
|
-
|
|
166
|
-
## Future Enhancement Possibilities
|
|
167
|
-
|
|
168
|
-
- Image editing capabilities (inpainting, outpainting)
|
|
169
|
-
- Batch generation support
|
|
170
|
-
- Image variation generation
|
|
171
|
-
- Progress bars for long-running operations
|
|
172
|
-
- Local image storage caching
|
|
173
|
-
- Configuration file support (JSON/YAML)
|
|
174
|
-
- Additional providers (Stability AI, Midjourney API)
|
|
175
|
-
- Image quality/resolution options
|
|
176
|
-
- Rate limiting and retry logic
|
|
177
|
-
- Cost estimation before generation
|
|
178
|
-
|
|
179
|
-
## Technical Highlights
|
|
180
|
-
|
|
181
|
-
1. **Zero Dependencies**: Uses only native Bun APIs (fetch, fs/promises)
|
|
182
|
-
2. **Type-Safe**: Comprehensive TypeScript types for all operations
|
|
183
|
-
3. **Clean Code**: Well-organized, readable, maintainable
|
|
184
|
-
4. **Error Resilient**: Handles all common error scenarios gracefully
|
|
185
|
-
5. **Extensible**: Easy to add new providers following existing pattern
|
|
186
|
-
6. **Production Ready**: Includes all necessary error handling and validation
|
|
187
|
-
|
|
188
|
-
## Quick Reference
|
|
189
|
-
|
|
190
|
-
| Provider | Model | Default Size | Custom Sizes |
|
|
191
|
-
|----------|-------|-------------|--------------|
|
|
192
|
-
| OpenAI | dall-e-3 | 1024x1024 | 1792x1024, 1024x1792 |
|
|
193
|
-
| Google | imagen-3.0-generate-001 | 1:1 | 3:4, 4:3, 9:16, 16:9 |
|
|
194
|
-
| xAI | aurora | Default | Provider-specific |
|
|
195
|
-
|
|
196
|
-
## Environment Setup
|
|
197
|
-
|
|
198
|
-
```bash
|
|
199
|
-
# OpenAI
|
|
200
|
-
export OPENAI_API_KEY="sk-..."
|
|
201
|
-
|
|
202
|
-
# Google
|
|
203
|
-
export GOOGLE_API_KEY="..."
|
|
204
|
-
export GOOGLE_PROJECT_ID="your-project"
|
|
205
|
-
|
|
206
|
-
# xAI
|
|
207
|
-
export XAI_API_KEY="..."
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
## License
|
|
211
|
-
|
|
212
|
-
MIT
|
|
213
|
-
|
|
214
|
-
---
|
|
215
|
-
|
|
216
|
-
Built with Bun, TypeScript, and Claude Code
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
# Quick Start Guide
|
|
2
|
-
|
|
3
|
-
Get started with the Image Generation Skill in 3 easy steps.
|
|
4
|
-
|
|
5
|
-
## Step 1: Set up API Keys
|
|
6
|
-
|
|
7
|
-
Copy the example environment file and add your API keys:
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
cp .env.example .env
|
|
11
|
-
# Edit .env with your favorite editor and add your API keys
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
Or export them directly:
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
export OPENAI_API_KEY="sk-..."
|
|
18
|
-
export GEMINI_API_KEY="..."
|
|
19
|
-
export GOOGLE_PROJECT_ID="your-project-id"
|
|
20
|
-
export XAI_API_KEY="..."
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Step 2: Generate Your First Image
|
|
24
|
-
|
|
25
|
-
Choose a provider and run:
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
# OpenAI
|
|
29
|
-
bun run src/index.ts generate \
|
|
30
|
-
--provider openai \
|
|
31
|
-
--prompt "a beautiful sunset over mountains" \
|
|
32
|
-
--output ./my-first-image.png
|
|
33
|
-
|
|
34
|
-
# Google
|
|
35
|
-
bun run src/index.ts generate \
|
|
36
|
-
--provider google \
|
|
37
|
-
--prompt "a beautiful sunset over mountains" \
|
|
38
|
-
--output ./my-first-image.png
|
|
39
|
-
|
|
40
|
-
# xAI
|
|
41
|
-
bun run src/index.ts generate \
|
|
42
|
-
--provider xai \
|
|
43
|
-
--prompt "a beautiful sunset over mountains" \
|
|
44
|
-
--output ./my-first-image.png
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## Step 3: Explore Advanced Options
|
|
48
|
-
|
|
49
|
-
### Custom Sizes
|
|
50
|
-
|
|
51
|
-
OpenAI sizes:
|
|
52
|
-
```bash
|
|
53
|
-
bun run src/index.ts generate \
|
|
54
|
-
-p openai \
|
|
55
|
-
--prompt "wide landscape" \
|
|
56
|
-
-o ./landscape.png \
|
|
57
|
-
--size 1792x1024
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
Google aspect ratios:
|
|
61
|
-
```bash
|
|
62
|
-
bun run src/index.ts generate \
|
|
63
|
-
-p google \
|
|
64
|
-
--prompt "portrait photo" \
|
|
65
|
-
-o ./portrait.png \
|
|
66
|
-
--size 3:4
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
### Run Example Scripts
|
|
70
|
-
|
|
71
|
-
```bash
|
|
72
|
-
cd examples
|
|
73
|
-
./openai-examples.sh
|
|
74
|
-
./google-examples.sh
|
|
75
|
-
./xai-examples.sh
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
## Tips
|
|
79
|
-
|
|
80
|
-
1. **Prompt Engineering**: Be specific and descriptive in your prompts
|
|
81
|
-
2. **Size Selection**: Choose the right size for your use case
|
|
82
|
-
- Square (1024x1024, 1:1): Social media posts, avatars
|
|
83
|
-
- Landscape (1792x1024, 16:9): Banners, headers
|
|
84
|
-
- Portrait (1024x1792, 9:16): Mobile wallpapers, stories
|
|
85
|
-
3. **Provider Selection**:
|
|
86
|
-
- OpenAI: Great for detailed, creative images
|
|
87
|
-
- Google: Best for photorealistic results
|
|
88
|
-
- xAI: Excellent for artistic interpretation
|
|
89
|
-
|
|
90
|
-
## Troubleshooting
|
|
91
|
-
|
|
92
|
-
### "API key required" error
|
|
93
|
-
Make sure your environment variables are set correctly.
|
|
94
|
-
|
|
95
|
-
### "Invalid size" error
|
|
96
|
-
Check the provider-specific size options in the help:
|
|
97
|
-
```bash
|
|
98
|
-
bun run src/index.ts --help
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
### Image quality issues
|
|
102
|
-
Try being more specific in your prompt or experiment with different providers.
|
|
103
|
-
|
|
104
|
-
## Next Steps
|
|
105
|
-
|
|
106
|
-
- Read the full [README.md](README.md) for detailed documentation
|
|
107
|
-
- Check [SKILL.md](SKILL.md) for skill metadata
|
|
108
|
-
- Explore the [examples/](examples/) directory for more use cases
|
|
109
|
-
- Review [src/](src/) for implementation details
|
|
110
|
-
|
|
111
|
-
Happy image generation!
|