agenter-app 1.0.0 → 1.0.2
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 +2 -0
- package/cli.js +94 -36
- package/package.json +3 -3
- package/public/agenter.ico +0 -0
- package/public/icon.png +0 -0
- package/public/index.html +3 -1
- package/scripts/install-shortcuts.ps1 +1 -1
- package/server.js +2 -0
package/README.md
CHANGED
|
@@ -19,6 +19,8 @@ agenter install # adds hooks to ~/.claude/settings.json (a backup is made) + D
|
|
|
19
19
|
|
|
20
20
|
Then **reload each VS Code window** (or start new Claude sessions). Hooks are read when a session starts.
|
|
21
21
|
|
|
22
|
+
Skipped `agenter install`? Running `agenter` notices the hooks are missing and offers to set them up.
|
|
23
|
+
|
|
22
24
|
Install it globally (`-g`), not with `npx`: the hooks point at the installed files, so they need to stay put.
|
|
23
25
|
If you move Node (a new Node version manager install, say), run `agenter install` again; it replaces the old hooks.
|
|
24
26
|
|
package/cli.js
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// The `agenter` command (npm i -g agenter-app). Each subcommand runs one of the existing scripts.
|
|
3
3
|
'use strict';
|
|
4
|
+
const fs = require('node:fs');
|
|
5
|
+
const os = require('node:os');
|
|
4
6
|
const path = require('node:path');
|
|
7
|
+
const readline = require('node:readline/promises');
|
|
5
8
|
const { spawnSync } = require('node:child_process');
|
|
6
9
|
const { version } = require('./package.json');
|
|
7
10
|
|
|
11
|
+
const CLAUDE_SETTINGS = path.join(os.homedir(), '.claude', 'settings.json');
|
|
12
|
+
// The same path install.js puts in the hook commands.
|
|
13
|
+
const HOOK_SCRIPT = path.join(__dirname, 'hook.js').replace(/\\/g, '/');
|
|
14
|
+
const PROMPT_FILE = path.join(os.homedir(), '.agenter', 'cli.json');
|
|
15
|
+
|
|
8
16
|
const [cmd = 'open', ...rest] = process.argv.slice(2);
|
|
9
17
|
const isWindows = process.platform === 'win32';
|
|
10
18
|
|
|
@@ -20,11 +28,59 @@ const shortcuts = (args = []) => {
|
|
|
20
28
|
return spawnSync('powershell.exe', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', ps1, ...args], { stdio: 'inherit' }).status ?? 1;
|
|
21
29
|
};
|
|
22
30
|
|
|
31
|
+
const install = (args = []) => {
|
|
32
|
+
const status = node('install.js', args);
|
|
33
|
+
return status === 0 ? shortcuts() : status;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// 'ok' when this copy's hooks are installed, 'other' when only an older copy's are, else 'missing'.
|
|
37
|
+
const hookState = () => {
|
|
38
|
+
let commands = [];
|
|
39
|
+
try {
|
|
40
|
+
const { hooks = {} } = JSON.parse(fs.readFileSync(CLAUDE_SETTINGS, 'utf8'));
|
|
41
|
+
commands = Object.values(hooks).flat().flatMap((g) => g?.hooks || []).map((h) => h?.command).filter((c) => typeof c === 'string');
|
|
42
|
+
} catch {}
|
|
43
|
+
if (commands.some((c) => c.includes(HOOK_SCRIPT))) return 'ok';
|
|
44
|
+
return commands.some((c) => /agenter[^"]*\/hook\.js"$/i.test(c)) ? 'other' : 'missing';
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// Setup is never run without asking. A "no" is remembered until Agenter moves to a new path.
|
|
48
|
+
async function offerSetup() {
|
|
49
|
+
const state = hookState();
|
|
50
|
+
if (state === 'ok') return;
|
|
51
|
+
try {
|
|
52
|
+
if (JSON.parse(fs.readFileSync(PROMPT_FILE, 'utf8')).declinedSetup === HOOK_SCRIPT) return;
|
|
53
|
+
} catch {}
|
|
54
|
+
|
|
55
|
+
const [why, ask] =
|
|
56
|
+
state === 'other'
|
|
57
|
+
? ['Your Claude hooks point at another copy of Agenter (an older install, or Node moved).', 'Point them at this one?']
|
|
58
|
+
: ["Agenter's hooks aren't set up yet, so your Claude sessions won't show up.", 'Set them up now?'];
|
|
59
|
+
if (!process.stdin.isTTY) {
|
|
60
|
+
console.log(`${why}\nRun: agenter install`);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
65
|
+
rl.on('SIGINT', () => process.exit(130));
|
|
66
|
+
const answer = (await rl.question(`${why}\n${ask} (Y/n) `)).trim().toLowerCase();
|
|
67
|
+
rl.close();
|
|
68
|
+
|
|
69
|
+
if (['', 'y', 'yes'].includes(answer)) {
|
|
70
|
+
install();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
fs.mkdirSync(path.dirname(PROMPT_FILE), { recursive: true });
|
|
74
|
+
fs.writeFileSync(PROMPT_FILE, JSON.stringify({ declinedSetup: HOOK_SCRIPT }, null, 2));
|
|
75
|
+
console.log("OK. Run 'agenter install' whenever you want them.");
|
|
76
|
+
}
|
|
77
|
+
|
|
23
78
|
const help = `Agenter ${version}: one inbox for every Claude Code and Codex session.
|
|
24
79
|
|
|
25
80
|
Usage: agenter [command]
|
|
26
81
|
|
|
27
|
-
(none), open Open the dashboard (starts the server if needed)
|
|
82
|
+
(none), open Open the dashboard (starts the server if needed); offers setup
|
|
83
|
+
if the hooks aren't installed yet
|
|
28
84
|
install Add Agenter's hooks to ~/.claude/settings.json (backed up first)
|
|
29
85
|
and, on Windows, Desktop and Start Menu shortcuts
|
|
30
86
|
uninstall Remove the hooks and shortcuts
|
|
@@ -34,38 +90,40 @@ Usage: agenter [command]
|
|
|
34
90
|
|
|
35
91
|
After installing, reload your VS Code windows so Claude sessions pick up the hooks.`;
|
|
36
92
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
93
|
+
(async () => {
|
|
94
|
+
let status = 0;
|
|
95
|
+
switch (cmd) {
|
|
96
|
+
case 'open':
|
|
97
|
+
await offerSetup();
|
|
98
|
+
status = node('open.js', rest);
|
|
99
|
+
break;
|
|
100
|
+
case 'install':
|
|
101
|
+
status = install(rest);
|
|
102
|
+
break;
|
|
103
|
+
case 'uninstall':
|
|
104
|
+
status = node('install.js', ['--uninstall']);
|
|
105
|
+
shortcuts(['-Remove']);
|
|
106
|
+
break;
|
|
107
|
+
case 'start':
|
|
108
|
+
status = node('server.js', rest);
|
|
109
|
+
break;
|
|
110
|
+
case 'shortcuts':
|
|
111
|
+
status = shortcuts(rest.includes('--startup') ? ['-Startup'] : []);
|
|
112
|
+
break;
|
|
113
|
+
case 'version':
|
|
114
|
+
case '--version':
|
|
115
|
+
case '-v':
|
|
116
|
+
console.log(version);
|
|
117
|
+
break;
|
|
118
|
+
case 'help':
|
|
119
|
+
case '--help':
|
|
120
|
+
case '-h':
|
|
121
|
+
console.log(help);
|
|
122
|
+
break;
|
|
123
|
+
default:
|
|
124
|
+
console.error(`Unknown command: ${cmd}\n`);
|
|
125
|
+
console.log(help);
|
|
126
|
+
status = 1;
|
|
127
|
+
}
|
|
128
|
+
process.exit(status);
|
|
129
|
+
})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agenter-app",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "One local dashboard to watch, approve and steer every Claude Code and Codex session on your machine.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
],
|
|
14
14
|
"author": "Ahmad Pandaog Aquino (https://ahmad-new-portfolio.vercel.app/)",
|
|
15
15
|
"license": "MIT",
|
|
16
|
-
"homepage": "https://
|
|
16
|
+
"homepage": "https://agenterlandingpage.vercel.app/",
|
|
17
17
|
"repository": {
|
|
18
18
|
"type": "git",
|
|
19
19
|
"url": "git+https://github.com/zxcoding123/agenter_app.git"
|
|
20
20
|
},
|
|
21
21
|
"bugs": {
|
|
22
|
-
"url": "https://
|
|
22
|
+
"url": "https://agenterlandingpage.vercel.app/"
|
|
23
23
|
},
|
|
24
24
|
"bin": {
|
|
25
25
|
"agenter": "cli.js"
|
|
Binary file
|
package/public/icon.png
ADDED
|
Binary file
|
package/public/index.html
CHANGED
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
6
|
<title>Agenter</title>
|
|
7
|
-
<link rel="icon" href="
|
|
7
|
+
<link rel="icon" href="/favicon.ico" sizes="any">
|
|
8
|
+
<link rel="icon" type="image/png" sizes="256x256" href="/icon.png">
|
|
9
|
+
<link rel="apple-touch-icon" href="/icon.png">
|
|
8
10
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
9
11
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
10
12
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&family=Geist+Mono:wght@400;500;600&display=swap">
|
|
@@ -20,7 +20,7 @@ foreach ($t in $targets) {
|
|
|
20
20
|
$lnk.TargetPath = "$env:SystemRoot\System32\wscript.exe"
|
|
21
21
|
$lnk.Arguments = "`"$root\Agenter.vbs`""
|
|
22
22
|
$lnk.WorkingDirectory = $root
|
|
23
|
-
$lnk.IconLocation = "$
|
|
23
|
+
$lnk.IconLocation = "$root\public\agenter.ico,0"
|
|
24
24
|
$lnk.Description = 'Watch and answer all your Claude Code sessions'
|
|
25
25
|
$lnk.Save()
|
|
26
26
|
"Created $t"
|
package/server.js
CHANGED
|
@@ -1230,6 +1230,8 @@ const STATIC = {
|
|
|
1230
1230
|
'/': ['index.html', 'text/html; charset=utf-8'],
|
|
1231
1231
|
'/app.js': ['app.js', 'text/javascript; charset=utf-8'],
|
|
1232
1232
|
'/style.css': ['style.css', 'text/css; charset=utf-8'],
|
|
1233
|
+
'/icon.png': ['icon.png', 'image/png'],
|
|
1234
|
+
'/favicon.ico': ['agenter.ico', 'image/x-icon'],
|
|
1233
1235
|
};
|
|
1234
1236
|
|
|
1235
1237
|
const ALLOWED_HOSTS = new Set([`127.0.0.1:${PORT}`, `localhost:${PORT}`]);
|