Revert "chore: Remove dss-claude-plugin directory"
Some checks failed
DSS Project Analysis / dss-context-update (push) Has been cancelled
Some checks failed
DSS Project Analysis / dss-context-update (push) Has been cancelled
This reverts commit 72cb7319f5.
This commit is contained in:
194
dss-claude-plugin/hooks/scripts/session-summary.js
Executable file
194
dss-claude-plugin/hooks/scripts/session-summary.js
Executable file
@@ -0,0 +1,194 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* DSS Session Summary Hook
|
||||
* Generates a summary report at the end of each Claude Code session.
|
||||
* Written from scratch for DSS.
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
// Configuration
|
||||
const DEFAULT_CONFIG = {
|
||||
session_summary: {
|
||||
enabled: true,
|
||||
output_file: '.dss-session-summary.md',
|
||||
include_git_diff: true,
|
||||
include_file_list: true,
|
||||
max_diff_lines: 100
|
||||
}
|
||||
};
|
||||
|
||||
function loadConfig() {
|
||||
const configPath = path.join(process.env.HOME || '', '.dss', 'hooks-config.json');
|
||||
try {
|
||||
if (fs.existsSync(configPath)) {
|
||||
const userConfig = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
||||
return { ...DEFAULT_CONFIG, ...userConfig };
|
||||
}
|
||||
} catch (e) {
|
||||
// Use defaults
|
||||
}
|
||||
return DEFAULT_CONFIG;
|
||||
}
|
||||
|
||||
function getGitInfo() {
|
||||
const info = {
|
||||
branch: '',
|
||||
status: '',
|
||||
diff: '',
|
||||
modifiedFiles: []
|
||||
};
|
||||
|
||||
try {
|
||||
// Check if in git repo
|
||||
execSync('git rev-parse --is-inside-work-tree', { stdio: 'pipe' });
|
||||
|
||||
// Get branch
|
||||
info.branch = execSync('git branch --show-current', { encoding: 'utf8' }).trim();
|
||||
|
||||
// Get status
|
||||
info.status = execSync('git status --short', { encoding: 'utf8' }).trim();
|
||||
|
||||
// Get modified files
|
||||
const statusLines = info.status.split('\n').filter(Boolean);
|
||||
info.modifiedFiles = statusLines.map(line => {
|
||||
const parts = line.trim().split(/\s+/);
|
||||
return {
|
||||
status: parts[0],
|
||||
file: parts.slice(1).join(' ')
|
||||
};
|
||||
});
|
||||
|
||||
// Get diff summary
|
||||
try {
|
||||
info.diff = execSync('git diff --stat', { encoding: 'utf8' }).trim();
|
||||
} catch (e) {
|
||||
info.diff = '';
|
||||
}
|
||||
} catch (e) {
|
||||
// Not a git repo or git not available
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
function getSessionStats() {
|
||||
// Try to read from session state if available
|
||||
const stats = {
|
||||
startTime: new Date().toISOString(),
|
||||
filesModified: 0,
|
||||
linesAdded: 0,
|
||||
linesRemoved: 0
|
||||
};
|
||||
|
||||
try {
|
||||
// Get diff stats from git
|
||||
const diffStat = execSync('git diff --numstat', { encoding: 'utf8' });
|
||||
const lines = diffStat.trim().split('\n').filter(Boolean);
|
||||
|
||||
for (const line of lines) {
|
||||
const [added, removed] = line.split('\t');
|
||||
stats.linesAdded += parseInt(added) || 0;
|
||||
stats.linesRemoved += parseInt(removed) || 0;
|
||||
stats.filesModified++;
|
||||
}
|
||||
} catch (e) {
|
||||
// Git not available
|
||||
}
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
function generateReport(config) {
|
||||
const summaryConfig = config.session_summary || {};
|
||||
const gitInfo = getGitInfo();
|
||||
const stats = getSessionStats();
|
||||
|
||||
const timestamp = new Date().toLocaleString();
|
||||
const lines = [];
|
||||
|
||||
lines.push('# DSS Session Summary');
|
||||
lines.push(`\n**Generated:** ${timestamp}`);
|
||||
|
||||
if (gitInfo.branch) {
|
||||
lines.push(`**Branch:** ${gitInfo.branch}`);
|
||||
}
|
||||
|
||||
lines.push('\n## Changes Overview');
|
||||
lines.push('');
|
||||
lines.push(`- Files modified: ${stats.filesModified}`);
|
||||
lines.push(`- Lines added: +${stats.linesAdded}`);
|
||||
lines.push(`- Lines removed: -${stats.linesRemoved}`);
|
||||
|
||||
if (summaryConfig.include_file_list && gitInfo.modifiedFiles.length > 0) {
|
||||
lines.push('\n## Modified Files');
|
||||
lines.push('');
|
||||
lines.push('| Status | File |');
|
||||
lines.push('|--------|------|');
|
||||
|
||||
const statusLabels = {
|
||||
'M': 'Modified',
|
||||
'A': 'Added',
|
||||
'D': 'Deleted',
|
||||
'R': 'Renamed',
|
||||
'??': 'Untracked'
|
||||
};
|
||||
|
||||
for (const file of gitInfo.modifiedFiles.slice(0, 20)) {
|
||||
const label = statusLabels[file.status] || file.status;
|
||||
lines.push(`| ${label} | ${file.file} |`);
|
||||
}
|
||||
|
||||
if (gitInfo.modifiedFiles.length > 20) {
|
||||
lines.push(`| ... | +${gitInfo.modifiedFiles.length - 20} more files |`);
|
||||
}
|
||||
}
|
||||
|
||||
if (summaryConfig.include_git_diff && gitInfo.diff) {
|
||||
lines.push('\n## Diff Summary');
|
||||
lines.push('');
|
||||
lines.push('```');
|
||||
const diffLines = gitInfo.diff.split('\n');
|
||||
const maxLines = summaryConfig.max_diff_lines || 100;
|
||||
lines.push(diffLines.slice(0, maxLines).join('\n'));
|
||||
if (diffLines.length > maxLines) {
|
||||
lines.push(`... (${diffLines.length - maxLines} more lines)`);
|
||||
}
|
||||
lines.push('```');
|
||||
}
|
||||
|
||||
lines.push('\n---');
|
||||
lines.push('*Generated by DSS Session Summary Hook*');
|
||||
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
function main() {
|
||||
const config = loadConfig();
|
||||
|
||||
if (!config.session_summary?.enabled) {
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
try {
|
||||
const report = generateReport(config);
|
||||
const outputFile = config.session_summary.output_file || '.dss-session-summary.md';
|
||||
const outputPath = path.join(process.cwd(), outputFile);
|
||||
|
||||
fs.writeFileSync(outputPath, report, 'utf8');
|
||||
|
||||
// Output confirmation
|
||||
console.log(JSON.stringify({
|
||||
systemMessage: `Session summary saved to ${outputFile}`,
|
||||
continue: true
|
||||
}));
|
||||
} catch (e) {
|
||||
// Fail silently
|
||||
}
|
||||
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user