Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/agents/src/__tests__/adapters.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ const ALL_AGENTS = AgentType.options;

describe('Agent Adapters', () => {
describe('getAllAdapters', () => {
it('should return all 44 registered adapters', () => {
it('should return all 45 registered adapters', () => {
const adapters = getAllAdapters();
expect(adapters).toBeInstanceOf(Array);
expect(adapters.length).toBe(44);
expect(adapters.length).toBe(45);
});

it('should include common agents', () => {
Expand Down
11 changes: 0 additions & 11 deletions packages/agents/src/__tests__/clawdbot.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,16 +236,6 @@ describe('ClawdbotAdapter', () => {
});

describe('isDetected', () => {
it('should detect Clawdbot from workspace skills directory', async () => {
mockExistsSync.mockImplementation((path) => {
return path === join(process.cwd(), 'skills');
});

const detected = await adapter.isDetected();

expect(detected).toBe(true);
});

it('should detect Clawdbot from global directory', async () => {
mockExistsSync.mockImplementation((path) => {
return path === join(homedir(), '.clawdbot');
Expand Down Expand Up @@ -287,7 +277,6 @@ describe('ClawdbotAdapter', () => {

await adapter.isDetected();

expect(mockExistsSync).toHaveBeenCalledWith(join(process.cwd(), 'skills'));
expect(mockExistsSync).toHaveBeenCalledWith(join(homedir(), '.clawdbot'));
expect(mockExistsSync).toHaveBeenCalledWith(join(process.cwd(), 'clawdbot.json'));
});
Expand Down
9 changes: 4 additions & 5 deletions packages/agents/src/clawdbot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ const config = AGENT_CONFIG.clawdbot;

export class ClawdbotAdapter implements AgentAdapter {
readonly type: AgentType = 'clawdbot';
readonly name = 'Clawdbot';
readonly skillsDir = config.skillsDir;
readonly configFile = config.configFile;
readonly name: string = 'Clawdbot';
readonly skillsDir: string = config.skillsDir;
readonly configFile: string = config.configFile;

generateConfig(skills: Skill[]): string {
const enabledSkills = skills.filter(s => s.enabled);
Expand Down Expand Up @@ -69,10 +69,9 @@ ${skillsXml}
}

async isDetected(): Promise<boolean> {
const projectSkills = join(process.cwd(), 'skills');
const globalClawdbot = join(homedir(), '.clawdbot');
const clawdbotConfig = join(process.cwd(), 'clawdbot.json');

return existsSync(projectSkills) || existsSync(globalClawdbot) || existsSync(clawdbotConfig);
return existsSync(globalClawdbot) || existsSync(clawdbotConfig);
}
}
4 changes: 4 additions & 0 deletions packages/agents/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { OpenCodeAdapter } from './opencode.js';
import { AntigravityAdapter } from './antigravity.js';
import { AmpAdapter } from './amp.js';
import { ClawdbotAdapter } from './clawdbot.js';
import { OpenClawAdapter } from './openclaw.js';
import { DroidAdapter } from './droid.js';
import { FactoryAdapter } from './factory.js';
import { GitHubCopilotAdapter } from './github-copilot.js';
Expand All @@ -29,6 +30,7 @@ export * from './opencode.js';
export * from './antigravity.js';
export * from './amp.js';
export * from './clawdbot.js';
export * from './openclaw.js';
export * from './droid.js';
export * from './factory.js';
export * from './github-copilot.js';
Expand All @@ -53,6 +55,7 @@ const adapters: Record<AgentType, AgentAdapter> = {
antigravity: new AntigravityAdapter(),
amp: new AmpAdapter(),
clawdbot: new ClawdbotAdapter(),
openclaw: new OpenClawAdapter(),
droid: new DroidAdapter(),
'github-copilot': new GitHubCopilotAdapter(),
goose: new GooseAdapter(),
Expand Down Expand Up @@ -120,6 +123,7 @@ export async function detectAgent(): Promise<AgentType> {
'opencode',
'antigravity',
'amp',
'openclaw',
'clawdbot',
'droid',
'github-copilot',
Expand Down
22 changes: 22 additions & 0 deletions packages/agents/src/openclaw.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { existsSync } from 'node:fs';
import { join } from 'node:path';
import { homedir } from 'node:os';
import { ClawdbotAdapter } from './clawdbot.js';
import type { AgentType } from '@skillkit/core';
import { AGENT_CONFIG } from '@skillkit/core';

const config = AGENT_CONFIG.openclaw;

export class OpenClawAdapter extends ClawdbotAdapter {
override readonly type: AgentType = 'openclaw';
override readonly name = 'OpenClaw';
override readonly skillsDir = config.skillsDir;
override readonly configFile = config.configFile;

override async isDetected(): Promise<boolean> {
const globalOpenClaw = join(homedir(), '.openclaw');
const openclawConfig = join(process.cwd(), 'openclaw.json');

return existsSync(globalOpenClaw) || existsSync(openclawConfig);
}
}
17 changes: 15 additions & 2 deletions packages/core/src/agent-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,29 @@ export const AGENT_CONFIG: Record<AgentType, AgentDirectoryConfig> = {
supportsAutoDiscovery: true,
},

// Clawdbot
clawdbot: {
skillsDir: '.clawdbot/skills',
configFile: 'AGENTS.md',
altSkillsDirs: ['skills'],
altSkillsDirs: ['skills', '~/.clawdbot/skills'],
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for altSkillsDirs usage to understand if tilde expansion is handled
rg -n -A5 'altSkillsDirs' --type=ts

Repository: rohitg00/skillkit

Length of output: 5531


🏁 Script executed:

# Get more context around the detectInstalledAgents method
sed -n '200,250p' packages/core/src/primer/generator.ts

Repository: rohitg00/skillkit

Length of output: 1527


🏁 Script executed:

# Check if there's any tilde expansion utilities used in the codebase
rg -n 'expandUser|expandTilde|homedir|resolve.*~' --type=ts packages/core/src/

Repository: rohitg00/skillkit

Length of output: 4291


🏁 Script executed:

# Check the full implementation of detectInstalledAgents to see complete logic
ast-grep --pattern 'detectInstalledAgents() {
  $$$
}'

Repository: rohitg00/skillkit

Length of output: 43


Tilde paths in altSkillsDirs will not expand correctly and should be removed or handled separately.

The clawdbot and openclaw configurations include tilde paths ('~/.clawdbot/skills' and '~/.openclaw/skills') in altSkillsDirs. However, in detectInstalledAgents() (line 219 of packages/core/src/primer/generator.ts), these paths are joined directly with projectPath using join(this.projectPath, altDir), which treats the tilde as a literal directory name. This produces invalid paths like /project/path/~/.clawdbot/skills instead of expanding to the home directory.

Remove the tilde paths from altSkillsDirs and rely on globalSkillsDir (which is already defined for both agents) for home directory discovery, or ensure tilde expansion is applied before the join() call.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/agent-config.ts` at line 117, The altSkillsDirs arrays
(symbol: altSkillsDirs in agent-config) contain tilde-prefixed entries that
won't expand when later joined with projectPath in detectInstalledAgents()
(method: detectInstalledAgents, uses join(this.projectPath, altDir)), so either
remove the '~' entries from altSkillsDirs and rely on the existing
globalSkillsDir for home-directory discovery (symbol: globalSkillsDir), or
implement explicit tilde-expansion before joining (e.g., expand '~' to
os.homedir()) so join(this.projectPath, ...) receives a proper absolute path;
update agent-config's altSkillsDirs to drop '~' entries if you prefer the former
approach.

configFormat: 'xml',
usesFrontmatter: true,
supportsAutoDiscovery: true,
},

openclaw: {
skillsDir: 'skills',
configFile: 'CLAUDE.md',
altSkillsDirs: ['~/.openclaw/skills'],
globalSkillsDir: '~/.openclaw/skills',
configFormat: 'xml',
usesFrontmatter: true,
frontmatterFields: [
'name', 'description', 'version', 'scan_exempt',
'permissions', 'triggers', 'metadata',
],
supportsAutoDiscovery: true,
},

// Droid (Factory)
droid: {
skillsDir: '.factory/skills',
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/agents/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ export const AGENT_DISCOVERY_PATHS: Record<AgentType, string[]> = {
'antigravity': ['.antigravity/agents'],
'amp': ['.amp/agents'],
'clawdbot': ['.clawdbot/agents', 'agents'],
'openclaw': ['agents', '.openclaw/agents'],
'droid': ['.droid/agents'],
'github-copilot': ['.github/agents', '.github/instructions', '.github/custom-agents'],
'goose': ['.goose/agents'],
Expand Down Expand Up @@ -277,6 +278,7 @@ export const ALL_AGENT_DISCOVERY_PATHS = [
'.cline/agents',
'.clawdbot/agents',
'.codebuddy/agents',
'.openclaw/agents',
'.codex/agents',
'.commandcode/agents',
'.continue/agents',
Expand Down Expand Up @@ -336,6 +338,7 @@ export const CUSTOM_AGENT_FORMAT_MAP: Record<AgentType, AgentFormatCategory> = {
'antigravity': 'claude-agent',
'amp': 'claude-agent',
'clawdbot': 'claude-agent',
'openclaw': 'claude-agent',
'droid': 'claude-agent',
'github-copilot': 'universal',
'goose': 'claude-agent',
Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/commands/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ const AGENT_FORMATS: Record<AgentType, AgentCommandFormat> = {
supportsSlashCommands: true,
supportsCommandFiles: true,
},
openclaw: {
agent: 'openclaw',
extension: '.md',
directory: '.claude/commands',
supportsSlashCommands: true,
supportsCommandFiles: true,
},
droid: {
agent: 'droid',
extension: '.md',
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/translator/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const AGENT_FORMAT_MAP: Record<AgentType, FormatCategory> = {
'antigravity': 'skill-md',
'amp': 'skill-md',
'clawdbot': 'skill-md',
'openclaw': 'skill-md',
'droid': 'skill-md',
'goose': 'skill-md',
'kilo': 'skill-md',
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const AgentType = z.enum([
"gemini-cli",
"amp",
"clawdbot",
"openclaw",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 New openclaw agent type missing from translateSkillToAll() hardcoded agent list

Adding openclaw to the AgentType enum at packages/core/src/types.ts:12 was not propagated to the hardcoded agent list in translateSkillToAll() at packages/core/src/skill-translator.ts:400-408. That function explicitly enumerates all 44 pre-existing agent types but omits the newly added openclaw. As a result, calling translateSkillToAll() will never produce a translation for the openclaw agent, silently skipping it while translating for every other agent.

Prompt for agents
The function translateSkillToAll() in packages/core/src/skill-translator.ts (around line 400-408) contains a hardcoded array of all AgentType values. The new 'openclaw' agent type was added to the AgentType enum in packages/core/src/types.ts but was not added to this list. Add 'openclaw' to the agents array in translateSkillToAll(), likely next to 'clawdbot' on line 402. Consider refactoring this to use AgentType.options from the zod enum to avoid future drift.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

"droid",
"github-copilot",
"goose",
Expand Down
Loading