
Improve Skill
- 1 installs
- Updated January 7, 2026
- ainergiz/mac-setup-guide
improve-skill is a Claude Code skill that analyzes coding-agent session transcripts to improve existing skills or create new ones.
About
improve-skill is a Claude Code skill that analyzes coding-agent session transcripts to improve an existing skill or extract a new one. Its extract-session.js script pulls the current Claude Code or Codex transcript, then it generates a prompt to run in a fresh session. A developer uses it after a session to capture what was learned into a skill.
- Auto-detects and extracts Claude Code or Codex session transcripts via a bundled script
- Generates a self-contained improvement or creation prompt for a fresh session
- Explains why a separate session gives cleaner, token-efficient skill analysis
Improve Skill by the numbers
- 1 all-time installs (skills.sh)
- Ranked #640 of 781 Skill Development skills by installs in the Skillselion catalog
- Data as of Jul 28, 2026 (Skillselion catalog sync)
improve-skill capabilities & compatibility
- Capabilities
- skill authoring · session analysis · transcript extraction
- Use cases
- documentation · refactoring
- Pricing
- Free
What improve-skill says it does
Analyze coding agent sessions to improve or create skills. Works with Claude Code and Codex.
Auto-detect agent and extract current session
npx skills add https://github.com/ainergiz/mac-setup-guide --skill improve-skillAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| Last updated | January 7, 2026 |
| Repository | ainergiz/mac-setup-guide ↗ |
What it does
Analyzing coding-agent session transcripts to improve an existing skill or extract a new one.
Who is it for?
Turning a completed Claude Code or Codex session into an improved or new skill.
Skip if: Authoring a skill from scratch with no session history to analyze.
When should I use this skill?
When asked to improve a skill based on a session or extract a new skill from session history.
What you get
An improved or newly extracted SKILL.md grounded in a real session transcript.
- extracted session transcript
- a skill improvement or creation prompt
By the numbers
- Supports 2 agents (Claude Code and Codex)
- extract-session.js is about 7.7KB
Files
Improve Skill
Analyze coding agent sessions to improve or create skills. Works with Claude Code and Codex.
Quick Start
Extract the current session and generate an improvement prompt:
# Auto-detect agent and extract current session
./scripts/extract-session.jsSession Extraction
The extract-session.js script finds and parses session files:
# Auto-detect (uses most recent session for current working directory)
./scripts/extract-session.js
# Specify agent type
./scripts/extract-session.js --agent claude
./scripts/extract-session.js --agent codex
# Specify a different working directory
./scripts/extract-session.js --cwd /path/to/projectSession file locations:
- Claude Code:
~/.claude/projects/<encoded-cwd>/*.jsonl - Codex:
~/.codex/sessions/YYYY/MM/DD/*.jsonl
Workflow: Improve an Existing Skill
When asked to improve a skill based on a session:
1. Extract the session transcript:
./scripts/extract-session.js > /tmp/session-transcript.txt2. Find the existing skill in one of these locations:
~/.claude/skills/<skill-name>/SKILL.md~/.codex/skills/<skill-name>/SKILL.md
3. Generate an improvement prompt for a new session:
═══════════════════════════════════════════════════════════════════════════════
COPY THE FOLLOWING PROMPT INTO A NEW AGENT SESSION:
═══════════════════════════════════════════════════════════════════════════════
I need to improve the "<skill-name>" skill based on a session where I used it.
First, read the current skill at: <path-to-skill>
Then analyze this session transcript to understand:
- Where I struggled to use the skill correctly
- What information was missing from the skill
- What examples would have helped
- What I had to figure out on my own
<session_transcript>
<paste transcript here>
</session_transcript>
Based on this analysis, improve the skill by:
1. Adding missing instructions or clarifications
2. Adding examples for common use cases discovered
3. Fixing any incorrect guidance
4. Making the skill more concise where possible
Write the improved skill back to the same location.
═══════════════════════════════════════════════════════════════════════════════Workflow: Create a New Skill
When asked to create a new skill from a session:
1. Extract the session transcript:
./scripts/extract-session.js > /tmp/session-transcript.txt2. Generate a creation prompt for a new session:
═══════════════════════════════════════════════════════════════════════════════
COPY THE FOLLOWING PROMPT INTO A NEW AGENT SESSION:
═══════════════════════════════════════════════════════════════════════════════
Analyze this session transcript to extract a reusable skill called "<skill-name>":
<session_transcript>
<paste transcript here>
</session_transcript>
Create a new skill that captures:
1. The core capability or workflow demonstrated
2. Key commands, APIs, or patterns used
3. Common pitfalls and how to avoid them
4. Example usage for typical scenarios
Write the skill to: ~/.claude/skills/<skill-name>/SKILL.md
Use this format:
---
name: <skill-name>
description: "<one-line description>"
---
# <Skill Name> Skill
<overview and quick reference>
## <Section for each major capability>
<instructions and examples>
═══════════════════════════════════════════════════════════════════════════════Why a Separate Session?
The improvement prompt is meant to be copied into a fresh agent session because:
1. Token efficiency - The current session already has a lot of context; starting fresh means only the transcript and skill are loaded 2. Clean analysis - The new session can focus purely on improvement without being influenced by the current task 3. Reproducibility - The prompt is self-contained and can be shared or reused
Tips for Good Skill Improvements
When analyzing a transcript, look for:
- Confusion patterns - Where did the agent retry or change approach?
- Missing examples - What specific commands or code patterns were discovered?
- Workarounds - What did the agent have to figure out that wasn't documented?
- Errors - What failed and how was it resolved?
- Successful patterns - What worked well and should be highlighted?
Keep skills concise - focus on the most important information and examples.
#!/usr/bin/env node
/**
* Extract session transcript from Claude Code or Codex session files.
*
* Usage:
* ./extract-session.js [session-path]
* ./extract-session.js --agent claude|codex [--cwd /path/to/dir]
*
* If no arguments, auto-detects based on current working directory.
*/
const fs = require('fs');
const path = require('path');
const os = require('os');
// Parse arguments
const args = process.argv.slice(2);
let sessionPath = null;
let agent = null;
let cwd = process.cwd();
for (let i = 0; i < args.length; i++) {
if (args[i] === '--agent' && args[i + 1]) {
agent = args[++i];
} else if (args[i] === '--cwd' && args[i + 1]) {
cwd = args[++i];
} else if (!args[i].startsWith('-')) {
sessionPath = args[i];
}
}
/**
* Encode CWD for session path lookup (Claude Code style)
*/
function encodeCwd(cwd) {
return cwd.replace(/\//g, '-');
}
/**
* Find the most recent session file in a directory
*/
function findMostRecentSession(dir) {
if (!fs.existsSync(dir)) return null;
const files = fs.readdirSync(dir)
.filter(f => f.endsWith('.jsonl'))
.map(f => ({
name: f,
path: path.join(dir, f),
mtime: fs.statSync(path.join(dir, f)).mtime
}))
.sort((a, b) => b.mtime - a.mtime);
return files.length > 0 ? files[0].path : null;
}
/**
* Find Codex session matching CWD
*/
function findCodexSession(targetCwd) {
const baseDir = path.join(os.homedir(), '.codex', 'sessions');
if (!fs.existsSync(baseDir)) return null;
// Find all session files, sorted by mtime
const allSessions = [];
function walkDir(dir) {
if (!fs.existsSync(dir)) return;
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory()) {
walkDir(fullPath);
} else if (entry.name.endsWith('.jsonl')) {
allSessions.push({
path: fullPath,
mtime: fs.statSync(fullPath).mtime
});
}
}
}
walkDir(baseDir);
allSessions.sort((a, b) => b.mtime - a.mtime);
// Find most recent matching CWD
for (const session of allSessions.slice(0, 50)) { // Check last 50
try {
const firstLine = fs.readFileSync(session.path, 'utf8').split('\n')[0];
const data = JSON.parse(firstLine);
if (data.payload?.cwd === targetCwd) {
return session.path;
}
} catch (e) {
// Skip invalid files
}
}
return null;
}
/**
* Auto-detect session based on CWD
*/
function autoDetectSession(cwd) {
// Try Claude Code first
const claudePath = path.join(os.homedir(), '.claude', 'projects', encodeCwd(cwd));
let session = findMostRecentSession(claudePath);
if (session) return { agent: 'claude', path: session };
// Try Codex
session = findCodexSession(cwd);
if (session) return { agent: 'codex', path: session };
return null;
}
/**
* Parse Claude Code session format
*/
function parseClaudeSession(content) {
const messages = [];
const lines = content.trim().split('\n');
for (const line of lines) {
try {
const entry = JSON.parse(line);
if (entry.message?.role && entry.message?.content) {
const msg = entry.message;
messages.push({
role: msg.role,
content: extractContent(msg.content),
timestamp: entry.timestamp
});
}
} catch (e) {
// Skip invalid lines
}
}
return messages;
}
/**
* Parse Codex session format
*/
function parseCodexSession(content) {
const messages = [];
const lines = content.trim().split('\n');
for (const line of lines) {
try {
const entry = JSON.parse(line);
if (entry.type === 'response_item' && entry.payload?.role) {
const payload = entry.payload;
messages.push({
role: payload.role,
content: extractContent(payload.content),
timestamp: entry.timestamp
});
}
} catch (e) {
// Skip invalid lines
}
}
return messages;
}
/**
* Extract text content from various content formats
*/
function extractContent(content) {
if (typeof content === 'string') return content;
if (!Array.isArray(content)) return JSON.stringify(content);
const parts = [];
for (const item of content) {
if (typeof item === 'string') {
parts.push(item);
} else if (item.type === 'text') {
parts.push(item.text);
} else if (item.type === 'input_text') {
parts.push(item.text);
} else if (item.type === 'tool_use') {
parts.push(`[Tool: ${item.name}]\n${JSON.stringify(item.input, null, 2)}`);
} else if (item.type === 'tool_result') {
const result = typeof item.content === 'string'
? item.content
: JSON.stringify(item.content);
// Truncate long tool results
const truncated = result.length > 500
? result.slice(0, 500) + '\n[... truncated ...]'
: result;
parts.push(`[Tool Result]\n${truncated}`);
} else {
parts.push(`[${item.type}]`);
}
}
return parts.join('\n');
}
/**
* Format messages as readable transcript
*/
function formatTranscript(messages, maxMessages = 100) {
const recent = messages.slice(-maxMessages);
const lines = [];
for (const msg of recent) {
const role = msg.role.toUpperCase();
lines.push(`\n### ${role}:\n`);
lines.push(msg.content);
}
if (messages.length > maxMessages) {
lines.unshift(`\n[... ${messages.length - maxMessages} earlier messages omitted ...]\n`);
}
return lines.join('\n');
}
// Main
async function main() {
let result;
if (sessionPath) {
// Explicit path provided
if (!fs.existsSync(sessionPath)) {
console.error(`Session file not found: ${sessionPath}`);
process.exit(1);
}
// Guess agent from path
if (sessionPath.includes('.codex')) {
result = { agent: 'codex', path: sessionPath };
} else {
// Default to Claude format
result = { agent: 'claude', path: sessionPath };
}
} else if (agent) {
// Agent specified, find session for that agent
if (agent === 'claude') {
const dir = path.join(os.homedir(), '.claude', 'projects', encodeCwd(cwd));
const session = findMostRecentSession(dir);
if (!session) {
console.error(`No Claude Code session found for: ${cwd}`);
process.exit(1);
}
result = { agent: 'claude', path: session };
} else if (agent === 'codex') {
const session = findCodexSession(cwd);
if (!session) {
console.error(`No Codex session found for: ${cwd}`);
process.exit(1);
}
result = { agent: 'codex', path: session };
} else {
console.error(`Unknown agent: ${agent}`);
process.exit(1);
}
} else {
// Auto-detect
result = autoDetectSession(cwd);
if (!result) {
console.error(`No session found for: ${cwd}`);
console.error('Try specifying --agent claude|codex or provide a session path directly.');
process.exit(1);
}
}
// Read and parse session
const content = fs.readFileSync(result.path, 'utf8');
let messages;
switch (result.agent) {
case 'claude':
messages = parseClaudeSession(content);
break;
case 'codex':
messages = parseCodexSession(content);
break;
}
// Output metadata and transcript
console.log(`# Session Transcript`);
console.log(`Agent: ${result.agent}`);
console.log(`File: ${result.path}`);
console.log(`Messages: ${messages.length}`);
console.log('');
console.log(formatTranscript(messages));
}
main().catch(e => {
console.error(e.message);
process.exit(1);
});
Related skills
FAQ
Which agents does improve-skill support?
Claude Code (~/.claude/projects/.../*.jsonl) and Codex (~/.codex/sessions/.../*.jsonl).
Why run the improvement in a separate session?
For token efficiency, clean analysis, and a self-contained reproducible prompt.