annotask 0.0.5 → 0.0.6

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/README.md CHANGED
@@ -169,6 +169,13 @@ Start your dev server, then open:
169
169
  - **Violation cards** — Shows impact level, rule, description, and affected element count
170
170
  - **One-click fix tasks** — Create tasks from violations with full context (HTML snippets, CSS selectors, source file/line, and fix suggestions)
171
171
 
172
+ ### Screenshots
173
+ - **Snipping tool** — Click "Add Screenshot" on any task form, then drag a region or click for full-page capture
174
+ - **Thumbnail preview** — Screenshot appears as a preview on the task form before submitting (removable)
175
+ - **Task-attached** — Screenshots are stored on the server and referenced by filename in the task
176
+ - **Multimodal AI context** — AI agents can download and view screenshots for visual understanding of what the user sees
177
+ - **Auto-cleanup** — Screenshot files are deleted when the task is accepted
178
+
172
179
  ### AI agent context
173
180
  - **Interaction history** — Optionally track user navigation and button/link clicks in the app so the AI agent understands how the user reached the current state
174
181
  - **Element context** — Optionally capture ancestor layout chain (3 levels of parent display, flex-direction, gap, grid-template) and DOM subtree (3 levels of children with tag, classes, text) for each task
@@ -186,10 +193,11 @@ Start your dev server, then open:
186
193
  annotask watch # Live stream of changes
187
194
  annotask report # Fetch current report JSON
188
195
  annotask status # Check connection
196
+ annotask screenshot <id> # Download a task's screenshot
189
197
  annotask init-skills # Install agent skills into your project
190
198
  ```
191
199
 
192
- Options: `--port=N`, `--host=H`, `--server=URL` (override server.json), `--mfe=NAME` (filter by MFE).
200
+ Options: `--port=N`, `--host=H`, `--server=URL` (override server.json), `--mfe=NAME` (filter by MFE), `--output=PATH` (for screenshot command).
193
201
 
194
202
  ## API
195
203
 
@@ -197,6 +205,8 @@ Options: `--port=N`, `--host=H`, `--server=URL` (override server.json), `--mfe=N
197
205
  - `GET /__annotask/api/tasks` — Task list (supports `?mfe=NAME` filter)
198
206
  - `POST /__annotask/api/tasks` — Create a task
199
207
  - `PATCH /__annotask/api/tasks/:id` — Update task status
208
+ - `POST /__annotask/api/screenshots` — Upload a screenshot (base64 PNG)
209
+ - `GET /__annotask/screenshots/:filename` — Serve a screenshot
200
210
  - `GET /__annotask/api/status` — Health check
201
211
  - `ws://localhost:5173/__annotask/ws` — Live WebSocket stream
202
212
 
package/dist/cli.js CHANGED
@@ -48,6 +48,10 @@ if (command === "watch") {
48
48
  initSkills();
49
49
  } else if (command === "screenshot") {
50
50
  fetchScreenshot();
51
+ } else if (command === "tasks") {
52
+ fetchTasks();
53
+ } else if (command === "update-task") {
54
+ updateTask();
51
55
  } else if (command === "help" || command === "--help") {
52
56
  printHelp();
53
57
  } else {
@@ -189,6 +193,45 @@ async function fetchScreenshot() {
189
193
  process.exit(1);
190
194
  }
191
195
  }
196
+ async function fetchTasks() {
197
+ try {
198
+ const tasksUrl = mfeFilter ? `${apiUrl}/tasks?mfe=${encodeURIComponent(mfeFilter)}` : `${apiUrl}/tasks`;
199
+ const res = await fetch(tasksUrl);
200
+ const data = await res.json();
201
+ console.log(JSON.stringify(data, null, 2));
202
+ } catch (err) {
203
+ console.error(`\x1B[31m[Annotask]\x1B[0m Failed to fetch tasks: ${err.message}`);
204
+ process.exit(1);
205
+ }
206
+ }
207
+ async function updateTask() {
208
+ const taskId = args[1];
209
+ const statusArg = args.find((a) => a.startsWith("--status="))?.split("=")[1];
210
+ const feedbackArg = args.find((a) => a.startsWith("--feedback="))?.split("=")[1];
211
+ if (!taskId || !statusArg) {
212
+ console.error("\x1B[31m[Annotask]\x1B[0m Usage: annotask update-task <task-id> --status=<status> [--feedback=<text>]");
213
+ console.error(" Valid statuses: pending, applied, review, accepted, denied");
214
+ process.exit(1);
215
+ }
216
+ try {
217
+ const body = { status: statusArg };
218
+ if (feedbackArg) body.feedback = feedbackArg;
219
+ const res = await fetch(`${apiUrl}/tasks/${taskId}`, {
220
+ method: "PATCH",
221
+ headers: { "Content-Type": "application/json" },
222
+ body: JSON.stringify(body)
223
+ });
224
+ const data = await res.json();
225
+ if (data.error) {
226
+ console.error(`\x1B[31m[Annotask]\x1B[0m ${data.error}`);
227
+ process.exit(1);
228
+ }
229
+ console.log(JSON.stringify(data, null, 2));
230
+ } catch (err) {
231
+ console.error(`\x1B[31m[Annotask]\x1B[0m Failed to update task: ${err.message}`);
232
+ process.exit(1);
233
+ }
234
+ }
192
235
  function initSkills() {
193
236
  const __dirname = dirname(fileURLToPath(import.meta.url));
194
237
  const srcSkills = resolve(__dirname, "..", "skills");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "annotask",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "module": "./dist/index.js",
@@ -16,37 +16,18 @@ Annotask is a visual markup tool that integrates with Vite and Webpack. The user
16
16
 
17
17
  ## Steps
18
18
 
19
- ### 0. Discover server URL
20
-
21
- Read `.annotask/server.json` in the **current working directory only** (never search parent directories):
22
-
23
- ```bash
24
- cat .annotask/server.json
25
- ```
26
-
27
- This returns `{ "url": "http://localhost:PORT", "port": PORT }`. Use the `url` value as `BASE_URL` for all API calls below.
28
-
29
- If the file contains a `"mfe"` field (e.g. `"mfe": "@myorg/my-mfe"`), this project is a **micro-frontend** and the server is running on a remote root shell. Save the `mfe` value as `MFE_FILTER` — you will use it to filter tasks in step 1.
30
-
31
- If the file does not exist, probe for a running server:
19
+ ### 0. Check server status
32
20
 
33
21
  ```bash
34
- curl -s http://localhost:24678/__annotask/api/status
35
- curl -s http://localhost:5173/__annotask/api/status
22
+ annotask status
36
23
  ```
37
24
 
38
- Use whichever responds with `{"status":"ok"}`. **IMPORTANT: Do NOT read server.json from parent or sibling directories it belongs to a different project.**
25
+ If this fails, the Annotask dev server isn't running. Ask the user to start it.
39
26
 
40
27
  ### 1. Fetch pending tasks
41
28
 
42
- If `MFE_FILTER` is set (from step 0), append it as a query parameter to filter tasks for this project:
43
-
44
29
  ```bash
45
- # Without MFE filter (standard single-project setup):
46
- curl -s $BASE_URL/__annotask/api/tasks
47
-
48
- # With MFE filter (micro-frontend setup):
49
- curl -s $BASE_URL/__annotask/api/tasks?mfe=$MFE_FILTER
30
+ annotask tasks
50
31
  ```
51
32
 
52
33
  Response:
@@ -62,13 +43,24 @@ Response:
62
43
  "file": "src/components/Header.vue",
63
44
  "line": 5,
64
45
  "action": "text_edit",
65
- "context": { "element_tag": "header" }
46
+ "context": { "element_tag": "header" },
47
+ "screenshot": "screenshot-1711800000-ab3kf.png"
66
48
  }
67
49
  ]
68
50
  }
69
51
  ```
70
52
 
71
- Each task has: `id`, `type`, `status`, `description` (what to do), `file`, `line`, `component`, and optionally `action` and `context` with element details.
53
+ Each task has: `id`, `type`, `status`, `description` (what to do), `file`, `line`, `component`, and optionally `action`, `context` with element details, and `screenshot` with a filename.
54
+
55
+ ### Screenshot reference
56
+
57
+ Some tasks include a `screenshot` field. The screenshot shows exactly what the user sees in the browser. To view it:
58
+
59
+ ```bash
60
+ annotask screenshot TASK_ID
61
+ ```
62
+
63
+ This downloads the PNG to `.annotask/screenshots/`. Use it as visual context alongside the task description and source code.
72
64
 
73
65
  ### 2. Process each pending task
74
66
 
@@ -80,10 +72,12 @@ Filter for `status: "pending"` tasks. For each:
80
72
 
81
73
  - **`annotation` with no action**: This is a free-text note. Read `description` and apply your best judgment to the source code. If `context.to_element` is present, this is an arrow annotation referencing two elements.
82
74
 
83
- - **`style_update`**: Apply CSS property change. `property` and `after` values tell you what to set. Use scoped styles, inline styles, or Tailwind classes based on project patterns.
75
+ - **`style_update`**: Apply CSS property changes. The `context.changes` array contains each change with `property`, `before`, and `after` values. Use scoped styles, inline styles, or Tailwind classes based on project patterns.
84
76
 
85
77
  - **`section_request`**: Create a new section in the template near the referenced element. The `description` field describes what content to create. `placement` gives spatial hints.
86
78
 
79
+ - **`a11y_fix`**: Fix an accessibility violation. The `context` contains `rule` (axe rule ID), `impact`, `help` (what to fix), `helpUrl` (WCAG reference), and `elements` array with `html` snippets, `selector`, `fix` suggestions, and source `file`/`line`/`component`.
80
+
87
81
  - **`theme_update`**: A design token value change from the Theme page. The `context` object contains:
88
82
  - `category`: which token category (`colors`, `typography.families`, `typography.scale`, `spacing`, `borders.radius`)
89
83
  - `role`: semantic role name (e.g., `primary`, `background`, `heading`)
@@ -102,12 +96,10 @@ Filter for `status: "pending"` tasks. For each:
102
96
 
103
97
  ### 3. Mark tasks as ready for review
104
98
 
105
- After applying each task, mark it:
99
+ After applying each task:
106
100
 
107
101
  ```bash
108
- curl -s -X PATCH $BASE_URL/__annotask/api/tasks/TASK_ID \
109
- -H "Content-Type: application/json" \
110
- -d '{"status": "review"}'
102
+ annotask update-task TASK_ID --status=review
111
103
  ```
112
104
 
113
105
  ### 4. Report to the user
@@ -125,7 +117,11 @@ If there are tasks with `status: "denied"` and a `feedback` field, the user reje
125
117
 
126
118
  ## Also check the live report
127
119
 
128
- The real-time report at `$BASE_URL/__annotask/api/report` contains the current session's markup. Use this as additional context — it shows what's on the user's screen right now. But tasks are the source of truth for what to apply.
120
+ ```bash
121
+ annotask report
122
+ ```
123
+
124
+ This returns both the live report (current session markup) and tasks. Use it as additional context — it shows what's on the user's screen right now. But tasks are the source of truth for what to apply.
129
125
 
130
126
  ## Task lifecycle
131
127
 
@@ -122,7 +122,36 @@ Search for:
122
122
 
123
123
  Use roles: `sm`, `md`, `lg`, `xl`, `full` (match by name or ascending size).
124
124
 
125
- ### 6. Detect icon library
125
+ ### 6. Scan breakpoints
126
+
127
+ Detect responsive breakpoints from whatever styling system the project uses. Output as a flat object mapping name → min-width value.
128
+
129
+ **Sources (check in order):**
130
+
131
+ 1. **Tailwind v4** (>= 4): Look in CSS files for `@theme` blocks defining `--breakpoint-*` custom properties, or `@custom-media` rules.
132
+
133
+ 2. **Tailwind v3** (< 4): Read `tailwind.config.{js,ts,mjs}`. Extract `theme.screens` or `theme.extend.screens`. Default Tailwind screens: `{ "sm": "640px", "md": "768px", "lg": "1024px", "xl": "1280px", "2xl": "1536px" }` — use these as fallback if Tailwind is detected but no custom screens are defined.
134
+
135
+ 3. **Bootstrap**: Check for `bootstrap` in package.json. Default Bootstrap breakpoints: `{ "sm": "576px", "md": "768px", "lg": "992px", "xl": "1200px", "xxl": "1400px" }`.
136
+
137
+ 4. **CSS custom properties**: Search `:root` for variables containing `breakpoint`, `screen`, `bp` in the name (e.g., `--bp-mobile: 480px`).
138
+
139
+ 5. **CSS `@media` patterns**: Scan `.css`, `.scss`, `.vue` files for `@media` queries with `min-width` or `max-width`. Extract the 3–6 most common breakpoint values and assign roles by ascending size: `sm`, `md`, `lg`, `xl`, `2xl`.
140
+
141
+ **Output example:**
142
+ ```json
143
+ "breakpoints": {
144
+ "sm": "640px",
145
+ "md": "768px",
146
+ "lg": "1024px",
147
+ "xl": "1280px",
148
+ "2xl": "1536px"
149
+ }
150
+ ```
151
+
152
+ If no breakpoints are detected, omit the `breakpoints` field (don't include an empty object).
153
+
154
+ ### 7. Detect icon library
126
155
 
127
156
  Check `package.json` dependencies for:
128
157
 
@@ -136,7 +165,7 @@ Check `package.json` dependencies for:
136
165
 
137
166
  Read the version from package.json.
138
167
 
139
- ### 7. Detect component library
168
+ ### 8. Detect component library
140
169
 
141
170
  Check `package.json` dependencies for:
142
171
 
@@ -157,7 +186,7 @@ grep -rh "from '${package}" --include='*.vue' --include='*.ts' --include='*.js'
157
186
 
158
187
  Extract component names from the imports. Read the version from package.json.
159
188
 
160
- ### 8. Write design spec
189
+ ### 9. Write design spec
161
190
 
162
191
  Create `.annotask/design-spec.json`:
163
192
 
@@ -190,6 +219,13 @@ Create `.annotask/design-spec.json`:
190
219
  { "role": "md", "value": "8px", "cssVar": "--radius-md", "source": "var(--radius-md)", "sourceFile": "src/assets/main.css", "sourceLine": 25 }
191
220
  ]
192
221
  },
222
+ "breakpoints": {
223
+ "sm": "640px",
224
+ "md": "768px",
225
+ "lg": "1024px",
226
+ "xl": "1280px",
227
+ "2xl": "1536px"
228
+ },
193
229
  "icons": {
194
230
  "library": "lucide",
195
231
  "version": "0.300.0"
@@ -202,11 +238,11 @@ Create `.annotask/design-spec.json`:
202
238
  }
203
239
  ```
204
240
 
205
- ### 9. Clean up old config
241
+ ### 10. Clean up old config
206
242
 
207
243
  If `.annotask/config.json` exists, delete it — it's been replaced by `design-spec.json`.
208
244
 
209
- ### 10. Update .gitignore
245
+ ### 11. Update .gitignore
210
246
 
211
247
  Check if `.gitignore` contains `.annotask/`. If not, append:
212
248
  ```
@@ -214,7 +250,7 @@ Check if `.gitignore` contains `.annotask/`. If not, append:
214
250
  .annotask/
215
251
  ```
216
252
 
217
- ### 11. Report to user
253
+ ### 12. Report to user
218
254
 
219
255
  Tell the user:
220
256
  - What was detected (framework, number of color/typography/spacing tokens, libraries)
@@ -16,19 +16,21 @@ Connect to the Annotask WebSocket and stream changes as the user makes them visu
16
16
 
17
17
  ## Steps
18
18
 
19
- 0. **Discover server URL** — read `.annotask/server.json` in the current working directory only (never parent directories):
19
+ 0. **Check server status**:
20
20
  ```bash
21
- cat .annotask/server.json
21
+ annotask status
22
22
  ```
23
- Use the `url` value as the server URL. If the file contains a `"mfe"` field, this is a micro-frontend setup — the server is running on a remote root shell. Save the `mfe` value for filtering. If not found, probe `curl -s http://localhost:24678/__annotask/api/status` then `curl -s http://localhost:5173/__annotask/api/status`. **Do NOT read server.json from parent or sibling directories.**
23
+ If this fails, the Annotask dev server isn't running. Ask the user to start it.
24
24
 
25
- 1. **Start watching** by running in the background:
25
+ 1. **Start watching**:
26
26
  ```bash
27
- npx @annotask/cli watch --port=PORT
27
+ annotask watch
28
28
  ```
29
- Or if the CLI isn't installed, poll the HTTP API:
29
+ This connects to the Annotask WebSocket and streams changes in real-time. If the CLI isn't installed globally, use `npx annotask watch`.
30
+
31
+ For a one-time snapshot instead of live streaming:
30
32
  ```bash
31
- curl -s $BASE_URL/__annotask/api/report
33
+ annotask report
32
34
  ```
33
35
 
34
36
  2. **Describe what you see** — as changes come in, summarize them in plain language: