Skip to content

Add Skills feature: Custom Skills in Skills.md#111

Merged
Akash-nath29 merged 2 commits intomainfrom
dev
Jan 26, 2026
Merged

Add Skills feature: Custom Skills in Skills.md#111
Akash-nath29 merged 2 commits intomainfrom
dev

Conversation

@Akash-nath29
Copy link
Owner

This pull request introduces a new persistent skills prompt feature to the agent, allowing guidance from a Skills.md file to be included in every conversation. It also clarifies the distinction between persistent skills (Skills.md) and task-specific guidance (Coderrr.md), and ensures the correct priority order when constructing prompts. Comprehensive unit tests are added to verify the loading and priority of these prompts. Additionally, Skills.md is now protected from accidental deletion.

Agent prompt enhancements:

  • Added support for loading a persistent skills prompt from Skills.md, which is prepended to every user request if present. The prompt construction now prioritizes: system prompt, then skills (Skills.md), then task guidance (Coderrr.md), then the user request. (src/agent.js) [1] [2] [3] [4]

File protection:

  • Added Skills.md to the list of protected files that cannot be deleted by the agent. (src/fileOps.js)

Testing:

  • Added a new test suite for the skills prompt, covering loading of Skills.md, interaction with Coderrr.md, prompt construction order, and edge cases (file absence, empty file, etc.). (tests/unit/skills.test.js)

Copilot AI review requested due to automatic review settings January 26, 2026 19:40
@vercel
Copy link

vercel bot commented Jan 26, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
coderrr-backend Ready Ready Preview, Comment Jan 26, 2026 7:40pm

@github-actions
Copy link

🚀 Thanks for opening a Pull Request!

A maintainer will review this soon.

Meanwhile:
✔ Ensure tests are passing
✔ Link related issues
✔ Code follows the project guidelines

Your contribution helps make this project better!

@Akash-nath29 Akash-nath29 merged commit 3b84911 into main Jan 26, 2026
48 of 60 checks passed
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a persistent “skills” layer to agent prompting via Skills.md, distinguishes it from task-specific guidance (Coderrr.md), and enforces a new prompt precedence order.

Changes:

  • Load and prepend a persistent skills prompt from Skills.md in Agent.chat() before task guidance and user input.
  • Protect Skills.md from agent-driven deletion by adding it to protected paths.
  • Add unit tests for Skills.md loading and prompt ordering behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
src/agent.js Introduces skillsPrompt, loads Skills.md, and updates prompt construction ordering.
src/fileOps.js Adds Skills.md to the protected paths list to prevent deletion.
tests/unit/skills.test.js Adds unit tests for skills/task prompt loading and intended priority ordering.

Comment on lines 14 to 18
const PROTECTED_PATHS = [
'Coderrr.md',
'Skills.md',
'.coderrr'
];
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

isProtectedPath() checks protected filenames with a case-sensitive match (PROTECTED_PATHS.includes(basename)). On case-insensitive file systems (e.g., Windows/macOS default), a deletion request for skills.md can still resolve to Skills.md and bypass protection. Consider normalizing both basename/relativePath and PROTECTED_PATHS to a consistent case (e.g., lower-case) before comparing so the protection can't be bypassed by casing.

Copilot uses AI. Check for mistakes.
Comment on lines +33 to +40
beforeEach(() => {
jest.clearAllMocks();
// Create a temporary directory for testing
tempDir = path.join(originalCwd, 'test-temp-skills');
if (!fs.existsSync(tempDir)) {
fs.mkdirSync(tempDir, { recursive: true });
}
});
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

The test temp directory uses a fixed path (test-temp-skills) under the repo root. This can collide across parallel Jest runs and can leave artifacts in the working tree if a test crashes before cleanup. Prefer creating a unique temp dir via fs.mkdtempSync(path.join(os.tmpdir(), ...)) and clean it up with fs.rmSync(tempDir, { recursive: true, force: true }).

Copilot uses AI. Check for mistakes.
Comment on lines +111 to +127
// Simulate prompt construction (from chat method logic)
let enhancedPrompt = 'User request';

// Task guidance first (will be wrapped by skills)
if (agent.customPrompt) {
enhancedPrompt = `[TASK GUIDANCE]\n${agent.customPrompt}\n\n[USER REQUEST]\n${enhancedPrompt}`;
}

// Skills prepended (comes before everything else)
if (agent.skillsPrompt) {
enhancedPrompt = `[SKILLS]\n${agent.skillsPrompt}\n\n${enhancedPrompt}`;
}

// Verify priority order: Skills comes first
expect(enhancedPrompt.startsWith('[SKILLS]')).toBe(true);
expect(enhancedPrompt.indexOf('[SKILLS]')).toBeLessThan(enhancedPrompt.indexOf('[TASK GUIDANCE]'));
expect(enhancedPrompt.indexOf('[TASK GUIDANCE]')).toBeLessThan(enhancedPrompt.indexOf('[USER REQUEST]'));
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

The prompt priority tests rebuild enhancedPrompt manually instead of exercising the production Agent.chat() logic. This duplicates implementation details and can keep passing even if chat() prompt construction changes. Consider calling agent.chat('User request', …) with scanOnFirstRequest: false and a mocked axios.post, then assert against the actual requestPayload.prompt passed to axios (order of [SKILLS], [TASK GUIDANCE], and [USER REQUEST]).

Copilot uses AI. Check for mistakes.
Comment on lines +92 to +98
loadSkillsPrompt() {
try {
const skillsPath = path.join(this.workingDir, 'Skills.md');
if (fs.existsSync(skillsPath)) {
this.skillsPrompt = fs.readFileSync(skillsPath, 'utf8').trim();
ui.info('Loaded skills from Skills.md');
}
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

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

loadSkillsPrompt() logs "Loaded skills from Skills.md" even when the file is present but trims down to an empty string. Since chat() later checks if (this.skillsPrompt) (truthy) before prepending, an empty Skills.md results in a "loaded" log but no skills section in the prompt. Consider treating an all-whitespace file as absent (e.g., set skillsPrompt back to null and/or only log when the trimmed content is non-empty) to keep behavior consistent.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments