@lelouchhe/webagent 0.1.2 → 0.1.3
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 +18 -1
- package/bin/webagent.mjs +4 -1
- package/dist/index.html +2 -2
- package/dist/js/app.mmjvjb37.js +10 -0
- package/dist/js/{commands.mmjrsqet.js → commands.mmjvjb37.js} +3 -3
- package/dist/js/{connection.mmjrsqet.js → connection.mmjvjb37.js} +3 -3
- package/dist/js/{events.mmjrsqet.js → events.mmjvjb37.js} +2 -2
- package/dist/js/{images.mmjrsqet.js → images.mmjvjb37.js} +1 -1
- package/dist/js/{input.mmjrsqet.js → input.mmjvjb37.js} +4 -4
- package/dist/js/{render.mmjrsqet.js → render.mmjvjb37.js} +1 -1
- package/lib/bridge.js +1 -1
- package/lib/session-manager.js +2 -1
- package/lib/ws-handler.js +10 -2
- package/package.json +1 -1
- package/dist/js/app.mmjrsqet.js +0 -10
- /package/dist/js/{state.mmjrsqet.js → state.mmjvjb37.js} +0 -0
- /package/dist/{styles.mmjrsqet.css → styles.mmjvjb37.css} +0 -0
package/README.md
CHANGED
|
@@ -45,7 +45,24 @@ Tech stack: Node.js + TypeScript (`--experimental-strip-types`), real-time WebSo
|
|
|
45
45
|
## Prerequisites
|
|
46
46
|
|
|
47
47
|
- Node.js 22.6+ (requires `--experimental-strip-types`)
|
|
48
|
-
- An ACP-compatible agent
|
|
48
|
+
- An ACP-compatible agent installed and authenticated
|
|
49
|
+
|
|
50
|
+
### ACP-Compatible Agents
|
|
51
|
+
|
|
52
|
+
WebAgent works with any agent that implements the [Agent Client Protocol](https://agentclientprotocol.com/). Some options:
|
|
53
|
+
|
|
54
|
+
| Agent | Command | Notes |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| [Copilot CLI](https://github.com/github/copilot-cli) | `copilot --acp` | Default. GitHub's AI pair programmer |
|
|
57
|
+
| [Claude Code](https://docs.anthropic.com/en/docs/agents/claude-code) | `claude --acp` | Anthropic's coding agent |
|
|
58
|
+
| [Gemini CLI](https://github.com/google-gemini/gemini-cli) | `gemini --acp` | Google's Gemini models |
|
|
59
|
+
| [OpenCode](https://opencode.ai/) | `opencode --acp` | Open-source, extensible |
|
|
60
|
+
|
|
61
|
+
See the [ACP Registry](https://agentclientprotocol.com/get-started/agents) for the full list. To use a different agent, set `agent_cmd` in your config:
|
|
62
|
+
|
|
63
|
+
```toml
|
|
64
|
+
agent_cmd = "claude --acp"
|
|
65
|
+
```
|
|
49
66
|
|
|
50
67
|
## Install
|
|
51
68
|
|
package/bin/webagent.mjs
CHANGED
|
@@ -13,7 +13,10 @@ const child = spawn(
|
|
|
13
13
|
{ stdio: "inherit" },
|
|
14
14
|
);
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
const signals = process.platform === "win32"
|
|
17
|
+
? ["SIGINT", "SIGTERM"]
|
|
18
|
+
: ["SIGINT", "SIGTERM", "SIGHUP"];
|
|
19
|
+
for (const sig of signals) {
|
|
17
20
|
process.on(sig, () => child.kill(sig));
|
|
18
21
|
}
|
|
19
22
|
|
package/dist/index.html
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
14
14
|
<script src="https://cdn.jsdelivr.net/npm/dompurify@3.3.2/dist/purify.min.js"></script>
|
|
15
15
|
<script>document.documentElement.setAttribute('data-theme', localStorage.getItem('theme') || 'auto');</script>
|
|
16
|
-
<link rel="stylesheet" href="/styles.
|
|
16
|
+
<link rel="stylesheet" href="/styles.mmjvjb37.css">
|
|
17
17
|
</head>
|
|
18
18
|
<body>
|
|
19
19
|
|
|
@@ -41,6 +41,6 @@
|
|
|
41
41
|
<input type="file" id="file-input" accept="image/*" multiple hidden>
|
|
42
42
|
</div>
|
|
43
43
|
|
|
44
|
-
<script type="module" src="/js/app.
|
|
44
|
+
<script type="module" src="/js/app.mmjvjb37.js"></script>
|
|
45
45
|
</body>
|
|
46
46
|
</html>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Boot entry point — imports all modules and starts the app
|
|
2
|
+
|
|
3
|
+
import './render.mmjvjb37.js'; // theme, click-to-collapse listeners
|
|
4
|
+
import './commands.mmjvjb37.js'; // slash menu listeners
|
|
5
|
+
import './images.mmjvjb37.js'; // attach/paste listeners
|
|
6
|
+
import './input.mmjvjb37.js'; // keyboard/send listeners
|
|
7
|
+
import { connect } from './connection.mmjvjb37.js';
|
|
8
|
+
|
|
9
|
+
connect();
|
|
10
|
+
if ('serviceWorker' in navigator) navigator.serviceWorker.register('/sw.js');
|
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
state, dom, setBusy, resetSessionUI, requestNewSession, sendCancel,
|
|
5
5
|
getConfigOption, getConfigValue, setHashSessionId, updateSessionInfo,
|
|
6
6
|
updateNewBtnVisibility,
|
|
7
|
-
} from './state.
|
|
8
|
-
import { addSystem, addMessage, scrollToBottom, escHtml, formatLocalTime } from './render.
|
|
9
|
-
import { loadHistory } from './events.
|
|
7
|
+
} from './state.mmjvjb37.js';
|
|
8
|
+
import { addSystem, addMessage, scrollToBottom, escHtml, formatLocalTime } from './render.mmjvjb37.js';
|
|
9
|
+
import { loadHistory } from './events.mmjvjb37.js';
|
|
10
10
|
|
|
11
11
|
// --- Slash command execution ---
|
|
12
12
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// WebSocket connection lifecycle
|
|
2
2
|
|
|
3
|
-
import { state, setBusy, getHashSessionId, requestNewSession, resetSessionUI, setConnectionStatus, clearCancelTimer } from './state.
|
|
4
|
-
import { addSystem, finishThinking, finishAssistant, finishBash, scrollToBottom } from './render.
|
|
5
|
-
import { handleEvent, loadHistory, loadNewEvents } from './events.
|
|
3
|
+
import { state, setBusy, getHashSessionId, requestNewSession, resetSessionUI, setConnectionStatus, clearCancelTimer } from './state.mmjvjb37.js';
|
|
4
|
+
import { addSystem, finishThinking, finishAssistant, finishBash, scrollToBottom } from './render.mmjvjb37.js';
|
|
5
|
+
import { handleEvent, loadHistory, loadNewEvents } from './events.mmjvjb37.js';
|
|
6
6
|
|
|
7
7
|
export function connect() {
|
|
8
8
|
const proto = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
@@ -4,12 +4,12 @@ import {
|
|
|
4
4
|
state, dom, setBusy, setConfigValue, getConfigOption, updateConfigOptions,
|
|
5
5
|
updateModeUI, resetSessionUI, requestNewSession, setHashSessionId, updateSessionInfo,
|
|
6
6
|
setConnectionStatus, clearCancelTimer,
|
|
7
|
-
} from './state.
|
|
7
|
+
} from './state.mmjvjb37.js';
|
|
8
8
|
import {
|
|
9
9
|
addMessage, addSystem, finishAssistant, finishThinking, hideWaiting,
|
|
10
10
|
scrollToBottom, renderMd, escHtml, renderPatchDiff, addBashBlock, finishBash, appendMessageElement,
|
|
11
11
|
formatLocalTime,
|
|
12
|
-
} from './render.
|
|
12
|
+
} from './render.mmjvjb37.js';
|
|
13
13
|
|
|
14
14
|
function finishPromptIfIdle() {
|
|
15
15
|
if (!state.pendingPromptDone) return;
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
import {
|
|
4
4
|
state, dom, setBusy, sendCancel,
|
|
5
5
|
getConfigOption, getConfigValue, updateNewBtnVisibility,
|
|
6
|
-
} from './state.
|
|
7
|
-
import { addMessage, addSystem, addBashBlock, showWaiting } from './render.
|
|
8
|
-
import { handleSlashCommand, hideSlashMenu, handleSlashMenuKey, updateSlashMenu } from './commands.
|
|
9
|
-
import { renderAttachPreview } from './images.
|
|
6
|
+
} from './state.mmjvjb37.js';
|
|
7
|
+
import { addMessage, addSystem, addBashBlock, showWaiting } from './render.mmjvjb37.js';
|
|
8
|
+
import { handleSlashCommand, hideSlashMenu, handleSlashMenuKey, updateSlashMenu } from './commands.mmjvjb37.js';
|
|
9
|
+
import { renderAttachPreview } from './images.mmjvjb37.js';
|
|
10
10
|
|
|
11
11
|
// Wire up cancel-timeout feedback (state.js cannot import render.js directly)
|
|
12
12
|
state._onCancelTimeout = () => addSystem('warn: Agent not responding to cancel');
|
package/lib/bridge.js
CHANGED
|
@@ -172,7 +172,7 @@ export class AgentBridge extends EventEmitter {
|
|
|
172
172
|
this.proc.kill();
|
|
173
173
|
await new Promise((resolve) => {
|
|
174
174
|
const timer = setTimeout(() => {
|
|
175
|
-
this.proc?.kill("SIGKILL");
|
|
175
|
+
this.proc?.kill(process.platform === "win32" ? undefined : "SIGKILL");
|
|
176
176
|
resolve();
|
|
177
177
|
}, 5000);
|
|
178
178
|
this.proc?.on("exit", () => {
|
package/lib/session-manager.js
CHANGED
|
@@ -191,8 +191,9 @@ export class SessionManager {
|
|
|
191
191
|
}
|
|
192
192
|
/** Kill all running bash processes (for shutdown). */
|
|
193
193
|
killAllBashProcs() {
|
|
194
|
+
const forceSignal = process.platform === "win32" ? undefined : "SIGKILL";
|
|
194
195
|
for (const [, proc] of this.runningBashProcs)
|
|
195
|
-
proc.kill(
|
|
196
|
+
proc.kill(forceSignal);
|
|
196
197
|
this.runningBashProcs.clear();
|
|
197
198
|
}
|
|
198
199
|
}
|
package/lib/ws-handler.js
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { WebSocket, WebSocketServer } from "ws";
|
|
3
3
|
import { WsMessageSchema, errorMessage } from "./types.js";
|
|
4
|
+
const IS_WIN = process.platform === "win32";
|
|
4
5
|
function interruptBashProc(proc) {
|
|
5
6
|
if (!proc)
|
|
6
7
|
return;
|
|
8
|
+
if (IS_WIN && typeof proc.pid === "number") {
|
|
9
|
+
// Windows: kill entire process tree since there are no process groups
|
|
10
|
+
spawn("taskkill", ["/T", "/F", "/PID", String(proc.pid)]).unref();
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
7
13
|
if (typeof proc.pid === "number") {
|
|
8
14
|
try {
|
|
9
15
|
process.kill(-proc.pid, "SIGINT");
|
|
@@ -196,9 +202,11 @@ export function setupWsHandler(deps) {
|
|
|
196
202
|
client.send(bashEvent);
|
|
197
203
|
}
|
|
198
204
|
}
|
|
199
|
-
const
|
|
205
|
+
const shell = IS_WIN ? (process.env.COMSPEC || "cmd.exe") : (process.env.SHELL || "bash");
|
|
206
|
+
const shellArgs = IS_WIN ? ["/s", "/c", msg.command] : ["-c", msg.command];
|
|
207
|
+
const child = spawn(shell, shellArgs, {
|
|
200
208
|
cwd,
|
|
201
|
-
detached:
|
|
209
|
+
detached: !IS_WIN,
|
|
202
210
|
env: { ...process.env, TERM: "dumb" },
|
|
203
211
|
stdio: ["ignore", "pipe", "pipe"],
|
|
204
212
|
});
|
package/package.json
CHANGED
package/dist/js/app.mmjrsqet.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
// Boot entry point — imports all modules and starts the app
|
|
2
|
-
|
|
3
|
-
import './render.mmjrsqet.js'; // theme, click-to-collapse listeners
|
|
4
|
-
import './commands.mmjrsqet.js'; // slash menu listeners
|
|
5
|
-
import './images.mmjrsqet.js'; // attach/paste listeners
|
|
6
|
-
import './input.mmjrsqet.js'; // keyboard/send listeners
|
|
7
|
-
import { connect } from './connection.mmjrsqet.js';
|
|
8
|
-
|
|
9
|
-
connect();
|
|
10
|
-
if ('serviceWorker' in navigator) navigator.serviceWorker.register('/sw.js');
|
|
File without changes
|
|
File without changes
|