screenhand 0.2.0 → 0.3.1
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 +165 -446
- package/bin/darwin-arm64/macos-bridge +0 -0
- package/dist/mcp-desktop.js +3615 -400
- package/dist/scripts/export-help-center.js +112 -0
- package/dist/scripts/marketing-loop.js +117 -0
- package/dist/scripts/observer-daemon.js +288 -0
- package/dist/scripts/orchestrator-daemon.js +399 -0
- package/dist/scripts/threads-campaign.js +208 -0
- package/dist/src/community/fetcher.js +109 -0
- package/dist/src/community/index.js +6 -0
- package/dist/src/community/publisher.js +191 -0
- package/dist/src/community/remote-api.js +121 -0
- package/dist/src/community/types.js +3 -0
- package/dist/src/community/validator.js +95 -0
- package/dist/src/context-tracker.js +489 -0
- package/dist/src/ingestion/coverage-auditor.js +233 -0
- package/dist/src/ingestion/doc-parser.js +164 -0
- package/dist/src/ingestion/index.js +8 -0
- package/dist/src/ingestion/menu-scanner.js +152 -0
- package/dist/src/ingestion/reference-merger.js +186 -0
- package/dist/src/ingestion/shortcut-extractor.js +180 -0
- package/dist/src/ingestion/tutorial-extractor.js +170 -0
- package/dist/src/ingestion/types.js +3 -0
- package/dist/src/jobs/manager.js +82 -14
- package/dist/src/jobs/runner.js +138 -15
- package/dist/src/learning/engine.js +356 -0
- package/dist/src/learning/index.js +9 -0
- package/dist/src/learning/locator-policy.js +120 -0
- package/dist/src/learning/pattern-policy.js +89 -0
- package/dist/src/learning/recovery-policy.js +116 -0
- package/dist/src/learning/sensor-policy.js +115 -0
- package/dist/src/learning/timing-model.js +204 -0
- package/dist/src/learning/topology-policy.js +90 -0
- package/dist/src/learning/types.js +9 -0
- package/dist/src/logging/timeline-logger.js +4 -1
- package/dist/src/memory/playbook-seeds.js +200 -0
- package/dist/src/memory/recall.js +60 -8
- package/dist/src/memory/service.js +30 -5
- package/dist/src/memory/store.js +34 -5
- package/dist/src/native/bridge-client.js +253 -31
- package/dist/src/observer/state.js +199 -0
- package/dist/src/observer/types.js +43 -0
- package/dist/src/orchestrator/state.js +68 -0
- package/dist/src/orchestrator/types.js +22 -0
- package/dist/src/perception/ax-source.js +162 -0
- package/dist/src/perception/cdp-source.js +162 -0
- package/dist/src/perception/coordinator.js +771 -0
- package/dist/src/perception/frame-differ.js +287 -0
- package/dist/src/perception/index.js +22 -0
- package/dist/src/perception/manager.js +199 -0
- package/dist/src/perception/types.js +47 -0
- package/dist/src/perception/vision-source.js +399 -0
- package/dist/src/planner/deterministic.js +298 -0
- package/dist/src/planner/executor.js +870 -0
- package/dist/src/planner/goal-store.js +92 -0
- package/dist/src/planner/index.js +21 -0
- package/dist/src/planner/planner.js +520 -0
- package/dist/src/planner/tool-registry.js +71 -0
- package/dist/src/planner/types.js +22 -0
- package/dist/src/platform/explorer.js +213 -0
- package/dist/src/platform/help-center-markdown.js +527 -0
- package/dist/src/platform/learner.js +257 -0
- package/dist/src/playbook/engine.js +296 -11
- package/dist/src/playbook/mcp-recorder.js +204 -0
- package/dist/src/playbook/recorder.js +3 -2
- package/dist/src/playbook/runner.js +1 -1
- package/dist/src/playbook/store.js +139 -10
- package/dist/src/recovery/detectors.js +156 -0
- package/dist/src/recovery/engine.js +327 -0
- package/dist/src/recovery/index.js +20 -0
- package/dist/src/recovery/strategies.js +274 -0
- package/dist/src/recovery/types.js +20 -0
- package/dist/src/runtime/accessibility-adapter.js +55 -18
- package/dist/src/runtime/applescript-adapter.js +8 -2
- package/dist/src/runtime/cdp-chrome-adapter.js +1 -1
- package/dist/src/runtime/executor.js +23 -3
- package/dist/src/runtime/locator-cache.js +24 -2
- package/dist/src/runtime/service.js +59 -15
- package/dist/src/runtime/session-manager.js +4 -1
- package/dist/src/runtime/vision-adapter.js +2 -1
- package/dist/src/state/app-map-types.js +72 -0
- package/dist/src/state/app-map.js +1974 -0
- package/dist/src/state/entity-tracker.js +108 -0
- package/dist/src/state/fusion.js +96 -0
- package/dist/src/state/index.js +21 -0
- package/dist/src/state/ladder-generator.js +236 -0
- package/dist/src/state/persistence.js +156 -0
- package/dist/src/state/types.js +17 -0
- package/dist/src/state/world-model.js +1456 -0
- package/dist/src/util/atomic-write.js +19 -4
- package/dist/src/util/sanitize.js +146 -0
- package/dist-app-maps/com.figma.Desktop.json +959 -0
- package/dist-app-maps/com.hnc.Discord.json +1146 -0
- package/dist-app-maps/notion.id.json +2831 -0
- package/dist-playbooks/canva-screenhand-carousel.json +445 -0
- package/dist-playbooks/codex-desktop.json +76 -0
- package/dist-playbooks/competitor-research-stack.json +122 -0
- package/dist-playbooks/davinci-color-grade.json +153 -0
- package/dist-playbooks/davinci-edit-timeline.json +162 -0
- package/dist-playbooks/davinci-render.json +114 -0
- package/dist-playbooks/devto.json +52 -0
- package/dist-playbooks/discord.json +41 -0
- package/dist-playbooks/google-flow-create-project.json +59 -0
- package/dist-playbooks/google-flow-edit-image.json +90 -0
- package/dist-playbooks/google-flow-edit-video.json +90 -0
- package/dist-playbooks/google-flow-generate-image.json +68 -0
- package/dist-playbooks/google-flow-generate-video.json +191 -0
- package/dist-playbooks/google-flow-open-project.json +48 -0
- package/dist-playbooks/google-flow-open-scenebuilder.json +64 -0
- package/dist-playbooks/google-flow-search-assets.json +64 -0
- package/dist-playbooks/instagram.json +57 -0
- package/dist-playbooks/linkedin.json +52 -0
- package/dist-playbooks/n8n.json +43 -0
- package/dist-playbooks/reddit.json +52 -0
- package/dist-playbooks/threads.json +59 -0
- package/dist-playbooks/x-twitter.json +59 -0
- package/dist-playbooks/youtube.json +59 -0
- package/dist-references/canva.json +646 -0
- package/dist-references/codex-desktop.json +305 -0
- package/dist-references/davinci-resolve-keyboard.json +594 -0
- package/dist-references/davinci-resolve-menu-map.json +1139 -0
- package/dist-references/davinci-resolve-menus-batch1.json +116 -0
- package/dist-references/davinci-resolve-menus-batch2.json +372 -0
- package/dist-references/davinci-resolve-menus-batch3.json +330 -0
- package/dist-references/davinci-resolve-menus-batch4.json +297 -0
- package/dist-references/davinci-resolve-shortcuts.json +333 -0
- package/dist-references/devpost.json +186 -0
- package/dist-references/devto.json +317 -0
- package/dist-references/discord.json +549 -0
- package/dist-references/figma.json +1186 -0
- package/dist-references/finder.json +146 -0
- package/dist-references/google-ads-transparency.json +95 -0
- package/dist-references/google-flow.json +649 -0
- package/dist-references/instagram.json +341 -0
- package/dist-references/linkedin.json +324 -0
- package/dist-references/meta-ad-library.json +86 -0
- package/dist-references/n8n.json +387 -0
- package/dist-references/notes.json +27 -0
- package/dist-references/notion.json +163 -0
- package/dist-references/reddit.json +341 -0
- package/dist-references/threads.json +337 -0
- package/dist-references/x-twitter.json +403 -0
- package/dist-references/youtube.json +373 -0
- package/native/macos-bridge/Package.swift +22 -0
- package/native/macos-bridge/Sources/AccessibilityBridge.swift +482 -0
- package/native/macos-bridge/Sources/AppManagement.swift +339 -0
- package/native/macos-bridge/Sources/CoreGraphicsBridge.swift +537 -0
- package/native/macos-bridge/Sources/ObserverBridge.swift +120 -0
- package/native/macos-bridge/Sources/StreamCapture.swift +136 -0
- package/native/macos-bridge/Sources/VisionBridge.swift +238 -0
- package/native/macos-bridge/Sources/main.swift +498 -0
- package/native/windows-bridge/AppManagement.cs +234 -0
- package/native/windows-bridge/InputBridge.cs +436 -0
- package/native/windows-bridge/Program.cs +270 -0
- package/native/windows-bridge/ScreenCapture.cs +453 -0
- package/native/windows-bridge/UIAutomationBridge.cs +571 -0
- package/native/windows-bridge/WindowsBridge.csproj +17 -0
- package/package.json +12 -1
- package/scripts/postinstall.cjs +127 -0
- package/dist/.audit-log.jsonl +0 -55
- package/dist/.screenhand/memory/.lock +0 -1
- package/dist/.screenhand/memory/actions.jsonl +0 -85
- package/dist/.screenhand/memory/errors.jsonl +0 -5
- package/dist/.screenhand/memory/errors.jsonl.bak +0 -4
- package/dist/.screenhand/memory/state.json +0 -35
- package/dist/.screenhand/memory/state.json.bak +0 -35
- package/dist/.screenhand/memory/strategies.jsonl +0 -12
- package/dist/agent/cli.js +0 -73
- package/dist/agent/loop.js +0 -258
- package/dist/config.js +0 -9
- package/dist/index.js +0 -56
- package/dist/logging/timeline-logger.js +0 -29
- package/dist/mcp/mcp-stdio-server.js +0 -448
- package/dist/mcp/server.js +0 -347
- package/dist/mcp-entry.js +0 -59
- package/dist/memory/recall.js +0 -160
- package/dist/memory/research.js +0 -98
- package/dist/memory/seeds.js +0 -89
- package/dist/memory/session.js +0 -161
- package/dist/memory/store.js +0 -391
- package/dist/memory/types.js +0 -4
- package/dist/monitor/codex-monitor.js +0 -377
- package/dist/monitor/task-queue.js +0 -84
- package/dist/monitor/types.js +0 -49
- package/dist/native/bridge-client.js +0 -174
- package/dist/native/macos-bridge-client.js +0 -5
- package/dist/npm-publish-helper.js +0 -117
- package/dist/npm-token-cdp.js +0 -113
- package/dist/npm-token-create.js +0 -135
- package/dist/npm-token-finish.js +0 -126
- package/dist/playbook/engine.js +0 -193
- package/dist/playbook/index.js +0 -4
- package/dist/playbook/recorder.js +0 -519
- package/dist/playbook/runner.js +0 -392
- package/dist/playbook/store.js +0 -166
- package/dist/playbook/types.js +0 -4
- package/dist/runtime/accessibility-adapter.js +0 -377
- package/dist/runtime/app-adapter.js +0 -48
- package/dist/runtime/applescript-adapter.js +0 -283
- package/dist/runtime/ax-role-map.js +0 -80
- package/dist/runtime/browser-adapter.js +0 -36
- package/dist/runtime/cdp-chrome-adapter.js +0 -505
- package/dist/runtime/composite-adapter.js +0 -205
- package/dist/runtime/executor.js +0 -250
- package/dist/runtime/locator-cache.js +0 -12
- package/dist/runtime/planning-loop.js +0 -47
- package/dist/runtime/service.js +0 -372
- package/dist/runtime/session-manager.js +0 -28
- package/dist/runtime/state-observer.js +0 -105
- package/dist/runtime/vision-adapter.js +0 -208
- package/dist/test-mcp-protocol.js +0 -138
- package/dist/types.js +0 -1
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "devto",
|
|
3
|
+
"name": "Dev.to Automation",
|
|
4
|
+
"description": "Battle-tested playbook for Dev.to browser automation via CDP. Covers creating posts, liking, commenting, bookmarking, searching, and profile management. Dev.to uses standard HTML elements (textarea, button) with React — native value setter needed for controlled inputs.",
|
|
5
|
+
"platform": "devto",
|
|
6
|
+
"version": "1.0.0",
|
|
7
|
+
"urlPatterns": [
|
|
8
|
+
"*dev.to*"
|
|
9
|
+
],
|
|
10
|
+
"tags": [
|
|
11
|
+
"devto",
|
|
12
|
+
"blog",
|
|
13
|
+
"developer",
|
|
14
|
+
"browser",
|
|
15
|
+
"cdp"
|
|
16
|
+
],
|
|
17
|
+
"successCount": 0,
|
|
18
|
+
"failCount": 0,
|
|
19
|
+
"urls": {
|
|
20
|
+
"home": "https://dev.to/",
|
|
21
|
+
"new_post": "https://dev.to/new",
|
|
22
|
+
"dashboard": "https://dev.to/dashboard",
|
|
23
|
+
"reading_list": "https://dev.to/readinglist",
|
|
24
|
+
"notifications": "https://dev.to/notifications",
|
|
25
|
+
"settings": "https://dev.to/settings",
|
|
26
|
+
"search": "https://dev.to/search?q={query}",
|
|
27
|
+
"profile": "https://dev.to/{username}",
|
|
28
|
+
"article": "https://dev.to/{username}/{slug}",
|
|
29
|
+
"tags": "https://dev.to/t/{tag}",
|
|
30
|
+
"top": "https://dev.to/top/{period}"
|
|
31
|
+
},
|
|
32
|
+
"selectors": {
|
|
33
|
+
"nav": {
|
|
34
|
+
"search_button": "button[aria-label='Search']",
|
|
35
|
+
"create_post": "a[href='/new']",
|
|
36
|
+
"notifications": "a[href='/notifications']",
|
|
37
|
+
"user_menu": "button#member-menu-button",
|
|
38
|
+
"dashboard": "a[href='/dashboard']",
|
|
39
|
+
"reading_list": "a[href='/readinglist']",
|
|
40
|
+
"settings": "a[href='/settings']",
|
|
41
|
+
"sign_out": "a[href='/signout_confirm']"
|
|
42
|
+
},
|
|
43
|
+
"post_editor": {
|
|
44
|
+
"title": "textarea#article-form-title",
|
|
45
|
+
"body": "textarea#article_body_markdown",
|
|
46
|
+
"tag_input": "input#tag-input",
|
|
47
|
+
"cover_image_input": "input#cover-image-input",
|
|
48
|
+
"publish_button": "button:has-text('Publish')",
|
|
49
|
+
"save_draft_button": "button:has-text('Save draft')",
|
|
50
|
+
"preview_button": "button:has-text('Preview')",
|
|
51
|
+
"edit_button": "button:has-text('Edit')",
|
|
52
|
+
"generate_image": "button:has-text('Generate Image')",
|
|
53
|
+
"cover_video_link": "button:has-text('Cover Video Link')"
|
|
54
|
+
},
|
|
55
|
+
"editor_toolbar": {
|
|
56
|
+
"bold": "button[aria-label='Bold']",
|
|
57
|
+
"italic": "button[aria-label='Italic']",
|
|
58
|
+
"link": "button[aria-label='Link']",
|
|
59
|
+
"ordered_list": "button[aria-label='Ordered list']",
|
|
60
|
+
"unordered_list": "button[aria-label='Unordered list']",
|
|
61
|
+
"heading": "button[aria-label='Heading']",
|
|
62
|
+
"quote": "button[aria-label='Quote']",
|
|
63
|
+
"upload_image": "button[aria-label='Upload image']",
|
|
64
|
+
"more_options": "button[aria-label='More options']"
|
|
65
|
+
},
|
|
66
|
+
"article_page": {
|
|
67
|
+
"reaction_trigger": "button#reaction-drawer-trigger",
|
|
68
|
+
"like_button": "[data-category='like']",
|
|
69
|
+
"jump_to_comments": "button#reaction-butt-comment",
|
|
70
|
+
"save_to_reading_list": "button#reaction-butt-readinglist",
|
|
71
|
+
"boost": "button#reaction-butt-boost",
|
|
72
|
+
"share_options": "button#article-show-more-button",
|
|
73
|
+
"comment_textarea": "textarea#text-area",
|
|
74
|
+
"comment_submit": "button:has-text('Submit')",
|
|
75
|
+
"comment_preview": "button:has-text('Preview')",
|
|
76
|
+
"sort_comments": "button#toggle-comments-sort-dropdown"
|
|
77
|
+
},
|
|
78
|
+
"feed": {
|
|
79
|
+
"article_card": "[class*='crayons-story']",
|
|
80
|
+
"article_link": "[class*='crayons-story'] a",
|
|
81
|
+
"article_title": "[class*='crayons-story__title']",
|
|
82
|
+
"article_tags": "[class*='crayons-tag']",
|
|
83
|
+
"article_user": "[class*='crayons-story'] [class*='profile-preview-card']"
|
|
84
|
+
},
|
|
85
|
+
"search": {
|
|
86
|
+
"search_input": "input#search-input",
|
|
87
|
+
"search_form": "form[action='/search']",
|
|
88
|
+
"search_results": "[class*='crayons-story']"
|
|
89
|
+
},
|
|
90
|
+
"profile": {
|
|
91
|
+
"follow_button": "button:has-text('Follow')",
|
|
92
|
+
"edit_profile": "button[aria-label='Edit profile']"
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"detection": {
|
|
96
|
+
"is_logged_in": "!!document.querySelector('a[href=\"/new\"]')",
|
|
97
|
+
"is_home": "window.location.pathname === '/'",
|
|
98
|
+
"is_editor": "window.location.pathname === '/new' || window.location.pathname.includes('/edit')",
|
|
99
|
+
"is_article": "!!document.querySelector('#reaction-drawer-trigger')",
|
|
100
|
+
"is_dashboard": "window.location.pathname === '/dashboard'",
|
|
101
|
+
"is_search": "window.location.pathname === '/search'",
|
|
102
|
+
"is_profile": "!!document.querySelector('button[aria-label=\"Edit profile\"]')"
|
|
103
|
+
},
|
|
104
|
+
"flows": {
|
|
105
|
+
"create_post": {
|
|
106
|
+
"steps": [
|
|
107
|
+
"Navigate to dev.to/new",
|
|
108
|
+
"Wait 2s for editor to load",
|
|
109
|
+
"Set title via native value setter on textarea#article-form-title",
|
|
110
|
+
"Dispatch input event to update React state",
|
|
111
|
+
"Set body via native value setter on textarea#article_body_markdown",
|
|
112
|
+
"Dispatch input event",
|
|
113
|
+
"Add tags: click input#tag-input, type tag name via browser_fill_form, type comma to confirm each tag",
|
|
114
|
+
"Optionally upload cover image via input#cover-image-input",
|
|
115
|
+
"Click 'Publish' button or 'Save draft'",
|
|
116
|
+
"Wait 3s for redirect to published article"
|
|
117
|
+
],
|
|
118
|
+
"guards": [
|
|
119
|
+
"Must be logged in"
|
|
120
|
+
],
|
|
121
|
+
"why": "Dev.to uses React controlled textareas — .value setter doesn't update React state. Must use Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, 'value').set.call(el, text) then dispatch input event. Tags are confirmed by typing comma after each tag name."
|
|
122
|
+
},
|
|
123
|
+
"like_article": {
|
|
124
|
+
"steps": [
|
|
125
|
+
"Navigate to article page",
|
|
126
|
+
"Find reaction drawer trigger: button#reaction-drawer-trigger",
|
|
127
|
+
"Click to expand reaction options",
|
|
128
|
+
"Click Like button: [data-category='like']",
|
|
129
|
+
"Verify reaction count increases"
|
|
130
|
+
],
|
|
131
|
+
"guards": [
|
|
132
|
+
"Must be logged in"
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
"comment_on_article": {
|
|
136
|
+
"steps": [
|
|
137
|
+
"Navigate to article page",
|
|
138
|
+
"Scroll to comment section",
|
|
139
|
+
"Find comment textarea: textarea#text-area (placeholder: 'Add to the discussion')",
|
|
140
|
+
"Set comment text via native value setter + input event dispatch",
|
|
141
|
+
"Click Submit button",
|
|
142
|
+
"Wait 2s for comment to post"
|
|
143
|
+
],
|
|
144
|
+
"guards": [
|
|
145
|
+
"Must be logged in"
|
|
146
|
+
],
|
|
147
|
+
"why": "Comment textarea is also React-controlled. Use native value setter approach."
|
|
148
|
+
},
|
|
149
|
+
"save_to_reading_list": {
|
|
150
|
+
"steps": [
|
|
151
|
+
"Navigate to article page",
|
|
152
|
+
"Click Save button: button#reaction-butt-readinglist",
|
|
153
|
+
"Verify button state changes"
|
|
154
|
+
],
|
|
155
|
+
"guards": [
|
|
156
|
+
"Must be logged in"
|
|
157
|
+
]
|
|
158
|
+
},
|
|
159
|
+
"boost_article": {
|
|
160
|
+
"steps": [
|
|
161
|
+
"Navigate to article page",
|
|
162
|
+
"Click Boost button: button#reaction-butt-boost",
|
|
163
|
+
"Verify boost count increases"
|
|
164
|
+
],
|
|
165
|
+
"guards": [
|
|
166
|
+
"Must be logged in"
|
|
167
|
+
]
|
|
168
|
+
},
|
|
169
|
+
"search": {
|
|
170
|
+
"steps": [
|
|
171
|
+
"Navigate to dev.to/search?q={query}",
|
|
172
|
+
"Wait 2s for search results to load",
|
|
173
|
+
"Extract articles from [class*='crayons-story'] elements",
|
|
174
|
+
"Get title, author, tags from article cards"
|
|
175
|
+
],
|
|
176
|
+
"guards": [],
|
|
177
|
+
"why": "Direct URL navigation is more reliable than typing in search input."
|
|
178
|
+
},
|
|
179
|
+
"follow_user": {
|
|
180
|
+
"steps": [
|
|
181
|
+
"Navigate to dev.to/{username}",
|
|
182
|
+
"Wait 2s for profile to load",
|
|
183
|
+
"Find Follow button: button with text 'Follow'",
|
|
184
|
+
"Click Follow via browser_human_click",
|
|
185
|
+
"Verify button changes to 'Following'"
|
|
186
|
+
],
|
|
187
|
+
"guards": [
|
|
188
|
+
"Must be logged in",
|
|
189
|
+
"Must not already be following"
|
|
190
|
+
]
|
|
191
|
+
},
|
|
192
|
+
"browse_tags": {
|
|
193
|
+
"steps": [
|
|
194
|
+
"Navigate to dev.to/t/{tag}",
|
|
195
|
+
"Wait 2s for tag page to load",
|
|
196
|
+
"Extract articles from feed",
|
|
197
|
+
"Follow tag if desired"
|
|
198
|
+
],
|
|
199
|
+
"guards": []
|
|
200
|
+
},
|
|
201
|
+
"view_dashboard": {
|
|
202
|
+
"steps": [
|
|
203
|
+
"Navigate to dev.to/dashboard",
|
|
204
|
+
"Wait 2s for dashboard to load",
|
|
205
|
+
"View published posts, drafts, analytics",
|
|
206
|
+
"Click on post to edit"
|
|
207
|
+
],
|
|
208
|
+
"guards": [
|
|
209
|
+
"Must be logged in"
|
|
210
|
+
]
|
|
211
|
+
},
|
|
212
|
+
"scroll_and_extract_feed": {
|
|
213
|
+
"steps": [
|
|
214
|
+
"Navigate to dev.to",
|
|
215
|
+
"Wait 2s for feed to load",
|
|
216
|
+
"Extract articles from [class*='crayons-story'] elements",
|
|
217
|
+
"Get title from [class*='crayons-story__title'], tags, author",
|
|
218
|
+
"Scroll down for more articles",
|
|
219
|
+
"Wait 1s for lazy-loaded content"
|
|
220
|
+
],
|
|
221
|
+
"guards": []
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
"errors": [
|
|
225
|
+
{
|
|
226
|
+
"error": "Login required",
|
|
227
|
+
"context": "Creating posts, liking, commenting, bookmarking",
|
|
228
|
+
"solution": "Log in manually. Dev.to supports GitHub, Twitter, Apple, Forem, and email login.",
|
|
229
|
+
"severity": "high"
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
"error": "React controlled textarea ignores direct .value assignment",
|
|
233
|
+
"context": "Title and body textareas don't update React state with simple value set",
|
|
234
|
+
"solution": "Use native value setter: Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, 'value').set.call(textarea, text). Then dispatch new Event('input', {bubbles: true}).",
|
|
235
|
+
"severity": "high"
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
"error": "Tags not confirmed without comma/Enter",
|
|
239
|
+
"context": "Typing tag name in #tag-input doesn't add it until comma or Enter",
|
|
240
|
+
"solution": "Use browser_fill_form to type tag name followed by comma. Each comma confirms one tag. Up to 4 tags allowed.",
|
|
241
|
+
"severity": "medium"
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
"error": "browser_fill_form types into textarea but React state empty",
|
|
245
|
+
"context": "CDP key events update DOM value but not React's internal state",
|
|
246
|
+
"solution": "Use native value setter approach for title and body. browser_fill_form works for tag input since it uses comma-triggered events.",
|
|
247
|
+
"severity": "medium"
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
"error": "Preview mode hides textarea",
|
|
251
|
+
"context": "Clicking Preview button switches from Edit view",
|
|
252
|
+
"solution": "Click Edit button to switch back to edit mode before typing.",
|
|
253
|
+
"severity": "low"
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
"error": "Frontmost app switches to VS Code when approving tool calls",
|
|
257
|
+
"context": "AccessibilityAdapter attaches to frontmost app",
|
|
258
|
+
"solution": "Use CDP browser tools — they work regardless of which app is frontmost.",
|
|
259
|
+
"severity": "high"
|
|
260
|
+
}
|
|
261
|
+
],
|
|
262
|
+
"policyNotes": {
|
|
263
|
+
"rate_limits": [
|
|
264
|
+
"Posts: no strict limit but don't spam",
|
|
265
|
+
"Comments: ~30/day recommended",
|
|
266
|
+
"Reactions: no strict limit",
|
|
267
|
+
"Dev.to is lenient but will flag spam accounts"
|
|
268
|
+
],
|
|
269
|
+
"safety": [
|
|
270
|
+
"Never automate login",
|
|
271
|
+
"Add 2-5s delays between actions",
|
|
272
|
+
"Use browser_stealth before interacting",
|
|
273
|
+
"Follow community guidelines — no spam posts",
|
|
274
|
+
"Use native value setter for React controlled inputs",
|
|
275
|
+
"Markdown is supported in post body and comments"
|
|
276
|
+
],
|
|
277
|
+
"tool_preferences": [
|
|
278
|
+
"browser_js with native value setter — for title, body, and comment textareas (React controlled)",
|
|
279
|
+
"browser_fill_form — for tag input (comma-separated), search input",
|
|
280
|
+
"browser_human_click — for Publish, Like, Boost, Follow buttons",
|
|
281
|
+
"browser_navigate — for search (direct URL), profile, tag pages"
|
|
282
|
+
]
|
|
283
|
+
},
|
|
284
|
+
"steps": [
|
|
285
|
+
{
|
|
286
|
+
"action": "navigate",
|
|
287
|
+
"url": "https://dev.to/",
|
|
288
|
+
"description": "Open Dev.to home feed"
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
"action": "wait",
|
|
292
|
+
"ms": 2000,
|
|
293
|
+
"description": "Wait for feed to load"
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
"action": "extract",
|
|
297
|
+
"target": "[class*='crayons-story']",
|
|
298
|
+
"format": "text",
|
|
299
|
+
"description": "Extract article cards from feed"
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
"action": "scroll",
|
|
303
|
+
"direction": "down",
|
|
304
|
+
"amount": 5,
|
|
305
|
+
"description": "Scroll for more articles"
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
"action": "wait",
|
|
309
|
+
"ms": 1000,
|
|
310
|
+
"description": "Wait for lazy-loaded articles"
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
"action": "screenshot",
|
|
314
|
+
"description": "Capture feed state"
|
|
315
|
+
}
|
|
316
|
+
]
|
|
317
|
+
}
|