claude-code-infinite 1.0.25 → 1.0.26
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 +35 -4
- package/dist/auto-update-runner.d.ts +13 -0
- package/dist/auto-update-runner.d.ts.map +1 -1
- package/dist/auto-update-runner.js +51 -7
- package/dist/auto-update-runner.js.map +1 -1
- package/dist/auto-update-setup.d.ts +19 -3
- package/dist/auto-update-setup.d.ts.map +1 -1
- package/dist/auto-update-setup.js +42 -16
- package/dist/auto-update-setup.js.map +1 -1
- package/dist/auto-update.d.ts +59 -6
- package/dist/auto-update.d.ts.map +1 -1
- package/dist/auto-update.js +207 -40
- package/dist/auto-update.js.map +1 -1
- package/dist/claude-auth.d.ts +47 -0
- package/dist/claude-auth.d.ts.map +1 -0
- package/dist/claude-auth.js +171 -0
- package/dist/claude-auth.js.map +1 -0
- package/dist/claude-locate.d.ts +62 -0
- package/dist/claude-locate.d.ts.map +1 -0
- package/dist/claude-locate.js +224 -0
- package/dist/claude-locate.js.map +1 -0
- package/dist/cli-main.js +103 -15
- package/dist/cli-main.js.map +1 -1
- package/dist/cli.js +7 -1
- package/dist/cli.js.map +1 -1
- package/dist/diagnostics-schema.d.ts +9 -1
- package/dist/diagnostics-schema.d.ts.map +1 -1
- package/dist/diagnostics-schema.js +26 -1
- package/dist/diagnostics-schema.js.map +1 -1
- package/dist/diagnostics.d.ts +5 -1
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js +17 -1
- package/dist/diagnostics.js.map +1 -1
- package/dist/memtree-mcp.d.ts.map +1 -1
- package/dist/memtree-mcp.js +8 -5
- package/dist/memtree-mcp.js.map +1 -1
- package/dist/notices.d.ts.map +1 -1
- package/dist/notices.js +3 -2
- package/dist/notices.js.map +1 -1
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +7 -0
- package/dist/proxy.js.map +1 -1
- package/dist/reqlog.d.ts +7 -0
- package/dist/reqlog.d.ts.map +1 -1
- package/dist/reqlog.js.map +1 -1
- package/dist/resume-repair.d.ts +2 -0
- package/dist/resume-repair.d.ts.map +1 -1
- package/dist/resume-repair.js +7 -5
- package/dist/resume-repair.js.map +1 -1
- package/dist/update-check.d.ts +2 -0
- package/dist/update-check.d.ts.map +1 -1
- package/dist/update-check.js.map +1 -1
- package/dist/update-lock.js +3 -1
- package/dist/update-lock.js.map +1 -1
- package/dist/update-wait.d.ts +25 -0
- package/dist/update-wait.d.ts.map +1 -0
- package/dist/update-wait.js +63 -0
- package/dist/update-wait.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How Claude Code is signed in, as a type only (and, for a Claude.ai login,
|
|
3
|
+
* the plan tier's name), for diagnostics and for one notice: `subscription` (a Claude.ai login, Pro/Max), `api_key`
|
|
4
|
+
* (ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, an apiKeyHelper or a Console key),
|
|
5
|
+
* `bedrock`, `vertex`, `foundry`, or `unknown`.
|
|
6
|
+
*
|
|
7
|
+
* No secret or account identifier is ever kept or sent. At startup the answer
|
|
8
|
+
* comes from env variable names being set, settings keys being present and
|
|
9
|
+
* `~/.claude.json` naming an `oauthAccount` (whose contents are not read out).
|
|
10
|
+
* Once Claude Code sends a request through the proxy, its auth header's shape
|
|
11
|
+
* decides it: an OAuth token (`sk-ant-oat…`) is a subscription, an
|
|
12
|
+
* `x-api-key` or `sk-ant-api…` bearer is an API key. Only that classification
|
|
13
|
+
* leaves this module.
|
|
14
|
+
*/
|
|
15
|
+
import * as fs from "node:fs";
|
|
16
|
+
import * as os from "node:os";
|
|
17
|
+
import * as path from "node:path";
|
|
18
|
+
export const CLAUDE_AUTH_TYPES = [
|
|
19
|
+
"subscription", "api_key", "bedrock", "vertex", "foundry", "unknown",
|
|
20
|
+
];
|
|
21
|
+
/** A Claude.ai plan tier, by name only. */
|
|
22
|
+
export const CLAUDE_PLANS = [
|
|
23
|
+
"free", "pro", "max", "max_5x", "max_20x", "team", "enterprise", "unknown",
|
|
24
|
+
];
|
|
25
|
+
/** Anthropic's 400 for an API key whose organization has no credit left. */
|
|
26
|
+
export const CREDIT_BALANCE_TOO_LOW = "credit_balance_too_low";
|
|
27
|
+
/** The sign-in type from env and Claude Code's config, before any request. */
|
|
28
|
+
export function claudeAuthFromConfig(opts = {}) {
|
|
29
|
+
const env = opts.env ?? process.env;
|
|
30
|
+
const read = opts.readFile ?? readTextOrNull;
|
|
31
|
+
if (envFlag(env.CLAUDE_CODE_USE_BEDROCK))
|
|
32
|
+
return "bedrock";
|
|
33
|
+
if (envFlag(env.CLAUDE_CODE_USE_VERTEX))
|
|
34
|
+
return "vertex";
|
|
35
|
+
if (envFlag(env.CLAUDE_CODE_USE_FOUNDRY))
|
|
36
|
+
return "foundry";
|
|
37
|
+
if (nonEmpty(env.ANTHROPIC_API_KEY) || nonEmpty(env.ANTHROPIC_AUTH_TOKEN))
|
|
38
|
+
return "api_key";
|
|
39
|
+
const home = opts.homedir ?? os.homedir();
|
|
40
|
+
const configDir = nonEmpty(env.CLAUDE_CONFIG_DIR) ? env.CLAUDE_CONFIG_DIR : path.join(home, ".claude");
|
|
41
|
+
if (settingsFiles(configDir, opts.cwd ?? process.cwd()).some((f) => hasApiKeyHelper(read(f)))) {
|
|
42
|
+
return "api_key";
|
|
43
|
+
}
|
|
44
|
+
const globalConfig = nonEmpty(env.CLAUDE_CONFIG_DIR)
|
|
45
|
+
? path.join(env.CLAUDE_CONFIG_DIR, ".claude.json")
|
|
46
|
+
: path.join(home, ".claude.json");
|
|
47
|
+
return authFromGlobalConfig(read(globalConfig));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The Claude.ai plan tier Claude Code recorded locally: `organizationType` and
|
|
51
|
+
* `organizationRateLimitTier` in `~/.claude.json`, else `subscriptionType` in
|
|
52
|
+
* `.credentials.json` (Linux and Windows). Only those values are matched, and
|
|
53
|
+
* only a known tier name comes out; "unknown" otherwise.
|
|
54
|
+
*/
|
|
55
|
+
export function claudePlanFromConfig(opts = {}) {
|
|
56
|
+
const env = opts.env ?? process.env;
|
|
57
|
+
const read = opts.readFile ?? readTextOrNull;
|
|
58
|
+
const home = opts.homedir ?? os.homedir();
|
|
59
|
+
const dir = nonEmpty(env.CLAUDE_CONFIG_DIR) ? env.CLAUDE_CONFIG_DIR : null;
|
|
60
|
+
const global = read(dir ? path.join(dir, ".claude.json") : path.join(home, ".claude.json"));
|
|
61
|
+
const fromGlobal = planFrom(stringField(global, "organizationType"), stringField(global, "organizationRateLimitTier"));
|
|
62
|
+
if (fromGlobal !== "unknown")
|
|
63
|
+
return fromGlobal;
|
|
64
|
+
const credentials = read(path.join(dir ?? path.join(home, ".claude"), ".credentials.json"));
|
|
65
|
+
return planFrom(stringField(credentials, "subscriptionType"), undefined);
|
|
66
|
+
}
|
|
67
|
+
/** The sign-in type a request's auth headers show, or undefined when they show none. */
|
|
68
|
+
export function claudeAuthFromHeaders(headers) {
|
|
69
|
+
if (nonEmpty(first(headers["x-api-key"])))
|
|
70
|
+
return "api_key";
|
|
71
|
+
const auth = first(headers["authorization"]);
|
|
72
|
+
if (!auth)
|
|
73
|
+
return undefined;
|
|
74
|
+
const token = /^Bearer\s+(\S+)/i.exec(auth.trim())?.[1] ?? "";
|
|
75
|
+
if (token.startsWith("sk-ant-oat"))
|
|
76
|
+
return "subscription";
|
|
77
|
+
if (token.startsWith("sk-ant-api"))
|
|
78
|
+
return "api_key";
|
|
79
|
+
return "unknown";
|
|
80
|
+
}
|
|
81
|
+
/** A known Anthropic error in a JSON error body, by code; undefined otherwise. */
|
|
82
|
+
export function upstreamErrorCode(body) {
|
|
83
|
+
const text = typeof body === "string" ? body : body.subarray(0, 16 * 1024).toString("utf8");
|
|
84
|
+
let message;
|
|
85
|
+
try {
|
|
86
|
+
message = JSON.parse(text)?.error?.message;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
return typeof message === "string" && /credit balance is too low/i.test(message)
|
|
92
|
+
? CREDIT_BALANCE_TOO_LOW
|
|
93
|
+
: undefined;
|
|
94
|
+
}
|
|
95
|
+
/** Printed once when Anthropic refused an API key for having no credit. */
|
|
96
|
+
export function creditNoticeText(color) {
|
|
97
|
+
const text = "ccc isn't free Claude: it runs your own Claude Code, and this API key has no credit. " +
|
|
98
|
+
"Sign in with a Claude Pro or Max plan (run `claude`, then /login) or add credit to the key.";
|
|
99
|
+
return color ? `\x1b[33m${text}\x1b[39m` : text;
|
|
100
|
+
}
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
// Config files
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
function settingsFiles(configDir, cwd) {
|
|
105
|
+
return [
|
|
106
|
+
path.join(configDir, "settings.json"),
|
|
107
|
+
path.join(cwd, ".claude", "settings.json"),
|
|
108
|
+
path.join(cwd, ".claude", "settings.local.json"),
|
|
109
|
+
];
|
|
110
|
+
}
|
|
111
|
+
function hasApiKeyHelper(text) {
|
|
112
|
+
if (text === null)
|
|
113
|
+
return false;
|
|
114
|
+
try {
|
|
115
|
+
const helper = JSON.parse(text)?.apiKeyHelper;
|
|
116
|
+
return typeof helper === "string" && helper.trim() !== "";
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Key names only: the file holds account details (and, for a Console login on
|
|
124
|
+
* some systems, the key), none of which is parsed out or kept.
|
|
125
|
+
*/
|
|
126
|
+
function authFromGlobalConfig(text) {
|
|
127
|
+
if (text === null)
|
|
128
|
+
return "unknown";
|
|
129
|
+
// A Console (API billing) login stores a key and may also record oauthAccount.
|
|
130
|
+
if (/"primaryApiKey"\s*:\s*"[^"]/.test(text))
|
|
131
|
+
return "api_key";
|
|
132
|
+
if (/"oauthAccount"\s*:\s*\{/.test(text))
|
|
133
|
+
return "subscription";
|
|
134
|
+
return "unknown";
|
|
135
|
+
}
|
|
136
|
+
/** "claude_max" + "default_claude_max_20x" → "max_20x"; "pro" → "pro". */
|
|
137
|
+
export function planFrom(type, rateTier) {
|
|
138
|
+
const t = (type ?? "").toLowerCase();
|
|
139
|
+
const tier = (rateTier ?? "").toLowerCase();
|
|
140
|
+
if (/max/.test(t))
|
|
141
|
+
return /20x/.test(tier) ? "max_20x" : /5x/.test(tier) ? "max_5x" : "max";
|
|
142
|
+
for (const plan of ["pro", "team", "enterprise", "free"]) {
|
|
143
|
+
if (new RegExp(`(^|_)${plan}($|_)`).test(t))
|
|
144
|
+
return plan;
|
|
145
|
+
}
|
|
146
|
+
return "unknown";
|
|
147
|
+
}
|
|
148
|
+
/** One short `"key": "value"` string (letters, digits, `_`), without parsing the rest. */
|
|
149
|
+
function stringField(text, key) {
|
|
150
|
+
if (text === null)
|
|
151
|
+
return undefined;
|
|
152
|
+
return new RegExp(`"${key}"\\s*:\\s*"([A-Za-z0-9_]{1,40})"`).exec(text)?.[1];
|
|
153
|
+
}
|
|
154
|
+
function readTextOrNull(file) {
|
|
155
|
+
try {
|
|
156
|
+
return fs.readFileSync(file, "utf8");
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function first(value) {
|
|
163
|
+
return Array.isArray(value) ? value[0] : value;
|
|
164
|
+
}
|
|
165
|
+
function nonEmpty(value) {
|
|
166
|
+
return typeof value === "string" && value.trim() !== "";
|
|
167
|
+
}
|
|
168
|
+
function envFlag(value) {
|
|
169
|
+
return value !== undefined && /^(1|true|yes|on)$/i.test(value.trim());
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=claude-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-auth.js","sourceRoot":"","sources":["../src/claude-auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finding Claude Code to launch, however it was installed.
|
|
3
|
+
*
|
|
4
|
+
* ccc launches `claude` through cross-spawn, which finds it on PATH (with
|
|
5
|
+
* PATHEXT on Windows, so npm's `claude.cmd` shim and the native `claude.exe`
|
|
6
|
+
* both run). What it cannot do is find a Claude Code that is installed but not
|
|
7
|
+
* on this terminal's PATH. On Windows that is the common case: the native
|
|
8
|
+
* installer puts `claude.exe` in `%USERPROFILE%\.local\bin` and may only ask
|
|
9
|
+
* the user to add it to PATH, winget links it under
|
|
10
|
+
* `%LOCALAPPDATA%\Microsoft\WinGet\Links`, and any installer that does update
|
|
11
|
+
* the user's PATH (in the registry) leaves terminals already open without it.
|
|
12
|
+
* So after PATH this looks in the user's and machine's registry PATH, then in
|
|
13
|
+
* each installer's own location. On macOS and Linux it checks the native
|
|
14
|
+
* installer's `~/.local/bin`, the legacy `~/.claude/local` and Homebrew.
|
|
15
|
+
*
|
|
16
|
+
* Only paths are probed; nothing is run except `reg query` on Windows, and
|
|
17
|
+
* only when PATH has no `claude`.
|
|
18
|
+
*/
|
|
19
|
+
/** Where Claude Code was found, for diagnostics (an enum, never a path). */
|
|
20
|
+
export declare const CLAUDE_SOURCES: readonly ["path", "registry-path", "native", "npm", "winget", "homebrew", "legacy-local"];
|
|
21
|
+
export type ClaudeSource = (typeof CLAUDE_SOURCES)[number];
|
|
22
|
+
export interface ClaudeLocation {
|
|
23
|
+
/** What to spawn: `claude` when it is on PATH, else its absolute path. */
|
|
24
|
+
command: string;
|
|
25
|
+
source: ClaudeSource;
|
|
26
|
+
/** Not on PATH: its directory, to put on the child's PATH. */
|
|
27
|
+
dir?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface LocateClaudeOptions {
|
|
30
|
+
platform?: NodeJS.Platform;
|
|
31
|
+
env?: NodeJS.ProcessEnv;
|
|
32
|
+
homedir?: string;
|
|
33
|
+
/** True when `file` exists and can be run. */
|
|
34
|
+
isExecutable?: (file: string) => boolean;
|
|
35
|
+
/** Windows: the user's and the machine's PATH from the registry. */
|
|
36
|
+
registryPath?: () => string[];
|
|
37
|
+
/** Directory entries (winget's package folders); [] when unreadable. */
|
|
38
|
+
listDir?: (dir: string) => string[];
|
|
39
|
+
}
|
|
40
|
+
/** Claude Code to launch, or null when it is not installed anywhere known. */
|
|
41
|
+
export declare function locateClaude(opts?: LocateClaudeOptions): ClaudeLocation | null;
|
|
42
|
+
/** The child's environment with `location.dir` first on PATH, when it was not on PATH. */
|
|
43
|
+
export declare function withClaudeOnPath(env: NodeJS.ProcessEnv, location: ClaudeLocation, platform?: NodeJS.Platform): NodeJS.ProcessEnv;
|
|
44
|
+
/**
|
|
45
|
+
* Said once, instead of launching, when Claude Code is not installed: the
|
|
46
|
+
* official install command for this OS and the sign-in step.
|
|
47
|
+
*/
|
|
48
|
+
export declare function claudeMissingText(platform?: NodeJS.Platform): string;
|
|
49
|
+
/**
|
|
50
|
+
* One line, not blocking, when ccc starts somewhere that is not a project:
|
|
51
|
+
* C:\Windows\System32 (where an admin terminal opens) or the home folder.
|
|
52
|
+
*/
|
|
53
|
+
export declare function cwdHintText(cwd: string, opts?: {
|
|
54
|
+
platform?: NodeJS.Platform;
|
|
55
|
+
env?: NodeJS.ProcessEnv;
|
|
56
|
+
homedir?: string;
|
|
57
|
+
}): string | null;
|
|
58
|
+
/** `%USERPROFILE%\.local\bin` → its value; unknown names stay as written. */
|
|
59
|
+
export declare function expandWindowsVars(value: string, env: NodeJS.ProcessEnv): string;
|
|
60
|
+
/** The Path values in `reg query` output (REG_SZ or REG_EXPAND_SZ). */
|
|
61
|
+
export declare function parseRegQueryPath(output: string): string | null;
|
|
62
|
+
//# sourceMappingURL=claude-locate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-locate.d.ts","sourceRoot":"","sources":["../src/claude-locate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAOH,4EAA4E;AAC5E,eAAO,MAAM,cAAc,2FAEjB,CAAC;AACX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D,MAAM,WAAW,cAAc;IAC7B,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,YAAY,CAAC;IACrB,8DAA8D;IAC9D,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACzC,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,MAAM,EAAE,CAAC;IAC9B,wEAAwE;IACxE,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;CACrC;AAED,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,IAAI,GAAE,mBAAwB,GAAG,cAAc,GAAG,IAAI,CAYlF;AAED,0FAA0F;AAC1F,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,QAAQ,EAAE,cAAc,EACxB,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C,MAAM,CAAC,UAAU,CAMnB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAAG,MAAM,CAStF;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACnF,MAAM,GAAG,IAAI,CAoBf;AAuGD,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAE/E;AAED,uEAAuE;AACvE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG/D"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finding Claude Code to launch, however it was installed.
|
|
3
|
+
*
|
|
4
|
+
* ccc launches `claude` through cross-spawn, which finds it on PATH (with
|
|
5
|
+
* PATHEXT on Windows, so npm's `claude.cmd` shim and the native `claude.exe`
|
|
6
|
+
* both run). What it cannot do is find a Claude Code that is installed but not
|
|
7
|
+
* on this terminal's PATH. On Windows that is the common case: the native
|
|
8
|
+
* installer puts `claude.exe` in `%USERPROFILE%\.local\bin` and may only ask
|
|
9
|
+
* the user to add it to PATH, winget links it under
|
|
10
|
+
* `%LOCALAPPDATA%\Microsoft\WinGet\Links`, and any installer that does update
|
|
11
|
+
* the user's PATH (in the registry) leaves terminals already open without it.
|
|
12
|
+
* So after PATH this looks in the user's and machine's registry PATH, then in
|
|
13
|
+
* each installer's own location. On macOS and Linux it checks the native
|
|
14
|
+
* installer's `~/.local/bin`, the legacy `~/.claude/local` and Homebrew.
|
|
15
|
+
*
|
|
16
|
+
* Only paths are probed; nothing is run except `reg query` on Windows, and
|
|
17
|
+
* only when PATH has no `claude`.
|
|
18
|
+
*/
|
|
19
|
+
import { spawnSync } from "node:child_process";
|
|
20
|
+
import * as fs from "node:fs";
|
|
21
|
+
import * as os from "node:os";
|
|
22
|
+
import * as path from "node:path";
|
|
23
|
+
/** Where Claude Code was found, for diagnostics (an enum, never a path). */
|
|
24
|
+
export const CLAUDE_SOURCES = [
|
|
25
|
+
"path", "registry-path", "native", "npm", "winget", "homebrew", "legacy-local",
|
|
26
|
+
];
|
|
27
|
+
/** Claude Code to launch, or null when it is not installed anywhere known. */
|
|
28
|
+
export function locateClaude(opts = {}) {
|
|
29
|
+
const platform = opts.platform ?? process.platform;
|
|
30
|
+
const env = opts.env ?? process.env;
|
|
31
|
+
const isExecutable = opts.isExecutable ?? defaultIsExecutable(platform);
|
|
32
|
+
const onPath = findOnPath("claude", pathDirs(env, platform), platform, env, isExecutable);
|
|
33
|
+
if (onPath)
|
|
34
|
+
return { command: "claude", source: "path" };
|
|
35
|
+
const home = opts.homedir ?? os.homedir();
|
|
36
|
+
for (const candidate of candidates(platform, env, home, opts)) {
|
|
37
|
+
const file = findOnPath("claude", candidate.dirs, platform, env, isExecutable);
|
|
38
|
+
if (file)
|
|
39
|
+
return { command: file, source: candidate.source, dir: pathFor(platform).dirname(file) };
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
/** The child's environment with `location.dir` first on PATH, when it was not on PATH. */
|
|
44
|
+
export function withClaudeOnPath(env, location, platform = process.platform) {
|
|
45
|
+
if (!location.dir)
|
|
46
|
+
return env;
|
|
47
|
+
const key = pathKey(env, platform);
|
|
48
|
+
const current = env[key];
|
|
49
|
+
const delimiter = platform === "win32" ? ";" : ":";
|
|
50
|
+
return { ...env, [key]: current ? `${location.dir}${delimiter}${current}` : location.dir };
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Said once, instead of launching, when Claude Code is not installed: the
|
|
54
|
+
* official install command for this OS and the sign-in step.
|
|
55
|
+
*/
|
|
56
|
+
export function claudeMissingText(platform = process.platform) {
|
|
57
|
+
const install = platform === "win32"
|
|
58
|
+
? " irm https://claude.ai/install.ps1 | iex (in PowerShell)"
|
|
59
|
+
: " curl -fsSL https://claude.ai/install.sh | bash";
|
|
60
|
+
return [
|
|
61
|
+
"Claude Code isn't installed. ccc runs Claude Code, so install it first:",
|
|
62
|
+
install,
|
|
63
|
+
"then open a new terminal, run `claude` once to sign in, and run ccc again.",
|
|
64
|
+
].join("\n");
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* One line, not blocking, when ccc starts somewhere that is not a project:
|
|
68
|
+
* C:\Windows\System32 (where an admin terminal opens) or the home folder.
|
|
69
|
+
*/
|
|
70
|
+
export function cwdHintText(cwd, opts = {}) {
|
|
71
|
+
const platform = opts.platform ?? process.platform;
|
|
72
|
+
const env = opts.env ?? process.env;
|
|
73
|
+
const p = pathFor(platform);
|
|
74
|
+
const same = (a, b) => {
|
|
75
|
+
const norm = (s) => p.resolve(s).replace(/[\\/]+$/, "");
|
|
76
|
+
return platform === "win32" || platform === "darwin"
|
|
77
|
+
? norm(a).toLowerCase() === norm(b).toLowerCase()
|
|
78
|
+
: norm(a) === norm(b);
|
|
79
|
+
};
|
|
80
|
+
const home = opts.homedir ?? os.homedir();
|
|
81
|
+
let where = null;
|
|
82
|
+
if (platform === "win32") {
|
|
83
|
+
const windows = env.SystemRoot || env.windir || "C:\\Windows";
|
|
84
|
+
if (["System32", "SysWOW64"].some((d) => same(cwd, p.join(windows, d))))
|
|
85
|
+
where = cwd;
|
|
86
|
+
}
|
|
87
|
+
if (where === null && home && same(cwd, home))
|
|
88
|
+
where = "your home folder";
|
|
89
|
+
if (where === null)
|
|
90
|
+
return null;
|
|
91
|
+
return `Tip: ccc is running in ${where}. Run it from your project folder (cd into it, then ccc) ` +
|
|
92
|
+
"so Claude Code works on that project.";
|
|
93
|
+
}
|
|
94
|
+
function candidates(platform, env, home, opts) {
|
|
95
|
+
if (platform === "win32")
|
|
96
|
+
return windowsCandidates(env, home, opts);
|
|
97
|
+
const p = path.posix;
|
|
98
|
+
return [
|
|
99
|
+
{ source: "native", dirs: [p.join(home, ".local", "bin")] },
|
|
100
|
+
{ source: "legacy-local", dirs: [p.join(home, ".claude", "local")] },
|
|
101
|
+
{ source: "homebrew", dirs: ["/opt/homebrew/bin", "/usr/local/bin", "/home/linuxbrew/.linuxbrew/bin"] },
|
|
102
|
+
{ source: "npm", dirs: [p.join(home, ".npm-global", "bin")] },
|
|
103
|
+
];
|
|
104
|
+
}
|
|
105
|
+
function windowsCandidates(env, home, opts) {
|
|
106
|
+
const w = path.win32;
|
|
107
|
+
const profile = envValue(env, "USERPROFILE") || home;
|
|
108
|
+
const appData = envValue(env, "APPDATA") || w.join(profile, "AppData", "Roaming");
|
|
109
|
+
const localAppData = envValue(env, "LOCALAPPDATA") || w.join(profile, "AppData", "Local");
|
|
110
|
+
const winget = w.join(localAppData, "Microsoft", "WinGet");
|
|
111
|
+
// The installers' own folders first (cheap stats); the registry (two spawns) last.
|
|
112
|
+
return [
|
|
113
|
+
{ source: "native", dirs: [w.join(profile, ".local", "bin")] },
|
|
114
|
+
{ source: "npm", dirs: [w.join(appData, "npm")] },
|
|
115
|
+
{ source: "winget", dirs: [w.join(winget, "Links"), ...wingetPackageDirs(winget, opts)] },
|
|
116
|
+
{ source: "registry-path", get dirs() { return registryDirs(env, opts); } },
|
|
117
|
+
];
|
|
118
|
+
}
|
|
119
|
+
function registryDirs(env, opts) {
|
|
120
|
+
return (opts.registryPath ?? (() => readRegistryPath(env)))()
|
|
121
|
+
.flatMap((value) => splitPath(expandWindowsVars(value, env), "win32"));
|
|
122
|
+
}
|
|
123
|
+
/** winget's own folders for Claude Code (Anthropic.ClaudeCode_<source hash>). */
|
|
124
|
+
function wingetPackageDirs(winget, opts) {
|
|
125
|
+
const packages = path.win32.join(winget, "Packages");
|
|
126
|
+
const list = opts.listDir ?? defaultListDir;
|
|
127
|
+
return list(packages)
|
|
128
|
+
.filter((name) => /^Anthropic\.ClaudeCode/i.test(name))
|
|
129
|
+
.map((name) => path.win32.join(packages, name));
|
|
130
|
+
}
|
|
131
|
+
function findOnPath(name, dirs, platform, env, isExecutable) {
|
|
132
|
+
const p = pathFor(platform);
|
|
133
|
+
const exts = platform === "win32"
|
|
134
|
+
? (envValue(env, "PATHEXT") || ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean)
|
|
135
|
+
: [""];
|
|
136
|
+
for (const dir of dirs) {
|
|
137
|
+
if (!dir)
|
|
138
|
+
continue;
|
|
139
|
+
for (const ext of exts) {
|
|
140
|
+
const file = p.join(dir, name + ext.toLowerCase());
|
|
141
|
+
if (isExecutable(file))
|
|
142
|
+
return file;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
function pathDirs(env, platform) {
|
|
148
|
+
return splitPath(env[pathKey(env, platform)] ?? "", platform);
|
|
149
|
+
}
|
|
150
|
+
function splitPath(value, platform) {
|
|
151
|
+
return value
|
|
152
|
+
.split(platform === "win32" ? ";" : ":")
|
|
153
|
+
.map((dir) => dir.trim().replace(/^"(.*)"$/, "$1"))
|
|
154
|
+
.filter(Boolean);
|
|
155
|
+
}
|
|
156
|
+
/** Windows env names are case-insensitive, but a copied env object is not. */
|
|
157
|
+
function pathKey(env, platform) {
|
|
158
|
+
if (platform !== "win32")
|
|
159
|
+
return "PATH";
|
|
160
|
+
return Object.keys(env).reverse().find((key) => key.toUpperCase() === "PATH") ?? "Path";
|
|
161
|
+
}
|
|
162
|
+
function envValue(env, name) {
|
|
163
|
+
const key = Object.keys(env).find((k) => k.toUpperCase() === name.toUpperCase());
|
|
164
|
+
return key === undefined ? undefined : env[key];
|
|
165
|
+
}
|
|
166
|
+
/** `%USERPROFILE%\.local\bin` → its value; unknown names stay as written. */
|
|
167
|
+
export function expandWindowsVars(value, env) {
|
|
168
|
+
return value.replace(/%([^%;]+)%/g, (whole, name) => envValue(env, name) ?? whole);
|
|
169
|
+
}
|
|
170
|
+
/** The Path values in `reg query` output (REG_SZ or REG_EXPAND_SZ). */
|
|
171
|
+
export function parseRegQueryPath(output) {
|
|
172
|
+
const m = /^\s*Path\s+REG_(?:EXPAND_)?SZ\s+(.*)$/im.exec(output);
|
|
173
|
+
return m ? m[1].trim() : null;
|
|
174
|
+
}
|
|
175
|
+
function readRegistryPath(env) {
|
|
176
|
+
// By full path: PATH is what may be broken here.
|
|
177
|
+
const root = envValue(env, "SystemRoot") || envValue(env, "windir") || "C:\\Windows";
|
|
178
|
+
const reg = path.win32.join(root, "System32", "reg.exe");
|
|
179
|
+
const keys = [
|
|
180
|
+
"HKCU\\Environment",
|
|
181
|
+
"HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment",
|
|
182
|
+
];
|
|
183
|
+
const out = [];
|
|
184
|
+
for (const key of keys) {
|
|
185
|
+
try {
|
|
186
|
+
const result = spawnSync(reg, ["query", key, "/v", "Path"], {
|
|
187
|
+
encoding: "utf8", timeout: 2000, windowsHide: true,
|
|
188
|
+
});
|
|
189
|
+
const value = result.status === 0 ? parseRegQueryPath(result.stdout ?? "") : null;
|
|
190
|
+
if (value)
|
|
191
|
+
out.push(value);
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
// No reg.exe (or not Windows): nothing more to search.
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return out;
|
|
198
|
+
}
|
|
199
|
+
function pathFor(platform) {
|
|
200
|
+
return platform === "win32" ? path.win32 : path.posix;
|
|
201
|
+
}
|
|
202
|
+
function defaultIsExecutable(platform) {
|
|
203
|
+
return (file) => {
|
|
204
|
+
try {
|
|
205
|
+
if (!fs.statSync(file).isFile())
|
|
206
|
+
return false;
|
|
207
|
+
if (platform !== "win32")
|
|
208
|
+
fs.accessSync(file, fs.constants.X_OK);
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function defaultListDir(dir) {
|
|
217
|
+
try {
|
|
218
|
+
return fs.readdirSync(dir);
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
return [];
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=claude-locate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-locate.js","sourceRoot":"","sources":["../src/claude-locate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,4EAA4E;AAC5E,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,cAAc;CACtE,CAAC;AAuBX,8EAA8E;AAC9E,MAAM,UAAU,YAAY,CAAC,OAA4B,EAAE;IACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;IACnD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACpC,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC;IAC1F,IAAI,MAAM;QAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IACzD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;IAC1C,KAAK,MAAM,SAAS,IAAI,UAAU,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;QAC9D,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC;QAC/E,IAAI,IAAI;YAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;IACrG,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,gBAAgB,CAC9B,GAAsB,EACtB,QAAwB,EACxB,WAA4B,OAAO,CAAC,QAAQ;IAE5C,IAAI,CAAC,QAAQ,CAAC,GAAG;QAAE,OAAO,GAAG,CAAC;IAC9B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB,MAAM,SAAS,GAAG,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IACnD,OAAO,EAAE,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,GAAG,SAAS,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;AAC7F,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAA4B,OAAO,CAAC,QAAQ;IAC5E,MAAM,OAAO,GAAG,QAAQ,KAAK,OAAO;QAClC,CAAC,CAAC,gEAAgE;QAClE,CAAC,CAAC,kDAAkD,CAAC;IACvD,OAAO;QACL,yEAAyE;QACzE,OAAO;QACP,4EAA4E;KAC7E,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CACzB,GAAW,EACX,OAAkF,EAAE;IAEpF,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;IACnD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACpC,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5B,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,EAAE;QACpC,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAChE,OAAO,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,QAAQ;YAClD,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;YACjD,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC,CAAC;IACF,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;IAC1C,IAAI,KAAK,GAAkB,IAAI,CAAC;IAChC,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,MAAM,IAAI,aAAa,CAAC;QAC9D,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;YAAE,KAAK,GAAG,GAAG,CAAC;IACvF,CAAC;IACD,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC;QAAE,KAAK,GAAG,kBAAkB,CAAC;IAC1E,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAChC,OAAO,0BAA0B,KAAK,2DAA2D;QAC/F,uCAAuC,CAAC;AAC5C,CAAC;AAWD,SAAS,UAAU,CACjB,QAAyB,EACzB,GAAsB,EACtB,IAAY,EACZ,IAAyB;IAEzB,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,iBAAiB,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACpE,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;IACrB,OAAO;QACL,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,EAAE;QAC3D,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,EAAE;QACpE,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,gBAAgB,EAAE,gCAAgC,CAAC,EAAE;QACvG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC,EAAE;KAC9D,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CACxB,GAAsB,EACtB,IAAY,EACZ,IAAyB;IAEzB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;IACrB,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC,IAAI,IAAI,CAAC;IACrD,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAClF,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAC1F,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,YAAY,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;IAC3D,mFAAmF;IACnF,OAAO;QACL,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,EAAE;QAC9D,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,EAAE;QACjD,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,EAAE;QACzF,EAAE,MAAM,EAAE,eAAe,EAAE,IAAI,IAAI,KAAK,OAAO,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;KAC5E,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,GAAsB,EAAE,IAAyB;IACrE,OAAO,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;SAC1D,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED,iFAAiF;AACjF,SAAS,iBAAiB,CAAC,MAAc,EAAE,IAAyB;IAClE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACrD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,IAAI,cAAc,CAAC;IAC5C,OAAO,IAAI,CAAC,QAAQ,CAAC;SAClB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACtD,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,UAAU,CACjB,IAAY,EACZ,IAAc,EACd,QAAyB,EACzB,GAAsB,EACtB,YAAuC;IAEvC,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5B,MAAM,IAAI,GAAG,QAAQ,KAAK,OAAO;QAC/B,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,qBAAqB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QAChF,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;YACnD,IAAI,YAAY,CAAC,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC;QACtC,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,QAAQ,CAAC,GAAsB,EAAE,QAAyB;IACjE,OAAO,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,SAAS,CAAC,KAAa,EAAE,QAAyB;IACzD,OAAO,KAAK;SACT,KAAK,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;SACvC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;SAClD,MAAM,CAAC,OAAO,CAAC,CAAC;AACrB,CAAC;AAED,8EAA8E;AAC9E,SAAS,OAAO,CAAC,GAAsB,EAAE,QAAyB;IAChE,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,MAAM,CAAC;IACxC,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC;AAC1F,CAAC;AAED,SAAS,QAAQ,CAAC,GAAsB,EAAE,IAAY;IACpD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IACjF,OAAO,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAClD,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,iBAAiB,CAAC,KAAa,EAAE,GAAsB;IACrE,OAAO,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC;AAC7F,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,MAAM,CAAC,GAAG,yCAAyC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAChC,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAsB;IAC9C,iDAAiD;IACjD,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC,IAAI,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,aAAa,CAAC;IACrF,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IACzD,MAAM,IAAI,GAAG;QACX,mBAAmB;QACnB,wEAAwE;KACzE,CAAC;IACF,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE;gBAC1D,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI;aACnD,CAAC,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAClF,IAAI,KAAK;gBAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,uDAAuD;QACzD,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,OAAO,CAAC,QAAyB;IACxC,OAAO,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;AACxD,CAAC;AAED,SAAS,mBAAmB,CAAC,QAAyB;IACpD,OAAO,CAAC,IAAI,EAAE,EAAE;QACd,IAAI,CAAC;YACH,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE;gBAAE,OAAO,KAAK,CAAC;YAC9C,IAAI,QAAQ,KAAK,OAAO;gBAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACjE,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,GAAW;IACjC,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|