@zeph-to/cli 1.21.0 → 1.22.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 +36 -22
- package/dist/cli.js +4 -1
- package/dist/installer.d.ts +6 -1
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +22 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -33,36 +33,50 @@ npx @zeph-to/cli notify --title "Hello"
|
|
|
33
33
|
|
|
34
34
|
## Quick Start
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
# Sign in via browser — auto-fetches your API key + hook into
|
|
38
|
-
# ~/.zeph/config.json (no copy-paste)
|
|
39
|
-
npx @zeph-to/cli login
|
|
36
|
+
Install the CLI globally, then run setup:
|
|
40
37
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
```bash
|
|
39
|
+
npm install -g @zeph-to/cli
|
|
40
|
+
zeph install
|
|
44
41
|
```
|
|
45
42
|
|
|
46
|
-
`
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
`zeph install` opens a browser sign-in on a fresh machine — the web app
|
|
44
|
+
issues an API key + hook as a matched pair and the CLI writes them to
|
|
45
|
+
`~/.zeph/config.json` (no copy-paste). Then it installs rules + hooks +
|
|
46
|
+
MCP for every detected agent (Claude Code / Cursor / Windsurf / Gemini /
|
|
47
|
+
Codex / …). Safe to re-run: a saved login is reused untouched (no
|
|
48
|
+
prompts), so a re-run just refreshes the agent integrations. To switch
|
|
49
|
+
account, `zeph install --relogin` forces a fresh sign-in.
|
|
50
|
+
|
|
51
|
+
**Why global, not `npx`?** `zeph cc` (drive a session from your phone)
|
|
52
|
+
needs `zeph` on your `PATH`, and the agent hooks this installs are
|
|
53
|
+
`$(command -v zeph || npx …)` — a global binary skips an npx cold-start
|
|
54
|
+
on *every* notification. For notifications only, with no phone control,
|
|
55
|
+
`npx @zeph-to/cli install` is a lighter alternative that skips the global
|
|
56
|
+
binary.
|
|
51
57
|
|
|
52
|
-
|
|
53
|
-
|
|
58
|
+
`~/.zeph/config.json` is the single source of truth — the CLI, the MCP
|
|
59
|
+
server, the plugin hooks, and the listener all read it. You never need
|
|
60
|
+
`ZEPH_API_KEY`-style env vars for a normal setup; they exist as overrides
|
|
61
|
+
(second account, CI).
|
|
62
|
+
|
|
63
|
+
Variants:
|
|
54
64
|
|
|
55
65
|
```bash
|
|
56
|
-
|
|
57
|
-
|
|
66
|
+
# Headless box (no browser): paste credentials from another machine's
|
|
67
|
+
# ~/.zeph/config.json
|
|
68
|
+
zeph install --key ak_... --hook hook_...
|
|
58
69
|
|
|
59
|
-
|
|
60
|
-
|
|
70
|
+
# Skip the interactive agent picker
|
|
71
|
+
zeph install --only claude,cursor
|
|
61
72
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
73
|
+
# Switch account — force a fresh browser sign-in over a saved login
|
|
74
|
+
zeph install --relogin
|
|
75
|
+
|
|
76
|
+
# Refresh credentials only (no agent re-install) — assumes you already
|
|
77
|
+
# ran `zeph install` once; on its own it does NOT wire MCP into agents
|
|
78
|
+
zeph login
|
|
79
|
+
```
|
|
66
80
|
|
|
67
81
|
To **send** notifications:
|
|
68
82
|
|
package/dist/cli.js
CHANGED
|
@@ -107,10 +107,13 @@ Login options:
|
|
|
107
107
|
|
|
108
108
|
Install options:
|
|
109
109
|
(no --key, no saved config → opens browser login automatically;
|
|
110
|
-
|
|
110
|
+
a saved login is reused untouched on re-run; headless falls back
|
|
111
|
+
to manual key entry)
|
|
111
112
|
--key <api-key> API key (non-interactive; skips browser login)
|
|
112
113
|
--hook <hook-id> Hook ID (non-interactive)
|
|
113
114
|
--base-url <url> Base URL (non-interactive)
|
|
115
|
+
--relogin Force a fresh browser sign-in even if a login is
|
|
116
|
+
already saved (switch account)
|
|
114
117
|
--web-url <url> Login web app URL [default: https://app.zeph.to]
|
|
115
118
|
--only <agents> Comma-separated agent ids to install for
|
|
116
119
|
(claude,cursor,windsurf,gemini,codex,copilot,cline,aider).
|
package/dist/installer.d.ts
CHANGED
|
@@ -3,7 +3,12 @@ import type { Agent } from './agents.js';
|
|
|
3
3
|
* True when install should auto-open browser login (ADR 0002): interactive
|
|
4
4
|
* context with no existing credential (--key/env/config all absent).
|
|
5
5
|
*/
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Interactive install, past the `--key` path: open a browser login only when
|
|
8
|
+
* there's nothing saved yet, or the user explicitly asked to re-authenticate
|
|
9
|
+
* with `--relogin`. A plain re-run keeps the saved login untouched.
|
|
10
|
+
*/
|
|
11
|
+
export declare const shouldReauth: (currentKey: string | undefined, relogin: boolean) => boolean;
|
|
7
12
|
/** Exported for tests (installGemini shells out to the real `gemini` binary,
|
|
8
13
|
* so the merge semantics can't be covered through it deterministically). */
|
|
9
14
|
export declare const mergeJsonFile: (filePath: string, patch: Record<string, unknown>) => void;
|
package/dist/installer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../src/installer.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AA4BzC;;;GAGG;AACH,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../src/installer.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AA4BzC;;;GAGG;AACH;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,YAAY,MAAM,GAAG,SAAS,EAAE,SAAS,OAAO,KAAG,OACxD,CAAC;AAoBzB;6EAC6E;AAC7E,eAAO,MAAM,aAAa,GAAI,UAAU,MAAM,EAAE,OAAO,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,IAqBhF,CAAC;AAgQF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,UAAU,KAAK,EAAE,EAAE,MAAM,MAAM,KAAG,KAAK,EAKxE,CAAC;AA8EF,eAAO,MAAM,aAAa,GAAU,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,KAAG,OAAO,CAAC,MAAM,CAkG1F,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 = exports.filterAgentsByIds = exports.mergeJsonFile = exports.
|
|
3
|
+
exports.handleInstall = exports.filterAgentsByIds = exports.mergeJsonFile = exports.shouldReauth = 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");
|
|
@@ -19,8 +19,13 @@ const fail = (msg) => console.log(` - ${msg}`);
|
|
|
19
19
|
* True when install should auto-open browser login (ADR 0002): interactive
|
|
20
20
|
* context with no existing credential (--key/env/config all absent).
|
|
21
21
|
*/
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Interactive install, past the `--key` path: open a browser login only when
|
|
24
|
+
* there's nothing saved yet, or the user explicitly asked to re-authenticate
|
|
25
|
+
* with `--relogin`. A plain re-run keeps the saved login untouched.
|
|
26
|
+
*/
|
|
27
|
+
const shouldReauth = (currentKey, relogin) => !currentKey || relogin;
|
|
28
|
+
exports.shouldReauth = shouldReauth;
|
|
24
29
|
const promptInput = (question) => {
|
|
25
30
|
const rl = (0, readline_1.createInterface)({ input: process.stdin, output: process.stdout });
|
|
26
31
|
return new Promise((resolve) => {
|
|
@@ -348,26 +353,12 @@ const testConnection = async (apiKey, baseUrl) => {
|
|
|
348
353
|
return false;
|
|
349
354
|
}
|
|
350
355
|
};
|
|
351
|
-
/** Interactive path when a credential already exists: prompt to keep/replace. */
|
|
352
|
-
const promptExistingCredentials = async (currentKey, existing) => {
|
|
353
|
-
if (currentKey)
|
|
354
|
-
console.log(` Current API Key: ${currentKey.slice(0, 12)}...`);
|
|
355
|
-
const keyInput = await promptInput(currentKey ? ' New API Key (Enter to keep): ' : ' API Key (from app > Settings > API Keys): ');
|
|
356
|
-
const currentHook = (0, config_js_1.resolvedEnv)('ZEPH_HOOK_ID') || existing.hookId;
|
|
357
|
-
if (currentHook)
|
|
358
|
-
console.log(` Current Hook ID: ${currentHook}`);
|
|
359
|
-
const hookInput = await promptInput(currentHook ? ' New Hook ID (Enter to keep, "none" to remove): ' : ' Hook ID (optional, for prompt/input): ');
|
|
360
|
-
return {
|
|
361
|
-
apiKey: keyInput || currentKey,
|
|
362
|
-
hookId: hookInput === 'none' ? undefined : (hookInput || currentHook),
|
|
363
|
-
baseUrl: existing.baseUrl,
|
|
364
|
-
};
|
|
365
|
-
};
|
|
366
356
|
/**
|
|
367
|
-
* Resolve API key + hook for install. Priority: --key/env/config (non-interactive
|
|
368
|
-
*
|
|
369
|
-
*
|
|
370
|
-
*
|
|
357
|
+
* Resolve API key + hook for install. Priority: --key/env/config (non-interactive)
|
|
358
|
+
* → a saved login is reused untouched on re-run → otherwise a brand-new
|
|
359
|
+
* interactive install opens browser login (ADR 0002), falling back to manual
|
|
360
|
+
* paste when headless. wsUrl/deviceId from a login are persisted by
|
|
361
|
+
* runLoginFlow and re-read at config-save time.
|
|
371
362
|
*/
|
|
372
363
|
const collectCredentials = async (args, installArgs, nonInteractive, existing) => {
|
|
373
364
|
if (nonInteractive) {
|
|
@@ -379,8 +370,15 @@ const collectCredentials = async (args, installArgs, nonInteractive, existing) =
|
|
|
379
370
|
}
|
|
380
371
|
console.log('');
|
|
381
372
|
const currentKey = (0, config_js_1.resolvedEnv)('ZEPH_API_KEY') || existing.apiKey;
|
|
382
|
-
|
|
383
|
-
|
|
373
|
+
// Re-run with a saved login: reuse it silently and move on to agent wiring.
|
|
374
|
+
// Switching accounts is `zeph login` or `zeph install --relogin`.
|
|
375
|
+
if (!(0, exports.shouldReauth)(currentKey, args.relogin === true)) {
|
|
376
|
+
console.log(` Using saved login (${currentKey.slice(0, 12)}…). Run \`zeph install --relogin\` to switch account.`);
|
|
377
|
+
return {
|
|
378
|
+
apiKey: currentKey,
|
|
379
|
+
hookId: (0, config_js_1.resolvedEnv)('ZEPH_HOOK_ID') || existing.hookId,
|
|
380
|
+
baseUrl: existing.baseUrl,
|
|
381
|
+
};
|
|
384
382
|
}
|
|
385
383
|
const result = await (0, login_js_1.runLoginFlow)({
|
|
386
384
|
webUrl: (0, login_js_1.resolveWebUrl)(args['web-url']),
|