src / config.ts
import { createConfigSchematics } from "@lmstudio/sdk";
import * as os from "os";
import * as path from "path";
export const configSchematics = createConfigSchematics()
.field(
"jevApiKey",
"string",
{
displayName: "Jev API key",
subtitle: "TypeSafe API key used to route skills. Leave blank to use the JEV_API_KEY environment variable.",
isProtected: true,
placeholder: "paste your key here",
},
"",
)
.field(
"threshold",
"numeric",
{
min: 0,
max: 1,
displayName: "Routing threshold",
subtitle: "Minimum jev probability to auto-apply a skill.",
slider: { min: 0, max: 1, step: 0.05 },
},
0.6,
)
.field(
"maxSkills",
"numeric",
{
int: true,
min: 0,
max: 5,
displayName: "Max skills per message",
subtitle: "0 disables auto-injection (hint list only).",
slider: { min: 0, max: 5, step: 1 },
},
2,
)
.field(
"historyTurns",
"numeric",
{
int: true,
min: 0,
max: 10,
displayName: "History turns for routing",
subtitle: "Recent messages sent to jev as context.",
slider: { min: 0, max: 10, step: 1 },
},
4,
)
.field(
"maxInjectedChars",
"numeric",
{
int: true,
min: 1000,
max: 60000,
displayName: "Max injected characters",
subtitle: "Cap on an injected SKILL.md body. The rest is available via read_skill_file.",
},
12000,
)
.field(
"showHintWhenNoMatch",
"boolean",
{
displayName: "Show available skills when nothing matched",
subtitle: "Append the <available_skills> list even when jev ran and matched nothing.",
},
false,
)
.build();
export const globalConfigSchematics = createConfigSchematics()
.field(
"skillsRoot",
"string",
{
displayName: "Skills root",
subtitle: "Directory whose subfolders contain SKILL.md files. ~ is expanded.",
},
"~/.agents/skills",
)
.build();
/** Expands a leading ~ to the home directory and normalises the path. An empty value means the default root. */
export function expandHome(p: string, home: string = os.homedir()): string {
const trimmed = p.trim();
if (trimmed === "") return path.join(home, ".agents/skills");
if (trimmed === "~") return home;
if (trimmed.startsWith("~/")) return path.join(home, trimmed.slice(2));
return path.resolve(trimmed);
}
src / config.ts
import { createConfigSchematics } from "@lmstudio/sdk";
import * as os from "os";
import * as path from "path";
export const configSchematics = createConfigSchematics()
.field(
"jevApiKey",
"string",
{
displayName: "Jev API key",
subtitle: "TypeSafe API key used to route skills. Leave blank to use the JEV_API_KEY environment variable.",
isProtected: true,
placeholder: "paste your key here",
},
"",
)
.field(
"threshold",
"numeric",
{
min: 0,
max: 1,
displayName: "Routing threshold",
subtitle: "Minimum jev probability to auto-apply a skill.",
slider: { min: 0, max: 1, step: 0.05 },
},
0.6,
)
.field(
"maxSkills",
"numeric",
{
int: true,
min: 0,
max: 5,
displayName: "Max skills per message",
subtitle: "0 disables auto-injection (hint list only).",
slider: { min: 0, max: 5, step: 1 },
},
2,
)
.field(
"historyTurns",
"numeric",
{
int: true,
min: 0,
max: 10,
displayName: "History turns for routing",
subtitle: "Recent messages sent to jev as context.",
slider: { min: 0, max: 10, step: 1 },
},
4,
)
.field(
"maxInjectedChars",
"numeric",
{
int: true,
min: 1000,
max: 60000,
displayName: "Max injected characters",
subtitle: "Cap on an injected SKILL.md body. The rest is available via read_skill_file.",
},
12000,
)
.field(
"showHintWhenNoMatch",
"boolean",
{
displayName: "Show available skills when nothing matched",
subtitle: "Append the <available_skills> list even when jev ran and matched nothing.",
},
false,
)
.build();
export const globalConfigSchematics = createConfigSchematics()
.field(
"skillsRoot",
"string",
{
displayName: "Skills root",
subtitle: "Directory whose subfolders contain SKILL.md files. ~ is expanded.",
},
"~/.agents/skills",
)
.build();
/** Expands a leading ~ to the home directory and normalises the path. An empty value means the default root. */
export function expandHome(p: string, home: string = os.homedir()): string {
const trimmed = p.trim();
if (trimmed === "") return path.join(home, ".agents/skills");
if (trimmed === "~") return home;
if (trimmed.startsWith("~/")) return path.join(home, trimmed.slice(2));
return path.resolve(trimmed);
}