agentclick 0.1.1 → 0.2.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/README.md +52 -108
- package/package.json +21 -3
- package/packages/server/dist/index.js +4 -0
- package/packages/server/src/index.ts +5 -0
- package/packages/web/dist/assets/index-BfM7acF_.js +67 -0
- package/packages/web/dist/assets/index-CrlEXNVh.css +1 -0
- package/packages/web/dist/index.html +2 -2
- package/AGENTS.md +0 -148
- package/packages/web/dist/assets/index-CLd6pAEL.js +0 -67
- package/packages/web/dist/assets/index-DAT8x7ee.css +0 -1
package/README.md
CHANGED
|
@@ -1,154 +1,98 @@
|
|
|
1
1
|
# AgentClick
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
AI agents fail silently and take irreversible actions. AgentClick puts a human review step between your agent and the world.
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/agentclick)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](https://www.npmjs.com/package/agentclick)
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Why AgentClick
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
- You can't drag steps to reorder them
|
|
17
|
-
- Every correction requires typing out instructions again
|
|
18
|
-
- The agent never remembers your preferences
|
|
19
|
-
|
|
20
|
-
## The Solution
|
|
21
|
-
|
|
22
|
-
When your agent finishes a task that needs your input, it opens a browser page — a purpose-built interaction UI. You click, choose, drag. No typing.
|
|
23
|
-
|
|
24
|
-
```
|
|
25
|
-
Agent finishes email draft
|
|
26
|
-
→ Browser opens automatically
|
|
27
|
-
→ You click paragraph → choose: Delete / Rewrite / Keep
|
|
28
|
-
→ You confirm
|
|
29
|
-
→ Agent continues, remembers your choices for next time
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
Every interaction teaches the agent your preferences. The more you use it, the less you need to explain.
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## Current Status
|
|
37
|
-
|
|
38
|
-
This project is already in a working prototype stage and supports multiple review flows end-to-end.
|
|
39
|
-
|
|
40
|
-
Implemented:
|
|
41
|
-
|
|
42
|
-
- Email review UI (legacy single-column + v2 inbox + draft layout)
|
|
43
|
-
- Action approval UI (approve/reject + note)
|
|
44
|
-
- Code/shell command review UI
|
|
45
|
-
- Session history homepage with recent sessions
|
|
46
|
-
- SQLite session persistence (`~/.openclaw/clawui-sessions.db`)
|
|
47
|
-
- Long-poll wait endpoint for agent integration (`/api/sessions/:id/wait`)
|
|
48
|
-
- Preference learning from paragraph deletions (writes rules to `MEMORY.md`)
|
|
49
|
-
- Keyboard shortcuts (`Cmd/Ctrl+Enter` submit, `Escape` handling)
|
|
50
|
-
- Browser auto-open on session creation
|
|
13
|
+
- **Not just approve/deny** -- edit the email subject, change the command, modify the payload before it sends.
|
|
14
|
+
- **Preference learning** -- delete a paragraph and tell AgentClick why. It writes the rule to disk so your agent never makes the same mistake again.
|
|
15
|
+
- **Framework-agnostic** -- works with OpenAI, Anthropic, LangChain, or any HTTP-capable agent. Just POST and long-poll.
|
|
51
16
|
|
|
52
17
|
---
|
|
53
18
|
|
|
54
19
|
## Quick Start
|
|
55
20
|
|
|
56
|
-
```bash
|
|
57
|
-
git clone https://github.com/agentlayer-io/AgentClick.git
|
|
58
|
-
cd AgentClick
|
|
59
|
-
npm install
|
|
60
|
-
npm run dev # dev mode: API on 3001, Vite UI on 5173
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Install (Global CLI)
|
|
64
|
-
|
|
65
21
|
```bash
|
|
66
22
|
npm install -g agentclick
|
|
67
23
|
agentclick
|
|
68
24
|
```
|
|
69
25
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
CLI options:
|
|
26
|
+
Then test it with a mock session:
|
|
73
27
|
|
|
74
28
|
```bash
|
|
75
|
-
|
|
76
|
-
|
|
29
|
+
curl -X POST http://localhost:3001/api/review \
|
|
30
|
+
-H "Content-Type: application/json" \
|
|
31
|
+
-d '{"type":"code_review","sessionKey":"test","payload":{"command":"rm -rf /tmp/old-cache","cwd":"/home/user","explanation":"Clean up stale cache directory","risk":"medium"}}'
|
|
77
32
|
```
|
|
78
33
|
|
|
79
|
-
|
|
34
|
+
A browser tab opens automatically. Review, approve or reject, and close the tab.
|
|
80
35
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
```bash
|
|
84
|
-
PORT=3001
|
|
85
|
-
OPENCLAW_WEBHOOK=http://localhost:18789/hooks/agent
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Create a local `.env` in the project root to override these values during development (server auto-loads it via `dotenv`).
|
|
36
|
+
---
|
|
89
37
|
|
|
90
|
-
|
|
38
|
+
## How It Works
|
|
91
39
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
```
|
|
40
|
+
1. **Agent POSTs structured data** to `http://localhost:3001/api/review` with a session key.
|
|
41
|
+
2. **User reviews, edits, and approves** in the browser -- paragraph-level delete/rewrite for emails, approve/reject for commands and actions.
|
|
42
|
+
3. **Agent receives the result** via long-poll (`GET /api/sessions/:id/wait`) and continues execution.
|
|
96
43
|
|
|
97
|
-
|
|
44
|
+
No WebSockets. No framework plugins. One HTTP endpoint in, one HTTP endpoint out.
|
|
98
45
|
|
|
99
|
-
|
|
46
|
+
---
|
|
100
47
|
|
|
101
|
-
|
|
48
|
+
## Comparison
|
|
102
49
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
50
|
+
| Feature | AgentClick | AgentGate | LangGraph interrupt() | Vercel AI SDK |
|
|
51
|
+
|---|---|---|---|---|
|
|
52
|
+
| Pre-built review UI | Yes | No | No | No |
|
|
53
|
+
| Edit before approve | Yes | No | No | No |
|
|
54
|
+
| Preference learning | Yes | No | No | No |
|
|
55
|
+
| Framework-agnostic | Yes | Yes | LangGraph only | Vercel only |
|
|
56
|
+
| Self-hosted | Yes | Yes | Yes | Cloud |
|
|
108
57
|
|
|
109
58
|
---
|
|
110
59
|
|
|
111
|
-
##
|
|
60
|
+
## Session Types
|
|
112
61
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
│ ├── server/ # Node.js + Express — receives agent data, handles callbacks
|
|
117
|
-
│ └── web/ # React + Vite + Tailwind — the interaction UI
|
|
118
|
-
├── skills/
|
|
119
|
-
│ └── clawui-email/
|
|
120
|
-
│ └── SKILL.md # OpenClaw skill definition
|
|
121
|
-
└── docs/
|
|
122
|
-
└── research.md # Market & technical research notes
|
|
123
|
-
```
|
|
62
|
+
- **email_review** -- two-column inbox and draft editor. Users can delete paragraphs with reasons, request rewrites, toggle intent suggestions, and confirm or regenerate.
|
|
63
|
+
- **code_review** -- displays the shell command, working directory, affected files as a collapsible tree, and risk level. Approve or reject with an optional note.
|
|
64
|
+
- **action_approval** -- generic high-risk action gate. Shows action description, detail, and risk badge. Approve or reject with an optional note.
|
|
124
65
|
|
|
125
66
|
---
|
|
126
67
|
|
|
127
|
-
##
|
|
68
|
+
## API
|
|
128
69
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
-
|
|
134
|
-
|
|
135
|
-
- [ ] **Next** — Remote mode UX + link delivery polish
|
|
136
|
-
- [ ] **Later** — Agent task visualization (Mission Control view)
|
|
137
|
-
- [ ] **Later** — Multi-framework support (beyond OpenClaw)
|
|
70
|
+
| Method | Endpoint | Description |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
| POST | `/api/review` | Agent creates a review session. Returns `{ sessionId, url }`. Browser opens automatically. |
|
|
73
|
+
| GET | `/api/sessions/:id` | Fetch session data (payload, status, result). |
|
|
74
|
+
| GET | `/api/sessions/:id/wait` | Long-poll. Blocks up to 5 minutes until the user completes the review. |
|
|
75
|
+
| POST | `/api/sessions/:id/complete` | UI submits the user's decision. Triggers preference learning and agent callback. |
|
|
138
76
|
|
|
139
77
|
---
|
|
140
78
|
|
|
141
|
-
##
|
|
142
|
-
|
|
143
|
-
[ClawX](https://github.com/ValueCell-ai/ClawX) is a desktop app for *managing* OpenClaw (installing skills, configuring channels, running the gateway). AgentClick is for *working with* your agent — reviewing its output, making decisions, teaching it your preferences. They're complementary.
|
|
79
|
+
## Development
|
|
144
80
|
|
|
145
|
-
|
|
81
|
+
```bash
|
|
82
|
+
git clone https://github.com/agentlayer-io/AgentClick.git
|
|
83
|
+
cd AgentClick
|
|
84
|
+
npm install
|
|
85
|
+
npm run dev
|
|
86
|
+
```
|
|
146
87
|
|
|
147
|
-
|
|
88
|
+
Server runs on `http://localhost:3001`, UI on `http://localhost:5173`.
|
|
148
89
|
|
|
149
|
-
|
|
90
|
+
For production-style single-port serving:
|
|
150
91
|
|
|
151
|
-
|
|
92
|
+
```bash
|
|
93
|
+
npm run build
|
|
94
|
+
npm start
|
|
95
|
+
```
|
|
152
96
|
|
|
153
97
|
---
|
|
154
98
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentclick",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Human-in-the-loop approval UI for AI agents. Review, edit, and approve agent actions in your browser before they execute.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"ai-agent",
|
|
7
|
+
"human-in-the-loop",
|
|
8
|
+
"approval",
|
|
9
|
+
"hitl",
|
|
10
|
+
"llm",
|
|
11
|
+
"langchain",
|
|
12
|
+
"openai",
|
|
13
|
+
"agent-ui",
|
|
14
|
+
"agentic",
|
|
15
|
+
"ai-safety",
|
|
16
|
+
"human-oversight"
|
|
17
|
+
],
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/agentlayer-io/AgentClick.git"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://github.com/agentlayer-io/AgentClick",
|
|
4
23
|
"bin": {
|
|
5
24
|
"agentclick": "./bin/agentclick.mjs"
|
|
6
25
|
},
|
|
@@ -11,8 +30,7 @@
|
|
|
11
30
|
"packages/server/package.json",
|
|
12
31
|
"packages/web/dist/",
|
|
13
32
|
"packages/web/package.json",
|
|
14
|
-
"README.md"
|
|
15
|
-
"AGENTS.md"
|
|
33
|
+
"README.md"
|
|
16
34
|
],
|
|
17
35
|
"workspaces": [
|
|
18
36
|
"packages/*"
|
|
@@ -183,6 +183,10 @@ function buildActionSummary(result) {
|
|
|
183
183
|
if (result.regenerate) {
|
|
184
184
|
lines.push('- User requested full regeneration.');
|
|
185
185
|
}
|
|
186
|
+
const intents = (result.selectedIntents ?? []);
|
|
187
|
+
if (intents.length > 0) {
|
|
188
|
+
lines.push(`- Intent decisions: ${intents.map(i => `${i.id} → ${i.accepted ? 'accepted' : 'rejected'}`).join(', ')}`);
|
|
189
|
+
}
|
|
186
190
|
return lines.join('\n');
|
|
187
191
|
}
|
|
188
192
|
if (SHOULD_SERVE_BUILT_WEB) {
|
|
@@ -206,6 +206,11 @@ function buildActionSummary(result: Record<string, unknown>): string {
|
|
|
206
206
|
lines.push('- User requested full regeneration.')
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
+
const intents = (result.selectedIntents ?? []) as Array<{ id: string; accepted: boolean }>
|
|
210
|
+
if (intents.length > 0) {
|
|
211
|
+
lines.push(`- Intent decisions: ${intents.map(i => `${i.id} → ${i.accepted ? 'accepted' : 'rejected'}`).join(', ')}`)
|
|
212
|
+
}
|
|
213
|
+
|
|
209
214
|
return lines.join('\n')
|
|
210
215
|
}
|
|
211
216
|
|