myshell-tools 2.0.0-alpha.0 → 2.1.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/CHANGELOG.md +13 -1
- package/README.md +6 -3
- package/dist/cli.js +85 -30
- package/dist/cli.js.map +1 -1
- package/dist/commands/doctor.d.ts +3 -2
- package/dist/commands/doctor.js +9 -5
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/login.d.ts +20 -0
- package/dist/commands/login.js +60 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/core/orchestrate.js +80 -28
- package/dist/core/orchestrate.js.map +1 -1
- package/dist/core/policy.d.ts +10 -0
- package/dist/core/policy.js +40 -0
- package/dist/core/policy.js.map +1 -1
- package/dist/core/review.d.ts +5 -0
- package/dist/core/review.js +2 -2
- package/dist/core/review.js.map +1 -1
- package/dist/infra/atomic.d.ts +0 -3
- package/dist/infra/atomic.js +1 -1
- package/dist/infra/atomic.js.map +1 -1
- package/dist/infra/config.d.ts +23 -0
- package/dist/infra/config.js +64 -0
- package/dist/infra/config.js.map +1 -0
- package/dist/infra/conversation-store.d.ts +42 -0
- package/dist/infra/conversation-store.js +14 -0
- package/dist/infra/conversation-store.js.map +1 -0
- package/dist/infra/conversations.d.ts +18 -0
- package/dist/infra/conversations.js +296 -0
- package/dist/infra/conversations.js.map +1 -0
- package/dist/infra/insights.d.ts +66 -0
- package/dist/infra/insights.js +105 -0
- package/dist/infra/insights.js.map +1 -0
- package/dist/infra/ledger.d.ts +4 -6
- package/dist/infra/ledger.js.map +1 -1
- package/dist/interface/menu.d.ts +112 -0
- package/dist/interface/menu.js +622 -0
- package/dist/interface/menu.js.map +1 -0
- package/dist/providers/claude.d.ts +4 -13
- package/dist/providers/claude.js +5 -4
- package/dist/providers/claude.js.map +1 -1
- package/dist/providers/codex.d.ts +6 -12
- package/dist/providers/codex.js +6 -4
- package/dist/providers/codex.js.map +1 -1
- package/dist/providers/detect.d.ts +63 -14
- package/dist/providers/detect.js +123 -27
- package/dist/providers/detect.js.map +1 -1
- package/dist/ui/tui.d.ts +127 -0
- package/dist/ui/tui.js +316 -0
- package/dist/ui/tui.js.map +1 -0
- package/package.json +4 -1
- package/dist/core/index.d.ts +0 -13
- package/dist/core/index.js +0 -12
- package/dist/core/index.js.map +0 -1
- package/dist/infra/index.d.ts +0 -9
- package/dist/infra/index.js +0 -7
- package/dist/infra/index.js.map +0 -1
- package/dist/providers/index.d.ts +0 -9
- package/dist/providers/index.js +0 -7
- package/dist/providers/index.js.map +0 -1
|
@@ -14,9 +14,10 @@
|
|
|
14
14
|
* permission-bypass flag here.
|
|
15
15
|
*
|
|
16
16
|
* Authentication note:
|
|
17
|
-
* Auth state is
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* Auth state is probed at detect() time by spawning `claude auth status` and
|
|
18
|
+
* parsing its JSON output (see detect.ts / parseClaudeAuth). An unauthenticated
|
|
19
|
+
* run will also surface at run time: the stderr is classified as category 'auth'
|
|
20
|
+
* by classifyError().
|
|
20
21
|
*
|
|
21
22
|
* Execa v9 streaming:
|
|
22
23
|
* We use `subprocess[Symbol.asyncIterator]()` (i.e. `for await … of subprocess`)
|
|
@@ -25,16 +26,6 @@
|
|
|
25
26
|
* yields one string per stdout line.
|
|
26
27
|
*/
|
|
27
28
|
import type { Provider } from './port.js';
|
|
28
|
-
/**
|
|
29
|
-
* Map a concrete model id to a CLI-safe alias so a stale full id never 404s.
|
|
30
|
-
*
|
|
31
|
-
* Patterns:
|
|
32
|
-
* - claude-opus-* → 'opus'
|
|
33
|
-
* - claude-sonnet-* → 'sonnet'
|
|
34
|
-
* - claude-haiku-* → 'haiku'
|
|
35
|
-
* - anything else → returned unchanged
|
|
36
|
-
*/
|
|
37
|
-
export declare function toClaudeModelArg(model: string): string;
|
|
38
29
|
/**
|
|
39
30
|
* Create a Claude provider adapter.
|
|
40
31
|
*
|
package/dist/providers/claude.js
CHANGED
|
@@ -14,9 +14,10 @@
|
|
|
14
14
|
* permission-bypass flag here.
|
|
15
15
|
*
|
|
16
16
|
* Authentication note:
|
|
17
|
-
* Auth state is
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* Auth state is probed at detect() time by spawning `claude auth status` and
|
|
18
|
+
* parsing its JSON output (see detect.ts / parseClaudeAuth). An unauthenticated
|
|
19
|
+
* run will also surface at run time: the stderr is classified as category 'auth'
|
|
20
|
+
* by classifyError().
|
|
20
21
|
*
|
|
21
22
|
* Execa v9 streaming:
|
|
22
23
|
* We use `subprocess[Symbol.asyncIterator]()` (i.e. `for await … of subprocess`)
|
|
@@ -40,7 +41,7 @@ import { parseClaudeLine } from './claude-parse.js';
|
|
|
40
41
|
* - claude-haiku-* → 'haiku'
|
|
41
42
|
* - anything else → returned unchanged
|
|
42
43
|
*/
|
|
43
|
-
|
|
44
|
+
function toClaudeModelArg(model) {
|
|
44
45
|
if (model.startsWith('claude-opus'))
|
|
45
46
|
return 'opus';
|
|
46
47
|
if (model.startsWith('claude-sonnet'))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/providers/claude.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/providers/claude.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,9 +11,11 @@
|
|
|
11
11
|
* full-access → '--sandbox danger-full-access'
|
|
12
12
|
*
|
|
13
13
|
* Authentication note:
|
|
14
|
-
* Auth state is
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* Auth state is probed at detect() time by spawning `codex login status` and
|
|
15
|
+
* inspecting both stdout and stderr (see detect.ts / parseCodexAuth). In
|
|
16
|
+
* practice codex writes "Logged in using ChatGPT" to stderr. An unauthenticated
|
|
17
|
+
* run will also surface at run time: the stderr/event is classified as category
|
|
18
|
+
* 'auth' by classifyError().
|
|
17
19
|
*
|
|
18
20
|
* costUsd note:
|
|
19
21
|
* Codex does NOT report a USD cost. The `done` event therefore omits
|
|
@@ -25,15 +27,7 @@
|
|
|
25
27
|
* lines as strings. Confirmed from execa types: the subprocess IS an
|
|
26
28
|
* AsyncIterable<string>.
|
|
27
29
|
*/
|
|
28
|
-
import type { Provider
|
|
29
|
-
/**
|
|
30
|
-
* Map the abstract {@link SandboxLevel} to the concrete `--sandbox` argument
|
|
31
|
-
* that the Codex CLI accepts.
|
|
32
|
-
*
|
|
33
|
-
* NEVER default to 'danger-full-access' — always require the caller to opt in
|
|
34
|
-
* explicitly by passing SandboxLevel 'full-access'.
|
|
35
|
-
*/
|
|
36
|
-
export declare function toSandboxArg(level: SandboxLevel): string;
|
|
30
|
+
import type { Provider } from './port.js';
|
|
37
31
|
/**
|
|
38
32
|
* Create a Codex provider adapter.
|
|
39
33
|
*
|
package/dist/providers/codex.js
CHANGED
|
@@ -11,9 +11,11 @@
|
|
|
11
11
|
* full-access → '--sandbox danger-full-access'
|
|
12
12
|
*
|
|
13
13
|
* Authentication note:
|
|
14
|
-
* Auth state is
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* Auth state is probed at detect() time by spawning `codex login status` and
|
|
15
|
+
* inspecting both stdout and stderr (see detect.ts / parseCodexAuth). In
|
|
16
|
+
* practice codex writes "Logged in using ChatGPT" to stderr. An unauthenticated
|
|
17
|
+
* run will also surface at run time: the stderr/event is classified as category
|
|
18
|
+
* 'auth' by classifyError().
|
|
17
19
|
*
|
|
18
20
|
* costUsd note:
|
|
19
21
|
* Codex does NOT report a USD cost. The `done` event therefore omits
|
|
@@ -39,7 +41,7 @@ import { createCodexParser } from './codex-parse.js';
|
|
|
39
41
|
* NEVER default to 'danger-full-access' — always require the caller to opt in
|
|
40
42
|
* explicitly by passing SandboxLevel 'full-access'.
|
|
41
43
|
*/
|
|
42
|
-
|
|
44
|
+
function toSandboxArg(level) {
|
|
43
45
|
switch (level) {
|
|
44
46
|
case 'read-only':
|
|
45
47
|
return 'read-only';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/providers/codex.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/providers/codex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAG9B,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,8EAA8E;AAC9E,2BAA2B;AAC3B,8EAA8E;AAE9E;;;;;;GAMG;AACH,SAAS,YAAY,CAAC,KAAmB;IACvC,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,WAAW;YACd,OAAO,WAAW,CAAC;QACrB,KAAK,iBAAiB;YACpB,OAAO,iBAAiB,CAAC;QAC3B,KAAK,aAAa;YAChB,OAAO,oBAAoB,CAAC;IAChC,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAuB;IACzD,MAAM,GAAG,GAAG,IAAI,EAAE,GAAG,IAAI,OAAO,CAAC;IAEjC,OAAO;QACL,EAAE,EAAE,OAAO;QAEX,MAAM;YACJ,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;QAED,KAAK,CAAC,CAAC,GAAG,CAAC,GAAoB,EAAE,MAAmB;YAClD,MAAM,IAAI,GAAG;gBACX,MAAM;gBACN,QAAQ;gBACR,IAAI;gBACJ,GAAG,CAAC,KAAK;gBACT,WAAW;gBACX,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC;aAC1B,CAAC;YAEF,6EAA6E;YAC7E,2EAA2E;YAC3E,MAAM,UAAU,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE;gBAClC,GAAG,EAAE,GAAG,CAAC,GAAG;gBACZ,KAAK,EAAE,GAAG,CAAC,MAAM,EAAO,qCAAqC;gBAC7D,YAAY,EAAE,MAAM;gBACpB,OAAO,EAAE,GAAG,CAAC,SAAS;gBACtB,MAAM,EAAE,KAAK;aACd,CAAC,CAAC;YAEH,oEAAoE;YACpE,MAAM,cAAc,GAAG,iBAAiB,EAAE,CAAC;YAE3C,IAAI,eAAe,GAAG,KAAK,CAAC;YAE5B,8BAA8B;YAC9B,sEAAsE;YACtE,kEAAkE;YAClE,IAAI,CAAC;gBACH,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;oBACpC,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;oBACpC,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;wBACxB,MAAM,EAAE,CAAC;wBACT,IAAI,EAAE,CAAC,IAAI,KAAK,MAAM,IAAI,EAAE,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;4BAC9C,eAAe,GAAG,IAAI,CAAC;wBACzB,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,yEAAyE;YAC3E,CAAC;YAED,gEAAgE;YAChE,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC;YAEhC,IAAI,CAAC,eAAe,EAAE,CAAC;gBACrB,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;oBACtB,MAAM;wBACJ,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,aAAa,CAAC,WAAW,EAAE,CAAC,CAAC;qBACrC,CAAC;gBACJ,CAAC;qBAAM,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;oBACrF,MAAM;wBACJ,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,aAAa,CAClB,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EACtD,MAAM,CAAC,QAAQ,IAAI,CAAC,CACrB;qBACF,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -3,17 +3,19 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Provider-detection logic.
|
|
5
5
|
*
|
|
6
|
-
* Claude detection is REAL: spawns `claude --version` to probe installation
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* Claude detection is REAL: spawns `claude --version` to probe installation,
|
|
7
|
+
* then `claude auth status` to probe real authentication state.
|
|
8
|
+
* Codex detection is REAL: spawns `codex --version` to probe installation,
|
|
9
|
+
* then `codex login status` to probe real authentication state.
|
|
10
|
+
*
|
|
11
|
+
* Plan labels are only set when clearly present in CLI output — never fabricated.
|
|
11
12
|
*/
|
|
12
13
|
export interface ProviderStatus {
|
|
13
14
|
readonly id: 'claude' | 'codex';
|
|
14
15
|
readonly installed: boolean;
|
|
15
16
|
readonly version: string | null;
|
|
16
17
|
readonly authenticated: boolean;
|
|
18
|
+
readonly plan: string | null;
|
|
17
19
|
readonly binaryPath: string | null;
|
|
18
20
|
readonly availableModels: readonly string[];
|
|
19
21
|
}
|
|
@@ -24,17 +26,64 @@ export interface EnvironmentStatus {
|
|
|
24
26
|
readonly platform: NodeJS.Platform;
|
|
25
27
|
}
|
|
26
28
|
/**
|
|
27
|
-
*
|
|
29
|
+
* Parse the output of `claude auth status` into an auth result.
|
|
30
|
+
*
|
|
31
|
+
* Real output shape (exit code 0, authenticated):
|
|
32
|
+
* ```json
|
|
33
|
+
* {
|
|
34
|
+
* "loggedIn": true,
|
|
35
|
+
* "authMethod": "claude.ai",
|
|
36
|
+
* "apiProvider": "firstParty",
|
|
37
|
+
* "email": "user@example.com",
|
|
38
|
+
* "orgId": "...",
|
|
39
|
+
* "orgName": "...",
|
|
40
|
+
* "subscriptionType": "pro"
|
|
41
|
+
* }
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* Authenticated when: exitCode === 0 AND the JSON contains `"loggedIn": true`.
|
|
45
|
+
* Plan: the `subscriptionType` string when present and non-empty, else null.
|
|
46
|
+
* Conservative: on any parse error, authenticated stays false and plan is null.
|
|
47
|
+
*/
|
|
48
|
+
export declare function parseClaudeAuth(stdout: string, _stderr: string, exitCode: number): {
|
|
49
|
+
authenticated: boolean;
|
|
50
|
+
plan: string | null;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Parse the output of `codex login status` into an auth result.
|
|
54
|
+
*
|
|
55
|
+
* Real output shape (exit code 0, authenticated):
|
|
56
|
+
* ```
|
|
57
|
+
* Logged in using ChatGPT ← written to stderr (not stdout)
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* Authenticated when: exitCode === 0 AND either stdout OR stderr contains
|
|
61
|
+
* "logged in" (case-insensitive). The haystack is built from both streams
|
|
62
|
+
* because `codex login status` writes to stderr in practice.
|
|
63
|
+
*
|
|
64
|
+
* Plan: null — codex login status does not expose a subscription/plan label.
|
|
65
|
+
* Conservative: on any unexpected output, authenticated stays false and plan is null.
|
|
66
|
+
*
|
|
67
|
+
* @remarks Codex has no plan/subscription field in `codex login status` output.
|
|
68
|
+
* plan is always null; it is never fabricated.
|
|
69
|
+
*/
|
|
70
|
+
export declare function parseCodexAuth(stdout: string, stderr: string, exitCode: number): {
|
|
71
|
+
authenticated: boolean;
|
|
72
|
+
plan: string | null;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Detect whether a provider CLI is installed and probe its real auth state.
|
|
28
76
|
*
|
|
29
|
-
* For 'claude': runs `claude --version` to confirm the binary is present
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* (category 'auth').
|
|
77
|
+
* For 'claude': runs `claude --version` to confirm the binary is present, then
|
|
78
|
+
* `claude auth status` (JSON output) to determine real auth state and plan.
|
|
79
|
+
* On spawn failure of the status command, falls back gracefully: installed
|
|
80
|
+
* remains true, authenticated false, plan null.
|
|
34
81
|
*
|
|
35
|
-
* For 'codex': runs `codex --version` to confirm the binary is present
|
|
36
|
-
*
|
|
37
|
-
*
|
|
82
|
+
* For 'codex': runs `codex --version` to confirm the binary is present, then
|
|
83
|
+
* `codex login status` to determine real auth state. Plan is always null because
|
|
84
|
+
* `codex login status` does not expose subscription information.
|
|
85
|
+
* On spawn failure of the status command, falls back gracefully: installed
|
|
86
|
+
* remains true, authenticated false, plan null.
|
|
38
87
|
*/
|
|
39
88
|
export declare function detectProvider(id: 'claude' | 'codex'): Promise<ProviderStatus>;
|
|
40
89
|
/**
|
package/dist/providers/detect.js
CHANGED
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Provider-detection logic.
|
|
5
5
|
*
|
|
6
|
-
* Claude detection is REAL: spawns `claude --version` to probe installation
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* Claude detection is REAL: spawns `claude --version` to probe installation,
|
|
7
|
+
* then `claude auth status` to probe real authentication state.
|
|
8
|
+
* Codex detection is REAL: spawns `codex --version` to probe installation,
|
|
9
|
+
* then `codex login status` to probe real authentication state.
|
|
10
|
+
*
|
|
11
|
+
* Plan labels are only set when clearly present in CLI output — never fabricated.
|
|
11
12
|
*/
|
|
12
13
|
import { execa } from 'execa';
|
|
13
14
|
// ---------------------------------------------------------------------------
|
|
@@ -19,25 +20,99 @@ function notDetected(id) {
|
|
|
19
20
|
installed: false,
|
|
20
21
|
version: null,
|
|
21
22
|
authenticated: false,
|
|
23
|
+
plan: null,
|
|
22
24
|
binaryPath: null,
|
|
23
25
|
availableModels: [],
|
|
24
26
|
};
|
|
25
27
|
}
|
|
26
28
|
// ---------------------------------------------------------------------------
|
|
29
|
+
// Pure auth parsers (no I/O — hermetic-testable)
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
/**
|
|
32
|
+
* Parse the output of `claude auth status` into an auth result.
|
|
33
|
+
*
|
|
34
|
+
* Real output shape (exit code 0, authenticated):
|
|
35
|
+
* ```json
|
|
36
|
+
* {
|
|
37
|
+
* "loggedIn": true,
|
|
38
|
+
* "authMethod": "claude.ai",
|
|
39
|
+
* "apiProvider": "firstParty",
|
|
40
|
+
* "email": "user@example.com",
|
|
41
|
+
* "orgId": "...",
|
|
42
|
+
* "orgName": "...",
|
|
43
|
+
* "subscriptionType": "pro"
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* Authenticated when: exitCode === 0 AND the JSON contains `"loggedIn": true`.
|
|
48
|
+
* Plan: the `subscriptionType` string when present and non-empty, else null.
|
|
49
|
+
* Conservative: on any parse error, authenticated stays false and plan is null.
|
|
50
|
+
*/
|
|
51
|
+
export function parseClaudeAuth(stdout, _stderr, exitCode) {
|
|
52
|
+
if (exitCode !== 0) {
|
|
53
|
+
return { authenticated: false, plan: null };
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
const data = JSON.parse(stdout.trim());
|
|
57
|
+
if (typeof data !== 'object' || data === null) {
|
|
58
|
+
return { authenticated: false, plan: null };
|
|
59
|
+
}
|
|
60
|
+
const obj = data;
|
|
61
|
+
const loggedIn = obj['loggedIn'] === true;
|
|
62
|
+
if (!loggedIn) {
|
|
63
|
+
return { authenticated: false, plan: null };
|
|
64
|
+
}
|
|
65
|
+
const sub = obj['subscriptionType'];
|
|
66
|
+
const plan = typeof sub === 'string' && sub.length > 0 ? sub : null;
|
|
67
|
+
return { authenticated: true, plan };
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return { authenticated: false, plan: null };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Parse the output of `codex login status` into an auth result.
|
|
75
|
+
*
|
|
76
|
+
* Real output shape (exit code 0, authenticated):
|
|
77
|
+
* ```
|
|
78
|
+
* Logged in using ChatGPT ← written to stderr (not stdout)
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* Authenticated when: exitCode === 0 AND either stdout OR stderr contains
|
|
82
|
+
* "logged in" (case-insensitive). The haystack is built from both streams
|
|
83
|
+
* because `codex login status` writes to stderr in practice.
|
|
84
|
+
*
|
|
85
|
+
* Plan: null — codex login status does not expose a subscription/plan label.
|
|
86
|
+
* Conservative: on any unexpected output, authenticated stays false and plan is null.
|
|
87
|
+
*
|
|
88
|
+
* @remarks Codex has no plan/subscription field in `codex login status` output.
|
|
89
|
+
* plan is always null; it is never fabricated.
|
|
90
|
+
*/
|
|
91
|
+
export function parseCodexAuth(stdout, stderr, exitCode) {
|
|
92
|
+
if (exitCode !== 0) {
|
|
93
|
+
return { authenticated: false, plan: null };
|
|
94
|
+
}
|
|
95
|
+
// Build haystack from both streams — codex login status uses stderr in practice.
|
|
96
|
+
const haystack = (stdout + '\n' + stderr).toLowerCase();
|
|
97
|
+
const authenticated = haystack.includes('logged in');
|
|
98
|
+
return { authenticated, plan: null };
|
|
99
|
+
}
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
27
101
|
// Public API
|
|
28
102
|
// ---------------------------------------------------------------------------
|
|
29
103
|
/**
|
|
30
|
-
* Detect whether a provider CLI is installed and
|
|
104
|
+
* Detect whether a provider CLI is installed and probe its real auth state.
|
|
31
105
|
*
|
|
32
|
-
* For 'claude': runs `claude --version` to confirm the binary is present
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* (category 'auth').
|
|
106
|
+
* For 'claude': runs `claude --version` to confirm the binary is present, then
|
|
107
|
+
* `claude auth status` (JSON output) to determine real auth state and plan.
|
|
108
|
+
* On spawn failure of the status command, falls back gracefully: installed
|
|
109
|
+
* remains true, authenticated false, plan null.
|
|
37
110
|
*
|
|
38
|
-
* For 'codex': runs `codex --version` to confirm the binary is present
|
|
39
|
-
*
|
|
40
|
-
*
|
|
111
|
+
* For 'codex': runs `codex --version` to confirm the binary is present, then
|
|
112
|
+
* `codex login status` to determine real auth state. Plan is always null because
|
|
113
|
+
* `codex login status` does not expose subscription information.
|
|
114
|
+
* On spawn failure of the status command, falls back gracefully: installed
|
|
115
|
+
* remains true, authenticated false, plan null.
|
|
41
116
|
*/
|
|
42
117
|
export async function detectProvider(id) {
|
|
43
118
|
if (id === 'claude') {
|
|
@@ -47,18 +122,29 @@ export async function detectProvider(id) {
|
|
|
47
122
|
timeout: 10_000,
|
|
48
123
|
});
|
|
49
124
|
if (result.exitCode === 0) {
|
|
125
|
+
// Binary confirmed present — now probe real auth state.
|
|
126
|
+
let authenticated = false;
|
|
127
|
+
let plan = null;
|
|
128
|
+
try {
|
|
129
|
+
const authResult = await execa('claude', ['auth', 'status'], {
|
|
130
|
+
reject: false,
|
|
131
|
+
timeout: 10_000,
|
|
132
|
+
});
|
|
133
|
+
const parsed = parseClaudeAuth(typeof authResult.stdout === 'string' ? authResult.stdout : '', typeof authResult.stderr === 'string' ? authResult.stderr : '', authResult.exitCode ?? 1);
|
|
134
|
+
authenticated = parsed.authenticated;
|
|
135
|
+
plan = parsed.plan;
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
// Spawn failure — leave authenticated false, plan null
|
|
139
|
+
}
|
|
50
140
|
return {
|
|
51
141
|
id: 'claude',
|
|
52
142
|
installed: true,
|
|
53
143
|
version: result.stdout.trim(),
|
|
54
144
|
binaryPath: 'claude',
|
|
55
145
|
availableModels: ['opus', 'sonnet', 'haiku'],
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
* if the binary is installed. The real auth state surfaces at run
|
|
59
|
-
* time when classifyError() maps an auth-related stderr to 'auth'.
|
|
60
|
-
*/
|
|
61
|
-
authenticated: true,
|
|
146
|
+
authenticated,
|
|
147
|
+
plan,
|
|
62
148
|
};
|
|
63
149
|
}
|
|
64
150
|
}
|
|
@@ -67,25 +153,35 @@ export async function detectProvider(id) {
|
|
|
67
153
|
}
|
|
68
154
|
return notDetected('claude');
|
|
69
155
|
}
|
|
70
|
-
// codex: run `codex --version` to probe installation
|
|
156
|
+
// codex: run `codex --version` to probe installation, then `codex login status`
|
|
71
157
|
try {
|
|
72
158
|
const result = await execa('codex', ['--version'], {
|
|
73
159
|
reject: false,
|
|
74
160
|
timeout: 10_000,
|
|
75
161
|
});
|
|
76
162
|
if (result.exitCode === 0) {
|
|
163
|
+
// Binary confirmed present — now probe real auth state.
|
|
164
|
+
let authenticated = false;
|
|
165
|
+
const plan = null; // codex login status never exposes plan
|
|
166
|
+
try {
|
|
167
|
+
const authResult = await execa('codex', ['login', 'status'], {
|
|
168
|
+
reject: false,
|
|
169
|
+
timeout: 10_000,
|
|
170
|
+
});
|
|
171
|
+
const parsed = parseCodexAuth(typeof authResult.stdout === 'string' ? authResult.stdout : '', typeof authResult.stderr === 'string' ? authResult.stderr : '', authResult.exitCode ?? 1);
|
|
172
|
+
authenticated = parsed.authenticated;
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
// Spawn failure — leave authenticated false, plan null
|
|
176
|
+
}
|
|
77
177
|
return {
|
|
78
178
|
id: 'codex',
|
|
79
179
|
installed: true,
|
|
80
180
|
version: result.stdout.trim(),
|
|
81
181
|
binaryPath: 'codex',
|
|
82
182
|
availableModels: ['gpt-5.5', 'gpt-5.4', 'gpt-5.4-mini'],
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
* if the binary is installed. The real auth state surfaces at run
|
|
86
|
-
* time when classifyError() maps an auth-related stderr to 'auth'.
|
|
87
|
-
*/
|
|
88
|
-
authenticated: true,
|
|
183
|
+
authenticated,
|
|
184
|
+
plan,
|
|
89
185
|
};
|
|
90
186
|
}
|
|
91
187
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/providers/detect.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/providers/detect.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/tui.d.ts
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/ui/tui.ts — Terminal UI rendering kit for myshell-tools v2.
|
|
3
|
+
*
|
|
4
|
+
* Zero-dependency pure string builders. Every color-emitting function accepts
|
|
5
|
+
* an explicit `color: boolean` argument; when false, no ANSI escape codes are
|
|
6
|
+
* emitted — safe for CI, pipes, and tests.
|
|
7
|
+
*
|
|
8
|
+
* Ported from dual-brain/src/tui.ts. Self-test block omitted (no I/O, no
|
|
9
|
+
* file reads, no import.meta.url branching). Math.random is never used.
|
|
10
|
+
*
|
|
11
|
+
* Honesty Contract: no hardcoded percentages, no fabricated figures, no mock
|
|
12
|
+
* AI-response phrases.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Strip ANSI escape codes from a string.
|
|
16
|
+
*/
|
|
17
|
+
export declare function stripAnsi(s: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Visible display width of a string.
|
|
20
|
+
* Strips ANSI codes first, then counts emoji/wide symbols as 2 columns.
|
|
21
|
+
*
|
|
22
|
+
* Variation selectors (U+FE00–U+FE0F, including U+FE0F / VS16) are counted
|
|
23
|
+
* as zero-width: a base symbol + VS16 (e.g. ⚠️ = U+26A0 + U+FE0F) renders
|
|
24
|
+
* as a single 2-column glyph in terminals — not 4 columns. Treating the
|
|
25
|
+
* variation selector as zero-width keeps box borders aligned.
|
|
26
|
+
*/
|
|
27
|
+
export declare function visibleLength(s: string): number;
|
|
28
|
+
/**
|
|
29
|
+
* Right-pad `s` with spaces so its visible width equals `width`.
|
|
30
|
+
* Accounts for wide emoji and ANSI codes.
|
|
31
|
+
*/
|
|
32
|
+
export declare function pad(s: string, width: number): string;
|
|
33
|
+
/**
|
|
34
|
+
* Renders a Unicode double-line box with a title bar and optional content lines.
|
|
35
|
+
*
|
|
36
|
+
* @param title - Title displayed in the top section.
|
|
37
|
+
* @param lines - Body lines displayed below the title divider.
|
|
38
|
+
* @param opts - Optional: `width` controls the inner content width (default 56).
|
|
39
|
+
*/
|
|
40
|
+
export declare function box(title: string, lines?: string[], opts?: {
|
|
41
|
+
width?: number;
|
|
42
|
+
}): string;
|
|
43
|
+
/**
|
|
44
|
+
* Renders a percentage progress bar using block characters.
|
|
45
|
+
* Clamps `percent` to 0–100. The percentage value is assembled by
|
|
46
|
+
* concatenation to avoid a digit-immediately-before-% literal in source.
|
|
47
|
+
*
|
|
48
|
+
* @param percent - Value to display (clamped 0–100).
|
|
49
|
+
* @param width - Track width in characters (default 20).
|
|
50
|
+
* @param opts - Optional label appended after the percentage.
|
|
51
|
+
*/
|
|
52
|
+
export declare function bar(percent: number, width?: number, opts?: {
|
|
53
|
+
label?: string;
|
|
54
|
+
}): string;
|
|
55
|
+
/**
|
|
56
|
+
* Returns a status badge emoji for the given status key.
|
|
57
|
+
* Unmapped keys return ❓.
|
|
58
|
+
*/
|
|
59
|
+
export declare function badge(status: string): string;
|
|
60
|
+
/**
|
|
61
|
+
* Returns a section separator line. When a label is provided it is included
|
|
62
|
+
* after the dash run.
|
|
63
|
+
*/
|
|
64
|
+
export declare function separator(label?: string): string;
|
|
65
|
+
/**
|
|
66
|
+
* Renders a menu grouped by section, with section separators.
|
|
67
|
+
* Items with the same `section` value are grouped together.
|
|
68
|
+
* Rows are formatted as ` [key] label`.
|
|
69
|
+
*
|
|
70
|
+
* @param options - Array of menu items; `section` is optional.
|
|
71
|
+
*/
|
|
72
|
+
export declare function menu(options: ReadonlyArray<{
|
|
73
|
+
key: string;
|
|
74
|
+
label: string;
|
|
75
|
+
section?: string;
|
|
76
|
+
}>): string;
|
|
77
|
+
/**
|
|
78
|
+
* Renders a rounded-corner panel box with a title bar.
|
|
79
|
+
*
|
|
80
|
+
* @param title - Panel title.
|
|
81
|
+
* @param content - Content string or array of strings.
|
|
82
|
+
* @param color - When false, no ANSI codes are emitted.
|
|
83
|
+
* @param opts - Optional: `width` (default 70).
|
|
84
|
+
*/
|
|
85
|
+
export declare function panel(title: string, content: string | string[], color: boolean, opts?: {
|
|
86
|
+
width?: number;
|
|
87
|
+
}): string;
|
|
88
|
+
/**
|
|
89
|
+
* Renders a mid-section horizontal divider using rounded-corner tee chars.
|
|
90
|
+
*
|
|
91
|
+
* @param width - Total display width (default: uses full width chars).
|
|
92
|
+
* @param color - When false, no ANSI codes are emitted.
|
|
93
|
+
*/
|
|
94
|
+
export declare function divider(width: number, color: boolean): string;
|
|
95
|
+
/**
|
|
96
|
+
* Renders a small status chip: a colored dot + dim label.
|
|
97
|
+
*
|
|
98
|
+
* @param label - Text label.
|
|
99
|
+
* @param healthy - True → green dot, false → red dot.
|
|
100
|
+
* @param color - When false, no ANSI codes are emitted.
|
|
101
|
+
*/
|
|
102
|
+
export declare function statusChip(label: string, healthy: boolean, color: boolean): string;
|
|
103
|
+
/**
|
|
104
|
+
* Renders a single line with `left` and `right` text separated by spaces to
|
|
105
|
+
* fill the given width.
|
|
106
|
+
*
|
|
107
|
+
* @param left - Left-aligned content (may include ANSI codes).
|
|
108
|
+
* @param right - Right-aligned content (may include ANSI codes).
|
|
109
|
+
* @param width - Total line width (default 70).
|
|
110
|
+
*/
|
|
111
|
+
export declare function headerBar(left: string, right: string, width?: number): string;
|
|
112
|
+
/**
|
|
113
|
+
* Renders a styled prompt line.
|
|
114
|
+
*
|
|
115
|
+
* @param text - Prompt hint text (leading `>` is stripped if present).
|
|
116
|
+
* @param color - When false, no ANSI codes are emitted.
|
|
117
|
+
*/
|
|
118
|
+
export declare function prompt(text: string, color: boolean): string;
|
|
119
|
+
/**
|
|
120
|
+
* Renders a one-line signal/log entry with a type icon.
|
|
121
|
+
*
|
|
122
|
+
* @param type - 'success' | 'warning' | 'info'
|
|
123
|
+
* @param text - Main message text.
|
|
124
|
+
* @param color - When false, no ANSI codes are emitted.
|
|
125
|
+
* @param meta - Optional dim metadata appended at the end.
|
|
126
|
+
*/
|
|
127
|
+
export declare function signalLine(type: 'success' | 'warning' | 'info', text: string, color: boolean, meta?: string): string;
|