@hasna/skills 0.1.46 → 0.1.47

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/dist/index.js CHANGED
@@ -170,7 +170,8 @@ var SKILL_ALIASES = {
170
170
  "pdf-reader": "read-pdf",
171
171
  "generate-image": "image",
172
172
  "image-generator": "image",
173
- "create-blog-article": "blog-article"
173
+ "create-blog-article": "blog-article",
174
+ "skill-diff": "diff-viewer"
174
175
  };
175
176
  function normalizeSkillSlug(name) {
176
177
  return name.trim();
@@ -199,7 +200,7 @@ var PREMIUM_SKILLS = [
199
200
  { slug: "brand-kit", displayName: "Brand Kit", tier: "premium", costCents: 400, providers: ["hosted"], description: "Hosted brand kit with logo usage, palette, typography, brand voice, sample applications, Markdown guide, PDF guide, and SVG assets" },
200
201
  { slug: "generate-book-cover", displayName: "Book Cover", tier: "premium", costCents: 20, providers: ["gpt-image-2"], description: "Professional book cover design from title and genre" },
201
202
  { slug: "remove-background", displayName: "Remove Background", tier: "premium", costCents: 10, providers: ["gemini-3-pro"], description: "AI-powered background removal from images" },
202
- { slug: "transcript", displayName: "Transcript", tier: "premium", costCents: 10, providers: ["whisper"], description: "Audio/video transcription with timestamps" },
203
+ { slug: "transcript", displayName: "Transcript", tier: "premium", costCents: 10, providers: ["openai", "elevenlabs", "deepgram", "hosted"], description: "Audio/video transcription with timestamps, diarization, and URL support" },
203
204
  { slug: "webcrawling", displayName: "Web Crawling", tier: "premium", costCents: 5, providers: ["firecrawl"], description: "Structured web page crawling and extraction" },
204
205
  { slug: "browse", displayName: "Browse", tier: "premium", costCents: 5, providers: ["browser"], description: "Web browsing and page interaction" },
205
206
  { slug: "read-pdf", displayName: "Read PDF", tier: "premium", costCents: 5, providers: ["cerebras"], description: "Hosted PDF extraction and structured content analysis" },
@@ -2806,9 +2807,9 @@ var MEDIA_PROCESSING_SKILLS = [
2806
2807
  {
2807
2808
  name: "transcript",
2808
2809
  displayName: "Transcript",
2809
- description: "Generate transcripts from audio and video files with timestamps",
2810
+ description: "Transcribe audio, video, and media URLs with OpenAI GPT-4o, ElevenLabs Scribe v2, DeepGram, or hosted runtime",
2810
2811
  category: "Media Processing",
2811
- tags: ["transcript", "audio", "video", "speech-to-text"]
2812
+ tags: ["transcript", "audio", "video", "speech-to-text", "diarization", "youtube"]
2812
2813
  },
2813
2814
  {
2814
2815
  name: "video-cut-suggester",
@@ -15482,7 +15483,7 @@ function finalize(ctx, schema) {
15482
15483
  result.$schema = "http://json-schema.org/draft-07/schema#";
15483
15484
  } else if (ctx.target === "draft-04") {
15484
15485
  result.$schema = "http://json-schema.org/draft-04/schema#";
15485
- } else if (ctx.target === "openapi-3.0") {}
15486
+ } else if (ctx.target === "openapi-3.0") {} else {}
15486
15487
  if (ctx.external?.uri) {
15487
15488
  const id = ctx.external.registry.get(schema)?.id;
15488
15489
  if (!id)
@@ -15730,7 +15731,7 @@ var literalProcessor = (schema, ctx, json, _params) => {
15730
15731
  if (val === undefined) {
15731
15732
  if (ctx.unrepresentable === "throw") {
15732
15733
  throw new Error("Literal `undefined` cannot be represented in JSON Schema");
15733
- }
15734
+ } else {}
15734
15735
  } else if (typeof val === "bigint") {
15735
15736
  if (ctx.unrepresentable === "throw") {
15736
15737
  throw new Error("BigInt literals cannot be represented in JSON Schema");
@@ -18811,7 +18812,7 @@ import { dirname as dirname4, relative as relative3 } from "path";
18811
18812
  // package.json
18812
18813
  var package_default = {
18813
18814
  name: "@hasna/skills",
18814
- version: "0.1.46",
18815
+ version: "0.1.47",
18815
18816
  description: "Skills library for AI coding agents",
18816
18817
  type: "module",
18817
18818
  bin: {
@@ -18880,7 +18881,7 @@ var package_default = {
18880
18881
  typescript: "^5"
18881
18882
  },
18882
18883
  dependencies: {
18883
- "@hasna/events": "^0.1.3",
18884
+ "@hasna/events": "^0.1.7",
18884
18885
  "@modelcontextprotocol/sdk": "^1.26.0",
18885
18886
  chalk: "^5.3.0",
18886
18887
  commander: "^12.1.0",
@@ -19064,18 +19065,29 @@ var runOutputSchema = objectSchema({
19064
19065
  exitCode: { type: "number", description: "Process exit code for local runs." },
19065
19066
  skill: stringSchema("Canonical skill slug."),
19066
19067
  remote: { type: "boolean", description: "Whether the skill was submitted to the hosted runtime." },
19067
- stdout: stringSchema("Captured stdout for local runs."),
19068
- stderr: stringSchema("Captured stderr for local runs."),
19068
+ stdoutPreview: objectSchema({
19069
+ text: stringSchema("Truncated stdout preview."),
19070
+ length: { type: "number" },
19071
+ truncated: { type: "boolean" }
19072
+ }, [], "Default compact stdout preview."),
19073
+ stderrPreview: objectSchema({
19074
+ text: stringSchema("Truncated stderr preview."),
19075
+ length: { type: "number" },
19076
+ truncated: { type: "boolean" }
19077
+ }, [], "Default compact stderr preview."),
19078
+ stdout: stringSchema("Captured stdout for local runs when detail:true is requested."),
19079
+ stderr: stringSchema("Captured stderr for local runs when detail:true is requested."),
19069
19080
  id: stringSchema("Remote run id when submitted remotely."),
19070
19081
  localRunId: stringSchema("Local run metadata id."),
19071
19082
  status: stringSchema("Run lifecycle status."),
19072
19083
  pricing: pricingSchema,
19073
- remoteRun: objectSchema({}, [], "Normalized hosted remote run contract.", true),
19074
- run: objectSchema({}, [], "Local run metadata.", true),
19084
+ remoteRun: objectSchema({}, [], "Compact hosted remote run summary by default; full contract when detail:true is requested.", true),
19085
+ run: objectSchema({}, [], "Compact local run metadata by default; full metadata when detail:true is requested.", true),
19075
19086
  nextActions: objectSchema({
19076
19087
  poll: stringSchema("Command to poll run status."),
19077
19088
  download: stringSchema("Command to download artifacts.")
19078
- })
19089
+ }),
19090
+ detailHint: stringSchema("How to request the complete payload.")
19079
19091
  }, [], "Skill run result.");
19080
19092
  var toolContracts = [
19081
19093
  {
@@ -19123,7 +19135,7 @@ var toolContracts = [
19123
19135
  {
19124
19136
  name: "list_skills",
19125
19137
  title: "List Skills",
19126
- description: "List skills from the basic or full registry profile.",
19138
+ description: "List skills from the basic or full registry profile. Returns a compact paged envelope by default.",
19127
19139
  params: ["category?", "profile?", "detail?", "limit?", "offset?"],
19128
19140
  category: "discovery",
19129
19141
  sideEffects: "none",
@@ -19139,7 +19151,11 @@ var toolContracts = [
19139
19151
  skills: arraySchema(skillSummarySchema),
19140
19152
  total: { type: "number" },
19141
19153
  offset: { type: "number" },
19142
- limit: { type: "number" }
19154
+ limit: { type: "number" },
19155
+ nextOffset: { type: "number" },
19156
+ hasMore: { type: "boolean" },
19157
+ nextArguments: objectSchema({}, [], "Arguments for the next page.", true),
19158
+ detailHint: stringSchema("How to request fuller skill objects.")
19143
19159
  })
19144
19160
  },
19145
19161
  {
@@ -19160,7 +19176,7 @@ var toolContracts = [
19160
19176
  {
19161
19177
  name: "search_skills",
19162
19178
  title: "Search Skills",
19163
- description: "Search skills by name, description, or tags.",
19179
+ description: "Search skills by name, description, or tags. Returns a compact paged envelope by default.",
19164
19180
  params: ["query", "profile?", "detail?", "limit?", "offset?"],
19165
19181
  category: "discovery",
19166
19182
  sideEffects: "none",
@@ -19172,7 +19188,16 @@ var toolContracts = [
19172
19188
  limit: { type: "number", minimum: 0 },
19173
19189
  offset: { type: "number", minimum: 0 }
19174
19190
  }, ["query"]),
19175
- outputSchema: objectSchema({ skills: arraySchema(skillSummarySchema) })
19191
+ outputSchema: objectSchema({
19192
+ skills: arraySchema(skillSummarySchema),
19193
+ total: { type: "number" },
19194
+ offset: { type: "number" },
19195
+ limit: { type: "number" },
19196
+ nextOffset: { type: "number" },
19197
+ hasMore: { type: "boolean" },
19198
+ nextArguments: objectSchema({}, [], "Arguments for the next page.", true),
19199
+ detailHint: stringSchema("How to request fuller skill objects.")
19200
+ })
19176
19201
  },
19177
19202
  {
19178
19203
  name: "get_skill_info",
@@ -19289,8 +19314,8 @@ var toolContracts = [
19289
19314
  {
19290
19315
  name: "run_skill",
19291
19316
  title: "Run Skill",
19292
- description: "Run a skill locally or through a configured remote runner.",
19293
- params: ["name", "input?", "args?", "approved?"],
19317
+ description: "Run a skill locally or through a configured remote runner. Returns compact stdout/stderr previews and run summaries by default; pass detail:true for full records.",
19318
+ params: ["name", "input?", "args?", "approved?", "detail?"],
19294
19319
  category: "execution",
19295
19320
  sideEffects: "local-process-or-remote-run",
19296
19321
  stable: true,
@@ -19298,28 +19323,33 @@ var toolContracts = [
19298
19323
  name: skillNameInput,
19299
19324
  input: runInputSchema,
19300
19325
  args: runArgsSchema,
19301
- approved: paidRunApprovalSchema
19326
+ approved: paidRunApprovalSchema,
19327
+ detail: { type: "boolean", default: false, description: "Return full stdout/stderr, remote run, and local run metadata." }
19302
19328
  }, ["name"]),
19303
19329
  outputSchema: runOutputSchema
19304
19330
  },
19305
19331
  {
19306
19332
  name: "get_run_status",
19307
19333
  title: "Get Run Status",
19308
- description: "Fetch remote run status and next actions.",
19309
- params: ["run_id"],
19334
+ description: "Fetch remote run status and next actions. Returns a compact status summary by default; pass detail:true for the complete remote run payload.",
19335
+ params: ["run_id", "detail?"],
19310
19336
  category: "execution",
19311
19337
  sideEffects: "none",
19312
19338
  stable: true,
19313
- inputSchema: objectSchema({ run_id: stringSchema("Remote or local run id.") }, ["run_id"]),
19339
+ inputSchema: objectSchema({
19340
+ run_id: stringSchema("Remote or local run id."),
19341
+ detail: { type: "boolean", default: false, description: "Return the complete remote run payload." }
19342
+ }, ["run_id"]),
19314
19343
  outputSchema: objectSchema({
19315
19344
  contractVersion: { type: "number", description: "Remote run payload contract version." },
19316
19345
  runId: stringSchema("Remote run id."),
19317
19346
  localRunId: stringSchema("Local run id."),
19318
- run: objectSchema({}, [], "Normalized remote run status.", true),
19347
+ run: objectSchema({}, [], "Compact remote run status by default; full status when detail:true is requested.", true),
19319
19348
  nextActions: objectSchema({
19320
19349
  poll: stringSchema("Command to poll run status."),
19321
19350
  download: stringSchema("Command to download artifacts.")
19322
- })
19351
+ }),
19352
+ detailHint: stringSchema("How to request the complete payload.")
19323
19353
  })
19324
19354
  },
19325
19355
  {
@@ -19414,13 +19444,25 @@ var toolContracts = [
19414
19444
  {
19415
19445
  name: "list_schedules",
19416
19446
  title: "List Schedules",
19417
- description: "List scheduled skill runs.",
19418
- params: [],
19447
+ description: "List scheduled skill runs as a compact paged envelope.",
19448
+ params: ["limit?", "offset?"],
19419
19449
  category: "scheduling",
19420
19450
  sideEffects: "none",
19421
19451
  stable: true,
19422
- inputSchema: objectSchema(),
19423
- outputSchema: arraySchema(objectSchema({}, [], "Schedule record.", true))
19452
+ inputSchema: objectSchema({
19453
+ limit: { type: "number", minimum: 0 },
19454
+ offset: { type: "number", minimum: 0 }
19455
+ }),
19456
+ outputSchema: objectSchema({
19457
+ schedules: arraySchema(objectSchema({}, [], "Compact schedule record.", true)),
19458
+ total: { type: "number" },
19459
+ offset: { type: "number" },
19460
+ limit: { type: "number" },
19461
+ nextOffset: { type: "number" },
19462
+ hasMore: { type: "boolean" },
19463
+ nextArguments: objectSchema({}, [], "Arguments for the next page.", true),
19464
+ detailHint: stringSchema("How to request complete schedule details.")
19465
+ })
19424
19466
  },
19425
19467
  {
19426
19468
  name: "remove_schedule",
@@ -0,0 +1,32 @@
1
+ export declare const DEFAULT_LIST_LIMIT = 30;
2
+ export declare const DEFAULT_SEARCH_LIMIT = 20;
3
+ export declare const DEFAULT_TAG_LIMIT = 80;
4
+ export declare const DEFAULT_MCP_LIMIT = 25;
5
+ export declare const MAX_PAGE_LIMIT = 200;
6
+ export declare const DEFAULT_PREVIEW_CHARS = 600;
7
+ export interface Page<T> {
8
+ items: T[];
9
+ total: number;
10
+ offset: number;
11
+ limit: number;
12
+ hasMore: boolean;
13
+ nextOffset: number | null;
14
+ }
15
+ export declare function truncateText(value: unknown, maxChars?: number): string;
16
+ export declare function previewText(value: unknown, maxChars?: number): {
17
+ text: string;
18
+ length: number;
19
+ truncated: boolean;
20
+ };
21
+ export declare function parsePageLimit(value: string | number | undefined, fallback: number, options?: {
22
+ max?: number;
23
+ allowAll?: boolean;
24
+ }): number;
25
+ export declare function parsePageOffset(value: string | number | undefined, fallback?: number): number;
26
+ export declare function paginate<T>(items: T[], options: {
27
+ limit: number;
28
+ offset?: number;
29
+ }): Page<T>;
30
+ export declare function showingLabel(total: number, shown: number, offset: number): string;
31
+ export declare function compactRunRecord(run: any): Record<string, unknown>;
32
+ export declare function compactRemoteRun(run: any): Record<string, unknown>;
@@ -11,6 +11,7 @@ export declare const SKILL_ALIASES: {
11
11
  readonly "generate-image": "image";
12
12
  readonly "image-generator": "image";
13
13
  readonly "create-blog-article": "blog-article";
14
+ readonly "skill-diff": "diff-viewer";
14
15
  };
15
16
  export type SkillAlias = keyof typeof SKILL_ALIASES;
16
17
  export declare function normalizeSkillSlug(name: string): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/skills",
3
- "version": "0.1.46",
3
+ "version": "0.1.47",
4
4
  "description": "Skills library for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -69,7 +69,7 @@
69
69
  "typescript": "^5"
70
70
  },
71
71
  "dependencies": {
72
- "@hasna/events": "^0.1.3",
72
+ "@hasna/events": "^0.1.7",
73
73
  "@modelcontextprotocol/sdk": "^1.26.0",
74
74
  "chalk": "^5.3.0",
75
75
  "commander": "^12.1.0",
@@ -1,100 +1,80 @@
1
1
  ---
2
2
  name: transcript
3
- description: Transcribe audio and video files using ElevenLabs Scribe, OpenAI Whisper, or Google Gemini. Supports automatic chunking for large files, speaker diarization, timestamps, and multiple output formats (text, SRT, VTT, JSON).
3
+ description: Transcribe audio, video, YouTube, Vimeo, and generic media URLs with iapp-transcriber or the hosted Skills runtime. Supports OpenAI GPT-4o transcription, OpenAI diarization, ElevenLabs Scribe v2, DeepGram, chunking, source metadata, subtitles, and JSON outputs.
4
4
  ---
5
5
 
6
- # Audio Transcription Skill
6
+ # Transcript
7
7
 
8
- This skill provides high-quality speech-to-text transcription using multiple AI providers. It automatically handles large files through compression and chunking.
8
+ Create transcripts from local audio/video files or media URLs. Use this skill when the user asks to transcribe, caption, diarize, summarize, or package spoken audio/video content.
9
9
 
10
- This CLI is API-backed. Set `SKILLS_API_KEY` when routing through the hosted skills/connectors runtime; provider-specific keys are managed by that runtime.
10
+ ## Choose The Runtime
11
11
 
12
- ## Supported Providers
12
+ - Use the hosted Skills runtime when the user explicitly runs `skills run transcript`, needs remote execution, or has only `SKILLS_API_KEY` configured.
13
+ - Use local `iapp-transcriber` when you are on this machine and need direct access to local files, YouTube/Vimeo/generic `yt-dlp` sources, transcript DB records, MCP tools, comments, exports, or OpenLoops follow-up workflows.
14
+ - The local command is `transcriber` when installed, or `bun run src/cli/index.ts` from `/home/hasna/Workspace/hasnaxyz/internalapp/iapp-transcriber`.
13
15
 
14
- ### ElevenLabs Scribe
15
- - **Accuracy**: 96.7% for English (industry-leading)
16
- - **Max file size**: 3GB / 10 hours
17
- - **Features**: Speaker diarization (up to 32 speakers), word-level timestamps
18
- - **Cost**: $0.40/hour
19
- - **Best for**: Multi-speaker recordings, highest accuracy needs
16
+ ## Hosted Usage
20
17
 
21
- ### OpenAI Whisper
22
- - **Accuracy**: Excellent
23
- - **Max file size**: 25MB (automatic chunking for larger files)
24
- - **Features**: Segment timestamps, language detection
25
- - **Cost**: $0.006/min ($0.003/min with GPT-4o Mini)
26
- - **Best for**: Standard transcription, good balance of cost and quality
18
+ ```bash
19
+ skills run transcript --source ./meeting.mp3 --title "Design review" --provider openai
20
+ skills run transcribe --source https://www.youtube.com/watch?v=... --provider openai --diarize
21
+ ```
27
22
 
28
- ### Google Gemini
29
- - **Accuracy**: Very good
30
- - **Max file size**: 2GB
31
- - **Features**: Multimodal analysis, summarization capabilities
32
- - **Cost**: ~$0.09-0.23/hour (generous free tier available)
33
- - **Best for**: Cost-sensitive projects, multimodal needs
23
+ Poll hosted runs with `skills runs status <run-id>` and download outputs with `skills exports download <run-id>`.
34
24
 
35
- ## Usage
25
+ ## Local Usage
36
26
 
37
- ### Basic Transcription
38
27
  ```bash
39
- bun run src/index.ts transcribe \
40
- --provider openai \
41
- --input ./recording.mp3
28
+ transcriber transcribe ./meeting.mp3 --provider openai --json
29
+ transcriber transcribe https://www.youtube.com/watch?v=... --provider openai --model gpt-4o-transcribe --json
30
+ transcriber transcribe ./meeting.mp3 --provider openai --diarize --json
31
+ transcriber export <transcript-id> --format srt --output captions.srt
42
32
  ```
43
33
 
44
- ### With Speaker Diarization
45
- ```bash
46
- bun run src/index.ts transcribe \
47
- --provider elevenlabs \
48
- --input ./meeting.mp3 \
49
- --diarize \
50
- --timestamps \
51
- --format srt
52
- ```
34
+ Local provider defaults:
53
35
 
54
- ### Export to Subtitles
55
- ```bash
56
- bun run src/index.ts transcribe \
57
- --provider gemini \
58
- --input ./video.mp4 \
59
- --format vtt \
60
- --output ./captions.vtt
61
- ```
36
+ - `openai`: default, uses `gpt-4o-transcribe`; `--diarize` uses `gpt-4o-transcribe-diarize`.
37
+ - `elevenlabs`: uses `scribe_v2`, supports diarization and keyterms.
38
+ - `deepgram`: uses Nova-3, supports diarization.
62
39
 
63
- ### View Provider Info
64
- ```bash
65
- bun run src/index.ts providers
66
- ```
40
+ Local requirements:
67
41
 
68
- ## Output Formats
42
+ - A configured provider credential for the selected local provider.
43
+ - `yt-dlp` for remote media URLs. Set `YTDLP_PATH` if needed.
44
+ - `ffmpeg`/`ffprobe`; the local app bundles npm ffmpeg/ffprobe and also respects `FFMPEG_PATH` and `FFPROBE_PATH`.
69
45
 
70
- | Format | Extension | Description |
71
- |--------|-----------|-------------|
72
- | text | .txt | Plain text transcript |
73
- | srt | .srt | SubRip subtitle format |
74
- | vtt | .vtt | WebVTT subtitle format |
75
- | json | .json | Full structured data with metadata |
46
+ ## Workflow
76
47
 
77
- ## Large File Handling
48
+ 1. Inspect source metadata first for URLs:
78
49
 
79
- The skill automatically handles files larger than provider limits:
50
+ ```bash
51
+ transcriber info <url> --json
52
+ ```
80
53
 
81
- - **Compression**: For OpenAI, files are first compressed using Opus codec
82
- - **Chunking**: Files are split into 10-minute segments with overlap
83
- - **Merging**: Results are intelligently merged to avoid duplicates
54
+ 2. Download audio when the user asks to keep media:
84
55
 
85
- ## Configuration
56
+ ```bash
57
+ transcriber download <url> --format mp3 --json
58
+ ```
86
59
 
87
- ```bash
88
- export SKILLS_API_KEY=your_skill_api_key
89
- ```
60
+ 3. Transcribe with JSON for automation:
90
61
 
91
- ## Dependencies
62
+ ```bash
63
+ transcriber transcribe <path-or-url> --provider openai --json
64
+ ```
92
65
 
93
- For chunking support (OpenAI with large files):
94
- - `ffmpeg` - Audio processing
95
- - `ffprobe` - Duration detection
66
+ 4. Export or post-process:
96
67
 
97
- Install on macOS:
98
- ```bash
99
- brew install ffmpeg
100
- ```
68
+ ```bash
69
+ transcriber get <id> --json
70
+ transcriber export <id> --format txt --output transcript.txt
71
+ transcriber summarize <id>
72
+ ```
73
+
74
+ 5. For repeat work, create OpenLoops command loops around JSON-producing commands, for example `transcriber feed check --json --dry-run`.
75
+
76
+ ## Safety
77
+
78
+ - Only fetch URLs the user is authorized to process.
79
+ - The local app rejects private/local URL hosts by default; set `TRANSCRIBER_ALLOW_PRIVATE_URLS=1` only for trusted internal sources.
80
+ - Prefer `--json` for scripts and OpenLoops so failures include a structured transcript record and nonzero exit code.
@@ -2,7 +2,7 @@
2
2
  "name": "transcript",
3
3
  "version": "1.0.0",
4
4
  "private": true,
5
- "description": "Audio/video transcription skill supporting ElevenLabs, OpenAI Whisper, and Google Gemini with automatic chunking for large files",
5
+ "description": "Audio/video transcription skill backed by iapp-transcriber, OpenAI GPT-4o transcription, ElevenLabs Scribe v2, and hosted Skills runtime",
6
6
  "type": "module",
7
7
  "skills": {
8
8
  "runtime": "hosted",
@@ -1,5 +0,0 @@
1
- {
2
- "env": {
3
- "CLAUDE_CODE_TASK_LIST_ID": "service-apidocs-dev"
4
- }
5
- }
@@ -1,5 +0,0 @@
1
- [install]
2
- peer = false
3
-
4
- [run]
5
- bun = true
@@ -1,5 +0,0 @@
1
- [install]
2
- peer = false
3
-
4
- [run]
5
- bun = true