myshell-tools 1.0.0 → 2.0.0-alpha.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 +44 -69
- package/LICENSE +21 -21
- package/README.md +178 -318
- package/dist/cli.d.ts +8 -0
- package/dist/cli.js +106 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/cost.d.ts +36 -0
- package/dist/commands/cost.js +103 -0
- package/dist/commands/cost.js.map +1 -0
- package/dist/commands/doctor.d.ts +36 -0
- package/dist/commands/doctor.js +115 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/core/assess.d.ts +25 -0
- package/dist/core/assess.js +142 -0
- package/dist/core/assess.js.map +1 -0
- package/dist/core/classify.d.ts +19 -0
- package/dist/core/classify.js +80 -0
- package/dist/core/classify.js.map +1 -0
- package/dist/core/escalate.d.ts +32 -0
- package/dist/core/escalate.js +57 -0
- package/dist/core/escalate.js.map +1 -0
- package/dist/core/index.d.ts +13 -0
- package/dist/core/index.js +12 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/orchestrate.d.ts +42 -0
- package/dist/core/orchestrate.js +439 -0
- package/dist/core/orchestrate.js.map +1 -0
- package/dist/core/policy.d.ts +9 -0
- package/dist/core/policy.js +27 -0
- package/dist/core/policy.js.map +1 -0
- package/dist/core/prompt.d.ts +26 -0
- package/dist/core/prompt.js +125 -0
- package/dist/core/prompt.js.map +1 -0
- package/dist/core/review.d.ts +46 -0
- package/dist/core/review.js +148 -0
- package/dist/core/review.js.map +1 -0
- package/dist/core/route.d.ts +28 -0
- package/dist/core/route.js +52 -0
- package/dist/core/route.js.map +1 -0
- package/dist/core/types.d.ts +141 -0
- package/dist/core/types.js +14 -0
- package/dist/core/types.js.map +1 -0
- package/dist/infra/atomic.d.ts +53 -0
- package/dist/infra/atomic.js +171 -0
- package/dist/infra/atomic.js.map +1 -0
- package/dist/infra/clock.d.ts +9 -0
- package/dist/infra/clock.js +15 -0
- package/dist/infra/clock.js.map +1 -0
- package/dist/infra/index.d.ts +9 -0
- package/dist/infra/index.js +7 -0
- package/dist/infra/index.js.map +1 -0
- package/dist/infra/ledger.d.ts +49 -0
- package/dist/infra/ledger.js +90 -0
- package/dist/infra/ledger.js.map +1 -0
- package/dist/infra/paths.d.ts +28 -0
- package/dist/infra/paths.js +38 -0
- package/dist/infra/paths.js.map +1 -0
- package/dist/infra/pricing.d.ts +47 -0
- package/dist/infra/pricing.js +151 -0
- package/dist/infra/pricing.js.map +1 -0
- package/dist/infra/session.d.ts +28 -0
- package/dist/infra/session.js +61 -0
- package/dist/infra/session.js.map +1 -0
- package/dist/interface/render.d.ts +27 -0
- package/dist/interface/render.js +134 -0
- package/dist/interface/render.js.map +1 -0
- package/dist/interface/repl.d.ts +23 -0
- package/dist/interface/repl.js +90 -0
- package/dist/interface/repl.js.map +1 -0
- package/dist/interface/run.d.ts +20 -0
- package/dist/interface/run.js +31 -0
- package/dist/interface/run.js.map +1 -0
- package/dist/providers/claude-parse.d.ts +24 -0
- package/dist/providers/claude-parse.js +113 -0
- package/dist/providers/claude-parse.js.map +1 -0
- package/dist/providers/claude.d.ts +45 -0
- package/dist/providers/claude.js +122 -0
- package/dist/providers/claude.js.map +1 -0
- package/dist/providers/codex-parse.d.ts +32 -0
- package/dist/providers/codex-parse.js +145 -0
- package/dist/providers/codex-parse.js.map +1 -0
- package/dist/providers/codex.d.ts +44 -0
- package/dist/providers/codex.js +124 -0
- package/dist/providers/codex.js.map +1 -0
- package/dist/providers/detect.d.ts +49 -0
- package/dist/providers/detect.js +125 -0
- package/dist/providers/detect.js.map +1 -0
- package/dist/providers/errors.d.ts +49 -0
- package/dist/providers/errors.js +189 -0
- package/dist/providers/errors.js.map +1 -0
- package/dist/providers/index.d.ts +9 -0
- package/dist/providers/index.js +7 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/port.d.ts +74 -0
- package/dist/providers/port.js +16 -0
- package/dist/providers/port.js.map +1 -0
- package/dist/providers/registry.d.ts +21 -0
- package/dist/providers/registry.js +34 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/ui/banner.d.ts +19 -0
- package/dist/ui/banner.js +32 -0
- package/dist/ui/banner.js.map +1 -0
- package/dist/ui/spinner.d.ts +27 -0
- package/dist/ui/spinner.js +67 -0
- package/dist/ui/spinner.js.map +1 -0
- package/dist/ui/theme.d.ts +32 -0
- package/dist/ui/theme.js +56 -0
- package/dist/ui/theme.js.map +1 -0
- package/package.json +55 -49
- package/data/orchestrator.json +0 -113
- package/src/auth/recovery.mjs +0 -328
- package/src/auth/refresh.mjs +0 -373
- package/src/chef.mjs +0 -348
- package/src/cli/doctor.mjs +0 -568
- package/src/cli/reset.mjs +0 -447
- package/src/cli/status.mjs +0 -379
- package/src/cli.mjs +0 -429
- package/src/commands/doctor.mjs +0 -375
- package/src/commands/help.mjs +0 -324
- package/src/commands/status.mjs +0 -331
- package/src/monitor/health.mjs +0 -486
- package/src/monitor/performance.mjs +0 -442
- package/src/monitor/report.mjs +0 -535
- package/src/orchestrator/classify.mjs +0 -391
- package/src/orchestrator/confidence.mjs +0 -151
- package/src/orchestrator/handoffs.mjs +0 -231
- package/src/orchestrator/review.mjs +0 -222
- package/src/providers/balance.mjs +0 -201
- package/src/providers/claude.mjs +0 -236
- package/src/providers/codex.mjs +0 -255
- package/src/providers/detect.mjs +0 -185
- package/src/providers/errors.mjs +0 -373
- package/src/providers/select.mjs +0 -162
- package/src/repl-enhanced.mjs +0 -417
- package/src/repl.mjs +0 -321
- package/src/state/archive.mjs +0 -366
- package/src/state/atomic.mjs +0 -116
- package/src/state/cleanup.mjs +0 -440
- package/src/state/recovery.mjs +0 -461
- package/src/state/session.mjs +0 -147
- package/src/ui/errors.mjs +0 -456
- package/src/ui/formatter.mjs +0 -327
- package/src/ui/icons.mjs +0 -318
- package/src/ui/progress.mjs +0 -468
- package/templates/prompts/confidence-format.txt +0 -14
- package/templates/prompts/ic-with-feedback.txt +0 -41
- package/templates/prompts/ic.txt +0 -13
- package/templates/prompts/manager-review.txt +0 -40
- package/templates/prompts/manager.txt +0 -14
- package/templates/prompts/worker.txt +0 -12
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/providers/detect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAsB9B,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,SAAS,WAAW,CAAC,EAAsB;IACzC,OAAO;QACL,EAAE;QACF,SAAS,EAAE,KAAK;QAChB,OAAO,EAAE,IAAI;QACb,aAAa,EAAE,KAAK;QACpB,UAAU,EAAE,IAAI;QAChB,eAAe,EAAE,EAAE;KACpB,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,EAAsB;IAEtB,IAAI,EAAE,KAAK,QAAQ,EAAE,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,EAAE;gBAClD,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE,MAAM;aAChB,CAAC,CAAC;YAEH,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;gBAC1B,OAAO;oBACL,EAAE,EAAE,QAAQ;oBACZ,SAAS,EAAE,IAAI;oBACf,OAAO,EAAG,MAAM,CAAC,MAAiB,CAAC,IAAI,EAAE;oBACzC,UAAU,EAAE,QAAQ;oBACpB,eAAe,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC;oBAC5C;;;;uBAIG;oBACH,aAAa,EAAE,IAAI;iBACpB,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,gEAAgE;QAClE,CAAC;QAED,OAAO,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAED,qDAAqD;IACrD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC,WAAW,CAAC,EAAE;YACjD,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,MAAM;SAChB,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO;gBACL,EAAE,EAAE,OAAO;gBACX,SAAS,EAAE,IAAI;gBACf,OAAO,EAAG,MAAM,CAAC,MAAiB,CAAC,IAAI,EAAE;gBACzC,UAAU,EAAE,OAAO;gBACnB,eAAe,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,cAAc,CAAC;gBACvD;;;;mBAIG;gBACH,aAAa,EAAE,IAAI;aACpB,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,gEAAgE;IAClE,CAAC;IAED,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACxC,cAAc,CAAC,QAAQ,CAAC;QACxB,cAAc,CAAC,OAAO,CAAC;KACxB,CAAC,CAAC;IAEH,OAAO;QACL,MAAM;QACN,KAAK;QACL,cAAc,EAAE,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS;QACnD,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAAsB;IACtD,QAAQ,EAAE,EAAE,CAAC;QACX,KAAK,QAAQ;YACX,OAAO,0CAA0C,CAAC;QACpD,KAAK,OAAO;YACV,OAAO,8BAA8B,CAAC;IAC1C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* errors.ts — Error types, classification, backoff calculation, and message
|
|
3
|
+
* formatting for provider CLI operations.
|
|
4
|
+
*
|
|
5
|
+
* Pure module: no child_process, no fs, no console.log. All functions return
|
|
6
|
+
* data; callers decide how to display or act on it.
|
|
7
|
+
*/
|
|
8
|
+
export type ErrorCategory = 'auth' | 'rate-limit' | 'timeout' | 'network' | 'model' | 'permission' | 'unknown';
|
|
9
|
+
export interface CliError {
|
|
10
|
+
category: ErrorCategory;
|
|
11
|
+
recoverable: boolean;
|
|
12
|
+
message: string;
|
|
13
|
+
suggestion: string;
|
|
14
|
+
}
|
|
15
|
+
export interface BackoffOptions {
|
|
16
|
+
/** Base delay in milliseconds for attempt 0. Defaults to 1000. */
|
|
17
|
+
baseMs?: number;
|
|
18
|
+
/** Multiplier applied each attempt. Defaults to 2. */
|
|
19
|
+
multiplier?: number;
|
|
20
|
+
/** Maximum delay in milliseconds. Defaults to 30_000. */
|
|
21
|
+
maxMs?: number;
|
|
22
|
+
/** Jitter fraction (0–1) applied as random ±fraction of the computed delay. Defaults to 0.15. */
|
|
23
|
+
jitter?: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Calculate how long to wait before the next retry attempt.
|
|
27
|
+
*
|
|
28
|
+
* Returns a value in milliseconds. With jitter the actual value will be within
|
|
29
|
+
* `[(1 - jitter) * delay, (1 + jitter) * delay]` where `delay` is the pure
|
|
30
|
+
* exponential value capped at `maxMs`.
|
|
31
|
+
*
|
|
32
|
+
* @param attempt - Zero-based attempt index (0 = first retry).
|
|
33
|
+
*/
|
|
34
|
+
export declare function calculateBackoff(attempt: number, opts?: BackoffOptions): number;
|
|
35
|
+
/**
|
|
36
|
+
* Classify a CLI failure into a structured {@link CliError}.
|
|
37
|
+
*
|
|
38
|
+
* @param stderr - The stderr output from the CLI process (may be empty).
|
|
39
|
+
* @param exitCode - The numeric exit code of the process.
|
|
40
|
+
*/
|
|
41
|
+
export declare function classifyError(stderr: string, exitCode: number): CliError;
|
|
42
|
+
/**
|
|
43
|
+
* Format a {@link CliError} into a human-readable string suitable for display.
|
|
44
|
+
* Does not include ANSI codes so it works in any context.
|
|
45
|
+
*
|
|
46
|
+
* @param error - A classified CLI error.
|
|
47
|
+
* @param provider - Optional provider name for contextual detail (e.g. `'claude'`).
|
|
48
|
+
*/
|
|
49
|
+
export declare function formatErrorMessage(error: CliError, provider?: string): string;
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* errors.ts — Error types, classification, backoff calculation, and message
|
|
3
|
+
* formatting for provider CLI operations.
|
|
4
|
+
*
|
|
5
|
+
* Pure module: no child_process, no fs, no console.log. All functions return
|
|
6
|
+
* data; callers decide how to display or act on it.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Calculate how long to wait before the next retry attempt.
|
|
10
|
+
*
|
|
11
|
+
* Returns a value in milliseconds. With jitter the actual value will be within
|
|
12
|
+
* `[(1 - jitter) * delay, (1 + jitter) * delay]` where `delay` is the pure
|
|
13
|
+
* exponential value capped at `maxMs`.
|
|
14
|
+
*
|
|
15
|
+
* @param attempt - Zero-based attempt index (0 = first retry).
|
|
16
|
+
*/
|
|
17
|
+
export function calculateBackoff(attempt, opts) {
|
|
18
|
+
const baseMs = opts?.baseMs ?? 1000;
|
|
19
|
+
const multiplier = opts?.multiplier ?? 2;
|
|
20
|
+
const maxMs = opts?.maxMs ?? 30_000;
|
|
21
|
+
const jitter = opts?.jitter ?? 0.15;
|
|
22
|
+
const exponential = Math.min(baseMs * multiplier ** attempt, maxMs);
|
|
23
|
+
const spread = exponential * jitter;
|
|
24
|
+
// Random value in [-spread, +spread]
|
|
25
|
+
const noise = (Math.random() * 2 - 1) * spread;
|
|
26
|
+
return Math.round(Math.max(0, exponential + noise));
|
|
27
|
+
}
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Internal pattern helpers
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
function includesAny(text, patterns) {
|
|
32
|
+
return patterns.some((p) => text.includes(p));
|
|
33
|
+
}
|
|
34
|
+
function isAuthStderr(lower) {
|
|
35
|
+
// token-related matches require a companion word to avoid false positives
|
|
36
|
+
const tokenExpired = lower.includes('token') && (lower.includes('expired') || lower.includes('invalid'));
|
|
37
|
+
return (tokenExpired ||
|
|
38
|
+
includesAny(lower, [
|
|
39
|
+
'authentication',
|
|
40
|
+
'unauthorized',
|
|
41
|
+
'401',
|
|
42
|
+
'invalid credentials',
|
|
43
|
+
'login required',
|
|
44
|
+
]));
|
|
45
|
+
}
|
|
46
|
+
function isRateLimitStderr(lower) {
|
|
47
|
+
const quotaExceeded = lower.includes('quota') && lower.includes('exceeded');
|
|
48
|
+
return (quotaExceeded || includesAny(lower, ['rate limit', '429', 'too many requests']));
|
|
49
|
+
}
|
|
50
|
+
function isTimeoutStderr(lower) {
|
|
51
|
+
// Exclude HTTP gateway codes (502/503/504) — those are network errors even
|
|
52
|
+
// though '504 Gateway Timeout' contains the word 'timeout'.
|
|
53
|
+
if (includesAny(lower, ['502', '503', '504']))
|
|
54
|
+
return false;
|
|
55
|
+
return includesAny(lower, ['timeout', 'timed out', 'deadline exceeded']);
|
|
56
|
+
}
|
|
57
|
+
function isNetworkStderr(lower) {
|
|
58
|
+
return includesAny(lower, [
|
|
59
|
+
'network',
|
|
60
|
+
'enotfound',
|
|
61
|
+
'econnreset',
|
|
62
|
+
'econnrefused',
|
|
63
|
+
'enetunreach',
|
|
64
|
+
'502',
|
|
65
|
+
'503',
|
|
66
|
+
'504',
|
|
67
|
+
'internal server error',
|
|
68
|
+
]);
|
|
69
|
+
}
|
|
70
|
+
function isModelStderr(lower) {
|
|
71
|
+
return includesAny(lower, [
|
|
72
|
+
'model not found',
|
|
73
|
+
'model does not exist',
|
|
74
|
+
'unsupported model',
|
|
75
|
+
'invalid model',
|
|
76
|
+
'context length',
|
|
77
|
+
'context window',
|
|
78
|
+
]);
|
|
79
|
+
}
|
|
80
|
+
function isPermissionStderr(lower, exitCode) {
|
|
81
|
+
return (exitCode === 126 ||
|
|
82
|
+
includesAny(lower, [
|
|
83
|
+
'permission denied',
|
|
84
|
+
'access denied',
|
|
85
|
+
'forbidden',
|
|
86
|
+
'403',
|
|
87
|
+
]));
|
|
88
|
+
}
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
// Per-category error descriptors
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
const CATEGORY_DESCRIPTORS = {
|
|
93
|
+
auth: {
|
|
94
|
+
recoverable: false,
|
|
95
|
+
message: 'Authentication failed.',
|
|
96
|
+
suggestion: 'Re-authenticate with the CLI (e.g. `claude auth login` or `codex login`) and try again.',
|
|
97
|
+
},
|
|
98
|
+
'rate-limit': {
|
|
99
|
+
recoverable: true,
|
|
100
|
+
message: 'Rate limit or quota exceeded.',
|
|
101
|
+
suggestion: 'Wait before retrying. Consider using a different model tier or reducing request frequency.',
|
|
102
|
+
},
|
|
103
|
+
timeout: {
|
|
104
|
+
recoverable: true,
|
|
105
|
+
message: 'The request timed out.',
|
|
106
|
+
suggestion: 'Simplify the request or increase the timeout threshold and retry.',
|
|
107
|
+
},
|
|
108
|
+
network: {
|
|
109
|
+
recoverable: true,
|
|
110
|
+
message: 'A network or server connectivity error occurred.',
|
|
111
|
+
suggestion: 'Check your internet connection. The server may be temporarily unavailable.',
|
|
112
|
+
},
|
|
113
|
+
model: {
|
|
114
|
+
recoverable: false,
|
|
115
|
+
message: 'The requested model is unavailable or the context limit was exceeded.',
|
|
116
|
+
suggestion: 'Verify the model name is correct, or shorten the input to fit within the context window.',
|
|
117
|
+
},
|
|
118
|
+
permission: {
|
|
119
|
+
recoverable: false,
|
|
120
|
+
message: 'Permission or access denied.',
|
|
121
|
+
suggestion: 'Verify your account has access to the requested resource or operation.',
|
|
122
|
+
},
|
|
123
|
+
unknown: {
|
|
124
|
+
recoverable: false,
|
|
125
|
+
message: 'An unexpected error occurred.',
|
|
126
|
+
suggestion: 'Review the stderr output for details. If the problem persists, report it with the full error text.',
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// Public classification function
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
/**
|
|
133
|
+
* Classify a CLI failure into a structured {@link CliError}.
|
|
134
|
+
*
|
|
135
|
+
* @param stderr - The stderr output from the CLI process (may be empty).
|
|
136
|
+
* @param exitCode - The numeric exit code of the process.
|
|
137
|
+
*/
|
|
138
|
+
export function classifyError(stderr, exitCode) {
|
|
139
|
+
const lower = stderr.toLowerCase();
|
|
140
|
+
let category;
|
|
141
|
+
if (isAuthStderr(lower)) {
|
|
142
|
+
category = 'auth';
|
|
143
|
+
}
|
|
144
|
+
else if (isRateLimitStderr(lower)) {
|
|
145
|
+
category = 'rate-limit';
|
|
146
|
+
}
|
|
147
|
+
else if (isTimeoutStderr(lower)) {
|
|
148
|
+
category = 'timeout';
|
|
149
|
+
}
|
|
150
|
+
else if (isNetworkStderr(lower)) {
|
|
151
|
+
category = 'network';
|
|
152
|
+
}
|
|
153
|
+
else if (isModelStderr(lower)) {
|
|
154
|
+
category = 'model';
|
|
155
|
+
}
|
|
156
|
+
else if (isPermissionStderr(lower, exitCode)) {
|
|
157
|
+
category = 'permission';
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
category = 'unknown';
|
|
161
|
+
}
|
|
162
|
+
const descriptor = CATEGORY_DESCRIPTORS[category];
|
|
163
|
+
return {
|
|
164
|
+
category,
|
|
165
|
+
recoverable: descriptor.recoverable,
|
|
166
|
+
message: descriptor.message,
|
|
167
|
+
suggestion: descriptor.suggestion,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
// ---------------------------------------------------------------------------
|
|
171
|
+
// Friendly message formatting
|
|
172
|
+
// ---------------------------------------------------------------------------
|
|
173
|
+
/**
|
|
174
|
+
* Format a {@link CliError} into a human-readable string suitable for display.
|
|
175
|
+
* Does not include ANSI codes so it works in any context.
|
|
176
|
+
*
|
|
177
|
+
* @param error - A classified CLI error.
|
|
178
|
+
* @param provider - Optional provider name for contextual detail (e.g. `'claude'`).
|
|
179
|
+
*/
|
|
180
|
+
export function formatErrorMessage(error, provider) {
|
|
181
|
+
const label = provider ? provider.toUpperCase() : 'CLI';
|
|
182
|
+
const lines = [`${label} Error [${error.category}]: ${error.message}`];
|
|
183
|
+
lines.push(`Suggestion: ${error.suggestion}`);
|
|
184
|
+
if (error.recoverable) {
|
|
185
|
+
lines.push('This error may be transient. Retrying with backoff is appropriate.');
|
|
186
|
+
}
|
|
187
|
+
return lines.join('\n');
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/providers/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { classifyError, calculateBackoff, formatErrorMessage } from './errors.js';
|
|
2
|
+
export type { CliError, ErrorCategory, BackoffOptions } from './errors.js';
|
|
3
|
+
export { detectProvider, detectEnvironment, getInstallCommand } from './detect.js';
|
|
4
|
+
export type { ProviderStatus, EnvironmentStatus } from './detect.js';
|
|
5
|
+
export type { Provider, ProviderEvent, ProviderRequest, Usage, SandboxLevel, ProviderId, } from './port.js';
|
|
6
|
+
export { createClaudeProvider, toClaudeModelArg } from './claude.js';
|
|
7
|
+
export { parseClaudeLine } from './claude-parse.js';
|
|
8
|
+
export { createCodexProvider, toSandboxArg } from './codex.js';
|
|
9
|
+
export { createCodexParser } from './codex-parse.js';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { classifyError, calculateBackoff, formatErrorMessage } from './errors.js';
|
|
2
|
+
export { detectProvider, detectEnvironment, getInstallCommand } from './detect.js';
|
|
3
|
+
export { createClaudeProvider, toClaudeModelArg } from './claude.js';
|
|
4
|
+
export { parseClaudeLine } from './claude-parse.js';
|
|
5
|
+
export { createCodexProvider, toSandboxArg } from './codex.js';
|
|
6
|
+
export { createCodexParser } from './codex-parse.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAElF,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAUnF,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/providers/port.ts — the Provider port (the keystone interface).
|
|
3
|
+
*
|
|
4
|
+
* The orchestration core talks to this interface and nothing vendor-specific.
|
|
5
|
+
* Claude and Codex each ship an adapter that implements `Provider`.
|
|
6
|
+
*
|
|
7
|
+
* Design contract:
|
|
8
|
+
* - `run()` returns an AsyncIterable so the UI can stream real tokens/tools as
|
|
9
|
+
* they arrive and the core can compute real cost from the `usage` event.
|
|
10
|
+
* - The prompt in `ProviderRequest` is delivered to the child process via STDIN
|
|
11
|
+
* (never as a shell argument) — see spawn.ts.
|
|
12
|
+
* - `model` is always a concrete model id (resolved from an alias before this
|
|
13
|
+
* layer), never a tier name or alias.
|
|
14
|
+
*/
|
|
15
|
+
import type { CliError } from './errors.js';
|
|
16
|
+
import type { ProviderStatus } from './detect.js';
|
|
17
|
+
export type { CliError } from './errors.js';
|
|
18
|
+
/** Privilege ladder mapped onto each CLI's sandbox flags. Default is workspace-write. */
|
|
19
|
+
export type SandboxLevel = 'read-only' | 'workspace-write' | 'full-access';
|
|
20
|
+
export type ProviderId = 'claude' | 'codex';
|
|
21
|
+
export interface Usage {
|
|
22
|
+
readonly inputTokens: number;
|
|
23
|
+
readonly outputTokens: number;
|
|
24
|
+
readonly cachedInputTokens?: number;
|
|
25
|
+
}
|
|
26
|
+
export interface ProviderRequest {
|
|
27
|
+
/** Concrete model id, e.g. 'claude-sonnet-4-6' (never an alias at this layer). */
|
|
28
|
+
readonly model: string;
|
|
29
|
+
/** The full prompt; delivered via STDIN, not argv. */
|
|
30
|
+
readonly prompt: string;
|
|
31
|
+
/** Working directory the model operates in. */
|
|
32
|
+
readonly cwd: string;
|
|
33
|
+
/** Privilege level for model-initiated actions. */
|
|
34
|
+
readonly sandbox: SandboxLevel;
|
|
35
|
+
/** Hard wall-clock timeout for the run. */
|
|
36
|
+
readonly timeoutMs: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Streaming events emitted by a provider run. Discriminated on `type`.
|
|
40
|
+
* The terminal event is exactly one of `done` or `error`.
|
|
41
|
+
*/
|
|
42
|
+
export type ProviderEvent = {
|
|
43
|
+
readonly type: 'text';
|
|
44
|
+
readonly delta: string;
|
|
45
|
+
} | {
|
|
46
|
+
readonly type: 'reasoning';
|
|
47
|
+
readonly delta: string;
|
|
48
|
+
} | {
|
|
49
|
+
readonly type: 'tool';
|
|
50
|
+
readonly name: string;
|
|
51
|
+
readonly phase: 'start' | 'end';
|
|
52
|
+
readonly detail?: string;
|
|
53
|
+
} | {
|
|
54
|
+
readonly type: 'usage';
|
|
55
|
+
readonly usage: Usage;
|
|
56
|
+
} | {
|
|
57
|
+
readonly type: 'done';
|
|
58
|
+
readonly text: string;
|
|
59
|
+
readonly usage?: Usage;
|
|
60
|
+
/** Cost in USD as reported by the provider CLI, when available (preferred
|
|
61
|
+
* over estimating from the pricing table — it accounts for caching etc.). */
|
|
62
|
+
readonly costUsd?: number;
|
|
63
|
+
readonly raw: unknown;
|
|
64
|
+
} | {
|
|
65
|
+
readonly type: 'error';
|
|
66
|
+
readonly error: CliError;
|
|
67
|
+
};
|
|
68
|
+
export interface Provider {
|
|
69
|
+
readonly id: ProviderId;
|
|
70
|
+
/** Probe install/auth/version/models. Cheap and cached by the adapter. */
|
|
71
|
+
detect(): Promise<ProviderStatus>;
|
|
72
|
+
/** Execute one request, streaming events until a terminal `done`/`error`. */
|
|
73
|
+
run(req: ProviderRequest, signal: AbortSignal): AsyncIterable<ProviderEvent>;
|
|
74
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/providers/port.ts — the Provider port (the keystone interface).
|
|
3
|
+
*
|
|
4
|
+
* The orchestration core talks to this interface and nothing vendor-specific.
|
|
5
|
+
* Claude and Codex each ship an adapter that implements `Provider`.
|
|
6
|
+
*
|
|
7
|
+
* Design contract:
|
|
8
|
+
* - `run()` returns an AsyncIterable so the UI can stream real tokens/tools as
|
|
9
|
+
* they arrive and the core can compute real cost from the `usage` event.
|
|
10
|
+
* - The prompt in `ProviderRequest` is delivered to the child process via STDIN
|
|
11
|
+
* (never as a shell argument) — see spawn.ts.
|
|
12
|
+
* - `model` is always a concrete model id (resolved from an alias before this
|
|
13
|
+
* layer), never a tier name or alias.
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=port.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"port.js","sourceRoot":"","sources":["../../src/providers/port.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/providers/registry.ts — provider registry for the CLI.
|
|
3
|
+
*
|
|
4
|
+
* Builds the Partial<Record<ProviderId, Provider>> map consumed by
|
|
5
|
+
* OrchestrateDeps. Each provider registers when `installed` is true — we gate
|
|
6
|
+
* on `installed`, NOT `authenticated`, because auth is only truly known at
|
|
7
|
+
* call time and errors render honestly via classifyError().
|
|
8
|
+
*
|
|
9
|
+
* With both Claude and Codex installed, `deps.providers` will have entries for
|
|
10
|
+
* both — which automatically activates cross-vendor review in the orchestrator.
|
|
11
|
+
*/
|
|
12
|
+
import type { Provider, ProviderId } from './port.js';
|
|
13
|
+
/**
|
|
14
|
+
* Discover which providers are available in the current environment and build
|
|
15
|
+
* the provider map for OrchestrateDeps.
|
|
16
|
+
*
|
|
17
|
+
* @param _cwd - Working directory (used by real adapters to locate project-
|
|
18
|
+
* level config; may be forwarded to adapters in a future phase).
|
|
19
|
+
* @returns A (possibly empty) map of available providers.
|
|
20
|
+
*/
|
|
21
|
+
export declare function buildProviders(_cwd: string): Promise<Partial<Record<ProviderId, Provider>>>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/providers/registry.ts — provider registry for the CLI.
|
|
3
|
+
*
|
|
4
|
+
* Builds the Partial<Record<ProviderId, Provider>> map consumed by
|
|
5
|
+
* OrchestrateDeps. Each provider registers when `installed` is true — we gate
|
|
6
|
+
* on `installed`, NOT `authenticated`, because auth is only truly known at
|
|
7
|
+
* call time and errors render honestly via classifyError().
|
|
8
|
+
*
|
|
9
|
+
* With both Claude and Codex installed, `deps.providers` will have entries for
|
|
10
|
+
* both — which automatically activates cross-vendor review in the orchestrator.
|
|
11
|
+
*/
|
|
12
|
+
import { detectEnvironment } from './detect.js';
|
|
13
|
+
import { createClaudeProvider } from './claude.js';
|
|
14
|
+
import { createCodexProvider } from './codex.js';
|
|
15
|
+
/**
|
|
16
|
+
* Discover which providers are available in the current environment and build
|
|
17
|
+
* the provider map for OrchestrateDeps.
|
|
18
|
+
*
|
|
19
|
+
* @param _cwd - Working directory (used by real adapters to locate project-
|
|
20
|
+
* level config; may be forwarded to adapters in a future phase).
|
|
21
|
+
* @returns A (possibly empty) map of available providers.
|
|
22
|
+
*/
|
|
23
|
+
export async function buildProviders(_cwd) {
|
|
24
|
+
const env = await detectEnvironment();
|
|
25
|
+
const providers = {};
|
|
26
|
+
if (env.claude.installed) {
|
|
27
|
+
providers.claude = createClaudeProvider();
|
|
28
|
+
}
|
|
29
|
+
if (env.codex.installed) {
|
|
30
|
+
providers.codex = createCodexProvider();
|
|
31
|
+
}
|
|
32
|
+
return providers;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/providers/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,IAAY;IAEZ,MAAM,GAAG,GAAG,MAAM,iBAAiB,EAAE,CAAC;IACtC,MAAM,SAAS,GAA0C,EAAE,CAAC;IAE5D,IAAI,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACzB,SAAS,CAAC,MAAM,GAAG,oBAAoB,EAAE,CAAC;IAC5C,CAAC;IAED,IAAI,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QACxB,SAAS,CAAC,KAAK,GAAG,mBAAmB,EAAE,CAAC;IAC1C,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/ui/banner.ts — Compact product banner for myshell-tools-sh.
|
|
3
|
+
*
|
|
4
|
+
* Renders a tasteful multi-line banner showing the product name, real version,
|
|
5
|
+
* and a one-line tagline. The version is always supplied by the caller (no
|
|
6
|
+
* hardcoded value). No fake stats, no fabricated figures.
|
|
7
|
+
*
|
|
8
|
+
* Honesty Contract: this file contains no hardcoded percentages, no fabricated
|
|
9
|
+
* figures, and no mock phrases.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Build a compact product banner string.
|
|
13
|
+
*
|
|
14
|
+
* @param version - The real semver string for this release (e.g. '1.2.3').
|
|
15
|
+
* @param color - When false, no ANSI escape codes are emitted.
|
|
16
|
+
* @returns A multi-line banner string (does not end with a newline beyond the
|
|
17
|
+
* last line so the caller controls spacing).
|
|
18
|
+
*/
|
|
19
|
+
export declare function banner(version: string, color: boolean): string;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/ui/banner.ts — Compact product banner for myshell-tools-sh.
|
|
3
|
+
*
|
|
4
|
+
* Renders a tasteful multi-line banner showing the product name, real version,
|
|
5
|
+
* and a one-line tagline. The version is always supplied by the caller (no
|
|
6
|
+
* hardcoded value). No fake stats, no fabricated figures.
|
|
7
|
+
*
|
|
8
|
+
* Honesty Contract: this file contains no hardcoded percentages, no fabricated
|
|
9
|
+
* figures, and no mock phrases.
|
|
10
|
+
*/
|
|
11
|
+
import { bold, cyan, dim } from './theme.js';
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Banner
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
/**
|
|
16
|
+
* Build a compact product banner string.
|
|
17
|
+
*
|
|
18
|
+
* @param version - The real semver string for this release (e.g. '1.2.3').
|
|
19
|
+
* @param color - When false, no ANSI escape codes are emitted.
|
|
20
|
+
* @returns A multi-line banner string (does not end with a newline beyond the
|
|
21
|
+
* last line so the caller controls spacing).
|
|
22
|
+
*/
|
|
23
|
+
export function banner(version, color) {
|
|
24
|
+
const name = bold(cyan('myshell-tools', color), color);
|
|
25
|
+
const ver = dim(`v${version}`, color);
|
|
26
|
+
const tag = dim('AI task orchestrator — honest, tier-aware, streaming', color);
|
|
27
|
+
return [
|
|
28
|
+
`${name} ${ver}`,
|
|
29
|
+
tag,
|
|
30
|
+
].join('\n');
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=banner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"banner.js","sourceRoot":"","sources":["../../src/ui/banner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAE7C,8EAA8E;AAC9E,SAAS;AACT,8EAA8E;AAE9E;;;;;;;GAOG;AACH,MAAM,UAAU,MAAM,CAAC,OAAe,EAAE,KAAc;IACpD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;IACvD,MAAM,GAAG,GAAI,GAAG,CAAC,IAAI,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;IACvC,MAAM,GAAG,GAAI,GAAG,CAAC,sDAAsD,EAAE,KAAK,CAAC,CAAC;IAEhF,OAAO;QACL,GAAG,IAAI,IAAI,GAAG,EAAE;QAChB,GAAG;KACJ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/ui/spinner.ts — Honest, indeterminate working indicator.
|
|
3
|
+
*
|
|
4
|
+
* Animates a braille-spinner frame while waiting for the first real output.
|
|
5
|
+
* No percentages, no fake progress — purely a "working" indicator.
|
|
6
|
+
* Frame cycling is deterministic (index-based); Math.random is never used.
|
|
7
|
+
*
|
|
8
|
+
* Honesty Contract: this file contains no hardcoded percentages, no fabricated
|
|
9
|
+
* figures, and no mock phrases.
|
|
10
|
+
*/
|
|
11
|
+
import type { OutputSink } from '../interface/render.js';
|
|
12
|
+
/** A minimal working-indicator that can be started and stopped. */
|
|
13
|
+
export interface Spinner {
|
|
14
|
+
/** Display the spinner with the given text. */
|
|
15
|
+
start(text: string): void;
|
|
16
|
+
/** Stop the spinner and clear the line (TTY) or do nothing (non-TTY). */
|
|
17
|
+
stop(): void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Create a spinner bound to the given OutputSink.
|
|
21
|
+
*
|
|
22
|
+
* - When `out.isTty` is true: animates braille frames + text on the current
|
|
23
|
+
* line using `\r`, driven by `setInterval`.
|
|
24
|
+
* - When `out.isTty` is false: prints the text once (static) and does nothing
|
|
25
|
+
* on stop — safe for CI / pipe output.
|
|
26
|
+
*/
|
|
27
|
+
export declare function createSpinner(out: OutputSink): Spinner;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/ui/spinner.ts — Honest, indeterminate working indicator.
|
|
3
|
+
*
|
|
4
|
+
* Animates a braille-spinner frame while waiting for the first real output.
|
|
5
|
+
* No percentages, no fake progress — purely a "working" indicator.
|
|
6
|
+
* Frame cycling is deterministic (index-based); Math.random is never used.
|
|
7
|
+
*
|
|
8
|
+
* Honesty Contract: this file contains no hardcoded percentages, no fabricated
|
|
9
|
+
* figures, and no mock phrases.
|
|
10
|
+
*/
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Frame set (braille dots — deterministic cycle, no Math.random)
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
const FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
15
|
+
const FRAME_INTERVAL_MS = 80;
|
|
16
|
+
/**
|
|
17
|
+
* Create a spinner bound to the given OutputSink.
|
|
18
|
+
*
|
|
19
|
+
* - When `out.isTty` is true: animates braille frames + text on the current
|
|
20
|
+
* line using `\r`, driven by `setInterval`.
|
|
21
|
+
* - When `out.isTty` is false: prints the text once (static) and does nothing
|
|
22
|
+
* on stop — safe for CI / pipe output.
|
|
23
|
+
*/
|
|
24
|
+
export function createSpinner(out) {
|
|
25
|
+
let frameIndex = 0;
|
|
26
|
+
let timer = null;
|
|
27
|
+
let active = false;
|
|
28
|
+
/** Exposed for deterministic testing: advance one frame and write it. */
|
|
29
|
+
function tick(text) {
|
|
30
|
+
frameIndex = (frameIndex + 1) % FRAMES.length;
|
|
31
|
+
const frame = FRAMES[frameIndex] ?? FRAMES[0] ?? '⠋';
|
|
32
|
+
out.write(`\r${frame} ${text}`);
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
start(text) {
|
|
36
|
+
if (active)
|
|
37
|
+
return;
|
|
38
|
+
active = true;
|
|
39
|
+
if (out.isTty) {
|
|
40
|
+
// Write the first frame immediately so there is no blank gap.
|
|
41
|
+
const frame = FRAMES[frameIndex] ?? FRAMES[0] ?? '⠋';
|
|
42
|
+
out.write(`\r${frame} ${text}`);
|
|
43
|
+
timer = setInterval(() => {
|
|
44
|
+
tick(text);
|
|
45
|
+
}, FRAME_INTERVAL_MS);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// Non-TTY: print once, no animation.
|
|
49
|
+
out.write(`${text}\n`);
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
stop() {
|
|
53
|
+
if (!active)
|
|
54
|
+
return;
|
|
55
|
+
active = false;
|
|
56
|
+
if (timer !== null) {
|
|
57
|
+
clearInterval(timer);
|
|
58
|
+
timer = null;
|
|
59
|
+
}
|
|
60
|
+
if (out.isTty) {
|
|
61
|
+
// Clear the spinner line so the real output follows cleanly.
|
|
62
|
+
out.write('\r\x1b[K');
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=spinner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/ui/spinner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,8EAA8E;AAC9E,iEAAiE;AACjE,8EAA8E;AAE9E,MAAM,MAAM,GAAsB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AACrF,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAc7B;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,GAAe;IAC3C,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,KAAK,GAA0C,IAAI,CAAC;IACxD,IAAI,MAAM,GAAG,KAAK,CAAC;IAEnB,yEAAyE;IACzE,SAAS,IAAI,CAAC,IAAY;QACxB,UAAU,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;QAC9C,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;QACrD,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,EAAE,CAAC,CAAC;IAClC,CAAC;IAED,OAAO;QACL,KAAK,CAAC,IAAY;YAChB,IAAI,MAAM;gBAAE,OAAO;YACnB,MAAM,GAAG,IAAI,CAAC;YAEd,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;gBACd,8DAA8D;gBAC9D,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;gBACrD,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,EAAE,CAAC,CAAC;gBAEhC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;oBACvB,IAAI,CAAC,IAAI,CAAC,CAAC;gBACb,CAAC,EAAE,iBAAiB,CAAC,CAAC;YACxB,CAAC;iBAAM,CAAC;gBACN,qCAAqC;gBACrC,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QAED,IAAI;YACF,IAAI,CAAC,MAAM;gBAAE,OAAO;YACpB,MAAM,GAAG,KAAK,CAAC;YAEf,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACnB,aAAa,CAAC,KAAK,CAAC,CAAC;gBACrB,KAAK,GAAG,IAAI,CAAC;YACf,CAAC;YAED,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;gBACd,6DAA6D;gBAC7D,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/ui/theme.ts — Centralised ANSI colour / format helpers.
|
|
3
|
+
*
|
|
4
|
+
* Every helper accepts a `color` boolean flag. When false the text is returned
|
|
5
|
+
* unchanged, which honours NO_COLOR and non-TTY contexts. No other module in
|
|
6
|
+
* the project should hardcode ANSI escape codes.
|
|
7
|
+
*
|
|
8
|
+
* Honesty contract: this file contains no hardcoded percentages, no fabricated
|
|
9
|
+
* figures, and no mock phrases.
|
|
10
|
+
*/
|
|
11
|
+
/** Dim / faint text. */
|
|
12
|
+
export declare function dim(text: string, color: boolean): string;
|
|
13
|
+
/** Bold text. */
|
|
14
|
+
export declare function bold(text: string, color: boolean): string;
|
|
15
|
+
/** Green text (success / ok). */
|
|
16
|
+
export declare function green(text: string, color: boolean): string;
|
|
17
|
+
/** Red text (failure / error). */
|
|
18
|
+
export declare function red(text: string, color: boolean): string;
|
|
19
|
+
/** Yellow text (warning / caution). */
|
|
20
|
+
export declare function yellow(text: string, color: boolean): string;
|
|
21
|
+
/** Cyan text (informational accent). */
|
|
22
|
+
export declare function cyan(text: string, color: boolean): string;
|
|
23
|
+
/**
|
|
24
|
+
* Render a labelled key in a key/value pair.
|
|
25
|
+
* e.g. `label('Status', true)` → bold cyan "Status"
|
|
26
|
+
*/
|
|
27
|
+
export declare function label(text: string, color: boolean): string;
|
|
28
|
+
/**
|
|
29
|
+
* Return a horizontal rule of the given width (default 40).
|
|
30
|
+
* The divider is dim when colour is enabled.
|
|
31
|
+
*/
|
|
32
|
+
export declare function divider(color: boolean, width?: number): string;
|