create-screenfix 0.1.0 → 0.1.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-screenfix",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Screenshot capture tool for Claude Code via MCP",
5
5
  "bin": {
6
6
  "create-screenfix": "./bin/create-screenfix.js"
@@ -26,8 +26,9 @@
26
26
  ],
27
27
  "repository": {
28
28
  "type": "git",
29
- "url": "https://github.com/anthropics/screenfix.git"
29
+ "url": "https://github.com/sukhdeepbangar/screenfix.git"
30
30
  },
31
+ "homepage": "https://sukhdeepbangar.github.io/screenfix",
31
32
  "license": "MIT",
32
33
  "dependencies": {
33
34
  "commander": "^11.0.0"
@@ -38,7 +38,7 @@ _current_controller = None
38
38
 
39
39
  def save_screenshot(temp_path: str) -> str:
40
40
  """Save screenshot from temp location to final location."""
41
- save_dir = Path(config.save_directory)
41
+ save_dir = Path(config.save_directory).resolve() # Absolute path
42
42
  save_dir.mkdir(parents=True, exist_ok=True)
43
43
 
44
44
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
@@ -46,7 +46,7 @@ def save_screenshot(temp_path: str) -> str:
46
46
  final_path = save_dir / filename
47
47
 
48
48
  shutil.move(temp_path, final_path)
49
- return str(final_path)
49
+ return str(final_path) # Returns absolute path
50
50
 
51
51
 
52
52
  def cleanup_temp_file(temp_path: str):
@@ -1,21 +1,16 @@
1
- """MCP server for ScreenFix."""
1
+ """MCP server for ScreenFix - daemon control only."""
2
2
 
3
3
  import asyncio
4
- import base64
5
4
  import json
6
5
  import os
7
6
  import subprocess
8
7
  import sys
9
8
  import time
10
9
  from pathlib import Path
11
- from typing import Any
12
10
 
13
11
  from mcp.server import Server
14
12
  from mcp.server.stdio import stdio_server
15
- from mcp.types import Tool, TextContent, ImageContent
16
-
17
- from .config import config
18
- from .task_tracker import get_tasks, get_pending_tasks, mark_task_complete
13
+ from mcp.types import Tool, TextContent
19
14
 
20
15
 
21
16
  STATE_FILE = Path.home() / ".config" / "screenfix" / "state.json"
@@ -45,30 +40,6 @@ def get_daemon_state() -> dict:
45
40
  return {"running": False, "listening": False}
46
41
 
47
42
 
48
- def get_screenshots() -> list[dict]:
49
- """Get list of screenshots."""
50
- save_dir = Path(config.save_directory)
51
- if not save_dir.exists():
52
- return []
53
-
54
- screenshots = []
55
- for f in save_dir.glob("*.png"):
56
- screenshots.append({
57
- "path": str(f),
58
- "filename": f.name,
59
- "modified": f.stat().st_mtime,
60
- })
61
-
62
- screenshots.sort(key=lambda x: x["modified"], reverse=True)
63
- return screenshots
64
-
65
-
66
- def get_last_screenshot() -> dict | None:
67
- """Get the most recent screenshot."""
68
- screenshots = get_screenshots()
69
- return screenshots[0] if screenshots else None
70
-
71
-
72
43
  def start_daemon() -> tuple[bool, str]:
73
44
  """Start the daemon as a background process."""
74
45
  state = get_daemon_state()
@@ -137,72 +108,13 @@ def create_server() -> Server:
137
108
  ),
138
109
  Tool(
139
110
  name="get_status",
140
- description="Get ScreenFix status",
111
+ description="Get ScreenFix daemon status",
141
112
  inputSchema={"type": "object", "properties": {}, "required": []},
142
113
  ),
143
- Tool(
144
- name="get_last_screenshot",
145
- description="Get the most recent screenshot with its image and related task",
146
- inputSchema={
147
- "type": "object",
148
- "properties": {
149
- "include_image": {
150
- "type": "boolean",
151
- "description": "Include image data",
152
- "default": True,
153
- }
154
- },
155
- "required": [],
156
- },
157
- ),
158
- Tool(
159
- name="list_screenshots",
160
- description="List all screenshots",
161
- inputSchema={
162
- "type": "object",
163
- "properties": {
164
- "limit": {"type": "integer", "default": 10}
165
- },
166
- "required": [],
167
- },
168
- ),
169
- Tool(
170
- name="get_tasks",
171
- description="Get tasks from tasks.md",
172
- inputSchema={
173
- "type": "object",
174
- "properties": {
175
- "pending_only": {"type": "boolean", "default": False}
176
- },
177
- "required": [],
178
- },
179
- ),
180
- Tool(
181
- name="complete_task",
182
- description="Mark a task as complete",
183
- inputSchema={
184
- "type": "object",
185
- "properties": {
186
- "task_text": {"type": "string", "description": "Task text to mark complete"}
187
- },
188
- "required": ["task_text"],
189
- },
190
- ),
191
- Tool(
192
- name="read_screenshot",
193
- description="Read a specific screenshot by path",
194
- inputSchema={
195
- "type": "object",
196
- "properties": {
197
- "path": {"type": "string", "description": "Path to screenshot"}
198
- },
199
- "required": ["path"],
200
- },
201
- ),
202
114
  ]
203
115
 
204
116
  @server.call_tool()
205
- async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent | ImageContent]:
117
+ async def call_tool(name: str, arguments: dict) -> list[TextContent]:
206
118
 
207
119
  if name == "start_daemon":
208
120
  success, message = start_daemon()
@@ -214,89 +126,15 @@ def create_server() -> Server:
214
126
 
215
127
  elif name == "get_status":
216
128
  state = get_daemon_state()
217
- screenshots = get_screenshots()
218
- tasks = get_pending_tasks()
219
-
220
129
  status = "Running" if state.get("running") else "Not running"
221
130
  text = f"""ScreenFix Status:
222
131
  - Daemon: {status}
223
- - Screenshots: {len(screenshots)}
224
- - Pending tasks: {len(tasks)}
225
132
 
226
- Use Cmd+Ctrl+Shift+4 to capture (instant, no delay)"""
133
+ Use Cmd+Ctrl+Shift+4 to capture (instant, no delay)
134
+ Screenshots saved to: ./screenfix/screenshots/
135
+ Tasks saved to: ./screenfix/tasks/screenfix-tasks.md"""
227
136
  return [TextContent(type="text", text=text)]
228
137
 
229
- elif name == "get_last_screenshot":
230
- include_image = arguments.get("include_image", True)
231
- screenshot = get_last_screenshot()
232
-
233
- if not screenshot:
234
- return [TextContent(type="text", text="No screenshots found. Use Cmd+Ctrl+Shift+4 to capture.")]
235
-
236
- result = [TextContent(type="text", text=f"Screenshot: {screenshot['path']}")]
237
-
238
- if include_image and os.path.exists(screenshot["path"]):
239
- with open(screenshot["path"], "rb") as f:
240
- image_data = base64.standard_b64encode(f.read()).decode("utf-8")
241
- result.append(ImageContent(type="image", data=image_data, mimeType="image/png"))
242
-
243
- tasks = get_tasks()
244
- for task in tasks:
245
- if task.get("screenshot") == screenshot["path"]:
246
- result.append(TextContent(
247
- type="text",
248
- text=f"\nTask: {task['text']}\nStatus: {'Done' if task['completed'] else 'Pending'}"
249
- ))
250
- break
251
-
252
- return result
253
-
254
- elif name == "list_screenshots":
255
- limit = arguments.get("limit", 10)
256
- screenshots = get_screenshots()[:limit]
257
-
258
- if not screenshots:
259
- return [TextContent(type="text", text="No screenshots found.")]
260
-
261
- lines = ["Screenshots:"]
262
- for i, s in enumerate(screenshots, 1):
263
- lines.append(f"{i}. {s['filename']}")
264
-
265
- return [TextContent(type="text", text="\n".join(lines))]
266
-
267
- elif name == "get_tasks":
268
- pending_only = arguments.get("pending_only", False)
269
- tasks = get_pending_tasks() if pending_only else get_tasks()
270
-
271
- if not tasks:
272
- return [TextContent(type="text", text="No tasks found.")]
273
-
274
- lines = ["Tasks:"]
275
- for i, task in enumerate(tasks, 1):
276
- status = "[x]" if task["completed"] else "[ ]"
277
- lines.append(f"{i}. {status} {task['text']}")
278
-
279
- return [TextContent(type="text", text="\n".join(lines))]
280
-
281
- elif name == "complete_task":
282
- task_text = arguments.get("task_text", "")
283
- if mark_task_complete(task_text):
284
- return [TextContent(type="text", text=f"Completed: {task_text}")]
285
- return [TextContent(type="text", text=f"Task not found: {task_text}")]
286
-
287
- elif name == "read_screenshot":
288
- path = arguments.get("path", "")
289
- if not path or not os.path.exists(path):
290
- return [TextContent(type="text", text=f"Not found: {path}")]
291
-
292
- with open(path, "rb") as f:
293
- image_data = base64.standard_b64encode(f.read()).decode("utf-8")
294
-
295
- return [
296
- TextContent(type="text", text=f"Screenshot: {path}"),
297
- ImageContent(type="image", data=image_data, mimeType="image/png"),
298
- ]
299
-
300
138
  return [TextContent(type="text", text=f"Unknown tool: {name}")]
301
139
 
302
140
  return server
@@ -1,6 +1,8 @@
1
1
  ---
2
- allowed-tools: mcp__screenfix__get_tasks, mcp__screenfix__complete_task
3
- description: View and manage ScreenFix tasks
2
+ allowed-tools: Read, Glob
3
+ description: View ScreenFix tasks and screenshots
4
4
  ---
5
5
 
6
- Get all tasks using `mcp__screenfix__get_tasks`. Show pending tasks and their screenshots.
6
+ 1. Read the tasks file at `./screenfix/tasks/screenfix-tasks.md`
7
+ 2. Use Glob to find screenshots: `./screenfix/screenshots/*.png`
8
+ 3. Show pending tasks (lines with `- [ ]`) and their associated screenshots
@@ -3,6 +3,6 @@ allowed-tools: mcp__screenfix__start_daemon, mcp__screenfix__get_status
3
3
  description: Start the ScreenFix daemon
4
4
  ---
5
5
 
6
- Start the ScreenFix daemon using `mcp__screenfix__start_daemon`. After starting, check the status.
6
+ Start the ScreenFix daemon using `mcp__screenfix__start_daemon`. After starting, check the status with `mcp__screenfix__get_status`.
7
7
 
8
8
  Once running, use **Cmd+Ctrl+Shift+4** to capture screenshots instantly (no delay).
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  allowed-tools: mcp__screenfix__get_status
3
- description: Check ScreenFix status
3
+ description: Check ScreenFix daemon status
4
4
  ---
5
5
 
6
6
  Check the current status of ScreenFix using `mcp__screenfix__get_status`.
@@ -1,14 +1,15 @@
1
1
  ---
2
- allowed-tools: mcp__screenfix__get_tasks, mcp__screenfix__get_last_screenshot, mcp__screenfix__read_screenshot, mcp__screenfix__complete_task, Read, Edit, Write, Bash, Glob, Grep
2
+ allowed-tools: Read, Edit, Write, Bash, Glob, Grep
3
3
  description: Execute the next pending ScreenFix task
4
4
  ---
5
5
 
6
- Get all pending tasks using `mcp__screenfix__get_tasks` with `pending_only: true`.
6
+ 1. Read the tasks file at `./screenfix/tasks/screenfix-tasks.md`
7
+ 2. Find the FIRST pending task (line with `- [ ]`)
7
8
 
8
- Take only the FIRST pending task:
9
- 1. Read the associated screenshot using `mcp__screenfix__read_screenshot`
9
+ For that task:
10
+ 1. The task line contains the screenshot path - read that screenshot using the Read tool
10
11
  2. Analyze the screenshot and the task instructions
11
12
  3. Implement the fix described in the instructions
12
- 4. Mark the task complete using `mcp__screenfix__complete_task`
13
+ 4. Mark the task complete by editing the tasks file: change `- [ ]` to `- [x]`
13
14
 
14
15
  Execute one task at a time.
@@ -1,14 +1,15 @@
1
1
  ---
2
- allowed-tools: mcp__screenfix__get_tasks, mcp__screenfix__get_last_screenshot, mcp__screenfix__read_screenshot, mcp__screenfix__complete_task, Read, Edit, Write, Bash, Glob, Grep
2
+ allowed-tools: Read, Edit, Write, Bash, Glob, Grep
3
3
  description: Execute all pending ScreenFix tasks automatically
4
4
  ---
5
5
 
6
- Get all pending tasks using `mcp__screenfix__get_tasks` with `pending_only: true`.
6
+ 1. Read the tasks file at `./screenfix/tasks/screenfix-tasks.md`
7
+ 2. Find all pending tasks (lines with `- [ ]`)
7
8
 
8
9
  For each pending task:
9
- 1. Read the associated screenshot using `mcp__screenfix__read_screenshot`
10
+ 1. The task line contains the screenshot path - read that screenshot using the Read tool
10
11
  2. Analyze the screenshot and the task instructions
11
12
  3. Implement the fix described in the instructions
12
- 4. Mark the task complete using `mcp__screenfix__complete_task`
13
+ 4. Mark the task complete by editing the tasks file: change `- [ ]` to `- [x]`
13
14
 
14
15
  Execute all tasks without asking for confirmation. Just do it.