@zeph-to/hook-sdk 1.8.0 → 1.9.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 +3 -2
- package/dist/cli.js +3 -0
- package/dist/installer.d.ts +7 -0
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +84 -27
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @zeph-to/hook-sdk
|
|
2
2
|
|
|
3
|
-
Push notification SDK + CLI for [Zeph](https://zeph.to).
|
|
3
|
+
Push notification SDK + CLI for [Zeph](https://zeph.to). The `ZephHook` SDK uses native `fetch` with no runtime dependencies; the `zeph` CLI adds `@inquirer/prompts` for its interactive installer.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -202,7 +202,8 @@ Push bodies are encrypted with AES-256-GCM. The wrapping key is derived via ECDH
|
|
|
202
202
|
## Requirements
|
|
203
203
|
|
|
204
204
|
- Node.js >= 18 (uses native `fetch`)
|
|
205
|
-
-
|
|
205
|
+
- The `ZephHook` SDK has no runtime dependencies. The CLI depends on
|
|
206
|
+
`@inquirer/prompts` for the interactive `zeph install` picker.
|
|
206
207
|
|
|
207
208
|
## License
|
|
208
209
|
|
package/dist/cli.js
CHANGED
|
@@ -97,6 +97,9 @@ Install options:
|
|
|
97
97
|
--key <api-key> API key (non-interactive)
|
|
98
98
|
--hook <hook-id> Hook ID (non-interactive)
|
|
99
99
|
--base-url <url> Base URL (non-interactive)
|
|
100
|
+
--only <agents> Comma-separated agent ids to install for
|
|
101
|
+
(claude,cursor,windsurf,gemini,codex,copilot,cline,aider).
|
|
102
|
+
Skips the interactive picker.
|
|
100
103
|
|
|
101
104
|
Uninstall options:
|
|
102
105
|
--dry-run Preview what would be removed, change nothing
|
package/dist/installer.d.ts
CHANGED
|
@@ -1,2 +1,9 @@
|
|
|
1
|
+
import type { Agent } from './agents.js';
|
|
2
|
+
/**
|
|
3
|
+
* Resolve agents from a non-interactive `--only cursor,gemini` flag.
|
|
4
|
+
* Matches on agent id; unknown ids are silently dropped. Exported for
|
|
5
|
+
* unit testing.
|
|
6
|
+
*/
|
|
7
|
+
export declare const filterAgentsByIds: (detected: Agent[], only: string) => Agent[];
|
|
1
8
|
export declare const handleInstall: (args: Record<string, string | boolean>) => Promise<number>;
|
|
2
9
|
//# sourceMappingURL=installer.d.ts.map
|
package/dist/installer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../src/installer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../src/installer.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAwSzC;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,UAAU,KAAK,EAAE,EAAE,MAAM,MAAM,KAAG,KAAK,EAKxE,CAAC;AAqBF,eAAO,MAAM,aAAa,GAAU,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,KAAG,OAAO,CAAC,MAAM,CA4H1F,CAAC"}
|
package/dist/installer.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.handleInstall = void 0;
|
|
3
|
+
exports.handleInstall = exports.filterAgentsByIds = void 0;
|
|
4
4
|
const child_process_1 = require("child_process");
|
|
5
5
|
const fs_1 = require("fs");
|
|
6
6
|
const os_1 = require("os");
|
|
@@ -251,6 +251,52 @@ const AGENT_INSTALLERS = {
|
|
|
251
251
|
cline: installCline,
|
|
252
252
|
aider: installAider,
|
|
253
253
|
};
|
|
254
|
+
// One-line summary of what each agent's installer does — shown in the
|
|
255
|
+
// interactive plan before anything is written.
|
|
256
|
+
const AGENT_PLAN_LABELS = {
|
|
257
|
+
claude: 'Claude Code — install plugin',
|
|
258
|
+
cursor: 'Cursor — MCP + hooks + rules',
|
|
259
|
+
windsurf: 'Windsurf — MCP + hooks + rules',
|
|
260
|
+
gemini: 'Gemini CLI — MCP + hooks + rules',
|
|
261
|
+
codex: 'Codex CLI — hooks + rules',
|
|
262
|
+
copilot: 'Copilot CLI — hooks + rules',
|
|
263
|
+
cline: 'Cline — rules',
|
|
264
|
+
aider: 'Aider — conventions',
|
|
265
|
+
};
|
|
266
|
+
// ── Agent selection ──────────────────────────────────────────────
|
|
267
|
+
/**
|
|
268
|
+
* Interactive agent picker — an @inquirer/prompts checkbox (arrow keys
|
|
269
|
+
* to move, space to toggle, enter to confirm). Every agent starts
|
|
270
|
+
* checked, so a bare Enter installs for all. Returns the chosen Agent[].
|
|
271
|
+
*
|
|
272
|
+
* Dynamic import keeps @inquirer/prompts (ESM) loadable from this
|
|
273
|
+
* CommonJS build, and means the dependency is only touched on the
|
|
274
|
+
* interactive path — `notify` / `list` / scripted `install --only`
|
|
275
|
+
* never load it.
|
|
276
|
+
*/
|
|
277
|
+
const pickAgentsInteractive = async (detected) => {
|
|
278
|
+
const { checkbox } = await import('@inquirer/prompts');
|
|
279
|
+
const picked = await checkbox({
|
|
280
|
+
message: 'Install Zeph for which agents? (space to toggle, enter to confirm)',
|
|
281
|
+
choices: detected.map((agent) => ({
|
|
282
|
+
name: AGENT_PLAN_LABELS[agent.id] ?? agent.name,
|
|
283
|
+
value: agent.id,
|
|
284
|
+
checked: true,
|
|
285
|
+
})),
|
|
286
|
+
loop: false,
|
|
287
|
+
});
|
|
288
|
+
return detected.filter((a) => picked.includes(a.id));
|
|
289
|
+
};
|
|
290
|
+
/**
|
|
291
|
+
* Resolve agents from a non-interactive `--only cursor,gemini` flag.
|
|
292
|
+
* Matches on agent id; unknown ids are silently dropped. Exported for
|
|
293
|
+
* unit testing.
|
|
294
|
+
*/
|
|
295
|
+
const filterAgentsByIds = (detected, only) => {
|
|
296
|
+
const ids = new Set(only.split(',').map((s) => s.trim().toLowerCase()).filter(Boolean));
|
|
297
|
+
return detected.filter((a) => ids.has(a.id));
|
|
298
|
+
};
|
|
299
|
+
exports.filterAgentsByIds = filterAgentsByIds;
|
|
254
300
|
// ── Test Connection ──────────────────────────────────────────────
|
|
255
301
|
const testConnection = async (apiKey, baseUrl) => {
|
|
256
302
|
try {
|
|
@@ -291,7 +337,32 @@ const handleInstall = async (args) => {
|
|
|
291
337
|
if (detected.length === 0) {
|
|
292
338
|
console.log('\n No supported agents found. Config will still be saved.\n');
|
|
293
339
|
}
|
|
294
|
-
// 2.
|
|
340
|
+
// 2. Choose which agents to install for — asked up front so the user
|
|
341
|
+
// sees the choice before being walked through credential prompts.
|
|
342
|
+
let selected = detected;
|
|
343
|
+
const onlyArg = args.only?.trim();
|
|
344
|
+
if (detected.length > 0) {
|
|
345
|
+
if (onlyArg) {
|
|
346
|
+
// Non-interactive or scripted: --only cursor,gemini
|
|
347
|
+
selected = (0, exports.filterAgentsByIds)(detected, onlyArg);
|
|
348
|
+
console.log(`\n --only ${onlyArg} → ${selected.map((a) => a.name).join(', ') || '(no match)'}`);
|
|
349
|
+
}
|
|
350
|
+
else if (nonInteractive) {
|
|
351
|
+
// Scripted run with no --only: keep the all-detected default
|
|
352
|
+
selected = detected;
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
try {
|
|
356
|
+
selected = await pickAgentsInteractive(detected);
|
|
357
|
+
}
|
|
358
|
+
catch {
|
|
359
|
+
// Ctrl-C in the picker (or no TTY) — treat as a clean cancel.
|
|
360
|
+
console.log('\n Cancelled.\n');
|
|
361
|
+
return 0;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
// 3. Collect credentials
|
|
295
366
|
const existing = (0, config_js_1.loadConfig)();
|
|
296
367
|
let apiKey;
|
|
297
368
|
let hookId;
|
|
@@ -321,33 +392,19 @@ const handleInstall = async (args) => {
|
|
|
321
392
|
console.error('\n Error: API key is required.\n');
|
|
322
393
|
return 1;
|
|
323
394
|
}
|
|
324
|
-
//
|
|
395
|
+
// 4. Show the resolved plan before touching anything (interactive only).
|
|
325
396
|
if (!nonInteractive) {
|
|
326
397
|
console.log('\n Will do:');
|
|
327
|
-
console.log(
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
const labels = {
|
|
331
|
-
claude: 'Install Claude Code plugin',
|
|
332
|
-
cursor: 'Setup Cursor (MCP + hooks + rules)',
|
|
333
|
-
windsurf: 'Setup Windsurf (MCP + hooks + rules)',
|
|
334
|
-
gemini: 'Setup Gemini CLI (MCP + hooks + rules)',
|
|
335
|
-
codex: 'Setup Codex CLI (hooks + rules)',
|
|
336
|
-
copilot: 'Setup Copilot CLI (hooks + rules)',
|
|
337
|
-
cline: 'Setup Cline (rules)',
|
|
338
|
-
aider: 'Setup Aider (conventions)',
|
|
339
|
-
};
|
|
340
|
-
console.log(` ${step}. ${labels[agent.id] ?? `Install for ${agent.name}`}`);
|
|
341
|
-
step++;
|
|
398
|
+
console.log(` - Save config to ${config_js_1.CONFIG_FILE}`);
|
|
399
|
+
for (const agent of selected) {
|
|
400
|
+
console.log(` - ${AGENT_PLAN_LABELS[agent.id] ?? `Install for ${agent.name}`}`);
|
|
342
401
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
if (confirm.toLowerCase() === 'n') {
|
|
346
|
-
console.log('\n Cancelled.\n');
|
|
347
|
-
return 0;
|
|
402
|
+
if (selected.length === 0) {
|
|
403
|
+
console.log(' (no agents selected — only the config file will be saved)');
|
|
348
404
|
}
|
|
405
|
+
console.log(' - Test connection');
|
|
349
406
|
}
|
|
350
|
-
//
|
|
407
|
+
// 5. Save config
|
|
351
408
|
console.log('');
|
|
352
409
|
const config = {
|
|
353
410
|
apiKey,
|
|
@@ -356,14 +413,14 @@ const handleInstall = async (args) => {
|
|
|
356
413
|
};
|
|
357
414
|
(0, config_js_1.saveConfig)(config);
|
|
358
415
|
ok(`Config saved to ${config_js_1.CONFIG_FILE}`);
|
|
359
|
-
//
|
|
360
|
-
for (const agent of
|
|
416
|
+
// 6. Install for the selected agents only
|
|
417
|
+
for (const agent of selected) {
|
|
361
418
|
console.log(`\n Installing for ${agent.name}...`);
|
|
362
419
|
const installer = AGENT_INSTALLERS[agent.id];
|
|
363
420
|
if (installer)
|
|
364
421
|
installer();
|
|
365
422
|
}
|
|
366
|
-
//
|
|
423
|
+
// 7. Test connection
|
|
367
424
|
console.log('\n Testing connection...');
|
|
368
425
|
await testConnection(apiKey, baseUrl);
|
|
369
426
|
console.log('\n Done! Restart your agents.\n');
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zeph-to/hook-sdk",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Zeph push notification SDK + CLI
|
|
3
|
+
"version": "1.9.0",
|
|
4
|
+
"description": "Zeph push notification SDK + CLI for AI agents",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"exports": {
|
|
@@ -62,5 +62,8 @@
|
|
|
62
62
|
"claude",
|
|
63
63
|
"devtools"
|
|
64
64
|
],
|
|
65
|
-
"license": "Apache-2.0"
|
|
65
|
+
"license": "Apache-2.0",
|
|
66
|
+
"dependencies": {
|
|
67
|
+
"@inquirer/prompts": "^8.4.3"
|
|
68
|
+
}
|
|
66
69
|
}
|