punchlist-axi 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Manassarn Manoonchai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # punchlist
2
+
3
+ Click-to-edit for any running web app, driven by any coding agent.
4
+
5
+ A local proxy sits in front of your dev server and injects a picker into every HTML page. You walk through the app (desktop or phone, also over Tailscale), mark the spots that need a change, and send them as one batch - a punch list. Your coding agent pulls the batch with a shell command, edits the source, and reports back; the browser shows the result as a toast.
6
+
7
+ Nothing in your app changes. It works in front of Rails (Turbo), SvelteKit/Vite, React, Vue and static servers.
8
+
9
+ ## Use
10
+
11
+ With the skill installed, ask your agent: `/punchlist 5173` (or "let me click the element I want changed").
12
+
13
+ By hand:
14
+
15
+ ```bash
16
+ node scripts/punchlist-axi.mjs start --target 5173 # proxy runs in the background, prints the link
17
+ node scripts/punchlist-axi.mjs wait # blocks until you press Send
18
+ node scripts/punchlist-axi.mjs done r1 "1: made it blue"
19
+ node scripts/punchlist-axi.mjs stop
20
+ ```
21
+
22
+ Open the printed link (its token sets an access cookie). In the page: press ◎ (Alt+Shift+E), tap an element or drag a box, write a note, repeat, then press **Send**. With ◎ off, selecting text shows an Annotate button. ⏸ (Alt+Shift+P) pauses animations. 🗒 lists your notes; notes survive reloads until sent.
23
+
24
+ Phone access: `tailscale serve --bg <port>`, then open the HTTPS link that `start` prints. Never use `tailscale funnel`: anyone who reaches the proxy can make your agent edit code.
25
+
26
+ Optional: `node scripts/punchlist-axi.mjs setup hooks` adds a SessionStart hook to Claude Code, Codex and OpenCode, so new agent sessions see the proxies running for their directory (`--project` for the repo config, `--remove` to undo).
27
+
28
+ `node scripts/punchlist-axi.mjs --help` is the full guide for agents.
29
+
30
+ ## Source hints
31
+
32
+ Each note carries hints that point the agent at the source:
33
+
34
+ - **Svelte 5 dev**: `file:line:col`
35
+ - **Rails**: the template chain, if `config.action_view.annotate_rendered_view_with_filenames = true` is set in development
36
+ - **React**: component names (and `_debugSource` on React 18 and older)
37
+ - **Vue 3**: component file
38
+
39
+ ## Open in your editor
40
+
41
+ When the hint names a file, the note panel shows **↗ Open**. The proxy opens that file (at the line, when the hint has one) in the editor on the machine where the proxy runs, so it also works when you tap on a phone. It uses [launch-editor](https://github.com/vitejs/launch-editor): it finds a running editor (VS Code, Cursor, Zed, JetBrains, Sublime...), or set `LAUNCH_EDITOR` (or `EDITOR`) in the shell that runs `start`. Only files inside the directory you started the proxy from can be opened.
42
+
43
+ When the hints name no file (only a component name, or nothing), the panel shows **🔎 Locate** instead. It sends a small request to your agent, which finds the file and opens it with `done <id> --open <file>[:line]`. This works with any framework, but it takes the agent's time and needs a `wait` running.
44
+
45
+ ## Known limits
46
+
47
+ - HTML is buffered before injection, so streamed HTML arrives all at once.
48
+ - Absolute dev-server URLs inside JS bundles are not rewritten (HTML only).
49
+ - Pages in cross-origin iframes cannot be picked.
50
+ - In annotate mode, touch scrolling is blocked on phones; turn ◎ off to scroll.
51
+ - One queue per proxy, no per-user attribution.
52
+
53
+ ## Develop
54
+
55
+ ```bash
56
+ pnpm install && pnpm test # pnpm version comes from package.json "packageManager"
57
+ ```
package/SKILL.md ADDED
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: punchlist
3
+ description: Click-to-edit for any running web app. Starts a local proxy in front of the user's dev server that injects an element picker, so the user can tap any element in a real browser (desktop or phone, also over Tailscale), type what should change, and you receive the element's selector, HTML, styles and source-file hints and edit the code. Use this whenever the user wants to point at UI and have it changed, says things like "let me click the element", "visual edit", "inspect and fix", "จิ้ม element แล้วแก้", or wants to tweak a page from their phone - even if they don't name this skill. Works with any server (Rails, SvelteKit, Vite, Next, static) with no changes to the app.
4
+ metadata:
5
+ argument-hint: <dev server port or URL>
6
+ ---
7
+
8
+ # punchlist
9
+
10
+ punchlist runs a proxy in the background in front of the user's dev server. The user annotates elements in the browser and presses Send; you pull the batch with a blocking command, edit the source, and report back. Nothing in the user's app changes.
11
+
12
+ ## Current guidance lives in the CLI
13
+
14
+ Do not follow workflow details from memory or from this file. Read the source of truth first:
15
+
16
+ ```bash
17
+ node "${CLAUDE_SKILL_DIR}/scripts/punchlist-axi.mjs" --help
18
+ ```
19
+
20
+ Then start the proxy. It returns at once and prints the link for the user and the next command to run:
21
+
22
+ ```bash
23
+ node "${CLAUDE_SKILL_DIR}/scripts/punchlist-axi.mjs" start --target <port|url>
24
+ ```
25
+
26
+ Do not wrap `start` in `nohup` or `&`; it already runs the proxy in the background.
27
+
28
+ **Paste the full link from the `start` output into your reply text.** The user does not see command output, and "I'll share the link" without the URL leaves them stuck. Then run `wait` as the `start` output says (as a background command, so new notes reach you without the user asking), and follow the instructions it prints.
29
+
30
+ ## Request
31
+
32
+ $ARGUMENTS
33
+
34
+ If the request above is non-empty, it names the dev server (port or URL) - read `--help`, then start the proxy for it. If it is empty, find the dev server port as `--help` describes.
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "punchlist-axi",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "Click-to-edit for any running web app: a proxy injects a picker, your coding agent pulls the batch of notes and edits the source.",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/narze/punchlist-axi.git"
10
+ },
11
+ "homepage": "https://github.com/narze/punchlist-axi#readme",
12
+ "bin": {
13
+ "punchlist-axi": "scripts/punchlist-axi.mjs"
14
+ },
15
+ "files": [
16
+ "scripts/punchlist-axi.mjs",
17
+ "scripts/punchlist-cli.mjs",
18
+ "scripts/client.js",
19
+ "SKILL.md"
20
+ ],
21
+ "engines": {
22
+ "node": ">=18"
23
+ },
24
+ "scripts": {
25
+ "build": "esbuild src/cli.mjs --bundle --platform=node --format=esm --target=node18 --banner:js='#!/usr/bin/env node\n// Generated from src/ by `pnpm build` - do not edit.\nimport { createRequire } from \"node:module\"; const require = createRequire(import.meta.url);' --outfile=scripts/punchlist-cli.mjs && esbuild src/punchlist-axi.mjs --bundle --platform=node --format=esm --target=node18 --banner:js='#!/usr/bin/env node\n// Generated from src/ by `pnpm build` - do not edit.' --external:./punchlist-cli.mjs --outfile=scripts/punchlist-axi.mjs",
26
+ "pretest": "pnpm run --silent build",
27
+ "test": "node test/cli.test.mjs && node test/proxy.test.mjs && node test/client.test.mjs && node test/drag.test.mjs"
28
+ },
29
+ "devDependencies": {
30
+ "axi-sdk-js": "^0.1.13",
31
+ "esbuild": "^0.28.2",
32
+ "jsdom": "^24.0.0",
33
+ "launch-editor": "^2.14.2"
34
+ },
35
+ "packageManager": "pnpm@12.11.2"
36
+ }