feat: add skills search and website

This commit is contained in:
Peter Steinberger
2025-12-20 17:31:09 +01:00
parent c4a67b7d02
commit ba0791b896
9 changed files with 125 additions and 23 deletions

View File

@@ -51,8 +51,8 @@ function buildNodeInstallCommand(
switch (prefs.nodeManager) {
case "pnpm":
return ["pnpm", "add", "-g", packageName];
case "bun":
return ["bun", "add", "-g", packageName];
case "yarn":
return ["yarn", "global", "add", packageName];
default:
return ["npm", "install", "-g", packageName];
}

View File

@@ -36,6 +36,7 @@ export type SkillStatusEntry = {
skillKey: string;
primaryEnv?: string;
emoji?: string;
homepage?: string;
always: boolean;
disabled: boolean;
eligible: boolean;
@@ -135,6 +136,12 @@ function buildSkillStatus(
const disabled = skillConfig?.enabled === false;
const always = entry.clawdis?.always === true;
const emoji = entry.clawdis?.emoji ?? entry.frontmatter.emoji;
const homepageRaw =
entry.clawdis?.homepage ??
entry.frontmatter.homepage ??
entry.frontmatter.website ??
entry.frontmatter.url;
const homepage = homepageRaw?.trim() ? homepageRaw.trim() : undefined;
const requiredBins = entry.clawdis?.requires?.bins ?? [];
const requiredEnv = entry.clawdis?.requires?.env ?? [];
@@ -182,6 +189,7 @@ function buildSkillStatus(
skillKey,
primaryEnv: entry.clawdis?.primaryEnv,
emoji,
homepage,
always,
disabled,
eligible,

View File

@@ -29,6 +29,7 @@ export type ClawdisSkillMetadata = {
skillKey?: string;
primaryEnv?: string;
emoji?: string;
homepage?: string;
requires?: {
bins?: string[];
env?: string[];
@@ -39,7 +40,7 @@ export type ClawdisSkillMetadata = {
export type SkillsInstallPreferences = {
preferBrew: boolean;
nodeManager: "npm" | "pnpm" | "bun";
nodeManager: "npm" | "pnpm" | "yarn";
};
type ParsedSkillFrontmatter = Record<string, string>;
@@ -189,7 +190,7 @@ export function resolveSkillsInstallPreferences(
typeof raw?.nodeManager === "string" ? raw.nodeManager.trim() : "";
const manager = managerRaw.toLowerCase();
const nodeManager =
manager === "pnpm" || manager === "bun" || manager === "npm"
manager === "pnpm" || manager === "yarn" || manager === "npm"
? (manager as SkillsInstallPreferences["nodeManager"])
: "npm";
return { preferBrew, nodeManager };
@@ -271,6 +272,10 @@ function resolveClawdisMetadata(
typeof clawdisObj.always === "boolean" ? clawdisObj.always : undefined,
emoji:
typeof clawdisObj.emoji === "string" ? clawdisObj.emoji : undefined,
homepage:
typeof clawdisObj.homepage === "string"
? clawdisObj.homepage
: undefined,
skillKey:
typeof clawdisObj.skillKey === "string"
? clawdisObj.skillKey

View File

@@ -97,6 +97,8 @@ export type CanvasHostConfig = {
enabled?: boolean;
/** Directory to serve (default: ~/clawd/canvas). */
root?: string;
/** HTTP port to listen on (default: 18793). */
port?: number;
};
export type GatewayControlUiConfig = {
@@ -135,7 +137,7 @@ export type SkillsLoadConfig = {
export type SkillsInstallConfig = {
preferBrew?: boolean;
nodeManager?: "npm" | "pnpm" | "bun";
nodeManager?: "npm" | "pnpm" | "yarn";
};
export type ClawdisConfig = {
@@ -147,6 +149,7 @@ export type ClawdisConfig = {
logging?: LoggingConfig;
browser?: BrowserConfig;
skillsLoad?: SkillsLoadConfig;
skillsInstall?: SkillsInstallConfig;
inbound?: {
allowFrom?: string[]; // E.164 numbers allowed to trigger auto-reply (without whatsapp:)
/** Agent working directory (preferred). Used as the default cwd for agent runs. */
@@ -188,7 +191,6 @@ export type ClawdisConfig = {
canvasHost?: CanvasHostConfig;
gateway?: GatewayConfig;
skills?: Record<string, SkillConfig>;
skillsInstall?: SkillsInstallConfig;
};
// New branding path (preferred)
@@ -349,6 +351,7 @@ const ClawdisSchema = z.object({
.object({
enabled: z.boolean().optional(),
root: z.string().optional(),
port: z.number().int().positive().optional(),
})
.optional(),
gateway: z
@@ -378,7 +381,7 @@ const ClawdisSchema = z.object({
.object({
preferBrew: z.boolean().optional(),
nodeManager: z
.union([z.literal("npm"), z.literal("pnpm"), z.literal("bun")])
.union([z.literal("npm"), z.literal("pnpm"), z.literal("yarn")])
.optional(),
})
.optional(),