@hasna/skills 0.1.18 → 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 +108 -372
- package/bin/index.js +10455 -9282
- package/bin/mcp.js +4793 -3402
- 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 +3 -3
- 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
- package/skills/skill-academic-journal-matcher/bin/cli.ts +0 -34
- package/skills/skill-action-item-router/bin/cli.ts +0 -34
- package/skills/skill-ad-creative-generator/bin/cli.ts +0 -34
- package/skills/skill-advanced-math/bin/cli.ts +0 -34
- package/skills/skill-analyze-data/bin/cli.ts +0 -19
- package/skills/skill-anomaly-investigator/bin/cli.ts +0 -34
- package/skills/skill-api-test-suite/bin/cli.ts +0 -34
- package/skills/skill-apidocs/bin/cli.ts +0 -87
- package/skills/skill-audio-cleanup-lab/bin/cli.ts +0 -6
- package/skills/skill-audiobook-chapter-proofer/bin/cli.ts +0 -34
- package/skills/skill-banner-ad-suite/bin/cli.ts +0 -34
- package/skills/skill-benchmark-finder/bin/cli.ts +0 -34
- package/skills/skill-bio-sequence-tool/bin/cli.ts +0 -34
- package/skills/skill-blog-topic-cluster/bin/cli.ts +0 -34
- package/skills/skill-brand-style-guide/bin/cli.ts +0 -19
- package/skills/skill-brand-voice-audit/bin/cli.ts +0 -34
- package/skills/skill-budget-variance-analyzer/bin/cli.ts +0 -6
- package/skills/skill-businessactivity/bin/cli.ts +0 -28
- package/skills/skill-calendar-events/bin/cli.ts +0 -34
- package/skills/skill-campaign-metric-brief/bin/cli.ts +0 -34
- package/skills/skill-campaign-moodboard/bin/cli.ts +0 -34
- package/skills/skill-caption-style-stylist/bin/cli.ts +0 -34
- package/skills/skill-chemistry-calculator/bin/cli.ts +0 -34
- package/skills/skill-churn-risk-notifier/bin/cli.ts +0 -34
- package/skills/skill-citation-formatter/bin/cli.ts +0 -34
- package/skills/skill-classroom-newsletter-kit/bin/cli.ts +0 -34
- package/skills/skill-color-palette-harmonizer/bin/cli.ts +0 -34
- package/skills/skill-competitor-ad-analyzer/bin/cli.ts +0 -34
- package/skills/skill-compliance-copy-check/bin/cli.ts +0 -34
- package/skills/skill-compliance-report-pack/bin/cli.ts +0 -34
- package/skills/skill-compress-video/bin/cli.ts +0 -19
- package/skills/skill-consolelog/bin/cli.ts +0 -884
- package/skills/skill-contract-plainlanguage/bin/cli.ts +0 -34
- package/skills/skill-copytone-translator/bin/cli.ts +0 -34
- package/skills/skill-create-blog-article/bin/cli.ts +0 -34
- package/skills/skill-create-ebook/bin/cli.ts +0 -34
- package/skills/skill-crm-note-enhancer/bin/cli.ts +0 -34
- package/skills/skill-customer-journey-mapper/bin/cli.ts +0 -34
- package/skills/skill-dashboard-builder/bin/cli.ts +0 -34
- package/skills/skill-dashboard-narrator/bin/cli.ts +0 -34
- package/skills/skill-data-anonymizer/bin/cli.ts +0 -34
- package/skills/skill-database-explorer/bin/cli.ts +0 -34
- package/skills/skill-dataset-health-check/bin/cli.ts +0 -34
- package/skills/skill-decision-journal/bin/cli.ts +0 -34
- package/skills/skill-delegation-brief-writer/bin/cli.ts +0 -34
- package/skills/skill-destination-briefing/bin/cli.ts +0 -34
- package/skills/skill-diff-viewer/bin/cli.ts +0 -34
- package/skills/skill-domainpurchase/bin/cli.ts +0 -683
- package/skills/skill-domainsearch/bin/cli.ts +0 -410
- package/skills/skill-educational-resource-finder/bin/cli.ts +0 -34
- package/skills/skill-email-campaign/bin/cli.ts +0 -34
- package/skills/skill-exam-readiness-check/bin/cli.ts +0 -34
- package/skills/skill-experiment-power-calculator/bin/cli.ts +0 -34
- package/skills/skill-extract-audio/bin/cli.ts +0 -19
- package/skills/skill-extract-frames/bin/cli.ts +0 -34
- package/skills/skill-extract-invoice/bin/cli.ts +0 -34
- package/skills/skill-family-activity-curator/bin/cli.ts +0 -34
- package/skills/skill-faq-packager/bin/cli.ts +0 -34
- package/skills/skill-feedback-survey-designer/bin/cli.ts +0 -34
- package/skills/skill-field-trip-planner/bin/cli.ts +0 -34
- package/skills/skill-file-organizer/bin/cli.ts +0 -34
- package/skills/skill-folder-tree/bin/cli.ts +0 -34
- package/skills/skill-forecast-scenario-lab/bin/cli.ts +0 -34
- package/skills/skill-form-filler/bin/cli.ts +0 -34
- package/skills/skill-generate-api-client/bin/cli.ts +0 -34
- package/skills/skill-generate-book-cover/bin/cli.ts +0 -34
- package/skills/skill-generate-chart/bin/cli.ts +0 -34
- package/skills/skill-generate-diagram/bin/cli.ts +0 -34
- package/skills/skill-generate-dockerfile/bin/cli.ts +0 -34
- package/skills/skill-generate-documentation/bin/cli.ts +0 -34
- package/skills/skill-generate-docx/bin/cli.ts +0 -6
- package/skills/skill-generate-env/bin/cli.ts +0 -34
- package/skills/skill-generate-excel/bin/cli.ts +0 -34
- package/skills/skill-generate-favicon/bin/cli.ts +0 -34
- package/skills/skill-generate-mock-data/bin/cli.ts +0 -34
- package/skills/skill-generate-pdf/bin/cli.ts +0 -6
- package/skills/skill-generate-pr-description/bin/cli.ts +0 -34
- package/skills/skill-generate-presentation/bin/cli.ts +0 -34
- package/skills/skill-generate-qrcode/bin/cli.ts +0 -34
- package/skills/skill-generate-regex/bin/cli.ts +0 -34
- package/skills/skill-generate-resume/bin/cli.ts +0 -34
- package/skills/skill-generate-sitemap/bin/cli.ts +0 -34
- package/skills/skill-generate-social-posts/bin/cli.ts +0 -34
- package/skills/skill-generate-sql/bin/cli.ts +0 -34
- package/skills/skill-gif-maker/bin/cli.ts +0 -34
- package/skills/skill-github-manager/bin/cli.ts +0 -34
- package/skills/skill-gmail/bin/cli.ts +0 -34
- package/skills/skill-goal-quarterly-roadmap/bin/cli.ts +0 -34
- package/skills/skill-grant-application-drafter/bin/cli.ts +0 -34
- package/skills/skill-grocery-basket-optimizer/bin/cli.ts +0 -34
- package/skills/skill-guest-communication-suite/bin/cli.ts +0 -34
- package/skills/skill-habit-reflection-digest/bin/cli.ts +0 -34
- package/skills/skill-highlight-reel-generator/bin/cli.ts +0 -34
- package/skills/skill-homework-feedback-coach/bin/cli.ts +0 -34
- package/skills/skill-household-maintenance-mgr/bin/cli.ts +0 -34
- package/skills/skill-http-server/bin/cli.ts +0 -34
- package/skills/skill-implementation-agent/bin/cli.ts +0 -34
- package/skills/skill-implementation-plan/bin/cli.ts +0 -34
- package/skills/skill-implementation-todo/bin/cli.ts +0 -34
- package/skills/skill-inbox-priority-planner/bin/cli.ts +0 -34
- package/skills/skill-invoice/bin/cli.ts +0 -20
- package/skills/skill-invoice-dispute-helper/bin/cli.ts +0 -34
- package/skills/skill-itinerary-architect/bin/cli.ts +0 -34
- package/skills/skill-jingle-composer/bin/cli.ts +0 -34
- package/skills/skill-kpi-digest-generator/bin/cli.ts +0 -34
- package/skills/skill-lab-notebook-formatter/bin/cli.ts +0 -34
- package/skills/skill-landing-page-copy/bin/cli.ts +0 -34
- package/skills/skill-latex-table-generator/bin/cli.ts +0 -34
- package/skills/skill-learning-style-profiler/bin/cli.ts +0 -34
- package/skills/skill-lesson-plan-customizer/bin/cli.ts +0 -34
- package/skills/skill-livestream-runofshow/bin/cli.ts +0 -34
- package/skills/skill-longform-structurer/bin/cli.ts +0 -34
- package/skills/skill-lorem-generator/bin/cli.ts +0 -34
- package/skills/skill-managehook/bin/cli.ts +0 -241
- package/skills/skill-managemcp/bin/cli.ts +0 -241
- package/skills/skill-manageskill/bin/cli.ts +0 -241
- package/skills/skill-markdown-validator/bin/cli.ts +0 -34
- package/skills/skill-mcp-builder/bin/cli.ts +0 -34
- package/skills/skill-meal-plan-designer/bin/cli.ts +0 -34
- package/skills/skill-meeting-insight-summarizer/bin/cli.ts +0 -34
- package/skills/skill-merge-pdfs/bin/cli.ts +0 -34
- package/skills/skill-microcopy-generator/bin/cli.ts +0 -34
- package/skills/skill-mindfulness-prompt-cache/bin/cli.ts +0 -34
- package/skills/skill-notion-manager/bin/cli.ts +0 -34
- package/skills/skill-onboarding-sequence-builder/bin/cli.ts +0 -34
- package/skills/skill-onsite-ops-checklist/bin/cli.ts +0 -34
- package/skills/skill-outreach-cadence-designer/bin/cli.ts +0 -34
- package/skills/skill-packaging-concept-studio/bin/cli.ts +0 -34
- package/skills/skill-packing-plan-pro/bin/cli.ts +0 -34
- package/skills/skill-parent-teacher-brief/bin/cli.ts +0 -34
- package/skills/skill-partner-kit-assembler/bin/cli.ts +0 -34
- package/skills/skill-payroll-change-prepper/bin/cli.ts +0 -34
- package/skills/skill-persona-based-adwriter/bin/cli.ts +0 -34
- package/skills/skill-persona-generator/bin/cli.ts +0 -34
- package/skills/skill-personal-daily-ops/bin/cli.ts +0 -34
- package/skills/skill-pet-care-scheduler/bin/cli.ts +0 -34
- package/skills/skill-podcast-show-notes/bin/cli.ts +0 -34
- package/skills/skill-presentation-theme-maker/bin/cli.ts +0 -34
- package/skills/skill-press-release-drafter/bin/cli.ts +0 -34
- package/skills/skill-print-collateral-designer/bin/cli.ts +0 -34
- package/skills/skill-procurement-scorecard/bin/cli.ts +0 -34
- package/skills/skill-product-demo-script/bin/cli.ts +0 -34
- package/skills/skill-product-mockup/bin/cli.ts +0 -34
- package/skills/skill-project-retro-companion/bin/cli.ts +0 -34
- package/skills/skill-proposal-redline-advisor/bin/cli.ts +0 -34
- package/skills/skill-regex-tester/bin/cli.ts +0 -34
- package/skills/skill-remove-background/bin/cli.ts +0 -34
- package/skills/skill-risk-disclosure-kit/bin/cli.ts +0 -34
- package/skills/skill-roi-comparison-tool/bin/cli.ts +0 -34
- package/skills/skill-sales-call-recapper/bin/cli.ts +0 -34
- package/skills/skill-salescopy/bin/cli.ts +0 -20
- package/skills/skill-scaffold-project/bin/cli.ts +0 -34
- package/skills/skill-scholarship-tracker/bin/cli.ts +0 -34
- package/skills/skill-scientific-figure-check/bin/cli.ts +0 -34
- package/skills/skill-seating-chart-maker/bin/cli.ts +0 -34
- package/skills/skill-security-audit/bin/cli.ts +0 -34
- package/skills/skill-seo-brief-builder/bin/cli.ts +0 -34
- package/skills/skill-slack-assistant/bin/cli.ts +0 -34
- package/skills/skill-sleep-routine-analyzer/bin/cli.ts +0 -34
- package/skills/skill-social-media-kit/bin/cli.ts +0 -34
- package/skills/skill-split-pdf/bin/cli.ts +0 -34
- package/skills/skill-sponsorship-proposal-lab/bin/cli.ts +0 -34
- package/skills/skill-spreadsheet-cleanroom/bin/cli.ts +0 -34
- package/skills/skill-statistical-test-selector/bin/cli.ts +0 -34
- package/skills/skill-stress-relief-playbook/bin/cli.ts +0 -34
- package/skills/skill-study-guide-builder/bin/cli.ts +0 -34
- package/skills/skill-subscription-spend-watcher/bin/cli.ts +0 -34
- package/skills/skill-subtitle/bin/cli.ts +0 -20
- package/skills/skill-survey-insight-extractor/bin/cli.ts +0 -34
- package/skills/skill-terraform-generator/bin/cli.ts +0 -34
- package/skills/skill-testimonial-graphics/bin/cli.ts +0 -34
- package/skills/skill-timesheet/bin/cli.ts +0 -47
- package/skills/skill-travel-budget-balancer/bin/cli.ts +0 -34
- package/skills/skill-validate-config/bin/cli.ts +0 -34
- package/skills/skill-video-cut-suggester/bin/cli.ts +0 -34
- package/skills/skill-video-downloader/bin/cli.ts +0 -34
- package/skills/skill-video-thumbnail/bin/cli.ts +0 -34
- package/skills/skill-voiceover-casting-assistant/bin/cli.ts +0 -34
- package/skills/skill-watermark/bin/cli.ts +0 -34
- package/skills/skill-webcrawling/bin/cli.ts +0 -21
- package/skills/skill-webinar-script-coach/bin/cli.ts +0 -34
- package/skills/skill-wellness-progress-reporter/bin/cli.ts +0 -34
- package/skills/skill-workout-cycle-planner/bin/cli.ts +0 -34
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
4
|
+
import { dirname, extname, resolve } from "path";
|
|
5
|
+
|
|
6
|
+
const VERSION = "0.1.0";
|
|
7
|
+
const DEFAULT_MODEL = process.env.ANTHROPIC_MODEL || "claude-sonnet-4-20250514";
|
|
8
|
+
const DEFAULT_PROMPT =
|
|
9
|
+
"Describe this image in detail. Extract any visible text, call out objects, layout, branding, and anything notable.";
|
|
10
|
+
const API_URL = process.env.ANTHROPIC_API_URL || "https://api.anthropic.com/v1/messages";
|
|
11
|
+
|
|
12
|
+
interface CliOptions {
|
|
13
|
+
input?: string;
|
|
14
|
+
prompt: string;
|
|
15
|
+
model: string;
|
|
16
|
+
maxTokens: number;
|
|
17
|
+
output?: string;
|
|
18
|
+
text: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface ImageAnalysisResult {
|
|
22
|
+
input: string;
|
|
23
|
+
sourceType: "file" | "url";
|
|
24
|
+
model: string;
|
|
25
|
+
prompt: string;
|
|
26
|
+
analysis: string;
|
|
27
|
+
stopReason: string | null;
|
|
28
|
+
usage: unknown;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function printHelp(): void {
|
|
32
|
+
console.log(`skill-read-image v${VERSION}
|
|
33
|
+
|
|
34
|
+
USAGE:
|
|
35
|
+
skill-read-image --input <path-or-url> [options]
|
|
36
|
+
|
|
37
|
+
OPTIONS:
|
|
38
|
+
-i, --input <path-or-url> Local image path or remote URL
|
|
39
|
+
-p, --prompt <text> Extraction or analysis prompt
|
|
40
|
+
-m, --model <name> Anthropic model to call
|
|
41
|
+
--max-tokens <n> Maximum response tokens
|
|
42
|
+
-o, --output <path> Save result to a file
|
|
43
|
+
--text Print only Claude's text response
|
|
44
|
+
--help Show this help message
|
|
45
|
+
--version Show the current version
|
|
46
|
+
`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function parseArgs(argv: string[]): CliOptions {
|
|
50
|
+
const options: CliOptions = {
|
|
51
|
+
prompt: DEFAULT_PROMPT,
|
|
52
|
+
model: DEFAULT_MODEL,
|
|
53
|
+
maxTokens: 1200,
|
|
54
|
+
text: false,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
58
|
+
const arg = argv[i];
|
|
59
|
+
switch (arg) {
|
|
60
|
+
case "--help":
|
|
61
|
+
case "-h":
|
|
62
|
+
printHelp();
|
|
63
|
+
process.exit(0);
|
|
64
|
+
case "--version":
|
|
65
|
+
case "-v":
|
|
66
|
+
console.log(VERSION);
|
|
67
|
+
process.exit(0);
|
|
68
|
+
case "--input":
|
|
69
|
+
case "-i":
|
|
70
|
+
options.input = argv[++i];
|
|
71
|
+
break;
|
|
72
|
+
case "--prompt":
|
|
73
|
+
case "-p":
|
|
74
|
+
options.prompt = argv[++i] ?? DEFAULT_PROMPT;
|
|
75
|
+
break;
|
|
76
|
+
case "--model":
|
|
77
|
+
case "-m":
|
|
78
|
+
options.model = argv[++i] ?? DEFAULT_MODEL;
|
|
79
|
+
break;
|
|
80
|
+
case "--max-tokens": {
|
|
81
|
+
const value = Number.parseInt(argv[++i] ?? "", 10);
|
|
82
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
83
|
+
throw new Error(`Invalid --max-tokens value: ${argv[i]}`);
|
|
84
|
+
}
|
|
85
|
+
options.maxTokens = value;
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
case "--output":
|
|
89
|
+
case "-o":
|
|
90
|
+
options.output = argv[++i];
|
|
91
|
+
break;
|
|
92
|
+
case "--text":
|
|
93
|
+
options.text = true;
|
|
94
|
+
break;
|
|
95
|
+
default:
|
|
96
|
+
if (arg.startsWith("-")) {
|
|
97
|
+
throw new Error(`Unknown option: ${arg}`);
|
|
98
|
+
}
|
|
99
|
+
if (!options.input) {
|
|
100
|
+
options.input = arg;
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
throw new Error(`Unexpected argument: ${arg}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (!options.input) {
|
|
108
|
+
throw new Error("Missing required --input <path-or-url> argument");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return options;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function isUrl(value: string): boolean {
|
|
115
|
+
try {
|
|
116
|
+
const url = new URL(value);
|
|
117
|
+
return url.protocol === "http:" || url.protocol === "https:";
|
|
118
|
+
} catch {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function getImageMediaType(value: string): string {
|
|
124
|
+
const extension = extname(value).toLowerCase();
|
|
125
|
+
switch (extension) {
|
|
126
|
+
case ".jpg":
|
|
127
|
+
case ".jpeg":
|
|
128
|
+
return "image/jpeg";
|
|
129
|
+
case ".png":
|
|
130
|
+
return "image/png";
|
|
131
|
+
case ".gif":
|
|
132
|
+
return "image/gif";
|
|
133
|
+
case ".webp":
|
|
134
|
+
return "image/webp";
|
|
135
|
+
default:
|
|
136
|
+
throw new Error(`Unsupported image format: ${extension || value}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async function buildImageBlock(input: string): Promise<{ block: Record<string, unknown>; sourceType: "file" | "url"; resolvedInput: string }> {
|
|
141
|
+
if (isUrl(input)) {
|
|
142
|
+
return {
|
|
143
|
+
block: {
|
|
144
|
+
type: "image",
|
|
145
|
+
source: {
|
|
146
|
+
type: "url",
|
|
147
|
+
url: input,
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
sourceType: "url",
|
|
151
|
+
resolvedInput: input,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const resolvedInput = resolve(input);
|
|
156
|
+
const mediaType = getImageMediaType(resolvedInput);
|
|
157
|
+
const bytes = await readFile(resolvedInput);
|
|
158
|
+
return {
|
|
159
|
+
block: {
|
|
160
|
+
type: "image",
|
|
161
|
+
source: {
|
|
162
|
+
type: "base64",
|
|
163
|
+
media_type: mediaType,
|
|
164
|
+
data: Buffer.from(bytes).toString("base64"),
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
sourceType: "file",
|
|
168
|
+
resolvedInput,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
async function callAnthropic(
|
|
173
|
+
model: string,
|
|
174
|
+
maxTokens: number,
|
|
175
|
+
prompt: string,
|
|
176
|
+
imageBlock: Record<string, unknown>,
|
|
177
|
+
): Promise<{ analysis: string; usage: unknown; stopReason: string | null }> {
|
|
178
|
+
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
179
|
+
if (!apiKey) {
|
|
180
|
+
throw new Error("Missing ANTHROPIC_API_KEY");
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const response = await fetch(API_URL, {
|
|
184
|
+
method: "POST",
|
|
185
|
+
headers: {
|
|
186
|
+
"content-type": "application/json",
|
|
187
|
+
"x-api-key": apiKey,
|
|
188
|
+
"anthropic-version": "2023-06-01",
|
|
189
|
+
},
|
|
190
|
+
body: JSON.stringify({
|
|
191
|
+
model,
|
|
192
|
+
max_tokens: maxTokens,
|
|
193
|
+
messages: [
|
|
194
|
+
{
|
|
195
|
+
role: "user",
|
|
196
|
+
content: [
|
|
197
|
+
imageBlock,
|
|
198
|
+
{
|
|
199
|
+
type: "text",
|
|
200
|
+
text: prompt,
|
|
201
|
+
},
|
|
202
|
+
],
|
|
203
|
+
},
|
|
204
|
+
],
|
|
205
|
+
}),
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
const payload = await response.json() as {
|
|
209
|
+
content?: Array<{ type: string; text?: string }>;
|
|
210
|
+
usage?: unknown;
|
|
211
|
+
stop_reason?: string | null;
|
|
212
|
+
error?: { message?: string };
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
if (!response.ok) {
|
|
216
|
+
throw new Error(payload.error?.message || `Anthropic request failed with status ${response.status}`);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const analysis = (payload.content ?? [])
|
|
220
|
+
.filter((entry) => entry.type === "text" && typeof entry.text === "string")
|
|
221
|
+
.map((entry) => entry.text)
|
|
222
|
+
.join("\n\n");
|
|
223
|
+
|
|
224
|
+
return {
|
|
225
|
+
analysis,
|
|
226
|
+
usage: payload.usage ?? null,
|
|
227
|
+
stopReason: payload.stop_reason ?? null,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
async function writeOutput(path: string, value: string): Promise<void> {
|
|
232
|
+
await mkdir(dirname(path), { recursive: true });
|
|
233
|
+
await writeFile(path, value, "utf8");
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
async function main(): Promise<void> {
|
|
237
|
+
const options = parseArgs(process.argv.slice(2));
|
|
238
|
+
const { block, sourceType, resolvedInput } = await buildImageBlock(options.input!);
|
|
239
|
+
const response = await callAnthropic(options.model, options.maxTokens, options.prompt, block);
|
|
240
|
+
|
|
241
|
+
const result: ImageAnalysisResult = {
|
|
242
|
+
input: resolvedInput,
|
|
243
|
+
sourceType,
|
|
244
|
+
model: options.model,
|
|
245
|
+
prompt: options.prompt,
|
|
246
|
+
analysis: response.analysis,
|
|
247
|
+
stopReason: response.stopReason,
|
|
248
|
+
usage: response.usage,
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
const output = options.text ? `${response.analysis}\n` : `${JSON.stringify(result, null, 2)}\n`;
|
|
252
|
+
|
|
253
|
+
if (options.output) {
|
|
254
|
+
await writeOutput(resolve(options.output), output);
|
|
255
|
+
} else {
|
|
256
|
+
process.stdout.write(output);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
main().catch((error) => {
|
|
261
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
262
|
+
process.stderr.write(`skill-read-image: ${message}\n`);
|
|
263
|
+
process.exit(1);
|
|
264
|
+
});
|
|
@@ -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,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skill-read-pdf
|
|
3
|
+
description: Analyze PDF files with Claude document blocks. Supports page-range selection, 20-page chunking, and merged structured output.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Read PDF
|
|
7
|
+
|
|
8
|
+
Analyze a PDF with Claude's native document support and return structured output for the requested pages.
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- Supports page range selection like `1-5,8,10-12`
|
|
13
|
+
- Chunks large selections into windows of up to 20 pages per request
|
|
14
|
+
- Emits merged JSON, markdown, or plain-text output
|
|
15
|
+
- Preserves chunk/page metadata so downstream tools can trace the source pages
|
|
16
|
+
|
|
17
|
+
## Requirements
|
|
18
|
+
|
|
19
|
+
- `ANTHROPIC_API_KEY` must be available in the environment
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# Read the whole PDF with markdown output
|
|
25
|
+
skill-read-pdf --input ./deck.pdf
|
|
26
|
+
|
|
27
|
+
# Restrict to a few pages
|
|
28
|
+
skill-read-pdf --input ./contract.pdf --pages 1-3,8 --format text
|
|
29
|
+
|
|
30
|
+
# Ask for specific structure and save it
|
|
31
|
+
skill-read-pdf \
|
|
32
|
+
--input ./invoice.pdf \
|
|
33
|
+
--prompt "Extract invoice metadata, every line item, and the payment terms." \
|
|
34
|
+
--format json \
|
|
35
|
+
--output ./invoice.json
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Options
|
|
39
|
+
|
|
40
|
+
| Option | Description | Default |
|
|
41
|
+
|--------|-------------|---------|
|
|
42
|
+
| `-i, --input <path-or-url>` | PDF file path or URL | required |
|
|
43
|
+
| `--pages <ranges>` | Page ranges like `1-5,8,10-12` | all pages |
|
|
44
|
+
| `-p, --prompt <text>` | What Claude should extract | text + tables + structure |
|
|
45
|
+
| `-f, --format <value>` | `json`, `markdown`, or `text` | `markdown` |
|
|
46
|
+
| `-m, --model <name>` | Anthropic model to call | `ANTHROPIC_MODEL` or built-in default |
|
|
47
|
+
| `--chunk-size <n>` | Pages per request (max 20) | 20 |
|
|
48
|
+
| `--max-tokens <n>` | Maximum response tokens per chunk | 1600 |
|
|
49
|
+
| `-o, --output <path>` | Save result to a file | stdout |
|
|
50
|
+
| `--text` | Emit only the merged extracted text | false |
|
|
51
|
+
| `--help` | Show usage | |
|
|
52
|
+
| `--version` | Show version | |
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hasnaxyz/skill-read-pdf",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Analyze PDFs with Claude document blocks and merge chunked output",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"skill-read-pdf": "src/index.ts"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"src",
|
|
12
|
+
"SKILL.md",
|
|
13
|
+
"tsconfig.json"
|
|
14
|
+
],
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "restricted"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"pdf",
|
|
20
|
+
"claude",
|
|
21
|
+
"document",
|
|
22
|
+
"ocr",
|
|
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
|
+
"pdf-lib": "^1.17.1"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/bun": "latest",
|
|
35
|
+
"typescript": "^5.7.0"
|
|
36
|
+
}
|
|
37
|
+
}
|