@hasna/skills 0.1.45 → 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/README.md +32 -1
- package/bin/index.js +469 -151
- package/bin/mcp.js +299 -68
- package/dist/index.js +108 -31
- package/dist/lib/compact-output.d.ts +32 -0
- package/dist/lib/skill-aliases.d.ts +1 -0
- package/package.json +2 -2
- package/skills/transcript/SKILL.md +53 -73
- package/skills/transcript/package.json +1 -1
- package/skills/apidocs/.claude/settings.json +0 -5
- package/skills/hook/bunfig.toml +0 -5
- package/skills/implementation/bunfig.toml +0 -5
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: ["
|
|
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" },
|
|
@@ -1320,12 +1321,47 @@ function ensurePortableSkillFiles(skillPath, manifest) {
|
|
|
1320
1321
|
writeFileSync2(join3(skillPath, "skill.json"), renderSkillJson(next));
|
|
1321
1322
|
if (!existsSync3(join3(skillPath, "AGENTS.md")))
|
|
1322
1323
|
writeFileSync2(join3(skillPath, "AGENTS.md"), renderAgentsMd(next));
|
|
1323
|
-
|
|
1324
|
-
writeFileSync2(join3(skillPath, "package.json"), renderPackageJson(next));
|
|
1324
|
+
ensurePackageJson(skillPath, next);
|
|
1325
1325
|
if (!existsSync3(join3(skillPath, "tsconfig.json")))
|
|
1326
1326
|
writeFileSync2(join3(skillPath, "tsconfig.json"), renderTsconfig());
|
|
1327
1327
|
return readPortableSkillManifest(skillPath, next.name);
|
|
1328
1328
|
}
|
|
1329
|
+
function ensurePackageJson(skillPath, manifest) {
|
|
1330
|
+
const pkgPath = join3(skillPath, "package.json");
|
|
1331
|
+
const first = manifest.commands[0] ?? { name: manifest.name, entry: "src/index.ts" };
|
|
1332
|
+
const commandName = normalizePortableSkillName(first.name || manifest.name);
|
|
1333
|
+
const entry = (first.entry ?? "src/index.ts").replace(/^\.\//, "");
|
|
1334
|
+
if (!existsSync3(pkgPath)) {
|
|
1335
|
+
writeFileSync2(pkgPath, renderPackageJson(manifest));
|
|
1336
|
+
return;
|
|
1337
|
+
}
|
|
1338
|
+
const existing = readJsonObject(pkgPath);
|
|
1339
|
+
const bin = {};
|
|
1340
|
+
if (isRecord(existing.bin)) {
|
|
1341
|
+
for (const [name, value] of Object.entries(existing.bin)) {
|
|
1342
|
+
if (typeof value === "string" && value.trim())
|
|
1343
|
+
bin[normalizePortableSkillName(name)] = value.replace(/^\.\//, "");
|
|
1344
|
+
}
|
|
1345
|
+
} else {
|
|
1346
|
+
const binEntry = stringValue(existing.bin);
|
|
1347
|
+
if (binEntry)
|
|
1348
|
+
bin[manifest.name] = binEntry.replace(/^\.\//, "");
|
|
1349
|
+
}
|
|
1350
|
+
bin[commandName] = entry;
|
|
1351
|
+
const scripts = isRecord(existing.scripts) ? { ...existing.scripts } : {};
|
|
1352
|
+
if (!stringValue(scripts.dev))
|
|
1353
|
+
scripts.dev = `bun run ${entry}`;
|
|
1354
|
+
writeFileSync2(pkgPath, `${JSON.stringify({
|
|
1355
|
+
...existing,
|
|
1356
|
+
name: manifest.name,
|
|
1357
|
+
version: manifest.version,
|
|
1358
|
+
description: manifest.description,
|
|
1359
|
+
type: stringValue(existing.type) ?? "module",
|
|
1360
|
+
bin,
|
|
1361
|
+
scripts
|
|
1362
|
+
}, null, 2)}
|
|
1363
|
+
`);
|
|
1364
|
+
}
|
|
1329
1365
|
function copySkillDirectory(source, destination) {
|
|
1330
1366
|
mkdirSync2(destination, { recursive: true });
|
|
1331
1367
|
cpSync(source, destination, {
|
|
@@ -2771,9 +2807,9 @@ var MEDIA_PROCESSING_SKILLS = [
|
|
|
2771
2807
|
{
|
|
2772
2808
|
name: "transcript",
|
|
2773
2809
|
displayName: "Transcript",
|
|
2774
|
-
description: "
|
|
2810
|
+
description: "Transcribe audio, video, and media URLs with OpenAI GPT-4o, ElevenLabs Scribe v2, DeepGram, or hosted runtime",
|
|
2775
2811
|
category: "Media Processing",
|
|
2776
|
-
tags: ["transcript", "audio", "video", "speech-to-text"]
|
|
2812
|
+
tags: ["transcript", "audio", "video", "speech-to-text", "diarization", "youtube"]
|
|
2777
2813
|
},
|
|
2778
2814
|
{
|
|
2779
2815
|
name: "video-cut-suggester",
|
|
@@ -15447,7 +15483,7 @@ function finalize(ctx, schema) {
|
|
|
15447
15483
|
result.$schema = "http://json-schema.org/draft-07/schema#";
|
|
15448
15484
|
} else if (ctx.target === "draft-04") {
|
|
15449
15485
|
result.$schema = "http://json-schema.org/draft-04/schema#";
|
|
15450
|
-
} else if (ctx.target === "openapi-3.0") {}
|
|
15486
|
+
} else if (ctx.target === "openapi-3.0") {} else {}
|
|
15451
15487
|
if (ctx.external?.uri) {
|
|
15452
15488
|
const id = ctx.external.registry.get(schema)?.id;
|
|
15453
15489
|
if (!id)
|
|
@@ -15695,7 +15731,7 @@ var literalProcessor = (schema, ctx, json, _params) => {
|
|
|
15695
15731
|
if (val === undefined) {
|
|
15696
15732
|
if (ctx.unrepresentable === "throw") {
|
|
15697
15733
|
throw new Error("Literal `undefined` cannot be represented in JSON Schema");
|
|
15698
|
-
}
|
|
15734
|
+
} else {}
|
|
15699
15735
|
} else if (typeof val === "bigint") {
|
|
15700
15736
|
if (ctx.unrepresentable === "throw") {
|
|
15701
15737
|
throw new Error("BigInt literals cannot be represented in JSON Schema");
|
|
@@ -18776,7 +18812,7 @@ import { dirname as dirname4, relative as relative3 } from "path";
|
|
|
18776
18812
|
// package.json
|
|
18777
18813
|
var package_default = {
|
|
18778
18814
|
name: "@hasna/skills",
|
|
18779
|
-
version: "0.1.
|
|
18815
|
+
version: "0.1.47",
|
|
18780
18816
|
description: "Skills library for AI coding agents",
|
|
18781
18817
|
type: "module",
|
|
18782
18818
|
bin: {
|
|
@@ -18845,7 +18881,7 @@ var package_default = {
|
|
|
18845
18881
|
typescript: "^5"
|
|
18846
18882
|
},
|
|
18847
18883
|
dependencies: {
|
|
18848
|
-
"@hasna/events": "^0.1.
|
|
18884
|
+
"@hasna/events": "^0.1.7",
|
|
18849
18885
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
18850
18886
|
chalk: "^5.3.0",
|
|
18851
18887
|
commander: "^12.1.0",
|
|
@@ -19029,18 +19065,29 @@ var runOutputSchema = objectSchema({
|
|
|
19029
19065
|
exitCode: { type: "number", description: "Process exit code for local runs." },
|
|
19030
19066
|
skill: stringSchema("Canonical skill slug."),
|
|
19031
19067
|
remote: { type: "boolean", description: "Whether the skill was submitted to the hosted runtime." },
|
|
19032
|
-
|
|
19033
|
-
|
|
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."),
|
|
19034
19080
|
id: stringSchema("Remote run id when submitted remotely."),
|
|
19035
19081
|
localRunId: stringSchema("Local run metadata id."),
|
|
19036
19082
|
status: stringSchema("Run lifecycle status."),
|
|
19037
19083
|
pricing: pricingSchema,
|
|
19038
|
-
remoteRun: objectSchema({}, [], "
|
|
19039
|
-
run: objectSchema({}, [], "
|
|
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),
|
|
19040
19086
|
nextActions: objectSchema({
|
|
19041
19087
|
poll: stringSchema("Command to poll run status."),
|
|
19042
19088
|
download: stringSchema("Command to download artifacts.")
|
|
19043
|
-
})
|
|
19089
|
+
}),
|
|
19090
|
+
detailHint: stringSchema("How to request the complete payload.")
|
|
19044
19091
|
}, [], "Skill run result.");
|
|
19045
19092
|
var toolContracts = [
|
|
19046
19093
|
{
|
|
@@ -19088,7 +19135,7 @@ var toolContracts = [
|
|
|
19088
19135
|
{
|
|
19089
19136
|
name: "list_skills",
|
|
19090
19137
|
title: "List Skills",
|
|
19091
|
-
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.",
|
|
19092
19139
|
params: ["category?", "profile?", "detail?", "limit?", "offset?"],
|
|
19093
19140
|
category: "discovery",
|
|
19094
19141
|
sideEffects: "none",
|
|
@@ -19104,7 +19151,11 @@ var toolContracts = [
|
|
|
19104
19151
|
skills: arraySchema(skillSummarySchema),
|
|
19105
19152
|
total: { type: "number" },
|
|
19106
19153
|
offset: { type: "number" },
|
|
19107
|
-
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.")
|
|
19108
19159
|
})
|
|
19109
19160
|
},
|
|
19110
19161
|
{
|
|
@@ -19125,7 +19176,7 @@ var toolContracts = [
|
|
|
19125
19176
|
{
|
|
19126
19177
|
name: "search_skills",
|
|
19127
19178
|
title: "Search Skills",
|
|
19128
|
-
description: "Search skills by name, description, or tags.",
|
|
19179
|
+
description: "Search skills by name, description, or tags. Returns a compact paged envelope by default.",
|
|
19129
19180
|
params: ["query", "profile?", "detail?", "limit?", "offset?"],
|
|
19130
19181
|
category: "discovery",
|
|
19131
19182
|
sideEffects: "none",
|
|
@@ -19137,7 +19188,16 @@ var toolContracts = [
|
|
|
19137
19188
|
limit: { type: "number", minimum: 0 },
|
|
19138
19189
|
offset: { type: "number", minimum: 0 }
|
|
19139
19190
|
}, ["query"]),
|
|
19140
|
-
outputSchema: objectSchema({
|
|
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
|
+
})
|
|
19141
19201
|
},
|
|
19142
19202
|
{
|
|
19143
19203
|
name: "get_skill_info",
|
|
@@ -19254,8 +19314,8 @@ var toolContracts = [
|
|
|
19254
19314
|
{
|
|
19255
19315
|
name: "run_skill",
|
|
19256
19316
|
title: "Run Skill",
|
|
19257
|
-
description: "Run a skill locally or through a configured remote runner.",
|
|
19258
|
-
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?"],
|
|
19259
19319
|
category: "execution",
|
|
19260
19320
|
sideEffects: "local-process-or-remote-run",
|
|
19261
19321
|
stable: true,
|
|
@@ -19263,28 +19323,33 @@ var toolContracts = [
|
|
|
19263
19323
|
name: skillNameInput,
|
|
19264
19324
|
input: runInputSchema,
|
|
19265
19325
|
args: runArgsSchema,
|
|
19266
|
-
approved: paidRunApprovalSchema
|
|
19326
|
+
approved: paidRunApprovalSchema,
|
|
19327
|
+
detail: { type: "boolean", default: false, description: "Return full stdout/stderr, remote run, and local run metadata." }
|
|
19267
19328
|
}, ["name"]),
|
|
19268
19329
|
outputSchema: runOutputSchema
|
|
19269
19330
|
},
|
|
19270
19331
|
{
|
|
19271
19332
|
name: "get_run_status",
|
|
19272
19333
|
title: "Get Run Status",
|
|
19273
|
-
description: "Fetch remote run status and next actions.",
|
|
19274
|
-
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?"],
|
|
19275
19336
|
category: "execution",
|
|
19276
19337
|
sideEffects: "none",
|
|
19277
19338
|
stable: true,
|
|
19278
|
-
inputSchema: objectSchema({
|
|
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"]),
|
|
19279
19343
|
outputSchema: objectSchema({
|
|
19280
19344
|
contractVersion: { type: "number", description: "Remote run payload contract version." },
|
|
19281
19345
|
runId: stringSchema("Remote run id."),
|
|
19282
19346
|
localRunId: stringSchema("Local run id."),
|
|
19283
|
-
run: objectSchema({}, [], "
|
|
19347
|
+
run: objectSchema({}, [], "Compact remote run status by default; full status when detail:true is requested.", true),
|
|
19284
19348
|
nextActions: objectSchema({
|
|
19285
19349
|
poll: stringSchema("Command to poll run status."),
|
|
19286
19350
|
download: stringSchema("Command to download artifacts.")
|
|
19287
|
-
})
|
|
19351
|
+
}),
|
|
19352
|
+
detailHint: stringSchema("How to request the complete payload.")
|
|
19288
19353
|
})
|
|
19289
19354
|
},
|
|
19290
19355
|
{
|
|
@@ -19379,13 +19444,25 @@ var toolContracts = [
|
|
|
19379
19444
|
{
|
|
19380
19445
|
name: "list_schedules",
|
|
19381
19446
|
title: "List Schedules",
|
|
19382
|
-
description: "List scheduled skill runs.",
|
|
19383
|
-
params: [],
|
|
19447
|
+
description: "List scheduled skill runs as a compact paged envelope.",
|
|
19448
|
+
params: ["limit?", "offset?"],
|
|
19384
19449
|
category: "scheduling",
|
|
19385
19450
|
sideEffects: "none",
|
|
19386
19451
|
stable: true,
|
|
19387
|
-
inputSchema: objectSchema(
|
|
19388
|
-
|
|
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
|
+
})
|
|
19389
19466
|
},
|
|
19390
19467
|
{
|
|
19391
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.
|
|
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.
|
|
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
|
|
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
|
-
#
|
|
6
|
+
# Transcript
|
|
7
7
|
|
|
8
|
-
|
|
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
|
-
|
|
10
|
+
## Choose The Runtime
|
|
11
11
|
|
|
12
|
-
|
|
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
|
-
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
64
|
-
```bash
|
|
65
|
-
bun run src/index.ts providers
|
|
66
|
-
```
|
|
40
|
+
Local requirements:
|
|
67
41
|
|
|
68
|
-
|
|
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
|
-
|
|
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
|
-
|
|
48
|
+
1. Inspect source metadata first for URLs:
|
|
78
49
|
|
|
79
|
-
|
|
50
|
+
```bash
|
|
51
|
+
transcriber info <url> --json
|
|
52
|
+
```
|
|
80
53
|
|
|
81
|
-
|
|
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
|
-
|
|
56
|
+
```bash
|
|
57
|
+
transcriber download <url> --format mp3 --json
|
|
58
|
+
```
|
|
86
59
|
|
|
87
|
-
|
|
88
|
-
export SKILLS_API_KEY=your_skill_api_key
|
|
89
|
-
```
|
|
60
|
+
3. Transcribe with JSON for automation:
|
|
90
61
|
|
|
91
|
-
|
|
62
|
+
```bash
|
|
63
|
+
transcriber transcribe <path-or-url> --provider openai --json
|
|
64
|
+
```
|
|
92
65
|
|
|
93
|
-
|
|
94
|
-
- `ffmpeg` - Audio processing
|
|
95
|
-
- `ffprobe` - Duration detection
|
|
66
|
+
4. Export or post-process:
|
|
96
67
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
|
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",
|
package/skills/hook/bunfig.toml
DELETED