@hasna/skills 0.1.19 → 0.1.20
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 +136 -18
- package/bin/index.js +33877 -33924
- package/bin/mcp.js +196 -95
- package/dist/cli/commands/completion.d.ts +5 -0
- package/dist/cli/commands/create-sync-config.d.ts +5 -0
- package/dist/cli/commands/diagnostic.d.ts +5 -0
- package/dist/cli/commands/init.d.ts +5 -0
- package/dist/cli/commands/install.d.ts +5 -0
- package/dist/cli/commands/introspect.d.ts +5 -0
- package/dist/cli/commands/list.d.ts +5 -0
- package/dist/cli/commands/runtime.d.ts +5 -0
- package/dist/cli/commands/schedule.d.ts +5 -0
- package/dist/index.js +197 -97
- package/dist/lib/config.d.ts +1 -1
- package/dist/lib/registry.d.ts +1 -11
- package/dist/lib/scheduler.d.ts +1 -1
- package/dist/lib/scheduler.test.d.ts +4 -0
- package/dist/lib/search.d.ts +17 -0
- package/package.json +1 -1
- package/skills/skill-commitpush/SKILL.md +57 -0
- package/skills/skill-commitpush/package.json +34 -0
- package/skills/skill-commitpush/src/index.ts +34 -0
- package/skills/skill-commitpush/tsconfig.json +17 -0
- package/skills/skill-commitpushpr/SKILL.md +55 -0
- package/skills/skill-commitpushpr/package.json +34 -0
- package/skills/skill-commitpushpr/src/index.ts +34 -0
- package/skills/skill-commitpushpr/tsconfig.json +17 -0
- package/skills/skill-monitor/SKILL.md +69 -0
- package/skills/skill-monitor/package.json +34 -0
- package/skills/skill-monitor/src/index.ts +34 -0
- package/skills/skill-monitor/tsconfig.json +17 -0
- package/skills/skill-read-csv/SKILL.md +62 -0
- package/skills/skill-read-csv/package.json +38 -0
- package/skills/skill-read-csv/src/index.ts +331 -0
- package/skills/skill-read-csv/tsconfig.json +17 -0
- package/skills/skill-read-excel/SKILL.md +64 -0
- package/skills/skill-read-excel/package.json +37 -0
- package/skills/skill-read-excel/src/index.ts +253 -0
- package/skills/skill-read-excel/tsconfig.json +17 -0
- package/skills/skill-read-image/SKILL.md +47 -0
- package/skills/skill-read-image/package.json +34 -0
- package/skills/skill-read-image/src/index.ts +264 -0
- package/skills/skill-read-image/tsconfig.json +17 -0
- package/skills/skill-read-pdf/SKILL.md +52 -0
- package/skills/skill-read-pdf/package.json +37 -0
- package/skills/skill-read-pdf/src/index.ts +376 -0
- package/skills/skill-read-pdf/tsconfig.json +17 -0
- package/skills/skill-tmux-session/SKILL.md +109 -0
- package/skills/skill-tmux-session/package.json +34 -0
- package/skills/skill-tmux-session/src/index.ts +34 -0
- package/skills/skill-tmux-session/tsconfig.json +17 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skill-read-excel
|
|
3
|
+
description: Parse XLS and XLSX workbooks into structured JSON with sheet metadata, named ranges, and formatted cell snapshots.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Read Excel
|
|
7
|
+
|
|
8
|
+
Parse Excel workbooks from disk and return structured JSON for one or more sheets.
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- Supports `.xls` and `.xlsx`
|
|
13
|
+
- Reads multiple sheets in one run
|
|
14
|
+
- Returns workbook metadata, named ranges, and per-sheet rows
|
|
15
|
+
- Preserves sheet order and includes formatted cell snapshots
|
|
16
|
+
- Allows limiting rows for large workbooks
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Parse all sheets
|
|
22
|
+
skill-read-excel --input ./forecast.xlsx
|
|
23
|
+
|
|
24
|
+
# Restrict to specific sheets
|
|
25
|
+
skill-read-excel --input ./ops.xls --sheets Summary,Costs
|
|
26
|
+
|
|
27
|
+
# Limit output and save it
|
|
28
|
+
skill-read-excel --input ./audit.xlsx --limit 100 --output ./audit.json
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Options
|
|
32
|
+
|
|
33
|
+
| Option | Description | Default |
|
|
34
|
+
|--------|-------------|---------|
|
|
35
|
+
| `-i, --input <path>` | Excel workbook to parse | required |
|
|
36
|
+
| `-s, --sheets <list>` | Comma-separated sheet names to include | all sheets |
|
|
37
|
+
| `-l, --limit <n>` | Limit rows returned per sheet | unlimited |
|
|
38
|
+
| `-o, --output <path>` | Save JSON result to a file | stdout |
|
|
39
|
+
| `--help` | Show usage | |
|
|
40
|
+
| `--version` | Show version | |
|
|
41
|
+
|
|
42
|
+
## Output Shape
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"input": "/absolute/path/to/workbook.xlsx",
|
|
47
|
+
"workbook": {
|
|
48
|
+
"sheetNames": ["Summary", "Data"],
|
|
49
|
+
"namedRanges": []
|
|
50
|
+
},
|
|
51
|
+
"sheets": [
|
|
52
|
+
{
|
|
53
|
+
"name": "Summary",
|
|
54
|
+
"index": 0,
|
|
55
|
+
"rowCount": 12,
|
|
56
|
+
"columnCount": 4,
|
|
57
|
+
"columns": ["month", "revenue", "cost"],
|
|
58
|
+
"rows": [
|
|
59
|
+
{ "month": "Jan", "revenue": 1000, "cost": 600 }
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
```
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hasnaxyz/skill-read-excel",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Parse XLS and XLSX workbooks into structured JSON",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"skill-read-excel": "src/index.ts"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"src",
|
|
12
|
+
"SKILL.md",
|
|
13
|
+
"tsconfig.json"
|
|
14
|
+
],
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "restricted"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"excel",
|
|
20
|
+
"xlsx",
|
|
21
|
+
"xls",
|
|
22
|
+
"spreadsheet",
|
|
23
|
+
"skill"
|
|
24
|
+
],
|
|
25
|
+
"license": "Apache-2.0",
|
|
26
|
+
"scripts": {
|
|
27
|
+
"start": "bun run src/index.ts",
|
|
28
|
+
"typecheck": "tsc --noEmit"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"xlsx": "^0.18.5"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/bun": "latest",
|
|
35
|
+
"typescript": "^5.7.0"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
4
|
+
import { dirname, resolve } from "path";
|
|
5
|
+
import * as XLSX from "xlsx";
|
|
6
|
+
|
|
7
|
+
const VERSION = "0.1.0";
|
|
8
|
+
|
|
9
|
+
interface CliOptions {
|
|
10
|
+
input?: string;
|
|
11
|
+
sheets?: string[];
|
|
12
|
+
limit?: number;
|
|
13
|
+
output?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface NamedRange {
|
|
17
|
+
name: string;
|
|
18
|
+
ref: string;
|
|
19
|
+
sheet?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface SheetResult {
|
|
23
|
+
name: string;
|
|
24
|
+
index: number;
|
|
25
|
+
range: string | null;
|
|
26
|
+
rowCount: number;
|
|
27
|
+
columnCount: number;
|
|
28
|
+
columns: string[];
|
|
29
|
+
rows: Array<Record<string, unknown>>;
|
|
30
|
+
formattedCells: Array<{ cell: string; raw?: unknown; formatted?: string; format?: string }>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface WorkbookResult {
|
|
34
|
+
input: string;
|
|
35
|
+
workbook: {
|
|
36
|
+
sheetNames: string[];
|
|
37
|
+
namedRanges: NamedRange[];
|
|
38
|
+
};
|
|
39
|
+
sheets: SheetResult[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function printHelp(): void {
|
|
43
|
+
console.log(`skill-read-excel v${VERSION}
|
|
44
|
+
|
|
45
|
+
USAGE:
|
|
46
|
+
skill-read-excel --input <path> [options]
|
|
47
|
+
|
|
48
|
+
OPTIONS:
|
|
49
|
+
-i, --input <path> Excel workbook to parse (.xls or .xlsx)
|
|
50
|
+
-s, --sheets <list> Comma-separated sheet names to include
|
|
51
|
+
-l, --limit <n> Limit rows returned per sheet
|
|
52
|
+
-o, --output <path> Save JSON result to a file
|
|
53
|
+
--help Show this help message
|
|
54
|
+
--version Show the current version
|
|
55
|
+
`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function parseArgs(argv: string[]): CliOptions {
|
|
59
|
+
const options: CliOptions = {};
|
|
60
|
+
|
|
61
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
62
|
+
const arg = argv[i];
|
|
63
|
+
switch (arg) {
|
|
64
|
+
case "--help":
|
|
65
|
+
case "-h":
|
|
66
|
+
printHelp();
|
|
67
|
+
process.exit(0);
|
|
68
|
+
case "--version":
|
|
69
|
+
case "-v":
|
|
70
|
+
console.log(VERSION);
|
|
71
|
+
process.exit(0);
|
|
72
|
+
case "--input":
|
|
73
|
+
case "-i":
|
|
74
|
+
options.input = argv[++i];
|
|
75
|
+
break;
|
|
76
|
+
case "--sheets":
|
|
77
|
+
case "-s":
|
|
78
|
+
options.sheets = (argv[++i] ?? "")
|
|
79
|
+
.split(",")
|
|
80
|
+
.map((value) => value.trim())
|
|
81
|
+
.filter(Boolean);
|
|
82
|
+
break;
|
|
83
|
+
case "--limit":
|
|
84
|
+
case "-l": {
|
|
85
|
+
const value = Number.parseInt(argv[++i] ?? "", 10);
|
|
86
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
87
|
+
throw new Error(`Invalid --limit value: ${argv[i]}`);
|
|
88
|
+
}
|
|
89
|
+
options.limit = value;
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
case "--output":
|
|
93
|
+
case "-o":
|
|
94
|
+
options.output = argv[++i];
|
|
95
|
+
break;
|
|
96
|
+
default:
|
|
97
|
+
if (arg.startsWith("-")) {
|
|
98
|
+
throw new Error(`Unknown option: ${arg}`);
|
|
99
|
+
}
|
|
100
|
+
if (!options.input) {
|
|
101
|
+
options.input = arg;
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
throw new Error(`Unexpected argument: ${arg}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (!options.input) {
|
|
109
|
+
throw new Error("Missing required --input <path> argument");
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return options;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function normalizeColumnName(value: unknown, index: number, seen: Set<string>): string {
|
|
116
|
+
const text = String(value ?? "")
|
|
117
|
+
.trim()
|
|
118
|
+
.toLowerCase()
|
|
119
|
+
.replace(/[^a-z0-9]+/g, "_")
|
|
120
|
+
.replace(/^_+|_+$/g, "") || `column_${index + 1}`;
|
|
121
|
+
|
|
122
|
+
let next = text;
|
|
123
|
+
let suffix = 2;
|
|
124
|
+
while (seen.has(next)) {
|
|
125
|
+
next = `${text}_${suffix}`;
|
|
126
|
+
suffix += 1;
|
|
127
|
+
}
|
|
128
|
+
seen.add(next);
|
|
129
|
+
return next;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function inferHeader(rows: unknown[][]): boolean {
|
|
133
|
+
if (rows.length < 2) {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
const first = rows[0];
|
|
137
|
+
const second = rows[1];
|
|
138
|
+
const unique = new Set(first.map((value) => String(value ?? "").trim().toLowerCase()).filter(Boolean));
|
|
139
|
+
const mostlyText = first.filter((value) => String(value ?? "").trim() !== "" && Number.isNaN(Number(value))).length >= Math.ceil(first.length / 2);
|
|
140
|
+
const secondHasNumeric = second.some((value) => String(value ?? "").trim() !== "" && !Number.isNaN(Number(value)));
|
|
141
|
+
return unique.size === first.length && mostlyText && secondHasNumeric;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function collectFormattedCells(sheet: XLSX.WorkSheet, maxCells = 50): Array<{ cell: string; raw?: unknown; formatted?: string; format?: string }> {
|
|
145
|
+
const result: Array<{ cell: string; raw?: unknown; formatted?: string; format?: string }> = [];
|
|
146
|
+
const entries = Object.entries(sheet).filter(([key]) => !key.startsWith("!"));
|
|
147
|
+
|
|
148
|
+
for (const [cell, value] of entries) {
|
|
149
|
+
if (result.length >= maxCells) {
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
const cellValue = value as XLSX.CellObject;
|
|
153
|
+
if (cellValue.z || cellValue.w) {
|
|
154
|
+
result.push({
|
|
155
|
+
cell,
|
|
156
|
+
raw: cellValue.v,
|
|
157
|
+
formatted: cellValue.w,
|
|
158
|
+
format: typeof cellValue.z === "string" ? cellValue.z : undefined,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function parseSheet(name: string, index: number, sheet: XLSX.WorkSheet, limit?: number): SheetResult {
|
|
167
|
+
const rows = XLSX.utils.sheet_to_json(sheet, {
|
|
168
|
+
header: 1,
|
|
169
|
+
defval: null,
|
|
170
|
+
raw: false,
|
|
171
|
+
blankrows: false,
|
|
172
|
+
}) as unknown[][];
|
|
173
|
+
|
|
174
|
+
const trimmedRows = limit ? rows.slice(0, limit + 1) : rows;
|
|
175
|
+
const hasHeader = inferHeader(trimmedRows);
|
|
176
|
+
const headerRow = trimmedRows[0] ?? [];
|
|
177
|
+
const seen = new Set<string>();
|
|
178
|
+
const columns = (hasHeader ? headerRow : headerRow.map((_, colIndex) => `column_${colIndex + 1}`))
|
|
179
|
+
.map((value, colIndex) => normalizeColumnName(value, colIndex, seen));
|
|
180
|
+
|
|
181
|
+
const dataRows = hasHeader ? trimmedRows.slice(1) : trimmedRows;
|
|
182
|
+
const normalizedRows = dataRows.map((row) =>
|
|
183
|
+
columns.reduce<Record<string, unknown>>((record, column, colIndex) => {
|
|
184
|
+
record[column] = row[colIndex] ?? null;
|
|
185
|
+
return record;
|
|
186
|
+
}, {})
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
return {
|
|
190
|
+
name,
|
|
191
|
+
index,
|
|
192
|
+
range: sheet["!ref"] ?? null,
|
|
193
|
+
rowCount: normalizedRows.length,
|
|
194
|
+
columnCount: columns.length,
|
|
195
|
+
columns,
|
|
196
|
+
rows: normalizedRows,
|
|
197
|
+
formattedCells: collectFormattedCells(sheet),
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function collectNamedRanges(workbook: XLSX.WorkBook): NamedRange[] {
|
|
202
|
+
const names = workbook.Workbook?.Names ?? [];
|
|
203
|
+
return names.map((entry) => ({
|
|
204
|
+
name: entry.Name ?? "",
|
|
205
|
+
ref: entry.Ref ?? "",
|
|
206
|
+
sheet: entry.Sheet != null ? workbook.SheetNames[entry.Sheet] : undefined,
|
|
207
|
+
}));
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
async function writeJson(path: string, payload: WorkbookResult): Promise<void> {
|
|
211
|
+
await mkdir(dirname(path), { recursive: true });
|
|
212
|
+
await writeFile(path, `${JSON.stringify(payload, null, 2)}\n`, "utf8");
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async function main(): Promise<void> {
|
|
216
|
+
const options = parseArgs(process.argv.slice(2));
|
|
217
|
+
const inputPath = resolve(options.input!);
|
|
218
|
+
const workbook = XLSX.readFile(inputPath, {
|
|
219
|
+
cellDates: true,
|
|
220
|
+
cellNF: true,
|
|
221
|
+
cellStyles: true,
|
|
222
|
+
dense: false,
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
const selectedSheetNames = options.sheets?.length
|
|
226
|
+
? workbook.SheetNames.filter((name) => options.sheets!.includes(name))
|
|
227
|
+
: workbook.SheetNames;
|
|
228
|
+
|
|
229
|
+
if (selectedSheetNames.length === 0) {
|
|
230
|
+
throw new Error("No matching sheets found");
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const result: WorkbookResult = {
|
|
234
|
+
input: inputPath,
|
|
235
|
+
workbook: {
|
|
236
|
+
sheetNames: workbook.SheetNames,
|
|
237
|
+
namedRanges: collectNamedRanges(workbook),
|
|
238
|
+
},
|
|
239
|
+
sheets: selectedSheetNames.map((name) => parseSheet(name, workbook.SheetNames.indexOf(name), workbook.Sheets[name], options.limit)),
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
if (options.output) {
|
|
243
|
+
await writeJson(resolve(options.output), result);
|
|
244
|
+
} else {
|
|
245
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
main().catch((error) => {
|
|
250
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
251
|
+
process.stderr.write(`skill-read-excel: ${message}\n`);
|
|
252
|
+
process.exit(1);
|
|
253
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"outDir": "./dist",
|
|
6
|
+
"rootDir": "./src",
|
|
7
|
+
"resolveJsonModule": true,
|
|
8
|
+
"noEmit": true
|
|
9
|
+
},
|
|
10
|
+
"include": [
|
|
11
|
+
"src/**/*"
|
|
12
|
+
],
|
|
13
|
+
"exclude": [
|
|
14
|
+
"node_modules",
|
|
15
|
+
"dist"
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skill-read-image
|
|
3
|
+
description: Analyze an image from a local path or URL with Claude vision. Supports prompt-controlled description, OCR, object counting, and brand/visual extraction.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Read Image
|
|
7
|
+
|
|
8
|
+
Analyze an image with Claude vision and return structured JSON containing the prompt, model, and extracted analysis.
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- Supports local files and remote URLs
|
|
13
|
+
- Accepts PNG, JPG, JPEG, GIF, and WEBP
|
|
14
|
+
- Prompt-controlled output for OCR, object counting, branding, layout analysis, and more
|
|
15
|
+
- Emits plain text or JSON
|
|
16
|
+
|
|
17
|
+
## Requirements
|
|
18
|
+
|
|
19
|
+
- `ANTHROPIC_API_KEY` must be available in the environment
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# Describe a local image
|
|
25
|
+
skill-read-image --input ./product-shot.jpg
|
|
26
|
+
|
|
27
|
+
# OCR a receipt from a URL
|
|
28
|
+
skill-read-image \
|
|
29
|
+
--input https://example.com/receipt.png \
|
|
30
|
+
--prompt "Extract every line item, subtotal, tax, and total."
|
|
31
|
+
|
|
32
|
+
# Return plain text only
|
|
33
|
+
skill-read-image --input ./wireframe.webp --text
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Options
|
|
37
|
+
|
|
38
|
+
| Option | Description | Default |
|
|
39
|
+
|--------|-------------|---------|
|
|
40
|
+
| `-i, --input <path-or-url>` | Local image path or image URL | required |
|
|
41
|
+
| `-p, --prompt <text>` | What Claude should extract or describe | detailed description + OCR |
|
|
42
|
+
| `-m, --model <name>` | Anthropic model to call | `ANTHROPIC_MODEL` or built-in default |
|
|
43
|
+
| `--max-tokens <n>` | Maximum response tokens | 1200 |
|
|
44
|
+
| `-o, --output <path>` | Save result to a file | stdout |
|
|
45
|
+
| `--text` | Emit only Claude's text response | false |
|
|
46
|
+
| `--help` | Show usage | |
|
|
47
|
+
| `--version` | Show version | |
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hasnaxyz/skill-read-image",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Analyze local or remote images with Claude vision",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"skill-read-image": "src/index.ts"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"src",
|
|
12
|
+
"SKILL.md",
|
|
13
|
+
"tsconfig.json"
|
|
14
|
+
],
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "restricted"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"image",
|
|
20
|
+
"vision",
|
|
21
|
+
"ocr",
|
|
22
|
+
"claude",
|
|
23
|
+
"skill"
|
|
24
|
+
],
|
|
25
|
+
"license": "Apache-2.0",
|
|
26
|
+
"scripts": {
|
|
27
|
+
"start": "bun run src/index.ts",
|
|
28
|
+
"typecheck": "tsc --noEmit"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/bun": "latest",
|
|
32
|
+
"typescript": "^5.7.0"
|
|
33
|
+
}
|
|
34
|
+
}
|