@tryhamster/gerbil 1.0.0-rc.0 → 1.0.0-rc.1
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 +79 -14
- package/dist/auto-update-DsWBBnEk.mjs +3 -0
- package/dist/browser/index.d.mts +401 -5
- package/dist/browser/index.d.mts.map +1 -1
- package/dist/browser/index.mjs +1772 -146
- package/dist/browser/index.mjs.map +1 -1
- package/dist/{chrome-backend-CtwPENIW.mjs → chrome-backend-JEPeM2YE.mjs} +1 -1
- package/dist/{chrome-backend-C5Un08O4.mjs → chrome-backend-Y9F7W5VQ.mjs} +514 -73
- package/dist/chrome-backend-Y9F7W5VQ.mjs.map +1 -0
- package/dist/cli.mjs +3359 -646
- package/dist/cli.mjs.map +1 -1
- package/dist/frameworks/express.d.mts +1 -1
- package/dist/frameworks/express.mjs +3 -3
- package/dist/frameworks/fastify.d.mts +1 -1
- package/dist/frameworks/fastify.mjs +3 -3
- package/dist/frameworks/hono.d.mts +1 -1
- package/dist/frameworks/hono.mjs +3 -3
- package/dist/frameworks/next.d.mts +2 -2
- package/dist/frameworks/next.mjs +3 -3
- package/dist/frameworks/react.d.mts +1 -1
- package/dist/frameworks/trpc.d.mts +1 -1
- package/dist/frameworks/trpc.mjs +3 -3
- package/dist/gerbil-DeQlX_Mt.mjs +5 -0
- package/dist/gerbil-POAz8peb.d.mts +431 -0
- package/dist/gerbil-POAz8peb.d.mts.map +1 -0
- package/dist/gerbil-yoSpRHgv.mjs +1463 -0
- package/dist/gerbil-yoSpRHgv.mjs.map +1 -0
- package/dist/index.d.mts +395 -9
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +8 -6
- package/dist/index.mjs.map +1 -1
- package/dist/integrations/ai-sdk.d.mts +122 -4
- package/dist/integrations/ai-sdk.d.mts.map +1 -1
- package/dist/integrations/ai-sdk.mjs +239 -11
- package/dist/integrations/ai-sdk.mjs.map +1 -1
- package/dist/integrations/langchain.d.mts +132 -2
- package/dist/integrations/langchain.d.mts.map +1 -1
- package/dist/integrations/langchain.mjs +176 -8
- package/dist/integrations/langchain.mjs.map +1 -1
- package/dist/integrations/llamaindex.d.mts +1 -1
- package/dist/integrations/llamaindex.mjs +3 -3
- package/dist/integrations/mcp-client.mjs +4 -4
- package/dist/integrations/mcp-client.mjs.map +1 -1
- package/dist/integrations/mcp.d.mts +2 -2
- package/dist/integrations/mcp.d.mts.map +1 -1
- package/dist/integrations/mcp.mjs +6 -6
- package/dist/{mcp-R8kRLIKb.mjs → mcp-Bitg4sjX.mjs} +10 -37
- package/dist/mcp-Bitg4sjX.mjs.map +1 -0
- package/dist/microphone-D-6y9aiE.mjs +3 -0
- package/dist/{models-DKULvhOr.mjs → models-BAtL8qsA.mjs} +42 -7
- package/dist/models-BAtL8qsA.mjs.map +1 -0
- package/dist/{models-De2-_GmQ.d.mts → models-CE0fBq0U.d.mts} +2 -2
- package/dist/models-CE0fBq0U.d.mts.map +1 -0
- package/dist/{one-liner-BUQR0nqq.mjs → one-liner-B1rmFto6.mjs} +2 -2
- package/dist/{one-liner-BUQR0nqq.mjs.map → one-liner-B1rmFto6.mjs.map} +1 -1
- package/dist/repl-D20JO260.mjs +10 -0
- package/dist/skills/index.d.mts +303 -12
- package/dist/skills/index.d.mts.map +1 -1
- package/dist/skills/index.mjs +6 -6
- package/dist/skills-5DxAV-rn.mjs +1435 -0
- package/dist/skills-5DxAV-rn.mjs.map +1 -0
- package/dist/stt-Bv_dum-R.mjs +433 -0
- package/dist/stt-Bv_dum-R.mjs.map +1 -0
- package/dist/stt-KzSoNvwI.mjs +3 -0
- package/dist/{tools-BsiEE6f2.mjs → tools-IYPrqoek.mjs} +6 -7
- package/dist/{tools-BsiEE6f2.mjs.map → tools-IYPrqoek.mjs.map} +1 -1
- package/dist/tts-5yWeP_I0.mjs +3 -0
- package/dist/tts-DG6denWG.mjs +729 -0
- package/dist/tts-DG6denWG.mjs.map +1 -0
- package/dist/types-s6Py2_DL.d.mts +353 -0
- package/dist/types-s6Py2_DL.d.mts.map +1 -0
- package/dist/{utils-7vXqtq2Q.mjs → utils-CkB4Roi6.mjs} +1 -1
- package/dist/{utils-7vXqtq2Q.mjs.map → utils-CkB4Roi6.mjs.map} +1 -1
- package/docs/ai-sdk.md +137 -21
- package/docs/browser.md +241 -2
- package/docs/memory.md +72 -0
- package/docs/stt.md +494 -0
- package/docs/tts.md +569 -0
- package/docs/vision.md +396 -0
- package/package.json +17 -18
- package/dist/auto-update-BbNHbSU1.mjs +0 -3
- package/dist/chrome-backend-C5Un08O4.mjs.map +0 -1
- package/dist/gerbil-BfnsFWRE.mjs +0 -644
- package/dist/gerbil-BfnsFWRE.mjs.map +0 -1
- package/dist/gerbil-BjW-z7Fq.mjs +0 -5
- package/dist/gerbil-DZ1k3ChC.d.mts +0 -138
- package/dist/gerbil-DZ1k3ChC.d.mts.map +0 -1
- package/dist/mcp-R8kRLIKb.mjs.map +0 -1
- package/dist/models-DKULvhOr.mjs.map +0 -1
- package/dist/models-De2-_GmQ.d.mts.map +0 -1
- package/dist/skills-D3CEpgDc.mjs +0 -630
- package/dist/skills-D3CEpgDc.mjs.map +0 -1
- package/dist/types-BS1N92Jt.d.mts +0 -183
- package/dist/types-BS1N92Jt.d.mts.map +0 -1
package/dist/skills-D3CEpgDc.mjs
DELETED
|
@@ -1,630 +0,0 @@
|
|
|
1
|
-
import { a as getInstance } from "./one-liner-BUQR0nqq.mjs";
|
|
2
|
-
import { pathToFileURL } from "url";
|
|
3
|
-
import { z } from "zod";
|
|
4
|
-
|
|
5
|
-
//#region src/skills/registry.ts
|
|
6
|
-
const registry = /* @__PURE__ */ new Map();
|
|
7
|
-
const skillSources = /* @__PURE__ */ new Map();
|
|
8
|
-
const RESERVED_NAMES = new Set([
|
|
9
|
-
"repl",
|
|
10
|
-
"chat",
|
|
11
|
-
"skills",
|
|
12
|
-
"tools",
|
|
13
|
-
"model",
|
|
14
|
-
"integrate",
|
|
15
|
-
"benchmark",
|
|
16
|
-
"info",
|
|
17
|
-
"serve",
|
|
18
|
-
"cache",
|
|
19
|
-
"generate",
|
|
20
|
-
"models",
|
|
21
|
-
"bench",
|
|
22
|
-
"r",
|
|
23
|
-
"c",
|
|
24
|
-
"g",
|
|
25
|
-
"help",
|
|
26
|
-
"version",
|
|
27
|
-
"gerbil"
|
|
28
|
-
]);
|
|
29
|
-
/**
|
|
30
|
-
* Define and register a skill
|
|
31
|
-
*
|
|
32
|
-
* @example
|
|
33
|
-
* ```ts
|
|
34
|
-
* const sentiment = defineSkill({
|
|
35
|
-
* name: "sentiment",
|
|
36
|
-
* description: "Analyze sentiment of text",
|
|
37
|
-
* input: z.object({ text: z.string() }),
|
|
38
|
-
* output: z.object({ sentiment: z.enum(["positive", "negative", "neutral"]) }),
|
|
39
|
-
* async run({ input, gerbil }) {
|
|
40
|
-
* return gerbil.json(`Analyze sentiment: ${input.text}`, { schema: this.output });
|
|
41
|
-
* }
|
|
42
|
-
* });
|
|
43
|
-
* ```
|
|
44
|
-
*/
|
|
45
|
-
function defineSkill(definition) {
|
|
46
|
-
if (!/^[a-z][a-z0-9-]*$/.test(definition.name)) throw new Error(`Skill name must be kebab-case starting with a letter: ${definition.name}`);
|
|
47
|
-
if (RESERVED_NAMES.has(definition.name)) throw new Error(`Skill name "${definition.name}" is reserved for CLI commands. Choose a different name.`);
|
|
48
|
-
const execute = async (input) => skill.run(input);
|
|
49
|
-
const skill = Object.assign(execute, {
|
|
50
|
-
definition,
|
|
51
|
-
async run(input, gerbil) {
|
|
52
|
-
const g = gerbil ?? await getInstance(definition.model);
|
|
53
|
-
let validatedInput = input;
|
|
54
|
-
if (definition.input) {
|
|
55
|
-
const parsed = definition.input.safeParse(input);
|
|
56
|
-
if (!parsed.success) throw new Error(`Invalid input for skill "${definition.name}": ${parsed.error.message}`);
|
|
57
|
-
validatedInput = parsed.data;
|
|
58
|
-
}
|
|
59
|
-
const ctx = {
|
|
60
|
-
input: validatedInput,
|
|
61
|
-
gerbil: g,
|
|
62
|
-
rawInput: input,
|
|
63
|
-
definition
|
|
64
|
-
};
|
|
65
|
-
const result = await definition.run.call(definition, ctx);
|
|
66
|
-
if (definition.output && typeof result !== "string") {
|
|
67
|
-
const parsed = definition.output.safeParse(result);
|
|
68
|
-
if (!parsed.success) throw new Error(`Invalid output from skill "${definition.name}": ${parsed.error.message}`);
|
|
69
|
-
return parsed.data;
|
|
70
|
-
}
|
|
71
|
-
return result;
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
registry.set(definition.name, skill);
|
|
75
|
-
return skill;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Get a skill by name
|
|
79
|
-
*
|
|
80
|
-
* @example
|
|
81
|
-
* ```ts
|
|
82
|
-
* const sentiment = useSkill("sentiment");
|
|
83
|
-
* const result = await sentiment({ text: "I love this!" });
|
|
84
|
-
* ```
|
|
85
|
-
*/
|
|
86
|
-
function useSkill(name) {
|
|
87
|
-
const skill = registry.get(name);
|
|
88
|
-
if (!skill) throw new Error(`Skill not found: "${name}". Available: ${listSkills().join(", ") || "none"}`);
|
|
89
|
-
return skill;
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* List all registered skill names
|
|
93
|
-
*/
|
|
94
|
-
function listSkills() {
|
|
95
|
-
return Array.from(registry.keys()).sort();
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Get skill metadata
|
|
99
|
-
*/
|
|
100
|
-
function getSkillInfo(name) {
|
|
101
|
-
const skill = registry.get(name);
|
|
102
|
-
if (!skill) return;
|
|
103
|
-
return {
|
|
104
|
-
name: skill.definition.name,
|
|
105
|
-
description: skill.definition.description,
|
|
106
|
-
version: skill.definition.version,
|
|
107
|
-
author: skill.definition.author,
|
|
108
|
-
builtin: !skillSources.has(name),
|
|
109
|
-
source: skillSources.get(name)
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Check if a skill exists
|
|
114
|
-
*/
|
|
115
|
-
function hasSkill(name) {
|
|
116
|
-
return registry.has(name);
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Remove a skill from registry
|
|
120
|
-
*/
|
|
121
|
-
function removeSkill(name) {
|
|
122
|
-
skillSources.delete(name);
|
|
123
|
-
return registry.delete(name);
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Clear all skills from registry
|
|
127
|
-
*/
|
|
128
|
-
function clearSkills() {
|
|
129
|
-
registry.clear();
|
|
130
|
-
skillSources.clear();
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Get all skill info
|
|
134
|
-
*/
|
|
135
|
-
function getAllSkillInfo() {
|
|
136
|
-
return listSkills().map((name) => getSkillInfo(name));
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Register a skill with its source file (used by loader)
|
|
140
|
-
* @internal
|
|
141
|
-
*/
|
|
142
|
-
function registerSkillWithSource(skill, source) {
|
|
143
|
-
registry.set(skill.definition.name, skill);
|
|
144
|
-
skillSources.set(skill.definition.name, source);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
//#endregion
|
|
148
|
-
//#region src/skills/loader.ts
|
|
149
|
-
/**
|
|
150
|
-
* Skill Loader
|
|
151
|
-
*
|
|
152
|
-
* Load skills from files, directories, and packages.
|
|
153
|
-
*/
|
|
154
|
-
/**
|
|
155
|
-
* Load skills from the project's .gerbil/skills/ directory
|
|
156
|
-
*
|
|
157
|
-
* This is the standard location for project-specific skills.
|
|
158
|
-
* Creates the directory structure if it doesn't exist.
|
|
159
|
-
*
|
|
160
|
-
* @example
|
|
161
|
-
* ```ts
|
|
162
|
-
* // Load from .gerbil/skills/ in current working directory
|
|
163
|
-
* const loaded = await loadProjectSkills();
|
|
164
|
-
* console.log(`Loaded ${loaded.length} project skills`);
|
|
165
|
-
* ```
|
|
166
|
-
*/
|
|
167
|
-
async function loadProjectSkills(cwd = process.cwd()) {
|
|
168
|
-
const path = await import("path");
|
|
169
|
-
const fs = await import("fs");
|
|
170
|
-
const gerbilDir = path.join(cwd, ".gerbil");
|
|
171
|
-
const skillsDir = path.join(gerbilDir, "skills");
|
|
172
|
-
if (!fs.existsSync(skillsDir)) return [];
|
|
173
|
-
return loadSkills(skillsDir);
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Load all skills from a directory
|
|
177
|
-
*
|
|
178
|
-
* @example
|
|
179
|
-
* ```ts
|
|
180
|
-
* // Load all *.skill.ts and *.skill.js files
|
|
181
|
-
* const loaded = await loadSkills("./skills");
|
|
182
|
-
* console.log(`Loaded ${loaded.length} skills`);
|
|
183
|
-
* ```
|
|
184
|
-
*/
|
|
185
|
-
async function loadSkills(dir, options = {}) {
|
|
186
|
-
const { patterns = ["*.skill.ts", "*.skill.js"] } = options;
|
|
187
|
-
const loaded = [];
|
|
188
|
-
try {
|
|
189
|
-
const fs = await import("fs");
|
|
190
|
-
const path = await import("path");
|
|
191
|
-
const resolvedDir = path.resolve(dir);
|
|
192
|
-
if (!fs.existsSync(resolvedDir)) throw new Error(`Skills directory not found: ${dir}`);
|
|
193
|
-
const files = fs.readdirSync(resolvedDir);
|
|
194
|
-
for (const file of files) if (patterns.some((pattern) => {
|
|
195
|
-
return (/* @__PURE__ */ new RegExp(`^${pattern.replace(/\*/g, ".*").replace(/\./g, "\\.")}$`)).test(file);
|
|
196
|
-
})) {
|
|
197
|
-
const skill = await loadSkill(path.join(resolvedDir, file));
|
|
198
|
-
if (skill) loaded.push(skill.definition.name);
|
|
199
|
-
}
|
|
200
|
-
} catch (error) {
|
|
201
|
-
if (error.code === "MODULE_NOT_FOUND") throw new Error(`Skills directory not found: ${dir}`);
|
|
202
|
-
throw error;
|
|
203
|
-
}
|
|
204
|
-
return loaded;
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* Load a single skill from a file
|
|
208
|
-
*
|
|
209
|
-
* @example
|
|
210
|
-
* ```ts
|
|
211
|
-
* const skill = await loadSkill("./skills/sentiment.skill.ts");
|
|
212
|
-
* if (skill) {
|
|
213
|
-
* const result = await skill({ text: "Hello" });
|
|
214
|
-
* }
|
|
215
|
-
* ```
|
|
216
|
-
*/
|
|
217
|
-
async function loadSkill(filePath) {
|
|
218
|
-
try {
|
|
219
|
-
const resolvedPath = (await import("path")).resolve(filePath);
|
|
220
|
-
const skill = (await import(pathToFileURL(resolvedPath).href)).default;
|
|
221
|
-
if (!skill?.definition) {
|
|
222
|
-
console.warn(`No valid skill found in ${filePath}`);
|
|
223
|
-
return null;
|
|
224
|
-
}
|
|
225
|
-
registerSkillWithSource(skill, resolvedPath);
|
|
226
|
-
return skill;
|
|
227
|
-
} catch (error) {
|
|
228
|
-
console.error(`Failed to load skill from ${filePath}:`, error);
|
|
229
|
-
return null;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
* Load skills from an npm package
|
|
234
|
-
*
|
|
235
|
-
* @example
|
|
236
|
-
* ```ts
|
|
237
|
-
* // Load skills from a package
|
|
238
|
-
* const loaded = await loadSkillPackage("gerbil-skills-extra");
|
|
239
|
-
* ```
|
|
240
|
-
*/
|
|
241
|
-
async function loadSkillPackage(packageName) {
|
|
242
|
-
try {
|
|
243
|
-
const module = await import(packageName);
|
|
244
|
-
const loaded = [];
|
|
245
|
-
for (const [_key, value] of Object.entries(module)) if (isSkill(value)) {
|
|
246
|
-
const skill = value;
|
|
247
|
-
registerSkillWithSource(skill, `npm:${packageName}`);
|
|
248
|
-
loaded.push(skill.definition.name);
|
|
249
|
-
}
|
|
250
|
-
if (module.default && typeof module.default === "object") {
|
|
251
|
-
for (const [_key, value] of Object.entries(module.default)) if (isSkill(value)) {
|
|
252
|
-
const skill = value;
|
|
253
|
-
registerSkillWithSource(skill, `npm:${packageName}`);
|
|
254
|
-
loaded.push(skill.definition.name);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
return loaded;
|
|
258
|
-
} catch (error) {
|
|
259
|
-
throw new Error(`Failed to load skill package "${packageName}": ${error}`);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* Check if a value is a Skill
|
|
264
|
-
*/
|
|
265
|
-
function isSkill(value) {
|
|
266
|
-
return typeof value === "function" && typeof value.definition === "object" && typeof value.definition.name === "string" && typeof value.definition.run === "function";
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
//#endregion
|
|
270
|
-
//#region src/skills/builtin/commit.ts
|
|
271
|
-
/**
|
|
272
|
-
* Commit Skill
|
|
273
|
-
*
|
|
274
|
-
* Generate git commit messages from staged changes.
|
|
275
|
-
*/
|
|
276
|
-
const CommitInput = z.object({
|
|
277
|
-
diff: z.string().optional(),
|
|
278
|
-
type: z.enum([
|
|
279
|
-
"conventional",
|
|
280
|
-
"simple",
|
|
281
|
-
"detailed"
|
|
282
|
-
]).default("conventional"),
|
|
283
|
-
maxLength: z.number().default(72)
|
|
284
|
-
});
|
|
285
|
-
async function getGitDiff() {
|
|
286
|
-
try {
|
|
287
|
-
const { execSync } = await import("child_process");
|
|
288
|
-
return execSync("git diff --staged", { encoding: "utf-8" });
|
|
289
|
-
} catch {
|
|
290
|
-
return "";
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
function getSystemPrompt(type) {
|
|
294
|
-
switch (type) {
|
|
295
|
-
case "conventional": return `Generate a git commit message following the Conventional Commits format.
|
|
296
|
-
Use one of these types: feat, fix, docs, style, refactor, perf, test, chore.
|
|
297
|
-
Format: type(scope): description
|
|
298
|
-
Keep it under 72 characters.
|
|
299
|
-
No period at the end.
|
|
300
|
-
Only output the commit message, nothing else.`;
|
|
301
|
-
case "detailed": return `Generate a detailed git commit message with a subject line and body.
|
|
302
|
-
Subject: under 72 chars, imperative mood
|
|
303
|
-
Body: explain what and why
|
|
304
|
-
Only output the commit message, nothing else.`;
|
|
305
|
-
default: return `Generate a concise git commit message.
|
|
306
|
-
Use imperative mood (e.g., "Add", "Fix", "Update").
|
|
307
|
-
Keep it under 72 characters.
|
|
308
|
-
No period at the end.
|
|
309
|
-
Only output the commit message, nothing else.`;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
const commit = defineSkill({
|
|
313
|
-
name: "commit",
|
|
314
|
-
description: "Generate a git commit message from staged changes",
|
|
315
|
-
version: "1.0.0",
|
|
316
|
-
input: CommitInput,
|
|
317
|
-
temperature: .3,
|
|
318
|
-
maxTokens: 100,
|
|
319
|
-
async run({ input, gerbil }) {
|
|
320
|
-
const { diff, type = "conventional", maxLength = 72 } = input;
|
|
321
|
-
const actualDiff = diff || await getGitDiff();
|
|
322
|
-
if (!actualDiff || actualDiff.trim().length === 0) throw new Error("No changes staged. Run `git add` first.");
|
|
323
|
-
let message = (await gerbil.generate(`Generate a commit message for the following diff:\n\n${actualDiff}`, {
|
|
324
|
-
system: getSystemPrompt(type),
|
|
325
|
-
maxTokens: this.maxTokens,
|
|
326
|
-
temperature: this.temperature
|
|
327
|
-
})).text.trim();
|
|
328
|
-
message = message.replace(/<think>[\s\S]*?<\/think>/g, "").trim();
|
|
329
|
-
message = message.replace(/<\/?think>/g, "").trim();
|
|
330
|
-
message = message.replace(/^["']|["']$/g, "");
|
|
331
|
-
message = message.split("\n")[0];
|
|
332
|
-
if (message.length > maxLength) message = `${message.substring(0, maxLength - 3)}...`;
|
|
333
|
-
return message;
|
|
334
|
-
}
|
|
335
|
-
});
|
|
336
|
-
|
|
337
|
-
//#endregion
|
|
338
|
-
//#region src/skills/builtin/explain.ts
|
|
339
|
-
/**
|
|
340
|
-
* Explain Skill
|
|
341
|
-
*
|
|
342
|
-
* Explain code or concepts at various levels.
|
|
343
|
-
*/
|
|
344
|
-
const ExplainInput = z.object({
|
|
345
|
-
content: z.string(),
|
|
346
|
-
level: z.enum([
|
|
347
|
-
"beginner",
|
|
348
|
-
"intermediate",
|
|
349
|
-
"expert"
|
|
350
|
-
]).default("intermediate"),
|
|
351
|
-
language: z.string().optional()
|
|
352
|
-
});
|
|
353
|
-
const levelGuide = {
|
|
354
|
-
beginner: "Explain like I'm new to programming. Use simple terms and analogies.",
|
|
355
|
-
intermediate: "Explain for someone with programming experience.",
|
|
356
|
-
expert: "Explain with technical depth, including implementation details."
|
|
357
|
-
};
|
|
358
|
-
const explain = defineSkill({
|
|
359
|
-
name: "explain",
|
|
360
|
-
description: "Explain code or concepts at various levels",
|
|
361
|
-
version: "1.0.0",
|
|
362
|
-
input: ExplainInput,
|
|
363
|
-
temperature: .5,
|
|
364
|
-
maxTokens: 500,
|
|
365
|
-
async run({ input, gerbil }) {
|
|
366
|
-
const { content, level = "intermediate", language } = input;
|
|
367
|
-
let systemPrompt = `You are a patient teacher.
|
|
368
|
-
${levelGuide[level]}`;
|
|
369
|
-
if (language) systemPrompt += `\nThis is ${language} code.`;
|
|
370
|
-
systemPrompt += "\nBe clear and concise.";
|
|
371
|
-
return (await gerbil.generate(`Explain this:\n\n${content}`, {
|
|
372
|
-
system: systemPrompt,
|
|
373
|
-
maxTokens: this.maxTokens,
|
|
374
|
-
temperature: this.temperature
|
|
375
|
-
})).text;
|
|
376
|
-
}
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
//#endregion
|
|
380
|
-
//#region src/skills/builtin/extract.ts
|
|
381
|
-
/**
|
|
382
|
-
* Extract Skill
|
|
383
|
-
*
|
|
384
|
-
* Extract structured data from content.
|
|
385
|
-
*/
|
|
386
|
-
const ExtractInput = z.object({
|
|
387
|
-
content: z.string(),
|
|
388
|
-
schema: z.any(),
|
|
389
|
-
context: z.string().optional()
|
|
390
|
-
});
|
|
391
|
-
const extract = defineSkill({
|
|
392
|
-
name: "extract",
|
|
393
|
-
description: "Extract structured data from content",
|
|
394
|
-
version: "1.0.0",
|
|
395
|
-
input: ExtractInput,
|
|
396
|
-
temperature: .3,
|
|
397
|
-
async run({ input, gerbil }) {
|
|
398
|
-
const { content, schema, context } = input;
|
|
399
|
-
let prompt = "Extract structured data from the following content.";
|
|
400
|
-
if (context) prompt += `\nContext: ${context}`;
|
|
401
|
-
prompt += `\n\nContent:\n${content}`;
|
|
402
|
-
return gerbil.json(prompt, { schema });
|
|
403
|
-
}
|
|
404
|
-
});
|
|
405
|
-
|
|
406
|
-
//#endregion
|
|
407
|
-
//#region src/skills/builtin/review.ts
|
|
408
|
-
/**
|
|
409
|
-
* Review Skill
|
|
410
|
-
*
|
|
411
|
-
* Code review with configurable focus areas.
|
|
412
|
-
*/
|
|
413
|
-
const ReviewInput = z.object({
|
|
414
|
-
code: z.string(),
|
|
415
|
-
focus: z.array(z.enum([
|
|
416
|
-
"security",
|
|
417
|
-
"performance",
|
|
418
|
-
"style",
|
|
419
|
-
"bugs",
|
|
420
|
-
"all"
|
|
421
|
-
])).default(["all"]),
|
|
422
|
-
format: z.enum([
|
|
423
|
-
"inline",
|
|
424
|
-
"summary",
|
|
425
|
-
"detailed"
|
|
426
|
-
]).default("summary")
|
|
427
|
-
});
|
|
428
|
-
const review = defineSkill({
|
|
429
|
-
name: "review",
|
|
430
|
-
description: "Code review with configurable focus areas",
|
|
431
|
-
version: "1.0.0",
|
|
432
|
-
input: ReviewInput,
|
|
433
|
-
temperature: .3,
|
|
434
|
-
maxTokens: 600,
|
|
435
|
-
async run({ input, gerbil }) {
|
|
436
|
-
const { code, focus = ["all"], format = "summary" } = input;
|
|
437
|
-
let systemPrompt = `You are a senior code reviewer.
|
|
438
|
-
Review the code for:`;
|
|
439
|
-
if (focus.includes("all")) systemPrompt += "\n- Security vulnerabilities\n- Performance issues\n- Code style and readability\n- Potential bugs";
|
|
440
|
-
else {
|
|
441
|
-
if (focus.includes("security")) systemPrompt += "\n- Security vulnerabilities";
|
|
442
|
-
if (focus.includes("performance")) systemPrompt += "\n- Performance issues";
|
|
443
|
-
if (focus.includes("style")) systemPrompt += "\n- Code style and readability";
|
|
444
|
-
if (focus.includes("bugs")) systemPrompt += "\n- Potential bugs";
|
|
445
|
-
}
|
|
446
|
-
if (format === "summary") systemPrompt += "\n\nProvide a brief summary of issues found.";
|
|
447
|
-
else if (format === "detailed") systemPrompt += "\n\nProvide detailed feedback with suggestions.";
|
|
448
|
-
else systemPrompt += "\n\nProvide inline-style comments.";
|
|
449
|
-
return (await gerbil.generate(`Review this code:\n\n${code}`, {
|
|
450
|
-
system: systemPrompt,
|
|
451
|
-
maxTokens: this.maxTokens,
|
|
452
|
-
temperature: this.temperature
|
|
453
|
-
})).text;
|
|
454
|
-
}
|
|
455
|
-
});
|
|
456
|
-
|
|
457
|
-
//#endregion
|
|
458
|
-
//#region src/skills/builtin/summarize.ts
|
|
459
|
-
/**
|
|
460
|
-
* Summarize Skill
|
|
461
|
-
*
|
|
462
|
-
* Summarize content in various lengths and formats.
|
|
463
|
-
*/
|
|
464
|
-
const SummarizeInput = z.object({
|
|
465
|
-
content: z.string(),
|
|
466
|
-
length: z.enum([
|
|
467
|
-
"short",
|
|
468
|
-
"medium",
|
|
469
|
-
"long"
|
|
470
|
-
]).default("medium"),
|
|
471
|
-
format: z.enum(["paragraph", "bullets"]).default("paragraph"),
|
|
472
|
-
focus: z.array(z.string()).optional()
|
|
473
|
-
});
|
|
474
|
-
const lengthGuide = {
|
|
475
|
-
short: "2-3 sentences",
|
|
476
|
-
medium: "1 paragraph (4-6 sentences)",
|
|
477
|
-
long: "2-3 paragraphs"
|
|
478
|
-
};
|
|
479
|
-
const maxTokensGuide = {
|
|
480
|
-
short: 100,
|
|
481
|
-
medium: 200,
|
|
482
|
-
long: 400
|
|
483
|
-
};
|
|
484
|
-
const summarize = defineSkill({
|
|
485
|
-
name: "summarize",
|
|
486
|
-
description: "Summarize content in various lengths and formats",
|
|
487
|
-
version: "1.0.0",
|
|
488
|
-
input: SummarizeInput,
|
|
489
|
-
temperature: .3,
|
|
490
|
-
async run({ input, gerbil }) {
|
|
491
|
-
const { content, length = "medium", format = "paragraph", focus } = input;
|
|
492
|
-
let systemPrompt = `You are a summarization expert.
|
|
493
|
-
Summarize the content in ${lengthGuide[length]}.`;
|
|
494
|
-
if (format === "bullets") systemPrompt += "\nUse bullet points.";
|
|
495
|
-
if (focus && focus.length > 0) systemPrompt += `\nFocus on: ${focus.join(", ")}.`;
|
|
496
|
-
systemPrompt += "\nOnly output the summary, nothing else.";
|
|
497
|
-
return (await gerbil.generate(`Summarize this:\n\n${content}`, {
|
|
498
|
-
system: systemPrompt,
|
|
499
|
-
maxTokens: maxTokensGuide[length],
|
|
500
|
-
temperature: this.temperature
|
|
501
|
-
})).text;
|
|
502
|
-
}
|
|
503
|
-
});
|
|
504
|
-
|
|
505
|
-
//#endregion
|
|
506
|
-
//#region src/skills/builtin/test.ts
|
|
507
|
-
/**
|
|
508
|
-
* Test Skill
|
|
509
|
-
*
|
|
510
|
-
* Generate tests for code.
|
|
511
|
-
*/
|
|
512
|
-
const TestInput = z.object({
|
|
513
|
-
code: z.string(),
|
|
514
|
-
framework: z.enum([
|
|
515
|
-
"jest",
|
|
516
|
-
"vitest",
|
|
517
|
-
"mocha",
|
|
518
|
-
"playwright"
|
|
519
|
-
]).default("vitest"),
|
|
520
|
-
style: z.enum([
|
|
521
|
-
"unit",
|
|
522
|
-
"integration",
|
|
523
|
-
"e2e"
|
|
524
|
-
]).default("unit")
|
|
525
|
-
});
|
|
526
|
-
const test = defineSkill({
|
|
527
|
-
name: "test",
|
|
528
|
-
description: "Generate tests for code",
|
|
529
|
-
version: "1.0.0",
|
|
530
|
-
input: TestInput,
|
|
531
|
-
temperature: .3,
|
|
532
|
-
maxTokens: 800,
|
|
533
|
-
async run({ input, gerbil }) {
|
|
534
|
-
const { code, framework, style } = input;
|
|
535
|
-
const systemPrompt = `You are a test engineer.
|
|
536
|
-
Generate ${style} tests using ${framework} for the provided code.
|
|
537
|
-
Include edge cases and error scenarios.
|
|
538
|
-
Only output the test code, no explanations.`;
|
|
539
|
-
return (await gerbil.generate(`Generate tests for:\n\n${code}`, {
|
|
540
|
-
system: systemPrompt,
|
|
541
|
-
maxTokens: this.maxTokens,
|
|
542
|
-
temperature: this.temperature
|
|
543
|
-
})).text;
|
|
544
|
-
}
|
|
545
|
-
});
|
|
546
|
-
|
|
547
|
-
//#endregion
|
|
548
|
-
//#region src/skills/builtin/title.ts
|
|
549
|
-
/**
|
|
550
|
-
* Title Skill
|
|
551
|
-
*
|
|
552
|
-
* Generate titles for content.
|
|
553
|
-
*/
|
|
554
|
-
const TitleInput = z.object({
|
|
555
|
-
content: z.string(),
|
|
556
|
-
style: z.enum([
|
|
557
|
-
"professional",
|
|
558
|
-
"clickbait",
|
|
559
|
-
"seo",
|
|
560
|
-
"simple"
|
|
561
|
-
]).default("professional"),
|
|
562
|
-
maxLength: z.number().default(60)
|
|
563
|
-
});
|
|
564
|
-
const styleGuide = {
|
|
565
|
-
professional: "Clear, informative, and professional",
|
|
566
|
-
clickbait: "Engaging and curiosity-inducing",
|
|
567
|
-
seo: "SEO-optimized with relevant keywords",
|
|
568
|
-
simple: "Simple and straightforward"
|
|
569
|
-
};
|
|
570
|
-
const title = defineSkill({
|
|
571
|
-
name: "title",
|
|
572
|
-
description: "Generate titles for content",
|
|
573
|
-
version: "1.0.0",
|
|
574
|
-
input: TitleInput,
|
|
575
|
-
temperature: .7,
|
|
576
|
-
maxTokens: 30,
|
|
577
|
-
async run({ input, gerbil }) {
|
|
578
|
-
const { content, style = "professional", maxLength = 60 } = input;
|
|
579
|
-
const systemPrompt = `Generate a title for the content.
|
|
580
|
-
Style: ${styleGuide[style]}
|
|
581
|
-
Max length: ${maxLength} characters
|
|
582
|
-
Only output the title, nothing else.`;
|
|
583
|
-
let generatedTitle = (await gerbil.generate(`Generate a title for:\n\n${content.substring(0, 1e3)}`, {
|
|
584
|
-
system: systemPrompt,
|
|
585
|
-
maxTokens: this.maxTokens,
|
|
586
|
-
temperature: this.temperature
|
|
587
|
-
})).text.trim();
|
|
588
|
-
generatedTitle = generatedTitle.replace(/^["']|["']$/g, "");
|
|
589
|
-
if (generatedTitle.length > maxLength) generatedTitle = `${generatedTitle.substring(0, maxLength - 3)}...`;
|
|
590
|
-
return generatedTitle;
|
|
591
|
-
}
|
|
592
|
-
});
|
|
593
|
-
|
|
594
|
-
//#endregion
|
|
595
|
-
//#region src/skills/builtin/translate.ts
|
|
596
|
-
/**
|
|
597
|
-
* Translate Skill
|
|
598
|
-
*
|
|
599
|
-
* Translate text between languages.
|
|
600
|
-
*/
|
|
601
|
-
const TranslateInput = z.object({
|
|
602
|
-
text: z.string(),
|
|
603
|
-
from: z.string().optional(),
|
|
604
|
-
to: z.string(),
|
|
605
|
-
preserveFormatting: z.boolean().default(true)
|
|
606
|
-
});
|
|
607
|
-
const translate = defineSkill({
|
|
608
|
-
name: "translate",
|
|
609
|
-
description: "Translate text between languages",
|
|
610
|
-
version: "1.0.0",
|
|
611
|
-
input: TranslateInput,
|
|
612
|
-
temperature: .3,
|
|
613
|
-
async run({ input, gerbil }) {
|
|
614
|
-
const { text, from, to, preserveFormatting } = input;
|
|
615
|
-
let systemPrompt = `You are a professional translator.
|
|
616
|
-
Translate the text to ${to}.`;
|
|
617
|
-
if (from) systemPrompt += `\nThe source language is ${from}.`;
|
|
618
|
-
if (preserveFormatting) systemPrompt += "\nPreserve the original formatting (paragraphs, lists, etc.).";
|
|
619
|
-
systemPrompt += "\nOnly output the translation, nothing else.";
|
|
620
|
-
return (await gerbil.generate(`Translate:\n\n${text}`, {
|
|
621
|
-
system: systemPrompt,
|
|
622
|
-
maxTokens: Math.ceil(text.length / 2),
|
|
623
|
-
temperature: this.temperature
|
|
624
|
-
})).text;
|
|
625
|
-
}
|
|
626
|
-
});
|
|
627
|
-
|
|
628
|
-
//#endregion
|
|
629
|
-
export { hasSkill as _, review as a, useSkill as b, commit as c, loadSkillPackage as d, loadSkills as f, getSkillInfo as g, getAllSkillInfo as h, summarize as i, loadProjectSkills as l, defineSkill as m, title as n, extract as o, clearSkills as p, test as r, explain as s, translate as t, loadSkill as u, listSkills as v, removeSkill as y };
|
|
630
|
-
//# sourceMappingURL=skills-D3CEpgDc.mjs.map
|