create-screenfix 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/create-screenfix.js +40 -0
- package/lib/doctor.js +120 -0
- package/lib/init.js +165 -0
- package/lib/uninstall.js +67 -0
- package/lib/update.js +62 -0
- package/package.json +35 -0
- package/python/build/lib/screenfix/__init__.py +3 -0
- package/python/build/lib/screenfix/annotation_window.py +222 -0
- package/python/build/lib/screenfix/clipboard_watcher.py +164 -0
- package/python/build/lib/screenfix/config.py +66 -0
- package/python/build/lib/screenfix/daemon.py +204 -0
- package/python/build/lib/screenfix/mcp_server.py +318 -0
- package/python/build/lib/screenfix/task_tracker.py +129 -0
- package/python/pyproject.toml +24 -0
- package/python/requirements.txt +5 -0
- package/python/screenfix/__init__.py +3 -0
- package/python/screenfix/annotation_window.py +222 -0
- package/python/screenfix/clipboard_watcher.py +164 -0
- package/python/screenfix/config.py +66 -0
- package/python/screenfix/daemon.py +204 -0
- package/python/screenfix/mcp_server.py +318 -0
- package/python/screenfix/task_tracker.py +129 -0
- package/python/screenfix.egg-info/PKG-INFO +11 -0
- package/python/screenfix.egg-info/SOURCES.txt +14 -0
- package/python/screenfix.egg-info/dependency_links.txt +1 -0
- package/python/screenfix.egg-info/entry_points.txt +3 -0
- package/python/screenfix.egg-info/requires.txt +5 -0
- package/python/screenfix.egg-info/top_level.txt +1 -0
- package/templates/commands/screenfix-list-tasks.md +6 -0
- package/templates/commands/screenfix-start.md +8 -0
- package/templates/commands/screenfix-status.md +6 -0
- package/templates/commands/screenfix-stop.md +6 -0
- package/templates/commands/screenfix-tasks-next.md +14 -0
- package/templates/commands/screenfix-tasks-yolo.md +14 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { program } = require('commander');
|
|
4
|
+
const init = require('../lib/init');
|
|
5
|
+
const doctor = require('../lib/doctor');
|
|
6
|
+
const uninstall = require('../lib/uninstall');
|
|
7
|
+
const update = require('../lib/update');
|
|
8
|
+
|
|
9
|
+
program
|
|
10
|
+
.name('create-screenfix')
|
|
11
|
+
.description('ScreenFix - Screenshot capture tool for Claude Code')
|
|
12
|
+
.version('0.1.0');
|
|
13
|
+
|
|
14
|
+
program
|
|
15
|
+
.command('init')
|
|
16
|
+
.description('Initialize ScreenFix in the current project')
|
|
17
|
+
.option('--skip-python', 'Skip Python dependency installation')
|
|
18
|
+
.action(init);
|
|
19
|
+
|
|
20
|
+
program
|
|
21
|
+
.command('doctor')
|
|
22
|
+
.description('Check ScreenFix installation and diagnose issues')
|
|
23
|
+
.action(doctor);
|
|
24
|
+
|
|
25
|
+
program
|
|
26
|
+
.command('uninstall')
|
|
27
|
+
.description('Remove ScreenFix from the current project')
|
|
28
|
+
.action(uninstall);
|
|
29
|
+
|
|
30
|
+
program
|
|
31
|
+
.command('update')
|
|
32
|
+
.description('Update ScreenFix to the latest version')
|
|
33
|
+
.action(update);
|
|
34
|
+
|
|
35
|
+
// Default action: run init when called without subcommand
|
|
36
|
+
if (process.argv.length === 2) {
|
|
37
|
+
init({});
|
|
38
|
+
} else {
|
|
39
|
+
program.parse();
|
|
40
|
+
}
|
package/lib/doctor.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
const { execSync } = require('child_process');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
|
|
6
|
+
function check(name, fn) {
|
|
7
|
+
try {
|
|
8
|
+
const result = fn();
|
|
9
|
+
if (result === true) {
|
|
10
|
+
console.log(`\x1b[32m✓\x1b[0m ${name}`);
|
|
11
|
+
return true;
|
|
12
|
+
} else if (result === false) {
|
|
13
|
+
console.log(`\x1b[31m✗\x1b[0m ${name}`);
|
|
14
|
+
return false;
|
|
15
|
+
} else {
|
|
16
|
+
console.log(`\x1b[32m✓\x1b[0m ${name}: ${result}`);
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
} catch (e) {
|
|
20
|
+
console.log(`\x1b[31m✗\x1b[0m ${name}: ${e.message}`);
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function doctor() {
|
|
26
|
+
console.log('\n\x1b[1mScreenFix Diagnostics\x1b[0m\n');
|
|
27
|
+
|
|
28
|
+
const installDir = process.cwd();
|
|
29
|
+
let allPassed = true;
|
|
30
|
+
|
|
31
|
+
// Check macOS
|
|
32
|
+
allPassed &= check('macOS', () => {
|
|
33
|
+
if (process.platform !== 'darwin') {
|
|
34
|
+
throw new Error('ScreenFix only works on macOS');
|
|
35
|
+
}
|
|
36
|
+
return true;
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Check Python version
|
|
40
|
+
allPassed &= check('Python 3.10+', () => {
|
|
41
|
+
const version = execSync('python3 --version', { encoding: 'utf8' }).trim();
|
|
42
|
+
const match = version.match(/Python (\d+)\.(\d+)/);
|
|
43
|
+
if (!match) throw new Error('Could not determine version');
|
|
44
|
+
const major = parseInt(match[1], 10);
|
|
45
|
+
const minor = parseInt(match[2], 10);
|
|
46
|
+
if (major < 3 || (major === 3 && minor < 10)) {
|
|
47
|
+
throw new Error(`Found ${major}.${minor}, need 3.10+`);
|
|
48
|
+
}
|
|
49
|
+
return `${major}.${minor}`;
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Check screenfix package installed
|
|
53
|
+
allPassed &= check('screenfix Python package', () => {
|
|
54
|
+
try {
|
|
55
|
+
execSync('python3 -c "import screenfix"', { encoding: 'utf8', stdio: 'pipe' });
|
|
56
|
+
return true;
|
|
57
|
+
} catch {
|
|
58
|
+
throw new Error('Not installed. Run: npx create-screenfix');
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Check .mcp.json exists
|
|
63
|
+
allPassed &= check('.mcp.json exists', () => {
|
|
64
|
+
const mcpPath = path.join(installDir, '.mcp.json');
|
|
65
|
+
if (!fs.existsSync(mcpPath)) {
|
|
66
|
+
throw new Error('Not found');
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Check .mcp.json has screenfix config
|
|
72
|
+
allPassed &= check('.mcp.json has screenfix config', () => {
|
|
73
|
+
const mcpPath = path.join(installDir, '.mcp.json');
|
|
74
|
+
if (!fs.existsSync(mcpPath)) {
|
|
75
|
+
throw new Error('.mcp.json not found');
|
|
76
|
+
}
|
|
77
|
+
const config = JSON.parse(fs.readFileSync(mcpPath, 'utf8'));
|
|
78
|
+
if (!config.mcpServers?.screenfix) {
|
|
79
|
+
throw new Error('screenfix not configured');
|
|
80
|
+
}
|
|
81
|
+
return true;
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Check slash commands exist
|
|
85
|
+
allPassed &= check('Slash commands installed', () => {
|
|
86
|
+
const commandsDir = path.join(installDir, '.claude', 'commands');
|
|
87
|
+
if (!fs.existsSync(commandsDir)) {
|
|
88
|
+
throw new Error('.claude/commands not found');
|
|
89
|
+
}
|
|
90
|
+
const commands = fs.readdirSync(commandsDir).filter(f => f.startsWith('screenfix-'));
|
|
91
|
+
if (commands.length === 0) {
|
|
92
|
+
throw new Error('No screenfix commands found');
|
|
93
|
+
}
|
|
94
|
+
return `${commands.length} commands`;
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Check daemon state
|
|
98
|
+
allPassed &= check('Daemon status', () => {
|
|
99
|
+
const statePath = path.join(os.homedir(), '.config', 'screenfix', 'state.json');
|
|
100
|
+
if (!fs.existsSync(statePath)) {
|
|
101
|
+
return 'Not running';
|
|
102
|
+
}
|
|
103
|
+
const state = JSON.parse(fs.readFileSync(statePath, 'utf8'));
|
|
104
|
+
if (state.listening) {
|
|
105
|
+
return `Running (PID: ${state.pid})`;
|
|
106
|
+
}
|
|
107
|
+
return 'Not running';
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
console.log('');
|
|
111
|
+
|
|
112
|
+
if (allPassed) {
|
|
113
|
+
console.log('\x1b[32mAll checks passed!\x1b[0m\n');
|
|
114
|
+
} else {
|
|
115
|
+
console.log('\x1b[33mSome checks failed. Run "npx create-screenfix" to fix.\x1b[0m\n');
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
module.exports = doctor;
|
package/lib/init.js
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
const { execSync, spawn } = require('child_process');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
|
|
6
|
+
function log(msg) {
|
|
7
|
+
console.log(msg);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function success(msg) {
|
|
11
|
+
console.log(`\x1b[32m✓\x1b[0m ${msg}`);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function error(msg) {
|
|
15
|
+
console.error(`\x1b[31m✗\x1b[0m ${msg}`);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function checkPrerequisites() {
|
|
19
|
+
// Check macOS
|
|
20
|
+
if (process.platform !== 'darwin') {
|
|
21
|
+
throw new Error('ScreenFix only works on macOS');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Check Python 3.10+
|
|
25
|
+
try {
|
|
26
|
+
const pythonVersion = execSync('python3 --version', { encoding: 'utf8' });
|
|
27
|
+
const match = pythonVersion.match(/Python (\d+)\.(\d+)/);
|
|
28
|
+
if (!match) {
|
|
29
|
+
throw new Error('Could not determine Python version');
|
|
30
|
+
}
|
|
31
|
+
const major = parseInt(match[1], 10);
|
|
32
|
+
const minor = parseInt(match[2], 10);
|
|
33
|
+
if (major < 3 || (major === 3 && minor < 10)) {
|
|
34
|
+
throw new Error(`Python 3.10+ is required (found ${major}.${minor})`);
|
|
35
|
+
}
|
|
36
|
+
success(`Python ${major}.${minor} detected`);
|
|
37
|
+
} catch (e) {
|
|
38
|
+
if (e.message.includes('Python 3.10+')) {
|
|
39
|
+
throw e;
|
|
40
|
+
}
|
|
41
|
+
throw new Error('Python 3 is not installed. Please install Python 3.10+');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Check pip
|
|
45
|
+
try {
|
|
46
|
+
execSync('python3 -m pip --version', { encoding: 'utf8', stdio: 'pipe' });
|
|
47
|
+
success('pip available');
|
|
48
|
+
} catch {
|
|
49
|
+
throw new Error('pip is not available. Please install pip for Python 3');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function installPythonPackage(installDir, options) {
|
|
54
|
+
if (options.skipPython) {
|
|
55
|
+
log('Skipping Python package installation (--skip-python)');
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
log('Installing Python dependencies...');
|
|
60
|
+
|
|
61
|
+
// Get the path to bundled Python source
|
|
62
|
+
const pythonSrcDir = path.join(__dirname, '..', 'python');
|
|
63
|
+
|
|
64
|
+
if (!fs.existsSync(pythonSrcDir)) {
|
|
65
|
+
throw new Error('Bundled Python package not found. Package may be corrupted.');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
// Install in user mode from bundled source
|
|
70
|
+
execSync(`python3 -m pip install --user "${pythonSrcDir}"`, {
|
|
71
|
+
encoding: 'utf8',
|
|
72
|
+
stdio: 'inherit'
|
|
73
|
+
});
|
|
74
|
+
success('Python package installed');
|
|
75
|
+
} catch (e) {
|
|
76
|
+
throw new Error('Failed to install Python package: ' + e.message);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function copyMcpConfig(installDir) {
|
|
81
|
+
const mcpConfig = {
|
|
82
|
+
mcpServers: {
|
|
83
|
+
screenfix: {
|
|
84
|
+
type: 'stdio',
|
|
85
|
+
command: 'python3',
|
|
86
|
+
args: ['-m', 'screenfix.mcp_server']
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const mcpPath = path.join(installDir, '.mcp.json');
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
if (fs.existsSync(mcpPath)) {
|
|
95
|
+
// Merge with existing .mcp.json
|
|
96
|
+
const existing = JSON.parse(fs.readFileSync(mcpPath, 'utf8'));
|
|
97
|
+
existing.mcpServers = existing.mcpServers || {};
|
|
98
|
+
existing.mcpServers.screenfix = mcpConfig.mcpServers.screenfix;
|
|
99
|
+
fs.writeFileSync(mcpPath, JSON.stringify(existing, null, 2) + '\n');
|
|
100
|
+
success('Updated .mcp.json (merged with existing)');
|
|
101
|
+
} else {
|
|
102
|
+
fs.writeFileSync(mcpPath, JSON.stringify(mcpConfig, null, 2) + '\n');
|
|
103
|
+
success('Created .mcp.json');
|
|
104
|
+
}
|
|
105
|
+
} catch (e) {
|
|
106
|
+
throw new Error('Failed to create .mcp.json: ' + e.message);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function copySlashCommands(installDir) {
|
|
111
|
+
const commandsDir = path.join(installDir, '.claude', 'commands');
|
|
112
|
+
const templatesDir = path.join(__dirname, '..', 'templates', 'commands');
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
// Create .claude/commands directory if it doesn't exist
|
|
116
|
+
fs.mkdirSync(commandsDir, { recursive: true });
|
|
117
|
+
|
|
118
|
+
// Get all command templates
|
|
119
|
+
const commands = fs.readdirSync(templatesDir).filter(f => f.endsWith('.md'));
|
|
120
|
+
|
|
121
|
+
for (const cmd of commands) {
|
|
122
|
+
const src = path.join(templatesDir, cmd);
|
|
123
|
+
const dest = path.join(commandsDir, cmd);
|
|
124
|
+
fs.copyFileSync(src, dest);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
success(`Installed ${commands.length} slash commands`);
|
|
128
|
+
} catch (e) {
|
|
129
|
+
throw new Error('Failed to copy slash commands: ' + e.message);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async function init(options) {
|
|
134
|
+
console.log('\n\x1b[1mScreenFix Setup\x1b[0m\n');
|
|
135
|
+
|
|
136
|
+
const installDir = process.cwd();
|
|
137
|
+
|
|
138
|
+
try {
|
|
139
|
+
// Step 1: Check prerequisites
|
|
140
|
+
log('Checking prerequisites...');
|
|
141
|
+
checkPrerequisites();
|
|
142
|
+
|
|
143
|
+
// Step 2: Install Python package
|
|
144
|
+
installPythonPackage(installDir, options);
|
|
145
|
+
|
|
146
|
+
// Step 3: Copy MCP config
|
|
147
|
+
copyMcpConfig(installDir);
|
|
148
|
+
|
|
149
|
+
// Step 4: Copy slash commands
|
|
150
|
+
copySlashCommands(installDir);
|
|
151
|
+
|
|
152
|
+
// Done
|
|
153
|
+
console.log('\n\x1b[32m\x1b[1mScreenFix installed successfully!\x1b[0m\n');
|
|
154
|
+
console.log('Next steps:');
|
|
155
|
+
console.log(' 1. Restart Claude Code to load the MCP server');
|
|
156
|
+
console.log(' 2. Run /screenfix-start to begin');
|
|
157
|
+
console.log(' 3. Use Cmd+Ctrl+Shift+4 to capture screenshots\n');
|
|
158
|
+
|
|
159
|
+
} catch (e) {
|
|
160
|
+
error(e.message);
|
|
161
|
+
process.exit(1);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
module.exports = init;
|
package/lib/uninstall.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
const { execSync } = require('child_process');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
function success(msg) {
|
|
6
|
+
console.log(`\x1b[32m✓\x1b[0m ${msg}`);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function warn(msg) {
|
|
10
|
+
console.log(`\x1b[33m!\x1b[0m ${msg}`);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async function uninstall() {
|
|
14
|
+
console.log('\n\x1b[1mUninstalling ScreenFix\x1b[0m\n');
|
|
15
|
+
|
|
16
|
+
const installDir = process.cwd();
|
|
17
|
+
|
|
18
|
+
// Remove slash commands
|
|
19
|
+
const commandsDir = path.join(installDir, '.claude', 'commands');
|
|
20
|
+
if (fs.existsSync(commandsDir)) {
|
|
21
|
+
const commands = fs.readdirSync(commandsDir).filter(f => f.startsWith('screenfix-'));
|
|
22
|
+
for (const cmd of commands) {
|
|
23
|
+
fs.unlinkSync(path.join(commandsDir, cmd));
|
|
24
|
+
}
|
|
25
|
+
if (commands.length > 0) {
|
|
26
|
+
success(`Removed ${commands.length} slash commands`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Remove screenfix from .mcp.json
|
|
31
|
+
const mcpPath = path.join(installDir, '.mcp.json');
|
|
32
|
+
if (fs.existsSync(mcpPath)) {
|
|
33
|
+
try {
|
|
34
|
+
const config = JSON.parse(fs.readFileSync(mcpPath, 'utf8'));
|
|
35
|
+
if (config.mcpServers?.screenfix) {
|
|
36
|
+
delete config.mcpServers.screenfix;
|
|
37
|
+
|
|
38
|
+
// If no other MCP servers, remove the file
|
|
39
|
+
if (Object.keys(config.mcpServers).length === 0) {
|
|
40
|
+
fs.unlinkSync(mcpPath);
|
|
41
|
+
success('Removed .mcp.json (no other servers configured)');
|
|
42
|
+
} else {
|
|
43
|
+
fs.writeFileSync(mcpPath, JSON.stringify(config, null, 2) + '\n');
|
|
44
|
+
success('Removed screenfix from .mcp.json');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
} catch (e) {
|
|
48
|
+
warn('Could not update .mcp.json: ' + e.message);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Uninstall Python package
|
|
53
|
+
try {
|
|
54
|
+
execSync('python3 -m pip uninstall -y screenfix', {
|
|
55
|
+
encoding: 'utf8',
|
|
56
|
+
stdio: 'pipe'
|
|
57
|
+
});
|
|
58
|
+
success('Uninstalled Python package');
|
|
59
|
+
} catch {
|
|
60
|
+
warn('Python package may not have been installed');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
console.log('\n\x1b[32mScreenFix uninstalled.\x1b[0m\n');
|
|
64
|
+
console.log('Note: Screenshots in ./screenfix/ were not deleted.\n');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
module.exports = uninstall;
|
package/lib/update.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
const { execSync } = require('child_process');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
function success(msg) {
|
|
6
|
+
console.log(`\x1b[32m✓\x1b[0m ${msg}`);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function log(msg) {
|
|
10
|
+
console.log(msg);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async function update() {
|
|
14
|
+
console.log('\n\x1b[1mUpdating ScreenFix\x1b[0m\n');
|
|
15
|
+
|
|
16
|
+
const installDir = process.cwd();
|
|
17
|
+
|
|
18
|
+
// Re-install Python package from bundled source
|
|
19
|
+
log('Updating Python package...');
|
|
20
|
+
const pythonSrcDir = path.join(__dirname, '..', 'python');
|
|
21
|
+
|
|
22
|
+
if (!fs.existsSync(pythonSrcDir)) {
|
|
23
|
+
console.error('\x1b[31m✗\x1b[0m Bundled Python package not found');
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
execSync(`python3 -m pip install --user --upgrade "${pythonSrcDir}"`, {
|
|
29
|
+
encoding: 'utf8',
|
|
30
|
+
stdio: 'inherit'
|
|
31
|
+
});
|
|
32
|
+
success('Python package updated');
|
|
33
|
+
} catch (e) {
|
|
34
|
+
console.error('\x1b[31m✗\x1b[0m Failed to update Python package');
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Re-copy slash commands (in case of updates)
|
|
39
|
+
log('Updating slash commands...');
|
|
40
|
+
const commandsDir = path.join(installDir, '.claude', 'commands');
|
|
41
|
+
const templatesDir = path.join(__dirname, '..', 'templates', 'commands');
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
fs.mkdirSync(commandsDir, { recursive: true });
|
|
45
|
+
|
|
46
|
+
const commands = fs.readdirSync(templatesDir).filter(f => f.endsWith('.md'));
|
|
47
|
+
for (const cmd of commands) {
|
|
48
|
+
const src = path.join(templatesDir, cmd);
|
|
49
|
+
const dest = path.join(commandsDir, cmd);
|
|
50
|
+
fs.copyFileSync(src, dest);
|
|
51
|
+
}
|
|
52
|
+
success(`Updated ${commands.length} slash commands`);
|
|
53
|
+
} catch (e) {
|
|
54
|
+
console.error('\x1b[31m✗\x1b[0m Failed to update slash commands: ' + e.message);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
console.log('\n\x1b[32mScreenFix updated successfully!\x1b[0m\n');
|
|
59
|
+
console.log('Restart Claude Code to apply changes.\n');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = update;
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-screenfix",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Screenshot capture tool for Claude Code via MCP",
|
|
5
|
+
"bin": {
|
|
6
|
+
"create-screenfix": "./bin/create-screenfix.js"
|
|
7
|
+
},
|
|
8
|
+
"keywords": [
|
|
9
|
+
"claude-code",
|
|
10
|
+
"mcp",
|
|
11
|
+
"screenshot",
|
|
12
|
+
"screenfix",
|
|
13
|
+
"claude"
|
|
14
|
+
],
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=16.0.0"
|
|
17
|
+
},
|
|
18
|
+
"os": [
|
|
19
|
+
"darwin"
|
|
20
|
+
],
|
|
21
|
+
"files": [
|
|
22
|
+
"bin/",
|
|
23
|
+
"lib/",
|
|
24
|
+
"templates/",
|
|
25
|
+
"python/"
|
|
26
|
+
],
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/anthropics/screenfix.git"
|
|
30
|
+
},
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"commander": "^11.0.0"
|
|
34
|
+
}
|
|
35
|
+
}
|