@moikapy/lich 0.5.0 → 0.5.1
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 +5 -0
- package/dist/chunk-6M6OAQGN.js +17 -0
- package/dist/chunk-6M6OAQGN.js.map +1 -0
- package/dist/cli.d.ts +9 -1
- package/dist/cli.js +78 -6
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +34 -37
- package/dist/index.js +1 -1
- package/dist/{tui-DT7XWDTX.js → tui-2VO6LAFM.js} +2 -2
- package/package.json +2 -1
- package/dist/chunk-ZVK3MUPC.js +0 -7
- package/dist/chunk-ZVK3MUPC.js.map +0 -1
- /package/dist/{tui-DT7XWDTX.js.map → tui-2VO6LAFM.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.1
|
|
4
|
+
|
|
5
|
+
- fix the CLI so bun's global bin enters main (symlink argv no longer skips the entry).
|
|
6
|
+
- read LICH_VERSION from package.json so lich --version is not stuck at 0.3.0.
|
|
7
|
+
|
|
3
8
|
## 0.5.0
|
|
4
9
|
|
|
5
10
|
- add a `game_bridge` example plugin that queues batched enemy actions
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { readFileSync } from "fs";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
function read_package_version() {
|
|
5
|
+
const pkg_path = fileURLToPath(new URL("../package.json", import.meta.url));
|
|
6
|
+
const pkg = JSON.parse(readFileSync(pkg_path, "utf8"));
|
|
7
|
+
if (typeof pkg.version !== "string" || pkg.version.length === 0) {
|
|
8
|
+
throw new Error("package.json is missing version");
|
|
9
|
+
}
|
|
10
|
+
return pkg.version;
|
|
11
|
+
}
|
|
12
|
+
var LICH_VERSION = read_package_version();
|
|
13
|
+
|
|
14
|
+
export {
|
|
15
|
+
LICH_VERSION
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=chunk-6M6OAQGN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Public surface of the lich agent harness. Pure re-exports, plus the package version.\n */\nimport { readFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\n\nfunction read_package_version(): string {\n const pkg_path = fileURLToPath(new URL(\"../package.json\", import.meta.url));\n const pkg = JSON.parse(readFileSync(pkg_path, \"utf8\")) as { version?: unknown };\n if (typeof pkg.version !== \"string\" || pkg.version.length === 0) {\n throw new Error(\"package.json is missing version\");\n }\n return pkg.version;\n}\n\nexport const LICH_VERSION = read_package_version();\n\nexport { Agent, create_agent, run_agent, create_agent_with_plugins } from \"./agent/agent.js\";\nexport type { AgentRunOptions, AgentRunResult } from \"./agent/agent.js\";\nexport type { AgentConfig } from \"./agent/config.js\";\nexport { parse_agent_config } from \"./agent/config.js\";\nexport { AgentEmitter } from \"./agent/events.js\";\nexport type { AgentEvent, AgentEventHandler, AgentEvents } from \"./agent/events.js\";\nexport type { LoopOutcome, LoopParams } from \"./agent/loop.js\";\nexport type {\n ChatOptions,\n ChatResult,\n Message,\n ProviderConfig,\n ToolCall,\n ToolDefinition,\n Usage,\n} from \"./providers/types.js\";\nexport { ProviderError } from \"./providers/types.js\";\nexport { ToolExecutor } from \"./tools/executor.js\";\nexport { ToolRegistry } from \"./tools/registry.js\";\nexport type { Tool, ToolContext, ToolResult } from \"./tools/types.js\";\nexport { register_builtin_tools } from \"./tools/builtin/index.js\";\nexport { HookedToolRunner } from \"./plugins/hooks.js\";\nexport { load_plugins, plugin_errors_summary } from \"./plugins/loader.js\";\nexport type { LoadedPlugin, PluginLoadError } from \"./plugins/loader.js\";\nexport type {\n AfterToolCallInfo,\n BeforeToolCallInfo,\n BeforeToolCallResult,\n HookContext,\n Plugin,\n PluginHooks,\n RunEndInfo,\n} from \"./plugins/types.js\";"],"mappings":";AAGA,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAE9B,SAAS,uBAA+B;AACtC,QAAM,WAAW,cAAc,IAAI,IAAI,mBAAmB,YAAY,GAAG,CAAC;AAC1E,QAAM,MAAM,KAAK,MAAM,aAAa,UAAU,MAAM,CAAC;AACrD,MAAI,OAAO,IAAI,YAAY,YAAY,IAAI,QAAQ,WAAW,GAAG;AAC/D,UAAM,IAAI,MAAM,iCAAiC;AAAA,EACnD;AACA,SAAO,IAAI;AACb;AAEO,IAAM,eAAe,qBAAqB;","names":[]}
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
declare function run_one_shot(config: unknown, input: string): Promise<number>;
|
|
3
3
|
declare function run_chat(config: unknown): Promise<number>;
|
|
4
|
+
interface CliEntryInput {
|
|
5
|
+
bun: boolean;
|
|
6
|
+
import_meta_main: boolean | undefined;
|
|
7
|
+
module_url: string;
|
|
8
|
+
argv1: string | undefined;
|
|
9
|
+
}
|
|
10
|
+
/** Bun uses `import.meta.main`. Node compares argv to this file, including a bin symlink. */
|
|
11
|
+
declare function is_cli_entry(input: CliEntryInput): boolean;
|
|
4
12
|
declare function run_cli(argv: string[]): Promise<number>;
|
|
5
13
|
|
|
6
|
-
export { run_chat, run_cli, run_one_shot };
|
|
14
|
+
export { type CliEntryInput, is_cli_entry, run_chat, run_cli, run_one_shot };
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
LICH_VERSION
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-6M6OAQGN.js";
|
|
5
5
|
import {
|
|
6
6
|
DEFAULT_GATEWAY_TOKEN_ENVS,
|
|
7
7
|
create_agent_with_plugins,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from "./chunk-CV2YH3FH.js";
|
|
12
12
|
|
|
13
13
|
// src/cli.ts
|
|
14
|
-
import { readFileSync as readFileSync2 } from "fs";
|
|
14
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2, realpathSync } from "fs";
|
|
15
15
|
import { createInterface } from "readline";
|
|
16
16
|
import path4 from "path";
|
|
17
17
|
import { fileURLToPath, pathToFileURL } from "url";
|
|
@@ -260,7 +260,16 @@ async function run_lich_update(request) {
|
|
|
260
260
|
}
|
|
261
261
|
return install_if_newer(request, registry);
|
|
262
262
|
}
|
|
263
|
+
function running_under_bun() {
|
|
264
|
+
return process.versions.bun !== void 0;
|
|
265
|
+
}
|
|
263
266
|
function default_command_runner(command, args) {
|
|
267
|
+
if (running_under_bun() === true) {
|
|
268
|
+
return bun_command_runner(command, args);
|
|
269
|
+
}
|
|
270
|
+
return node_command_runner(command, args);
|
|
271
|
+
}
|
|
272
|
+
function node_command_runner(command, args) {
|
|
264
273
|
return new Promise((resolve) => {
|
|
265
274
|
let stdout = "";
|
|
266
275
|
let stderr = "";
|
|
@@ -296,6 +305,45 @@ function default_command_runner(command, args) {
|
|
|
296
305
|
});
|
|
297
306
|
});
|
|
298
307
|
}
|
|
308
|
+
async function read_piped_text(stream, forward, write) {
|
|
309
|
+
const reader = stream.getReader();
|
|
310
|
+
const decoder = new TextDecoder();
|
|
311
|
+
let text = "";
|
|
312
|
+
for (; ; ) {
|
|
313
|
+
const next = await reader.read();
|
|
314
|
+
if (next.done === true) {
|
|
315
|
+
return text;
|
|
316
|
+
}
|
|
317
|
+
const chunk = decoder.decode(next.value, { stream: true });
|
|
318
|
+
text += chunk;
|
|
319
|
+
if (forward === true) {
|
|
320
|
+
write(chunk);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
function bun_command_runner(command, args) {
|
|
325
|
+
const forward = args[0] === "install";
|
|
326
|
+
try {
|
|
327
|
+
const child = Bun.spawn([command, ...args], {
|
|
328
|
+
stdin: "ignore",
|
|
329
|
+
stdout: "pipe",
|
|
330
|
+
stderr: "pipe"
|
|
331
|
+
});
|
|
332
|
+
return Promise.all([
|
|
333
|
+
read_piped_text(child.stdout, forward, (text) => {
|
|
334
|
+
process.stdout.write(text);
|
|
335
|
+
}),
|
|
336
|
+
read_piped_text(child.stderr, forward, (text) => {
|
|
337
|
+
process.stderr.write(text);
|
|
338
|
+
}),
|
|
339
|
+
child.exited
|
|
340
|
+
]).then(([stdout, stderr, exit_code]) => ({ exit_code, stdout, stderr }));
|
|
341
|
+
} catch (error) {
|
|
342
|
+
const coded = error;
|
|
343
|
+
const stderr = typeof coded.message === "string" ? coded.message : "spawn failed";
|
|
344
|
+
return Promise.resolve({ exit_code: 127, stdout: "", stderr, error_code: coded.code });
|
|
345
|
+
}
|
|
346
|
+
}
|
|
299
347
|
async function run_update(module_path) {
|
|
300
348
|
return run_lich_update({
|
|
301
349
|
installed_version: LICH_VERSION,
|
|
@@ -892,7 +940,7 @@ function run_init(options) {
|
|
|
892
940
|
return 0;
|
|
893
941
|
}
|
|
894
942
|
async function run_tui_entry(config) {
|
|
895
|
-
const { run_tui } = await import("./tui-
|
|
943
|
+
const { run_tui } = await import("./tui-2VO6LAFM.js");
|
|
896
944
|
return run_tui(config);
|
|
897
945
|
}
|
|
898
946
|
function gateway_platforms(config, cli_platforms) {
|
|
@@ -906,12 +954,35 @@ async function run_gateway_entry(config, platforms) {
|
|
|
906
954
|
const { run_gateway } = await import("./gateway-W6S43ETE.js");
|
|
907
955
|
return run_gateway(config, gateway_platforms(config, platforms));
|
|
908
956
|
}
|
|
957
|
+
function is_cli_entry(input) {
|
|
958
|
+
if (input.bun === true) {
|
|
959
|
+
return input.import_meta_main === true;
|
|
960
|
+
}
|
|
961
|
+
return node_entry_matches(input.module_url, input.argv1);
|
|
962
|
+
}
|
|
909
963
|
function is_main_module() {
|
|
910
|
-
|
|
911
|
-
|
|
964
|
+
return is_cli_entry({
|
|
965
|
+
bun: process.versions.bun !== void 0,
|
|
966
|
+
import_meta_main: import.meta.main,
|
|
967
|
+
module_url: import.meta.url,
|
|
968
|
+
argv1: process.argv[1]
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
function node_entry_matches(module_url, entry) {
|
|
972
|
+
if (entry === void 0 || entry === "") {
|
|
973
|
+
return false;
|
|
974
|
+
}
|
|
975
|
+
const resolved = path4.resolve(entry);
|
|
976
|
+
if (module_url === pathToFileURL(resolved).href) {
|
|
977
|
+
return true;
|
|
978
|
+
}
|
|
979
|
+
return same_real_file(fileURLToPath(module_url), resolved);
|
|
980
|
+
}
|
|
981
|
+
function same_real_file(left, right) {
|
|
982
|
+
if (existsSync3(left) === false || existsSync3(right) === false) {
|
|
912
983
|
return false;
|
|
913
984
|
}
|
|
914
|
-
return
|
|
985
|
+
return realpathSync(left) === realpathSync(right);
|
|
915
986
|
}
|
|
916
987
|
async function run_cli(argv) {
|
|
917
988
|
const options = parse_args(argv);
|
|
@@ -968,6 +1039,7 @@ if (is_main_module() === true) {
|
|
|
968
1039
|
});
|
|
969
1040
|
}
|
|
970
1041
|
export {
|
|
1042
|
+
is_cli_entry,
|
|
971
1043
|
run_chat,
|
|
972
1044
|
run_cli,
|
|
973
1045
|
run_one_shot
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/cli_config.ts","../src/cli_update.ts","../src/setup_wizard.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Thin zero-dependency CLI for lich: one-shot tasks, interactive chat,\n * config files, and environment-based provider resolution.\n */\nimport { readFileSync } from \"node:fs\";\nimport { createInterface, type Interface } from \"node:readline\";\nimport path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { create_agent_with_plugins, type Agent, type AgentRunResult } from \"./agent/agent.js\";\nimport { parse_agent_config, type AgentConfig } from \"./agent/config.js\";\nimport { AgentEmitter } from \"./agent/events.js\";\nimport { LICH_VERSION } from \"./index.js\";\nimport { load_config, config_template, existing_config_path, starter_config_object, write_lich_config } from \"./cli_config.js\";\nimport { run_update } from \"./cli_update.js\";\nimport { ask_line as ask_wizard_line, build_setup_config, collect_setup_answers } from \"./setup_wizard.js\";\n\ntype ProviderKind = \"openai_compat\" | \"anthropic\" | \"ollama\";\n\ninterface CliOptions {\n config_path?: string;\n help?: boolean;\n version?: boolean;\n overrides: Record<string, string>;\n positionals: string[];\n}\n\nconst FLAG_KEYS: Record<string, string> = {\n \"--work-dir\": \"work_dir\",\n \"--max-turns\": \"max_turns\",\n \"--model\": \"provider_model\",\n \"--provider-kind\": \"provider_kind\",\n \"--base-url\": \"provider_base_url\",\n \"--api-key-env\": \"provider_api_key_env\",\n \"--system-prompt\": \"system_prompt\",\n \"--session-dir\": \"session_dir\",\n \"--log-level\": \"log_level\",\n};\n\nconst DEFAULT_BASE_URLS: Record<ProviderKind, string> = {\n openai_compat: \"https://api.openai.com/v1\",\n anthropic: \"https://api.anthropic.com\",\n ollama: \"http://localhost:11434\",\n};\n\nconst DEFAULT_ENV_API_KEYS: Record<ProviderKind, string | undefined> = {\n openai_compat: \"OPENAI_API_KEY\",\n anthropic: \"ANTHROPIC_API_KEY\",\n ollama: undefined, // ollama needs no api key\n};\n\nfunction usage_text(): string {\n return [\n \"lich — a TypeScript AI agent harness\",\n \"\",\n \"Usage:\",\n \" lich open the TUI (first run: setup wizard, then TUI)\",\n \" lich init write .lich/config.json without the wizard (flags apply; never overwrites)\",\n ' lich \"one shot task\" run a single task and print the reply',\n \" lich chat interactive chat (commands: /exit, /quit)\",\n \" lich tui interactive terminal UI (ink)\",\n \" lich gateway <plat..> messaging gateway (webhook|telegram|discord|twitch)\",\n \" lich config print a starter config template (save as .lich/config.json)\",\n \" lich update install a newer @moikapy/lich from npm, if one exists\",\n \" lich --help show this help\",\n \" lich --version print version\",\n \"\",\n \"Flags (before or after the subcommand):\",\n \" --config <path> JSON config file parsed by parse_agent_config\",\n \" --work-dir <path> working directory for tools\",\n \" --max-turns <n> loop turn budget (default 25)\",\n \" --model <m> model name (default from LICH_MODEL)\",\n \" --provider-kind <k> openai_compat | anthropic | ollama (default LICH_PROVIDER_KIND)\",\n \" --base-url <u> provider base url (default LICH_BASE_URL)\",\n \" --api-key-env <NAME> env var holding the api key (default LICH_API_KEY_ENV; unused by ollama)\",\n \" --system-prompt <s> system prompt override\",\n \" --session-dir <path> session transcript directory\",\n \" --log-level <level> debug | info | warn | error\",\n ].join(\"\\n\");\n}\n\nfunction error_message(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/** Mode-aware config failure message; one-shot keeps the generic variant. */\nfunction error_for_mode(mode: string, base_message: string): string {\n if (mode === \"tui\") {\n return \"lich tui: no model configured — set LICH_MODEL (e.g. glm-5.3-flash:cloud), pass --model, or create .lich/config.json (`lich config` prints a template)\";\n }\n if (mode === \"gateway\") {\n return \"lich gateway: no model configured — set LICH_MODEL (e.g. glm-5.3-flash:cloud), pass --model, or create .lich/config.json (`lich config` prints a template)\";\n }\n if (mode === \"chat\") {\n return \"lich chat: no model configured — set LICH_MODEL (e.g. glm-5.3-flash:cloud), pass --model, or create .lich/config.json (`lich config` prints a template)\";\n }\n return base_message;\n}\n\nfunction parse_args(argv: string[]): CliOptions {\n const options: CliOptions = { overrides: {}, positionals: [] };\n for (let index = 0; index < argv.length; index += 1) {\n const arg = argv[index];\n if (arg === undefined) {\n break;\n }\n if (arg === \"--help\") {\n options.help = true;\n continue;\n }\n if (arg === \"--version\") {\n options.version = true;\n continue;\n }\n if (arg === \"--config\") {\n const value = argv[index + 1];\n if (value === undefined) {\n throw new Error(\"--config requires a path\");\n }\n options.config_path = value;\n index += 1;\n continue;\n }\n const override_key = FLAG_KEYS[arg];\n if (override_key === undefined) {\n if (arg.startsWith(\"--\") === true) {\n throw new Error(`unknown flag: ${arg}`);\n }\n options.positionals.push(arg);\n continue;\n }\n const value = argv[index + 1];\n if (value === undefined || value.startsWith(\"--\") === true) {\n throw new Error(`${arg} requires a value`);\n }\n options.overrides[override_key] = value;\n index += 1;\n }\n return options;\n}\n\nfunction env_provider(overrides: Record<string, string>): Record<string, unknown> {\n const kind_value = overrides[\"provider_kind\"] ?? process.env.LICH_PROVIDER_KIND ?? \"openai_compat\";\n if (kind_value !== \"openai_compat\" && kind_value !== \"anthropic\" && kind_value !== \"ollama\") {\n throw new Error(`unknown provider kind \"${kind_value}\" (expected openai_compat, anthropic, or ollama)`);\n }\n const kind: ProviderKind = kind_value;\n const model = overrides[\"provider_model\"] ?? process.env.LICH_MODEL;\n if (model === undefined || model.length === 0) {\n throw new Error(\"no model configured: set LICH_MODEL, pass --model, or create .lich/config.json (`lich config` prints a template)\");\n }\n return {\n kind,\n name: \"default\",\n model,\n base_url: overrides[\"provider_base_url\"] ?? process.env.LICH_BASE_URL ?? DEFAULT_BASE_URLS[kind],\n api_key_env: overrides[\"provider_api_key_env\"] ?? process.env.LICH_API_KEY_ENV ?? DEFAULT_ENV_API_KEYS[kind],\n };\n}\n\nfunction load_config_file(config_path: string): Record<string, unknown> {\n try {\n const raw = readFileSync(config_path, \"utf8\");\n const parsed = JSON.parse(raw) as unknown;\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new Error(\"config root must be a JSON object\");\n }\n return parsed as Record<string, unknown>;\n } catch (error) {\n throw new Error(`cannot use config file ${config_path}: ${error_message(error)}`);\n }\n}\n\nfunction apply_provider_override(config: Record<string, unknown>, overrides: Record<string, string>): void {\n const keys = [\"provider_kind\", \"provider_model\", \"provider_base_url\", \"provider_api_key_env\"] as const;\n const any_present = keys.some((key) => overrides[key] !== undefined);\n if (any_present === false) {\n return;\n }\n const providers = config[\"providers\"];\n if (Array.isArray(providers) === false || providers.length === 0) {\n config[\"providers\"] = [env_provider(overrides)];\n return;\n }\n const first = providers[0];\n if (typeof first !== \"object\" || first === null) {\n throw new Error(\"config providers[0] must be an object\");\n }\n const provider = first as Record<string, unknown>;\n for (const key of keys) {\n const value = overrides[key];\n if (value !== undefined) {\n provider[key.replace(\"provider_\", \"\")] = value;\n }\n }\n}\n\nfunction apply_overrides(config: Record<string, unknown>, overrides: Record<string, string>): void {\n for (const key of [\"work_dir\", \"system_prompt\", \"session_dir\", \"log_level\"]) {\n if (overrides[key] !== undefined) {\n config[key] = overrides[key];\n }\n }\n if (overrides[\"max_turns\"] !== undefined) {\n const turns = Number(overrides[\"max_turns\"]);\n if (Number.isInteger(turns) === false || turns < 1) {\n throw new Error(\"--max-turns must be a positive integer\");\n }\n config[\"max_turns\"] = turns;\n }\n apply_provider_override(config, overrides);\n}\n\n/** Same search as the wizard: `--work-dir` (else cwd), then the user-home file. */\nfunction load_discovered_config(work_dir: string): Record<string, unknown> | undefined {\n const found = existing_config_path(work_dir);\n if (found === undefined) {\n return undefined;\n }\n return load_config(found);\n}\n\nfunction build_config(options: CliOptions): AgentConfig {\n const base =\n options.config_path === undefined\n ? load_discovered_config(work_dir_of(options)) ?? { providers: [env_provider(options.overrides)] }\n : load_config_file(options.config_path);\n apply_overrides(base, options.overrides);\n const providers = base[\"providers\"];\n if (Array.isArray(providers) === false || providers.length === 0) {\n throw new Error(\"no model configured: set LICH_MODEL, pass --model, or create .lich/config.json (`lich config` prints a template)\");\n }\n return parse_agent_config(base);\n}\n\n/** build_config with the failure message prefixed for the invoking subcommand. */\nfunction build_config_for(options: CliOptions, mode: string): AgentConfig {\n try {\n return build_config(options);\n } catch (error) {\n throw new Error(error_for_mode(mode, error_message(error)));\n }\n}\n\nfunction attach_progress(emitter: AgentEmitter): () => void {\n return emitter.on((event) => {\n if (event.type === \"turn_start\") {\n process.stderr.write(`\\n[lich] turn ${event.turn}`);\n return;\n }\n if (event.type === \"tool_call_end\") {\n const status = event.result.ok === true ? \"ok\" : `error: ${event.result.error ?? \"\"}`;\n process.stderr.write(`\\n[lich] ${event.call.name}: ${status}`);\n return;\n }\n if (event.type === \"final\") {\n process.stderr.write(\"\\n\");\n }\n });\n}\n\nexport async function run_one_shot(config: unknown, input: string): Promise<number> {\n const agent = await create_agent_with_plugins(config);\n const stop_progress = attach_progress(agent.events);\n let result: AgentRunResult;\n try {\n result = await agent.run({ input });\n } finally {\n stop_progress();\n }\n const final = result.outcome.final;\n if (final !== undefined && final.content.length > 0) {\n process.stdout.write(`${final.content}\\n`);\n }\n if (result.outcome.stopped_reason === \"budget\") {\n process.stderr.write(`[lich] budget exhausted after ${result.outcome.turns_used} turns\\n`);\n return 1;\n }\n if (result.outcome.stopped_reason === \"aborted\") {\n process.stderr.write(\"[lich] run aborted\\n\");\n return 1;\n }\n return 0;\n}\n\nasync function run_chat_turn(agent: Agent, input: string): Promise<void> {\n const stop_progress = attach_progress(agent.events);\n try {\n const result = await agent.run({ input });\n const final = result.outcome.final;\n if (final !== undefined && final.content.length > 0) {\n process.stdout.write(`${final.content}\\n`);\n }\n process.stdout.write(`[turns ${result.outcome.turns_used} | tokens ${result.usage_total.total_tokens}]\\n`);\n } catch (error) {\n process.stderr.write(`[lich] ${error_message(error)}\\n`);\n } finally {\n stop_progress();\n }\n}\n\nfunction ask_line(rl: Interface): Promise<string> {\n return new Promise((resolve) => {\n const on_close = (): void => resolve(\"\");\n rl.question(\"> \", (answer) => {\n rl.removeListener(\"close\", on_close);\n resolve(answer);\n });\n rl.once(\"close\", on_close);\n });\n}\n\nexport async function run_chat(config: unknown): Promise<number> {\n const agent = await create_agent_with_plugins(config);\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n try {\n for (;;) {\n const line = await ask_line(rl);\n if (line.trim() === \"\") {\n return 0;\n }\n const command = line.trim();\n if (command === \"/exit\" || command === \"/quit\") {\n return 0;\n }\n await run_chat_turn(agent, command);\n }\n } finally {\n rl.close();\n }\n}\n\nfunction model_hint(options: CliOptions): string | undefined {\n const model = options.overrides[\"provider_model\"] ?? process.env.LICH_MODEL;\n if (model === undefined || model.length === 0) {\n return undefined;\n }\n return model;\n}\n\nfunction skip_setup_message(existing: string): string {\n if (existing.endsWith(`${path.sep}.lich${path.sep}config.json`) === true) {\n return `lich: .lich/config.json already exists at ${existing}; skipping setup`;\n }\n return `lich: config already exists at ${existing}; skipping setup`;\n}\n\nfunction work_dir_of(options: CliOptions): string {\n return options.overrides[\"work_dir\"] ?? process.cwd();\n}\n\nasync function offer_wizard(work_dir: string, hint?: string): Promise<string | \"cancelled\"> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n try {\n const answers = await collect_setup_answers(work_dir, (prompt) => ask_wizard_line(rl, prompt), hint);\n if (answers === undefined) {\n return \"cancelled\";\n }\n const result = write_lich_config(work_dir, build_setup_config(answers));\n process.stdout.write(`${result.message}\\n`);\n return result.path;\n } finally {\n rl.close();\n }\n}\n\nasync function maybe_first_run(options: CliOptions, work_dir: string): Promise<number | undefined> {\n if (options.config_path !== undefined) {\n return undefined;\n }\n const existing = existing_config_path(work_dir);\n if (existing !== undefined) {\n process.stdout.write(`${skip_setup_message(existing)}\\n`);\n options.config_path = existing;\n return undefined;\n }\n const wrote = await offer_wizard(work_dir, model_hint(options));\n if (wrote === \"cancelled\") {\n process.stderr.write(\"lich: setup cancelled; nothing written\\n\");\n return 1;\n }\n options.config_path = wrote;\n return undefined;\n}\n\nasync function run_bare(options: CliOptions): Promise<number> {\n if (process.stdin.isTTY !== true) {\n process.stderr.write(\"lich: stdin is not a TTY; skipping setup wizard. Run `lich init` to write .lich/config.json, or `lich --help` for usage.\\n\");\n return 1;\n }\n const work_dir = work_dir_of(options);\n const stopped = await maybe_first_run(options, work_dir);\n if (stopped !== undefined) {\n return stopped;\n }\n return run_tui_entry(build_config_for(options, \"tui\"));\n}\n\nfunction model_still_placeholder(config: Record<string, unknown>): boolean {\n const providers = config[\"providers\"];\n const first = Array.isArray(providers) === true ? providers[0] : undefined;\n if (typeof first !== \"object\" || first === null) {\n return false;\n }\n return (first as Record<string, unknown>)[\"model\"] === \"<model-name>\";\n}\n\nfunction run_init(options: CliOptions): number {\n if (options.positionals.length > 1) {\n throw new Error(\"init takes no extra arguments\");\n }\n const config = starter_config_object();\n apply_overrides(config, options.overrides);\n const result = write_lich_config(work_dir_of(options), config);\n process.stdout.write(`${result.message}\\n`);\n if (result.written === true && model_still_placeholder(config) === true) {\n process.stdout.write(\"next: edit the model in .lich/config.json if needed, then run `lich`\\n\");\n }\n return 0;\n}\n\nasync function run_tui_entry(config: ReturnType<typeof build_config>): Promise<number> {\n const { run_tui } = await import(\"./tui.js\");\n return run_tui(config);\n}\n\nfunction gateway_platforms(config: AgentConfig, cli_platforms: readonly string[]): readonly string[] {\n if (cli_platforms.length > 0) {\n return cli_platforms;\n }\n const configured = config.gateway?.platforms ?? [];\n return configured.length === 0 ? [\"webhook\"] : configured;\n}\n\nasync function run_gateway_entry(config: AgentConfig, platforms: string[]): Promise<number> {\n const { run_gateway } = await import(\"./gateway.js\");\n return run_gateway(config, gateway_platforms(config, platforms));\n}\n\nfunction is_main_module(): boolean {\n const entry = process.argv[1];\n if (entry === undefined) {\n return false;\n }\n return import.meta.url === pathToFileURL(path.resolve(entry)).href;\n}\n\nexport async function run_cli(argv: string[]): Promise<number> {\n const options = parse_args(argv);\n if (options.help === true) {\n process.stdout.write(`${usage_text()}\\n`);\n return 0;\n }\n if (options.version === true) {\n process.stdout.write(`${LICH_VERSION}\\n`);\n return 0;\n }\n const [first] = options.positionals;\n if (first === undefined) {\n return run_bare(options);\n }\n if (first === \"init\") {\n return run_init(options);\n }\n if (first === \"config\") {\n process.stdout.write(`${config_template()}\\n`);\n return 0;\n }\n if (first === \"update\") {\n if (options.positionals.length > 1) {\n throw new Error(\"update takes no arguments\");\n }\n return run_update(fileURLToPath(import.meta.url));\n }\n if (first === \"chat\") {\n if (options.positionals.length > 1) {\n throw new Error(\"chat mode takes no task argument\");\n }\n return run_chat(build_config_for(options, first));\n }\n if (first === \"tui\") {\n return run_tui_entry(build_config_for(options, first));\n }\n if (first === \"gateway\") {\n return run_gateway_entry(build_config_for(options, first), options.positionals.slice(1));\n }\n return run_one_shot(build_config_for(options, \"one-shot\"), options.positionals.join(\" \"));\n}\n\nif (is_main_module() === true) {\n run_cli(process.argv.slice(2))\n .then((code) => {\n process.exitCode = code;\n })\n .catch((error) => {\n process.stderr.write(`lich: ${error_message(error)}\\n`);\n process.stderr.write(\"run `lich --help` for usage\\n\");\n process.exitCode = 1;\n });\n}","/**\n * Config-file discovery for the CLI: an ordered search chain, safe loading,\n * and a starter template so `lich tui` works with zero environment setup.\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport path from \"node:path\";\nimport { safe_json_parse } from \"./util/json.js\";\n\nconst LICH_DIRNAME = \".lich\";\nconst CONFIG_RELPATH = `${LICH_DIRNAME}/config.json`;\nconst DEFAULT_USER_CONFIG = \".config/lich/config.json\";\n\n/** Ordered absolute chain: work_dir (default cwd) first, then the user config home. */\nexport function config_search_paths(work_dir?: string): string[] {\n const root = work_dir ?? process.cwd();\n const first = path.resolve(root, CONFIG_RELPATH);\n const second = path.resolve(homedir(), DEFAULT_USER_CONFIG);\n return first === second ? [first] : [first, second];\n}\n\n/** Explicit path must exist (else throw); otherwise walk the chain, undefined when absent. */\nexport function find_config_file(explicit?: string): string | undefined {\n if (explicit !== undefined) {\n if (existsSync(explicit) === false) {\n throw new Error(`config not found: ${explicit}`);\n }\n return explicit;\n }\n return existing_config_path(process.cwd());\n}\n\n/** Load the first config found as an object; undefined when absent, throw on bad json. */\nexport function load_config(explicit?: string): Record<string, unknown> | undefined {\n const found = find_config_file(explicit);\n if (found === undefined) {\n return undefined;\n }\n const raw = readFileSync(found, \"utf8\");\n const parsed = safe_json_parse<unknown>(raw);\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new Error(`invalid config json: ${found}`);\n }\n return parsed as Record<string, unknown>;\n}\n\n/** Starter config honoring LICH_* env hints; `lich config` prints it. */\nexport function config_template(): string {\n const kind = process.env.LICH_PROVIDER_KIND ?? \"ollama\";\n const provider: Record<string, unknown> = {\n kind,\n name: \"main\",\n model: process.env.LICH_MODEL ?? \"<model-name>\",\n };\n if (kind === \"ollama\") {\n provider[\"base_url\"] = \"http://localhost:11434\";\n }\n return JSON.stringify({ providers: [provider], max_turns: 25 }, null, 2);\n}\n\n/** mkdir -p `${work_dir}/.lich` and return the directory path. */\nexport function ensure_lich_config_dir(work_dir: string): string {\n const dir = path.resolve(work_dir, LICH_DIRNAME);\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n\n/** Project config path: the first entry in the search chain. */\nexport function project_config_path(work_dir: string): string {\n return path.resolve(work_dir, CONFIG_RELPATH);\n}\n\n/** First existing file on `config_search_paths(work_dir)`. */\nexport function existing_config_path(work_dir: string): string | undefined {\n for (const candidate of config_search_paths(work_dir)) {\n if (existsSync(candidate) === true) {\n return candidate;\n }\n }\n return undefined;\n}\n\nexport interface LichConfigWriteResult {\n path: string;\n written: boolean;\n message: string;\n}\n\n/** Parsed `config_template()` object. Does not write. */\nexport function starter_config_object(): Record<string, unknown> {\n const parsed: unknown = JSON.parse(config_template());\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new Error(\"config template must be a JSON object\");\n }\n return parsed as Record<string, unknown>;\n}\n\n/**\n * Create `.lich/` and write `config.json` once. The only writer of that file.\n * Existing files are left untouched.\n */\nexport function write_lich_config(work_dir: string, config: Record<string, unknown>): LichConfigWriteResult {\n ensure_lich_config_dir(work_dir);\n const file = project_config_path(work_dir);\n if (existsSync(file) === true) {\n return already_exists(file);\n }\n try {\n writeFileSync(file, `${JSON.stringify(config, null, 2)}\\n`, { encoding: \"utf8\", flag: \"wx\" });\n } catch (error) {\n if (is_eexist(error) === true) {\n return already_exists(file);\n }\n throw error;\n }\n return { path: file, written: true, message: `wrote ${file}` };\n}\n\nfunction already_exists(file: string): LichConfigWriteResult {\n return {\n path: file,\n written: false,\n message: `lich: .lich/config.json already exists at ${file}; not overwriting`,\n };\n}\n\nfunction is_eexist(error: unknown): boolean {\n return typeof error === \"object\" && error !== null && \"code\" in error && (error as { code?: unknown }).code === \"EEXIST\";\n}\n","/**\n * `lich update`: compare the installed version to the npm registry and,\n * when newer, shell out to `npm install -g @moikapy/lich@latest`.\n */\nimport { spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { LICH_VERSION } from \"./index.js\";\n\nexport const PACKAGE_NAME = \"@moikapy/lich\";\nexport const VIEW_ARGS = [\"view\", PACKAGE_NAME, \"version\"] as const;\nexport const INSTALL_ARGS = [\"install\", \"-g\", `${PACKAGE_NAME}@latest`] as const;\n\nexport type InstallKind = \"npm\" | \"git\" | \"npx\";\n\nexport interface CommandResult {\n exit_code: number;\n stdout: string;\n stderr: string;\n error_code?: string;\n}\n\nexport type CommandRunner = (command: string, args: readonly string[]) => Promise<CommandResult>;\n\nexport interface UpdateIo {\n write_stdout: (text: string) => void;\n write_stderr: (text: string) => void;\n}\n\nexport interface UpdateRequest extends UpdateIo {\n installed_version: string;\n install_kind: InstallKind;\n run_command: CommandRunner;\n}\n\ntype Semver = [number, number, number, string];\ntype VersionRelation = \"update\" | \"current\" | \"invalid\";\n\nconst NPM_MISSING =\n \"lich: npm is not on PATH. Install Node.js, or run `npm install -g @moikapy/lich@latest` once npm is available.\\n\";\nconst EXIT_FIRST_HINT =\n \"Exit any running `lich tui` or `lich gateway` first — npm cannot replace the package while those processes are running.\\n\";\n\nfunction parse_semver(version: string): Semver | null {\n const match = /^v?(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?$/.exec(version.trim());\n if (match === null || match[1] === undefined || match[2] === undefined || match[3] === undefined) {\n return null;\n }\n return [Number(match[1]), Number(match[2]), Number(match[3]), match[4] ?? \"\"];\n}\n\n/** `update` when the registry version is strictly newer than the installed one. */\nexport function version_relation(installed: string, registry: string): VersionRelation {\n const left = parse_semver(installed);\n const right = parse_semver(registry);\n if (left === null || right === null) {\n return \"invalid\";\n }\n for (let index = 0; index < 3; index += 1) {\n const installed_part = left[index];\n const registry_part = right[index];\n if (typeof installed_part !== \"number\" || typeof registry_part !== \"number\") {\n return \"invalid\";\n }\n if (installed_part < registry_part) {\n return \"update\";\n }\n if (installed_part > registry_part) {\n return \"current\";\n }\n }\n if (left[3] !== \"\" && right[3] === \"\") {\n return \"update\";\n }\n return \"current\";\n}\n\n/** npm global, a git clone (`git pull`), or an npx temporary copy. */\nexport function detect_install_kind(\n module_path: string,\n env: NodeJS.ProcessEnv,\n has_git: (dir: string) => boolean,\n): InstallKind {\n if (env.npm_command === \"exec\" || module_path.includes(`${path.sep}_npx${path.sep}`)) {\n return \"npx\";\n }\n let dir = path.dirname(path.resolve(module_path));\n const root = path.parse(dir).root;\n while (dir !== root) {\n if (path.basename(dir) === \"node_modules\") {\n return \"npm\";\n }\n if (has_git(dir) === true) {\n return \"git\";\n }\n const parent = path.dirname(dir);\n if (parent === dir) {\n break;\n }\n dir = parent;\n }\n return \"npm\";\n}\n\nfunction blocked_install_message(kind: InstallKind): string | null {\n if (kind === \"git\") {\n return \"lich: this copy is a git clone, not an npm install. Update with `git pull` in the repository.\\n\";\n }\n if (kind === \"npx\") {\n return \"lich: npx runs a temporary copy and cannot persist an update. Install with `npm install -g @moikapy/lich`.\\n\";\n }\n return null;\n}\n\nfunction registry_version(viewed: CommandResult, request: UpdateRequest): string | null {\n if (viewed.error_code === \"ENOENT\") {\n request.write_stderr(NPM_MISSING);\n return null;\n }\n if (viewed.exit_code !== 0) {\n const detail = viewed.stderr.trim() || viewed.stdout.trim() || `exit ${viewed.exit_code}`;\n request.write_stderr(`lich: could not read the registry version of ${PACKAGE_NAME}: ${detail}\\n`);\n return null;\n }\n const registry = viewed.stdout.trim();\n if (parse_semver(registry) === null) {\n request.write_stderr(`lich: could not read the registry version of ${PACKAGE_NAME}: unexpected version \"${registry}\"\\n`);\n return null;\n }\n return registry;\n}\n\nfunction is_permission_failure(installed: CommandResult): boolean {\n if (installed.error_code === \"EACCES\" || installed.error_code === \"EPERM\") {\n return true;\n }\n const text = `${installed.stderr}\\n${installed.stdout}`.toLowerCase();\n return text.includes(\"eacces\") || text.includes(\"eperm\") || text.includes(\"permission denied\");\n}\n\nfunction report_install(request: UpdateRequest, installed: CommandResult): number {\n if (installed.exit_code === 0) {\n request.write_stdout(`updated ${PACKAGE_NAME}. Run \\`lich --version\\` in a new shell to confirm.\\n`);\n return 0;\n }\n if (installed.error_code === \"ENOENT\") {\n request.write_stderr(NPM_MISSING);\n return 1;\n }\n if (is_permission_failure(installed) === true) {\n request.write_stderr(\"lich: npm install failed (permission denied). Use a writable npm prefix, or run `npm install -g @moikapy/lich@latest` yourself.\\n\");\n return 1;\n }\n const detail = installed.stderr.trim() || `exit ${installed.exit_code}`;\n request.write_stderr(`lich: npm install failed: ${detail}\\n`);\n return 1;\n}\n\nasync function install_if_newer(request: UpdateRequest, registry: string): Promise<number> {\n const relation = version_relation(request.installed_version, registry);\n if (relation === \"invalid\") {\n request.write_stderr(`lich: could not compare versions (installed ${request.installed_version}, registry ${registry})\\n`);\n return 1;\n }\n if (relation !== \"update\") {\n request.write_stdout(`lich ${request.installed_version} is up to date\\n`);\n return 0;\n }\n request.write_stdout(`lich ${request.installed_version} -> ${registry}\\n`);\n request.write_stdout(EXIT_FIRST_HINT);\n const installed = await request.run_command(\"npm\", INSTALL_ARGS);\n return report_install(request, installed);\n}\n\n/** Decide whether to install. Tests inject `run_command` so neither lookup nor install hits the network. */\nexport async function run_lich_update(request: UpdateRequest): Promise<number> {\n const blocked = blocked_install_message(request.install_kind);\n if (blocked !== null) {\n request.write_stderr(blocked);\n return 1;\n }\n const viewed = await request.run_command(\"npm\", VIEW_ARGS);\n const registry = registry_version(viewed, request);\n if (registry === null) {\n return 1;\n }\n return install_if_newer(request, registry);\n}\n\n/** Default spawn. Forwards only `npm install` output; `npm view` stays quiet. */\nexport function default_command_runner(command: string, args: readonly string[]): Promise<CommandResult> {\n return new Promise((resolve) => {\n let stdout = \"\";\n let stderr = \"\";\n let settled = false;\n const finish = (result: CommandResult): void => {\n if (settled === true) {\n return;\n }\n settled = true;\n resolve(result);\n };\n const forward = args[0] === \"install\";\n const child = spawn(command, [...args], { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n child.stdout?.on(\"data\", (chunk: Buffer) => {\n const text = chunk.toString();\n stdout += text;\n if (forward === true) {\n process.stdout.write(text);\n }\n });\n child.stderr?.on(\"data\", (chunk: Buffer) => {\n const text = chunk.toString();\n stderr += text;\n if (forward === true) {\n process.stderr.write(text);\n }\n });\n child.on(\"error\", (error: NodeJS.ErrnoException) => {\n finish({ exit_code: 127, stdout, stderr: error.message, error_code: error.code });\n });\n child.on(\"close\", (code) => {\n finish({ exit_code: code ?? 1, stdout, stderr });\n });\n });\n}\n\nexport async function run_update(module_path: string): Promise<number> {\n return run_lich_update({\n installed_version: LICH_VERSION,\n install_kind: detect_install_kind(module_path, process.env, (dir) => existsSync(path.join(dir, \".git\"))),\n run_command: default_command_runner,\n write_stdout: (text) => {\n process.stdout.write(text);\n },\n write_stderr: (text) => {\n process.stderr.write(text);\n },\n });\n}\n","/**\n * First-run setup wizard. Builds an AgentConfig object; does not write the file.\n * Callers pass the object to write_lich_config.\n */\nimport { readdirSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { Interface } from \"node:readline\";\nimport { DEFAULT_GATEWAY_TOKEN_ENVS, is_env_var_name } from \"./gateway/token_env.js\";\n\nexport type ProviderKind = \"ollama\" | \"openai_compat\" | \"anthropic\";\n\nconst PLATFORMS = [\"webhook\", \"telegram\", \"discord\", \"twitch\"] as const;\nconst PLUGIN_EXT = /\\.(mjs|js|ts|mts|cts|jsx|tsx)$/;\n\nconst PROVIDER_DEFAULTS: Record<ProviderKind, { model: string; base_url: string; api_key_env?: string }> = {\n ollama: { model: \"llama3.2\", base_url: \"http://localhost:11434\" },\n openai_compat: { model: \"gpt-4.1-mini\", base_url: \"https://api.openai.com/v1\", api_key_env: \"OPENAI_API_KEY\" },\n anthropic: { model: \"claude-sonnet-4\", base_url: \"https://api.anthropic.com\", api_key_env: \"ANTHROPIC_API_KEY\" },\n};\n\nexport interface SetupAnswers {\n agent_name: string;\n provider_kind: ProviderKind;\n model: string;\n base_url: string;\n api_key_env?: string;\n platforms: string[];\n token_envs: Record<string, string>;\n plugins: string[];\n}\n\nexport type AskLine = (prompt: string) => Promise<string | undefined>;\n\n/** Plugin entry files under `.lich/plugins`, as work_dir-relative specifiers. */\nfunction discover_plugin_entries(work_dir: string): string[] {\n const dir = path.resolve(work_dir, \".lich\", \"plugins\");\n let names: string[];\n try {\n names = readdirSync(dir);\n } catch {\n return [];\n }\n const entries: string[] = [];\n for (const name of names) {\n if (PLUGIN_EXT.test(name) === true) {\n entries.push(path.posix.join(\".lich/plugins\", name));\n }\n }\n return entries;\n}\n\n/** Object the agent schema already accepts. Omits gateway when no platforms were chosen. */\nexport function build_setup_config(answers: SetupAnswers): Record<string, unknown> {\n const provider: Record<string, unknown> = {\n kind: answers.provider_kind,\n name: \"main\",\n model: answers.model,\n base_url: answers.base_url,\n };\n if (answers.api_key_env !== undefined && answers.api_key_env.length > 0) {\n provider[\"api_key_env\"] = answers.api_key_env;\n }\n const config: Record<string, unknown> = {\n agent_name: answers.agent_name,\n providers: [provider],\n max_turns: 25,\n plugins: answers.plugins,\n };\n if (answers.platforms.length > 0) {\n config[\"gateway\"] = { platforms: answers.platforms, token_envs: answers.token_envs };\n }\n return config;\n}\n\nfunction blank_as_default(raw: string, fallback: string): string {\n const trimmed = raw.trim();\n return trimmed.length === 0 ? fallback : trimmed;\n}\n\nfunction parse_kind(raw: string): ProviderKind | undefined {\n const trimmed = raw.trim();\n const kind = trimmed.length === 0 ? \"ollama\" : trimmed;\n if (kind === \"ollama\" || kind === \"openai_compat\" || kind === \"anthropic\") {\n return kind;\n }\n return undefined;\n}\n\nfunction parse_platforms(raw: string): string[] {\n const seen = new Set<string>();\n const platforms: string[] = [];\n for (const part of raw.split(\",\")) {\n const name = part.trim().toLowerCase();\n if ((PLATFORMS as readonly string[]).includes(name) === false || seen.has(name) === true) {\n continue;\n }\n seen.add(name);\n platforms.push(name);\n }\n return platforms;\n}\n\n/** One prompt. Resolves undefined on Ctrl+C or a closed stream so nothing is written. */\nexport function ask_line(rl: Interface, prompt: string): Promise<string | undefined> {\n return new Promise((resolve) => {\n let settled = false;\n const finish = (value: string | undefined): void => {\n if (settled === true) {\n return;\n }\n settled = true;\n rl.removeListener(\"SIGINT\", on_sigint);\n rl.removeListener(\"close\", on_close);\n resolve(value);\n };\n const on_sigint = (): void => finish(undefined);\n const on_close = (): void => finish(undefined);\n rl.once(\"SIGINT\", on_sigint);\n rl.once(\"close\", on_close);\n rl.question(prompt, (answer) => finish(answer));\n });\n}\n\nasync function ask_name(ask: AskLine): Promise<string | undefined> {\n const raw = await ask(\"Agent name [lich]: \");\n if (raw === undefined) {\n return undefined;\n }\n return blank_as_default(raw, \"lich\");\n}\n\nasync function ask_provider(\n ask: AskLine,\n model_hint?: string,\n): Promise<Pick<SetupAnswers, \"provider_kind\" | \"model\" | \"base_url\" | \"api_key_env\"> | undefined> {\n const kind_raw = await ask(\"Provider kind (ollama|openai_compat|anthropic) [ollama]: \");\n if (kind_raw === undefined) {\n return undefined;\n }\n let kind = parse_kind(kind_raw);\n if (kind === undefined) {\n const retry = await ask(\"Unknown kind. Provider kind (ollama|openai_compat|anthropic) [ollama]: \");\n if (retry === undefined) {\n return undefined;\n }\n kind = parse_kind(retry) ?? \"ollama\";\n }\n const defaults = PROVIDER_DEFAULTS[kind];\n const model_default = model_hint !== undefined && model_hint.length > 0 ? model_hint : defaults.model;\n const model_raw = await ask(`Model [${model_default}]: `);\n if (model_raw === undefined) {\n return undefined;\n }\n const url_raw = await ask(`Base URL [${defaults.base_url}]: `);\n if (url_raw === undefined) {\n return undefined;\n }\n const key_default = defaults.api_key_env ?? \"\";\n const key_prompt = key_default.length === 0 ? \"API key env var name (empty to skip): \" : `API key env var name [${key_default}]: `;\n const key_raw = await ask(key_prompt);\n if (key_raw === undefined) {\n return undefined;\n }\n const api_key_env = blank_as_default(key_raw, key_default);\n return {\n provider_kind: kind,\n model: blank_as_default(model_raw, model_default),\n base_url: blank_as_default(url_raw, defaults.base_url),\n api_key_env: api_key_env.length === 0 ? undefined : api_key_env,\n };\n}\n\nfunction token_env_name(raw: string, fallback: string): string | undefined {\n const name = blank_as_default(raw, fallback);\n return is_env_var_name(name) === true ? name : undefined;\n}\n\nasync function ask_token_env(ask: AskLine, platform: string, fallback: string): Promise<string | undefined> {\n const first = await ask(`${platform} token env var [${fallback}] (name only, not the secret): `);\n if (first === undefined) {\n return undefined;\n }\n const named = token_env_name(first, fallback);\n if (named !== undefined) {\n return named;\n }\n const retry = await ask(`Env var name must match [A-Za-z_][A-Za-z0-9_]* [${fallback}]: `);\n if (retry === undefined) {\n return undefined;\n }\n return token_env_name(retry, fallback);\n}\n\nasync function ask_gateway(ask: AskLine): Promise<{ platforms: string[]; token_envs: Record<string, string> } | undefined> {\n const raw = await ask(\"Gateway platforms (webhook,telegram,discord,twitch; empty to skip): \");\n if (raw === undefined) {\n return undefined;\n }\n const platforms = parse_platforms(raw);\n const token_envs: Record<string, string> = {};\n for (const platform of platforms) {\n const name = await ask_token_env(ask, platform, DEFAULT_GATEWAY_TOKEN_ENVS[platform] ?? \"\");\n if (name === undefined) {\n return undefined;\n }\n token_envs[platform] = name;\n }\n return { platforms, token_envs };\n}\n\nasync function ask_plugins(work_dir: string, ask: AskLine): Promise<string[] | undefined> {\n const found = discover_plugin_entries(work_dir);\n if (found.length === 0) {\n return [];\n }\n const enabled: string[] = [];\n for (const entry of found) {\n const answer = await ask(`Enable plugin ${entry}? [y/N]: `);\n if (answer === undefined) {\n return undefined;\n }\n const yes = answer.trim().toLowerCase();\n if (yes === \"y\" || yes === \"yes\") {\n enabled.push(entry);\n }\n }\n return enabled;\n}\n\n/** All steps skippable. Undefined means Ctrl+C or a rejected env name: caller must not write. */\nexport async function collect_setup_answers(work_dir: string, ask: AskLine, model_hint?: string): Promise<SetupAnswers | undefined> {\n const agent_name = await ask_name(ask);\n if (agent_name === undefined) {\n return undefined;\n }\n const provider = await ask_provider(ask, model_hint);\n if (provider === undefined) {\n return undefined;\n }\n const gateway = await ask_gateway(ask);\n if (gateway === undefined) {\n return undefined;\n }\n const plugins = await ask_plugins(work_dir, ask);\n if (plugins === undefined) {\n return undefined;\n }\n return { agent_name, ...provider, platforms: gateway.platforms, token_envs: gateway.token_envs, plugins };\n}\n"],"mappings":"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","names":["readFileSync","path","existsSync","path","path","existsSync","path","path","model_hint","value","readFileSync","ask_line","path"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/cli_config.ts","../src/cli_update.ts","../src/setup_wizard.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Thin zero-dependency CLI for lich: one-shot tasks, interactive chat,\n * config files, and environment-based provider resolution.\n */\nimport { existsSync, readFileSync, realpathSync } from \"node:fs\";\nimport { createInterface, type Interface } from \"node:readline\";\nimport path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { create_agent_with_plugins, type Agent, type AgentRunResult } from \"./agent/agent.js\";\nimport { parse_agent_config, type AgentConfig } from \"./agent/config.js\";\nimport { AgentEmitter } from \"./agent/events.js\";\nimport { LICH_VERSION } from \"./index.js\";\nimport { load_config, config_template, existing_config_path, starter_config_object, write_lich_config } from \"./cli_config.js\";\nimport { run_update } from \"./cli_update.js\";\nimport { ask_line as ask_wizard_line, build_setup_config, collect_setup_answers } from \"./setup_wizard.js\";\n\ntype ProviderKind = \"openai_compat\" | \"anthropic\" | \"ollama\";\n\ninterface CliOptions {\n config_path?: string;\n help?: boolean;\n version?: boolean;\n overrides: Record<string, string>;\n positionals: string[];\n}\n\nconst FLAG_KEYS: Record<string, string> = {\n \"--work-dir\": \"work_dir\",\n \"--max-turns\": \"max_turns\",\n \"--model\": \"provider_model\",\n \"--provider-kind\": \"provider_kind\",\n \"--base-url\": \"provider_base_url\",\n \"--api-key-env\": \"provider_api_key_env\",\n \"--system-prompt\": \"system_prompt\",\n \"--session-dir\": \"session_dir\",\n \"--log-level\": \"log_level\",\n};\n\nconst DEFAULT_BASE_URLS: Record<ProviderKind, string> = {\n openai_compat: \"https://api.openai.com/v1\",\n anthropic: \"https://api.anthropic.com\",\n ollama: \"http://localhost:11434\",\n};\n\nconst DEFAULT_ENV_API_KEYS: Record<ProviderKind, string | undefined> = {\n openai_compat: \"OPENAI_API_KEY\",\n anthropic: \"ANTHROPIC_API_KEY\",\n ollama: undefined, // ollama needs no api key\n};\n\nfunction usage_text(): string {\n return [\n \"lich — a TypeScript AI agent harness\",\n \"\",\n \"Usage:\",\n \" lich open the TUI (first run: setup wizard, then TUI)\",\n \" lich init write .lich/config.json without the wizard (flags apply; never overwrites)\",\n ' lich \"one shot task\" run a single task and print the reply',\n \" lich chat interactive chat (commands: /exit, /quit)\",\n \" lich tui interactive terminal UI (ink)\",\n \" lich gateway <plat..> messaging gateway (webhook|telegram|discord|twitch)\",\n \" lich config print a starter config template (save as .lich/config.json)\",\n \" lich update install a newer @moikapy/lich from npm, if one exists\",\n \" lich --help show this help\",\n \" lich --version print version\",\n \"\",\n \"Flags (before or after the subcommand):\",\n \" --config <path> JSON config file parsed by parse_agent_config\",\n \" --work-dir <path> working directory for tools\",\n \" --max-turns <n> loop turn budget (default 25)\",\n \" --model <m> model name (default from LICH_MODEL)\",\n \" --provider-kind <k> openai_compat | anthropic | ollama (default LICH_PROVIDER_KIND)\",\n \" --base-url <u> provider base url (default LICH_BASE_URL)\",\n \" --api-key-env <NAME> env var holding the api key (default LICH_API_KEY_ENV; unused by ollama)\",\n \" --system-prompt <s> system prompt override\",\n \" --session-dir <path> session transcript directory\",\n \" --log-level <level> debug | info | warn | error\",\n ].join(\"\\n\");\n}\n\nfunction error_message(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/** Mode-aware config failure message; one-shot keeps the generic variant. */\nfunction error_for_mode(mode: string, base_message: string): string {\n if (mode === \"tui\") {\n return \"lich tui: no model configured — set LICH_MODEL (e.g. glm-5.3-flash:cloud), pass --model, or create .lich/config.json (`lich config` prints a template)\";\n }\n if (mode === \"gateway\") {\n return \"lich gateway: no model configured — set LICH_MODEL (e.g. glm-5.3-flash:cloud), pass --model, or create .lich/config.json (`lich config` prints a template)\";\n }\n if (mode === \"chat\") {\n return \"lich chat: no model configured — set LICH_MODEL (e.g. glm-5.3-flash:cloud), pass --model, or create .lich/config.json (`lich config` prints a template)\";\n }\n return base_message;\n}\n\nfunction parse_args(argv: string[]): CliOptions {\n const options: CliOptions = { overrides: {}, positionals: [] };\n for (let index = 0; index < argv.length; index += 1) {\n const arg = argv[index];\n if (arg === undefined) {\n break;\n }\n if (arg === \"--help\") {\n options.help = true;\n continue;\n }\n if (arg === \"--version\") {\n options.version = true;\n continue;\n }\n if (arg === \"--config\") {\n const value = argv[index + 1];\n if (value === undefined) {\n throw new Error(\"--config requires a path\");\n }\n options.config_path = value;\n index += 1;\n continue;\n }\n const override_key = FLAG_KEYS[arg];\n if (override_key === undefined) {\n if (arg.startsWith(\"--\") === true) {\n throw new Error(`unknown flag: ${arg}`);\n }\n options.positionals.push(arg);\n continue;\n }\n const value = argv[index + 1];\n if (value === undefined || value.startsWith(\"--\") === true) {\n throw new Error(`${arg} requires a value`);\n }\n options.overrides[override_key] = value;\n index += 1;\n }\n return options;\n}\n\nfunction env_provider(overrides: Record<string, string>): Record<string, unknown> {\n const kind_value = overrides[\"provider_kind\"] ?? process.env.LICH_PROVIDER_KIND ?? \"openai_compat\";\n if (kind_value !== \"openai_compat\" && kind_value !== \"anthropic\" && kind_value !== \"ollama\") {\n throw new Error(`unknown provider kind \"${kind_value}\" (expected openai_compat, anthropic, or ollama)`);\n }\n const kind: ProviderKind = kind_value;\n const model = overrides[\"provider_model\"] ?? process.env.LICH_MODEL;\n if (model === undefined || model.length === 0) {\n throw new Error(\"no model configured: set LICH_MODEL, pass --model, or create .lich/config.json (`lich config` prints a template)\");\n }\n return {\n kind,\n name: \"default\",\n model,\n base_url: overrides[\"provider_base_url\"] ?? process.env.LICH_BASE_URL ?? DEFAULT_BASE_URLS[kind],\n api_key_env: overrides[\"provider_api_key_env\"] ?? process.env.LICH_API_KEY_ENV ?? DEFAULT_ENV_API_KEYS[kind],\n };\n}\n\nfunction load_config_file(config_path: string): Record<string, unknown> {\n try {\n const raw = readFileSync(config_path, \"utf8\");\n const parsed = JSON.parse(raw) as unknown;\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new Error(\"config root must be a JSON object\");\n }\n return parsed as Record<string, unknown>;\n } catch (error) {\n throw new Error(`cannot use config file ${config_path}: ${error_message(error)}`);\n }\n}\n\nfunction apply_provider_override(config: Record<string, unknown>, overrides: Record<string, string>): void {\n const keys = [\"provider_kind\", \"provider_model\", \"provider_base_url\", \"provider_api_key_env\"] as const;\n const any_present = keys.some((key) => overrides[key] !== undefined);\n if (any_present === false) {\n return;\n }\n const providers = config[\"providers\"];\n if (Array.isArray(providers) === false || providers.length === 0) {\n config[\"providers\"] = [env_provider(overrides)];\n return;\n }\n const first = providers[0];\n if (typeof first !== \"object\" || first === null) {\n throw new Error(\"config providers[0] must be an object\");\n }\n const provider = first as Record<string, unknown>;\n for (const key of keys) {\n const value = overrides[key];\n if (value !== undefined) {\n provider[key.replace(\"provider_\", \"\")] = value;\n }\n }\n}\n\nfunction apply_overrides(config: Record<string, unknown>, overrides: Record<string, string>): void {\n for (const key of [\"work_dir\", \"system_prompt\", \"session_dir\", \"log_level\"]) {\n if (overrides[key] !== undefined) {\n config[key] = overrides[key];\n }\n }\n if (overrides[\"max_turns\"] !== undefined) {\n const turns = Number(overrides[\"max_turns\"]);\n if (Number.isInteger(turns) === false || turns < 1) {\n throw new Error(\"--max-turns must be a positive integer\");\n }\n config[\"max_turns\"] = turns;\n }\n apply_provider_override(config, overrides);\n}\n\n/** Same search as the wizard: `--work-dir` (else cwd), then the user-home file. */\nfunction load_discovered_config(work_dir: string): Record<string, unknown> | undefined {\n const found = existing_config_path(work_dir);\n if (found === undefined) {\n return undefined;\n }\n return load_config(found);\n}\n\nfunction build_config(options: CliOptions): AgentConfig {\n const base =\n options.config_path === undefined\n ? load_discovered_config(work_dir_of(options)) ?? { providers: [env_provider(options.overrides)] }\n : load_config_file(options.config_path);\n apply_overrides(base, options.overrides);\n const providers = base[\"providers\"];\n if (Array.isArray(providers) === false || providers.length === 0) {\n throw new Error(\"no model configured: set LICH_MODEL, pass --model, or create .lich/config.json (`lich config` prints a template)\");\n }\n return parse_agent_config(base);\n}\n\n/** build_config with the failure message prefixed for the invoking subcommand. */\nfunction build_config_for(options: CliOptions, mode: string): AgentConfig {\n try {\n return build_config(options);\n } catch (error) {\n throw new Error(error_for_mode(mode, error_message(error)));\n }\n}\n\nfunction attach_progress(emitter: AgentEmitter): () => void {\n return emitter.on((event) => {\n if (event.type === \"turn_start\") {\n process.stderr.write(`\\n[lich] turn ${event.turn}`);\n return;\n }\n if (event.type === \"tool_call_end\") {\n const status = event.result.ok === true ? \"ok\" : `error: ${event.result.error ?? \"\"}`;\n process.stderr.write(`\\n[lich] ${event.call.name}: ${status}`);\n return;\n }\n if (event.type === \"final\") {\n process.stderr.write(\"\\n\");\n }\n });\n}\n\nexport async function run_one_shot(config: unknown, input: string): Promise<number> {\n const agent = await create_agent_with_plugins(config);\n const stop_progress = attach_progress(agent.events);\n let result: AgentRunResult;\n try {\n result = await agent.run({ input });\n } finally {\n stop_progress();\n }\n const final = result.outcome.final;\n if (final !== undefined && final.content.length > 0) {\n process.stdout.write(`${final.content}\\n`);\n }\n if (result.outcome.stopped_reason === \"budget\") {\n process.stderr.write(`[lich] budget exhausted after ${result.outcome.turns_used} turns\\n`);\n return 1;\n }\n if (result.outcome.stopped_reason === \"aborted\") {\n process.stderr.write(\"[lich] run aborted\\n\");\n return 1;\n }\n return 0;\n}\n\nasync function run_chat_turn(agent: Agent, input: string): Promise<void> {\n const stop_progress = attach_progress(agent.events);\n try {\n const result = await agent.run({ input });\n const final = result.outcome.final;\n if (final !== undefined && final.content.length > 0) {\n process.stdout.write(`${final.content}\\n`);\n }\n process.stdout.write(`[turns ${result.outcome.turns_used} | tokens ${result.usage_total.total_tokens}]\\n`);\n } catch (error) {\n process.stderr.write(`[lich] ${error_message(error)}\\n`);\n } finally {\n stop_progress();\n }\n}\n\nfunction ask_line(rl: Interface): Promise<string> {\n return new Promise((resolve) => {\n const on_close = (): void => resolve(\"\");\n rl.question(\"> \", (answer) => {\n rl.removeListener(\"close\", on_close);\n resolve(answer);\n });\n rl.once(\"close\", on_close);\n });\n}\n\nexport async function run_chat(config: unknown): Promise<number> {\n const agent = await create_agent_with_plugins(config);\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n try {\n for (;;) {\n const line = await ask_line(rl);\n if (line.trim() === \"\") {\n return 0;\n }\n const command = line.trim();\n if (command === \"/exit\" || command === \"/quit\") {\n return 0;\n }\n await run_chat_turn(agent, command);\n }\n } finally {\n rl.close();\n }\n}\n\nfunction model_hint(options: CliOptions): string | undefined {\n const model = options.overrides[\"provider_model\"] ?? process.env.LICH_MODEL;\n if (model === undefined || model.length === 0) {\n return undefined;\n }\n return model;\n}\n\nfunction skip_setup_message(existing: string): string {\n if (existing.endsWith(`${path.sep}.lich${path.sep}config.json`) === true) {\n return `lich: .lich/config.json already exists at ${existing}; skipping setup`;\n }\n return `lich: config already exists at ${existing}; skipping setup`;\n}\n\nfunction work_dir_of(options: CliOptions): string {\n return options.overrides[\"work_dir\"] ?? process.cwd();\n}\n\nasync function offer_wizard(work_dir: string, hint?: string): Promise<string | \"cancelled\"> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n try {\n const answers = await collect_setup_answers(work_dir, (prompt) => ask_wizard_line(rl, prompt), hint);\n if (answers === undefined) {\n return \"cancelled\";\n }\n const result = write_lich_config(work_dir, build_setup_config(answers));\n process.stdout.write(`${result.message}\\n`);\n return result.path;\n } finally {\n rl.close();\n }\n}\n\nasync function maybe_first_run(options: CliOptions, work_dir: string): Promise<number | undefined> {\n if (options.config_path !== undefined) {\n return undefined;\n }\n const existing = existing_config_path(work_dir);\n if (existing !== undefined) {\n process.stdout.write(`${skip_setup_message(existing)}\\n`);\n options.config_path = existing;\n return undefined;\n }\n const wrote = await offer_wizard(work_dir, model_hint(options));\n if (wrote === \"cancelled\") {\n process.stderr.write(\"lich: setup cancelled; nothing written\\n\");\n return 1;\n }\n options.config_path = wrote;\n return undefined;\n}\n\nasync function run_bare(options: CliOptions): Promise<number> {\n if (process.stdin.isTTY !== true) {\n process.stderr.write(\"lich: stdin is not a TTY; skipping setup wizard. Run `lich init` to write .lich/config.json, or `lich --help` for usage.\\n\");\n return 1;\n }\n const work_dir = work_dir_of(options);\n const stopped = await maybe_first_run(options, work_dir);\n if (stopped !== undefined) {\n return stopped;\n }\n return run_tui_entry(build_config_for(options, \"tui\"));\n}\n\nfunction model_still_placeholder(config: Record<string, unknown>): boolean {\n const providers = config[\"providers\"];\n const first = Array.isArray(providers) === true ? providers[0] : undefined;\n if (typeof first !== \"object\" || first === null) {\n return false;\n }\n return (first as Record<string, unknown>)[\"model\"] === \"<model-name>\";\n}\n\nfunction run_init(options: CliOptions): number {\n if (options.positionals.length > 1) {\n throw new Error(\"init takes no extra arguments\");\n }\n const config = starter_config_object();\n apply_overrides(config, options.overrides);\n const result = write_lich_config(work_dir_of(options), config);\n process.stdout.write(`${result.message}\\n`);\n if (result.written === true && model_still_placeholder(config) === true) {\n process.stdout.write(\"next: edit the model in .lich/config.json if needed, then run `lich`\\n\");\n }\n return 0;\n}\n\nasync function run_tui_entry(config: ReturnType<typeof build_config>): Promise<number> {\n const { run_tui } = await import(\"./tui.js\");\n return run_tui(config);\n}\n\nfunction gateway_platforms(config: AgentConfig, cli_platforms: readonly string[]): readonly string[] {\n if (cli_platforms.length > 0) {\n return cli_platforms;\n }\n const configured = config.gateway?.platforms ?? [];\n return configured.length === 0 ? [\"webhook\"] : configured;\n}\n\nasync function run_gateway_entry(config: AgentConfig, platforms: string[]): Promise<number> {\n const { run_gateway } = await import(\"./gateway.js\");\n return run_gateway(config, gateway_platforms(config, platforms));\n}\n\nexport interface CliEntryInput {\n bun: boolean;\n import_meta_main: boolean | undefined;\n module_url: string;\n argv1: string | undefined;\n}\n\n/** Bun uses `import.meta.main`. Node compares argv to this file, including a bin symlink. */\nexport function is_cli_entry(input: CliEntryInput): boolean {\n if (input.bun === true) {\n return input.import_meta_main === true;\n }\n return node_entry_matches(input.module_url, input.argv1);\n}\n\nfunction is_main_module(): boolean {\n return is_cli_entry({\n bun: process.versions.bun !== undefined,\n import_meta_main: import.meta.main,\n module_url: import.meta.url,\n argv1: process.argv[1],\n });\n}\n\nfunction node_entry_matches(module_url: string, entry: string | undefined): boolean {\n if (entry === undefined || entry === \"\") {\n return false;\n }\n const resolved = path.resolve(entry);\n if (module_url === pathToFileURL(resolved).href) {\n return true;\n }\n return same_real_file(fileURLToPath(module_url), resolved);\n}\n\nfunction same_real_file(left: string, right: string): boolean {\n if (existsSync(left) === false || existsSync(right) === false) {\n return false;\n }\n return realpathSync(left) === realpathSync(right);\n}\n\nexport async function run_cli(argv: string[]): Promise<number> {\n const options = parse_args(argv);\n if (options.help === true) {\n process.stdout.write(`${usage_text()}\\n`);\n return 0;\n }\n if (options.version === true) {\n process.stdout.write(`${LICH_VERSION}\\n`);\n return 0;\n }\n const [first] = options.positionals;\n if (first === undefined) {\n return run_bare(options);\n }\n if (first === \"init\") {\n return run_init(options);\n }\n if (first === \"config\") {\n process.stdout.write(`${config_template()}\\n`);\n return 0;\n }\n if (first === \"update\") {\n if (options.positionals.length > 1) {\n throw new Error(\"update takes no arguments\");\n }\n return run_update(fileURLToPath(import.meta.url));\n }\n if (first === \"chat\") {\n if (options.positionals.length > 1) {\n throw new Error(\"chat mode takes no task argument\");\n }\n return run_chat(build_config_for(options, first));\n }\n if (first === \"tui\") {\n return run_tui_entry(build_config_for(options, first));\n }\n if (first === \"gateway\") {\n return run_gateway_entry(build_config_for(options, first), options.positionals.slice(1));\n }\n return run_one_shot(build_config_for(options, \"one-shot\"), options.positionals.join(\" \"));\n}\n\nif (is_main_module() === true) {\n run_cli(process.argv.slice(2))\n .then((code) => {\n process.exitCode = code;\n })\n .catch((error) => {\n process.stderr.write(`lich: ${error_message(error)}\\n`);\n process.stderr.write(\"run `lich --help` for usage\\n\");\n process.exitCode = 1;\n });\n}","/**\n * Config-file discovery for the CLI: an ordered search chain, safe loading,\n * and a starter template so `lich tui` works with zero environment setup.\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport path from \"node:path\";\nimport { safe_json_parse } from \"./util/json.js\";\n\nconst LICH_DIRNAME = \".lich\";\nconst CONFIG_RELPATH = `${LICH_DIRNAME}/config.json`;\nconst DEFAULT_USER_CONFIG = \".config/lich/config.json\";\n\n/** Ordered absolute chain: work_dir (default cwd) first, then the user config home. */\nexport function config_search_paths(work_dir?: string): string[] {\n const root = work_dir ?? process.cwd();\n const first = path.resolve(root, CONFIG_RELPATH);\n const second = path.resolve(homedir(), DEFAULT_USER_CONFIG);\n return first === second ? [first] : [first, second];\n}\n\n/** Explicit path must exist (else throw); otherwise walk the chain, undefined when absent. */\nexport function find_config_file(explicit?: string): string | undefined {\n if (explicit !== undefined) {\n if (existsSync(explicit) === false) {\n throw new Error(`config not found: ${explicit}`);\n }\n return explicit;\n }\n return existing_config_path(process.cwd());\n}\n\n/** Load the first config found as an object; undefined when absent, throw on bad json. */\nexport function load_config(explicit?: string): Record<string, unknown> | undefined {\n const found = find_config_file(explicit);\n if (found === undefined) {\n return undefined;\n }\n const raw = readFileSync(found, \"utf8\");\n const parsed = safe_json_parse<unknown>(raw);\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new Error(`invalid config json: ${found}`);\n }\n return parsed as Record<string, unknown>;\n}\n\n/** Starter config honoring LICH_* env hints; `lich config` prints it. */\nexport function config_template(): string {\n const kind = process.env.LICH_PROVIDER_KIND ?? \"ollama\";\n const provider: Record<string, unknown> = {\n kind,\n name: \"main\",\n model: process.env.LICH_MODEL ?? \"<model-name>\",\n };\n if (kind === \"ollama\") {\n provider[\"base_url\"] = \"http://localhost:11434\";\n }\n return JSON.stringify({ providers: [provider], max_turns: 25 }, null, 2);\n}\n\n/** mkdir -p `${work_dir}/.lich` and return the directory path. */\nexport function ensure_lich_config_dir(work_dir: string): string {\n const dir = path.resolve(work_dir, LICH_DIRNAME);\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n\n/** Project config path: the first entry in the search chain. */\nexport function project_config_path(work_dir: string): string {\n return path.resolve(work_dir, CONFIG_RELPATH);\n}\n\n/** First existing file on `config_search_paths(work_dir)`. */\nexport function existing_config_path(work_dir: string): string | undefined {\n for (const candidate of config_search_paths(work_dir)) {\n if (existsSync(candidate) === true) {\n return candidate;\n }\n }\n return undefined;\n}\n\nexport interface LichConfigWriteResult {\n path: string;\n written: boolean;\n message: string;\n}\n\n/** Parsed `config_template()` object. Does not write. */\nexport function starter_config_object(): Record<string, unknown> {\n const parsed: unknown = JSON.parse(config_template());\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new Error(\"config template must be a JSON object\");\n }\n return parsed as Record<string, unknown>;\n}\n\n/**\n * Create `.lich/` and write `config.json` once. The only writer of that file.\n * Existing files are left untouched.\n */\nexport function write_lich_config(work_dir: string, config: Record<string, unknown>): LichConfigWriteResult {\n ensure_lich_config_dir(work_dir);\n const file = project_config_path(work_dir);\n if (existsSync(file) === true) {\n return already_exists(file);\n }\n try {\n writeFileSync(file, `${JSON.stringify(config, null, 2)}\\n`, { encoding: \"utf8\", flag: \"wx\" });\n } catch (error) {\n if (is_eexist(error) === true) {\n return already_exists(file);\n }\n throw error;\n }\n return { path: file, written: true, message: `wrote ${file}` };\n}\n\nfunction already_exists(file: string): LichConfigWriteResult {\n return {\n path: file,\n written: false,\n message: `lich: .lich/config.json already exists at ${file}; not overwriting`,\n };\n}\n\nfunction is_eexist(error: unknown): boolean {\n return typeof error === \"object\" && error !== null && \"code\" in error && (error as { code?: unknown }).code === \"EEXIST\";\n}\n","/**\n * `lich update`: compare the installed version to the npm registry and,\n * when newer, shell out to `npm install -g @moikapy/lich@latest`.\n */\nimport { spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { LICH_VERSION } from \"./index.js\";\n\nexport const PACKAGE_NAME = \"@moikapy/lich\";\nexport const VIEW_ARGS = [\"view\", PACKAGE_NAME, \"version\"] as const;\nexport const INSTALL_ARGS = [\"install\", \"-g\", `${PACKAGE_NAME}@latest`] as const;\n\nexport type InstallKind = \"npm\" | \"git\" | \"npx\";\n\nexport interface CommandResult {\n exit_code: number;\n stdout: string;\n stderr: string;\n error_code?: string;\n}\n\nexport type CommandRunner = (command: string, args: readonly string[]) => Promise<CommandResult>;\n\nexport interface UpdateIo {\n write_stdout: (text: string) => void;\n write_stderr: (text: string) => void;\n}\n\nexport interface UpdateRequest extends UpdateIo {\n installed_version: string;\n install_kind: InstallKind;\n run_command: CommandRunner;\n}\n\ntype Semver = [number, number, number, string];\ntype VersionRelation = \"update\" | \"current\" | \"invalid\";\n\nconst NPM_MISSING =\n \"lich: npm is not on PATH. Install Node.js, or run `npm install -g @moikapy/lich@latest` once npm is available.\\n\";\nconst EXIT_FIRST_HINT =\n \"Exit any running `lich tui` or `lich gateway` first — npm cannot replace the package while those processes are running.\\n\";\n\nfunction parse_semver(version: string): Semver | null {\n const match = /^v?(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?$/.exec(version.trim());\n if (match === null || match[1] === undefined || match[2] === undefined || match[3] === undefined) {\n return null;\n }\n return [Number(match[1]), Number(match[2]), Number(match[3]), match[4] ?? \"\"];\n}\n\n/** `update` when the registry version is strictly newer than the installed one. */\nexport function version_relation(installed: string, registry: string): VersionRelation {\n const left = parse_semver(installed);\n const right = parse_semver(registry);\n if (left === null || right === null) {\n return \"invalid\";\n }\n for (let index = 0; index < 3; index += 1) {\n const installed_part = left[index];\n const registry_part = right[index];\n if (typeof installed_part !== \"number\" || typeof registry_part !== \"number\") {\n return \"invalid\";\n }\n if (installed_part < registry_part) {\n return \"update\";\n }\n if (installed_part > registry_part) {\n return \"current\";\n }\n }\n if (left[3] !== \"\" && right[3] === \"\") {\n return \"update\";\n }\n return \"current\";\n}\n\n/** npm global, a git clone (`git pull`), or an npx temporary copy. */\nexport function detect_install_kind(\n module_path: string,\n env: NodeJS.ProcessEnv,\n has_git: (dir: string) => boolean,\n): InstallKind {\n if (env.npm_command === \"exec\" || module_path.includes(`${path.sep}_npx${path.sep}`)) {\n return \"npx\";\n }\n let dir = path.dirname(path.resolve(module_path));\n const root = path.parse(dir).root;\n while (dir !== root) {\n if (path.basename(dir) === \"node_modules\") {\n return \"npm\";\n }\n if (has_git(dir) === true) {\n return \"git\";\n }\n const parent = path.dirname(dir);\n if (parent === dir) {\n break;\n }\n dir = parent;\n }\n return \"npm\";\n}\n\nfunction blocked_install_message(kind: InstallKind): string | null {\n if (kind === \"git\") {\n return \"lich: this copy is a git clone, not an npm install. Update with `git pull` in the repository.\\n\";\n }\n if (kind === \"npx\") {\n return \"lich: npx runs a temporary copy and cannot persist an update. Install with `npm install -g @moikapy/lich`.\\n\";\n }\n return null;\n}\n\nfunction registry_version(viewed: CommandResult, request: UpdateRequest): string | null {\n if (viewed.error_code === \"ENOENT\") {\n request.write_stderr(NPM_MISSING);\n return null;\n }\n if (viewed.exit_code !== 0) {\n const detail = viewed.stderr.trim() || viewed.stdout.trim() || `exit ${viewed.exit_code}`;\n request.write_stderr(`lich: could not read the registry version of ${PACKAGE_NAME}: ${detail}\\n`);\n return null;\n }\n const registry = viewed.stdout.trim();\n if (parse_semver(registry) === null) {\n request.write_stderr(`lich: could not read the registry version of ${PACKAGE_NAME}: unexpected version \"${registry}\"\\n`);\n return null;\n }\n return registry;\n}\n\nfunction is_permission_failure(installed: CommandResult): boolean {\n if (installed.error_code === \"EACCES\" || installed.error_code === \"EPERM\") {\n return true;\n }\n const text = `${installed.stderr}\\n${installed.stdout}`.toLowerCase();\n return text.includes(\"eacces\") || text.includes(\"eperm\") || text.includes(\"permission denied\");\n}\n\nfunction report_install(request: UpdateRequest, installed: CommandResult): number {\n if (installed.exit_code === 0) {\n request.write_stdout(`updated ${PACKAGE_NAME}. Run \\`lich --version\\` in a new shell to confirm.\\n`);\n return 0;\n }\n if (installed.error_code === \"ENOENT\") {\n request.write_stderr(NPM_MISSING);\n return 1;\n }\n if (is_permission_failure(installed) === true) {\n request.write_stderr(\"lich: npm install failed (permission denied). Use a writable npm prefix, or run `npm install -g @moikapy/lich@latest` yourself.\\n\");\n return 1;\n }\n const detail = installed.stderr.trim() || `exit ${installed.exit_code}`;\n request.write_stderr(`lich: npm install failed: ${detail}\\n`);\n return 1;\n}\n\nasync function install_if_newer(request: UpdateRequest, registry: string): Promise<number> {\n const relation = version_relation(request.installed_version, registry);\n if (relation === \"invalid\") {\n request.write_stderr(`lich: could not compare versions (installed ${request.installed_version}, registry ${registry})\\n`);\n return 1;\n }\n if (relation !== \"update\") {\n request.write_stdout(`lich ${request.installed_version} is up to date\\n`);\n return 0;\n }\n request.write_stdout(`lich ${request.installed_version} -> ${registry}\\n`);\n request.write_stdout(EXIT_FIRST_HINT);\n const installed = await request.run_command(\"npm\", INSTALL_ARGS);\n return report_install(request, installed);\n}\n\n/** Decide whether to install. Tests inject `run_command` so neither lookup nor install hits the network. */\nexport async function run_lich_update(request: UpdateRequest): Promise<number> {\n const blocked = blocked_install_message(request.install_kind);\n if (blocked !== null) {\n request.write_stderr(blocked);\n return 1;\n }\n const viewed = await request.run_command(\"npm\", VIEW_ARGS);\n const registry = registry_version(viewed, request);\n if (registry === null) {\n return 1;\n }\n return install_if_newer(request, registry);\n}\n\nfunction running_under_bun(): boolean {\n return process.versions.bun !== undefined;\n}\n\n/** Default spawn. Forwards only `npm install` output; `npm view` stays quiet. */\nexport function default_command_runner(command: string, args: readonly string[]): Promise<CommandResult> {\n if (running_under_bun() === true) {\n return bun_command_runner(command, args);\n }\n return node_command_runner(command, args);\n}\n\nfunction node_command_runner(command: string, args: readonly string[]): Promise<CommandResult> {\n return new Promise((resolve) => {\n let stdout = \"\";\n let stderr = \"\";\n let settled = false;\n const finish = (result: CommandResult): void => {\n if (settled === true) {\n return;\n }\n settled = true;\n resolve(result);\n };\n const forward = args[0] === \"install\";\n const child = spawn(command, [...args], { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n child.stdout?.on(\"data\", (chunk: Buffer) => {\n const text = chunk.toString();\n stdout += text;\n if (forward === true) {\n process.stdout.write(text);\n }\n });\n child.stderr?.on(\"data\", (chunk: Buffer) => {\n const text = chunk.toString();\n stderr += text;\n if (forward === true) {\n process.stderr.write(text);\n }\n });\n child.on(\"error\", (error: NodeJS.ErrnoException) => {\n finish({ exit_code: 127, stdout, stderr: error.message, error_code: error.code });\n });\n child.on(\"close\", (code) => {\n finish({ exit_code: code ?? 1, stdout, stderr });\n });\n });\n}\n\nasync function read_piped_text(\n stream: ReadableStream<Uint8Array>,\n forward: boolean,\n write: (text: string) => void,\n): Promise<string> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let text = \"\";\n for (;;) {\n const next = await reader.read();\n if (next.done === true) {\n return text;\n }\n const chunk = decoder.decode(next.value, { stream: true });\n text += chunk;\n if (forward === true) {\n write(chunk);\n }\n }\n}\n\nfunction bun_command_runner(command: string, args: readonly string[]): Promise<CommandResult> {\n const forward = args[0] === \"install\";\n try {\n const child = Bun.spawn([command, ...args], {\n stdin: \"ignore\",\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n return Promise.all([\n read_piped_text(child.stdout, forward, (text) => {\n process.stdout.write(text);\n }),\n read_piped_text(child.stderr, forward, (text) => {\n process.stderr.write(text);\n }),\n child.exited,\n ]).then(([stdout, stderr, exit_code]) => ({ exit_code, stdout, stderr }));\n } catch (error) {\n const coded = error as { code?: string; message?: string };\n const stderr = typeof coded.message === \"string\" ? coded.message : \"spawn failed\";\n return Promise.resolve({ exit_code: 127, stdout: \"\", stderr, error_code: coded.code });\n }\n}\n\nexport async function run_update(module_path: string): Promise<number> {\n return run_lich_update({\n installed_version: LICH_VERSION,\n install_kind: detect_install_kind(module_path, process.env, (dir) => existsSync(path.join(dir, \".git\"))),\n run_command: default_command_runner,\n write_stdout: (text) => {\n process.stdout.write(text);\n },\n write_stderr: (text) => {\n process.stderr.write(text);\n },\n });\n}\n","/**\n * First-run setup wizard. Builds an AgentConfig object; does not write the file.\n * Callers pass the object to write_lich_config.\n */\nimport { readdirSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { Interface } from \"node:readline\";\nimport { DEFAULT_GATEWAY_TOKEN_ENVS, is_env_var_name } from \"./gateway/token_env.js\";\n\nexport type ProviderKind = \"ollama\" | \"openai_compat\" | \"anthropic\";\n\nconst PLATFORMS = [\"webhook\", \"telegram\", \"discord\", \"twitch\"] as const;\nconst PLUGIN_EXT = /\\.(mjs|js|ts|mts|cts|jsx|tsx)$/;\n\nconst PROVIDER_DEFAULTS: Record<ProviderKind, { model: string; base_url: string; api_key_env?: string }> = {\n ollama: { model: \"llama3.2\", base_url: \"http://localhost:11434\" },\n openai_compat: { model: \"gpt-4.1-mini\", base_url: \"https://api.openai.com/v1\", api_key_env: \"OPENAI_API_KEY\" },\n anthropic: { model: \"claude-sonnet-4\", base_url: \"https://api.anthropic.com\", api_key_env: \"ANTHROPIC_API_KEY\" },\n};\n\nexport interface SetupAnswers {\n agent_name: string;\n provider_kind: ProviderKind;\n model: string;\n base_url: string;\n api_key_env?: string;\n platforms: string[];\n token_envs: Record<string, string>;\n plugins: string[];\n}\n\nexport type AskLine = (prompt: string) => Promise<string | undefined>;\n\n/** Plugin entry files under `.lich/plugins`, as work_dir-relative specifiers. */\nfunction discover_plugin_entries(work_dir: string): string[] {\n const dir = path.resolve(work_dir, \".lich\", \"plugins\");\n let names: string[];\n try {\n names = readdirSync(dir);\n } catch {\n return [];\n }\n const entries: string[] = [];\n for (const name of names) {\n if (PLUGIN_EXT.test(name) === true) {\n entries.push(path.posix.join(\".lich/plugins\", name));\n }\n }\n return entries;\n}\n\n/** Object the agent schema already accepts. Omits gateway when no platforms were chosen. */\nexport function build_setup_config(answers: SetupAnswers): Record<string, unknown> {\n const provider: Record<string, unknown> = {\n kind: answers.provider_kind,\n name: \"main\",\n model: answers.model,\n base_url: answers.base_url,\n };\n if (answers.api_key_env !== undefined && answers.api_key_env.length > 0) {\n provider[\"api_key_env\"] = answers.api_key_env;\n }\n const config: Record<string, unknown> = {\n agent_name: answers.agent_name,\n providers: [provider],\n max_turns: 25,\n plugins: answers.plugins,\n };\n if (answers.platforms.length > 0) {\n config[\"gateway\"] = { platforms: answers.platforms, token_envs: answers.token_envs };\n }\n return config;\n}\n\nfunction blank_as_default(raw: string, fallback: string): string {\n const trimmed = raw.trim();\n return trimmed.length === 0 ? fallback : trimmed;\n}\n\nfunction parse_kind(raw: string): ProviderKind | undefined {\n const trimmed = raw.trim();\n const kind = trimmed.length === 0 ? \"ollama\" : trimmed;\n if (kind === \"ollama\" || kind === \"openai_compat\" || kind === \"anthropic\") {\n return kind;\n }\n return undefined;\n}\n\nfunction parse_platforms(raw: string): string[] {\n const seen = new Set<string>();\n const platforms: string[] = [];\n for (const part of raw.split(\",\")) {\n const name = part.trim().toLowerCase();\n if ((PLATFORMS as readonly string[]).includes(name) === false || seen.has(name) === true) {\n continue;\n }\n seen.add(name);\n platforms.push(name);\n }\n return platforms;\n}\n\n/** One prompt. Resolves undefined on Ctrl+C or a closed stream so nothing is written. */\nexport function ask_line(rl: Interface, prompt: string): Promise<string | undefined> {\n return new Promise((resolve) => {\n let settled = false;\n const finish = (value: string | undefined): void => {\n if (settled === true) {\n return;\n }\n settled = true;\n rl.removeListener(\"SIGINT\", on_sigint);\n rl.removeListener(\"close\", on_close);\n resolve(value);\n };\n const on_sigint = (): void => finish(undefined);\n const on_close = (): void => finish(undefined);\n rl.once(\"SIGINT\", on_sigint);\n rl.once(\"close\", on_close);\n rl.question(prompt, (answer) => finish(answer));\n });\n}\n\nasync function ask_name(ask: AskLine): Promise<string | undefined> {\n const raw = await ask(\"Agent name [lich]: \");\n if (raw === undefined) {\n return undefined;\n }\n return blank_as_default(raw, \"lich\");\n}\n\nasync function ask_provider(\n ask: AskLine,\n model_hint?: string,\n): Promise<Pick<SetupAnswers, \"provider_kind\" | \"model\" | \"base_url\" | \"api_key_env\"> | undefined> {\n const kind_raw = await ask(\"Provider kind (ollama|openai_compat|anthropic) [ollama]: \");\n if (kind_raw === undefined) {\n return undefined;\n }\n let kind = parse_kind(kind_raw);\n if (kind === undefined) {\n const retry = await ask(\"Unknown kind. Provider kind (ollama|openai_compat|anthropic) [ollama]: \");\n if (retry === undefined) {\n return undefined;\n }\n kind = parse_kind(retry) ?? \"ollama\";\n }\n const defaults = PROVIDER_DEFAULTS[kind];\n const model_default = model_hint !== undefined && model_hint.length > 0 ? model_hint : defaults.model;\n const model_raw = await ask(`Model [${model_default}]: `);\n if (model_raw === undefined) {\n return undefined;\n }\n const url_raw = await ask(`Base URL [${defaults.base_url}]: `);\n if (url_raw === undefined) {\n return undefined;\n }\n const key_default = defaults.api_key_env ?? \"\";\n const key_prompt = key_default.length === 0 ? \"API key env var name (empty to skip): \" : `API key env var name [${key_default}]: `;\n const key_raw = await ask(key_prompt);\n if (key_raw === undefined) {\n return undefined;\n }\n const api_key_env = blank_as_default(key_raw, key_default);\n return {\n provider_kind: kind,\n model: blank_as_default(model_raw, model_default),\n base_url: blank_as_default(url_raw, defaults.base_url),\n api_key_env: api_key_env.length === 0 ? undefined : api_key_env,\n };\n}\n\nfunction token_env_name(raw: string, fallback: string): string | undefined {\n const name = blank_as_default(raw, fallback);\n return is_env_var_name(name) === true ? name : undefined;\n}\n\nasync function ask_token_env(ask: AskLine, platform: string, fallback: string): Promise<string | undefined> {\n const first = await ask(`${platform} token env var [${fallback}] (name only, not the secret): `);\n if (first === undefined) {\n return undefined;\n }\n const named = token_env_name(first, fallback);\n if (named !== undefined) {\n return named;\n }\n const retry = await ask(`Env var name must match [A-Za-z_][A-Za-z0-9_]* [${fallback}]: `);\n if (retry === undefined) {\n return undefined;\n }\n return token_env_name(retry, fallback);\n}\n\nasync function ask_gateway(ask: AskLine): Promise<{ platforms: string[]; token_envs: Record<string, string> } | undefined> {\n const raw = await ask(\"Gateway platforms (webhook,telegram,discord,twitch; empty to skip): \");\n if (raw === undefined) {\n return undefined;\n }\n const platforms = parse_platforms(raw);\n const token_envs: Record<string, string> = {};\n for (const platform of platforms) {\n const name = await ask_token_env(ask, platform, DEFAULT_GATEWAY_TOKEN_ENVS[platform] ?? \"\");\n if (name === undefined) {\n return undefined;\n }\n token_envs[platform] = name;\n }\n return { platforms, token_envs };\n}\n\nasync function ask_plugins(work_dir: string, ask: AskLine): Promise<string[] | undefined> {\n const found = discover_plugin_entries(work_dir);\n if (found.length === 0) {\n return [];\n }\n const enabled: string[] = [];\n for (const entry of found) {\n const answer = await ask(`Enable plugin ${entry}? [y/N]: `);\n if (answer === undefined) {\n return undefined;\n }\n const yes = answer.trim().toLowerCase();\n if (yes === \"y\" || yes === \"yes\") {\n enabled.push(entry);\n }\n }\n return enabled;\n}\n\n/** All steps skippable. Undefined means Ctrl+C or a rejected env name: caller must not write. */\nexport async function collect_setup_answers(work_dir: string, ask: AskLine, model_hint?: string): Promise<SetupAnswers | undefined> {\n const agent_name = await ask_name(ask);\n if (agent_name === undefined) {\n return undefined;\n }\n const provider = await ask_provider(ask, model_hint);\n if (provider === undefined) {\n return undefined;\n }\n const gateway = await ask_gateway(ask);\n if (gateway === undefined) {\n return undefined;\n }\n const plugins = await ask_plugins(work_dir, ask);\n if (plugins === undefined) {\n return undefined;\n }\n return { agent_name, ...provider, platforms: gateway.platforms, token_envs: gateway.token_envs, plugins };\n}\n"],"mappings":";;;;;;;;;;;;;AAKA,SAAS,cAAAA,aAAY,gBAAAC,eAAc,oBAAoB;AACvD,SAAS,uBAAuC;AAChD,OAAOC,WAAU;AACjB,SAAS,eAAe,qBAAqB;;;ACJ7C,SAAS,YAAY,WAAW,cAAc,qBAAqB;AACnE,SAAS,eAAe;AACxB,OAAO,UAAU;AAGjB,IAAM,eAAe;AACrB,IAAM,iBAAiB,GAAG,YAAY;AACtC,IAAM,sBAAsB;AAGrB,SAAS,oBAAoB,UAA6B;AAC/D,QAAM,OAAO,YAAY,QAAQ,IAAI;AACrC,QAAM,QAAQ,KAAK,QAAQ,MAAM,cAAc;AAC/C,QAAM,SAAS,KAAK,QAAQ,QAAQ,GAAG,mBAAmB;AAC1D,SAAO,UAAU,SAAS,CAAC,KAAK,IAAI,CAAC,OAAO,MAAM;AACpD;AAGO,SAAS,iBAAiB,UAAuC;AACtE,MAAI,aAAa,QAAW;AAC1B,QAAI,WAAW,QAAQ,MAAM,OAAO;AAClC,YAAM,IAAI,MAAM,qBAAqB,QAAQ,EAAE;AAAA,IACjD;AACA,WAAO;AAAA,EACT;AACA,SAAO,qBAAqB,QAAQ,IAAI,CAAC;AAC3C;AAGO,SAAS,YAAY,UAAwD;AAClF,QAAM,QAAQ,iBAAiB,QAAQ;AACvC,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AACA,QAAM,MAAM,aAAa,OAAO,MAAM;AACtC,QAAM,SAAS,gBAAyB,GAAG;AAC3C,MAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,MAAM,QAAQ,MAAM,GAAG;AAC1E,UAAM,IAAI,MAAM,wBAAwB,KAAK,EAAE;AAAA,EACjD;AACA,SAAO;AACT;AAGO,SAAS,kBAA0B;AACxC,QAAM,OAAO,QAAQ,IAAI,sBAAsB;AAC/C,QAAM,WAAoC;AAAA,IACxC;AAAA,IACA,MAAM;AAAA,IACN,OAAO,QAAQ,IAAI,cAAc;AAAA,EACnC;AACA,MAAI,SAAS,UAAU;AACrB,aAAS,UAAU,IAAI;AAAA,EACzB;AACA,SAAO,KAAK,UAAU,EAAE,WAAW,CAAC,QAAQ,GAAG,WAAW,GAAG,GAAG,MAAM,CAAC;AACzE;AAGO,SAAS,uBAAuB,UAA0B;AAC/D,QAAM,MAAM,KAAK,QAAQ,UAAU,YAAY;AAC/C,YAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAClC,SAAO;AACT;AAGO,SAAS,oBAAoB,UAA0B;AAC5D,SAAO,KAAK,QAAQ,UAAU,cAAc;AAC9C;AAGO,SAAS,qBAAqB,UAAsC;AACzE,aAAW,aAAa,oBAAoB,QAAQ,GAAG;AACrD,QAAI,WAAW,SAAS,MAAM,MAAM;AAClC,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AASO,SAAS,wBAAiD;AAC/D,QAAM,SAAkB,KAAK,MAAM,gBAAgB,CAAC;AACpD,MAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,MAAM,QAAQ,MAAM,GAAG;AAC1E,UAAM,IAAI,MAAM,uCAAuC;AAAA,EACzD;AACA,SAAO;AACT;AAMO,SAAS,kBAAkB,UAAkB,QAAwD;AAC1G,yBAAuB,QAAQ;AAC/B,QAAM,OAAO,oBAAoB,QAAQ;AACzC,MAAI,WAAW,IAAI,MAAM,MAAM;AAC7B,WAAO,eAAe,IAAI;AAAA,EAC5B;AACA,MAAI;AACF,kBAAc,MAAM,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,GAAM,EAAE,UAAU,QAAQ,MAAM,KAAK,CAAC;AAAA,EAC9F,SAAS,OAAO;AACd,QAAI,UAAU,KAAK,MAAM,MAAM;AAC7B,aAAO,eAAe,IAAI;AAAA,IAC5B;AACA,UAAM;AAAA,EACR;AACA,SAAO,EAAE,MAAM,MAAM,SAAS,MAAM,SAAS,SAAS,IAAI,GAAG;AAC/D;AAEA,SAAS,eAAe,MAAqC;AAC3D,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS,6CAA6C,IAAI;AAAA,EAC5D;AACF;AAEA,SAAS,UAAU,OAAyB;AAC1C,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,SAAU,MAA6B,SAAS;AAClH;;;AC5HA,SAAS,aAAa;AACtB,SAAS,cAAAC,mBAAkB;AAC3B,OAAOC,WAAU;AAGV,IAAM,eAAe;AACrB,IAAM,YAAY,CAAC,QAAQ,cAAc,SAAS;AAClD,IAAM,eAAe,CAAC,WAAW,MAAM,GAAG,YAAY,SAAS;AA2BtE,IAAM,cACJ;AACF,IAAM,kBACJ;AAEF,SAAS,aAAa,SAAgC;AACpD,QAAM,QAAQ,gDAAgD,KAAK,QAAQ,KAAK,CAAC;AACjF,MAAI,UAAU,QAAQ,MAAM,CAAC,MAAM,UAAa,MAAM,CAAC,MAAM,UAAa,MAAM,CAAC,MAAM,QAAW;AAChG,WAAO;AAAA,EACT;AACA,SAAO,CAAC,OAAO,MAAM,CAAC,CAAC,GAAG,OAAO,MAAM,CAAC,CAAC,GAAG,OAAO,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE;AAC9E;AAGO,SAAS,iBAAiB,WAAmB,UAAmC;AACrF,QAAM,OAAO,aAAa,SAAS;AACnC,QAAM,QAAQ,aAAa,QAAQ;AACnC,MAAI,SAAS,QAAQ,UAAU,MAAM;AACnC,WAAO;AAAA,EACT;AACA,WAAS,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG;AACzC,UAAM,iBAAiB,KAAK,KAAK;AACjC,UAAM,gBAAgB,MAAM,KAAK;AACjC,QAAI,OAAO,mBAAmB,YAAY,OAAO,kBAAkB,UAAU;AAC3E,aAAO;AAAA,IACT;AACA,QAAI,iBAAiB,eAAe;AAClC,aAAO;AAAA,IACT;AACA,QAAI,iBAAiB,eAAe;AAClC,aAAO;AAAA,IACT;AAAA,EACF;AACA,MAAI,KAAK,CAAC,MAAM,MAAM,MAAM,CAAC,MAAM,IAAI;AACrC,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAGO,SAAS,oBACd,aACA,KACA,SACa;AACb,MAAI,IAAI,gBAAgB,UAAU,YAAY,SAAS,GAAGC,MAAK,GAAG,OAAOA,MAAK,GAAG,EAAE,GAAG;AACpF,WAAO;AAAA,EACT;AACA,MAAI,MAAMA,MAAK,QAAQA,MAAK,QAAQ,WAAW,CAAC;AAChD,QAAM,OAAOA,MAAK,MAAM,GAAG,EAAE;AAC7B,SAAO,QAAQ,MAAM;AACnB,QAAIA,MAAK,SAAS,GAAG,MAAM,gBAAgB;AACzC,aAAO;AAAA,IACT;AACA,QAAI,QAAQ,GAAG,MAAM,MAAM;AACzB,aAAO;AAAA,IACT;AACA,UAAM,SAASA,MAAK,QAAQ,GAAG;AAC/B,QAAI,WAAW,KAAK;AAClB;AAAA,IACF;AACA,UAAM;AAAA,EACR;AACA,SAAO;AACT;AAEA,SAAS,wBAAwB,MAAkC;AACjE,MAAI,SAAS,OAAO;AAClB,WAAO;AAAA,EACT;AACA,MAAI,SAAS,OAAO;AAClB,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,QAAuB,SAAuC;AACtF,MAAI,OAAO,eAAe,UAAU;AAClC,YAAQ,aAAa,WAAW;AAChC,WAAO;AAAA,EACT;AACA,MAAI,OAAO,cAAc,GAAG;AAC1B,UAAM,SAAS,OAAO,OAAO,KAAK,KAAK,OAAO,OAAO,KAAK,KAAK,QAAQ,OAAO,SAAS;AACvF,YAAQ,aAAa,gDAAgD,YAAY,KAAK,MAAM;AAAA,CAAI;AAChG,WAAO;AAAA,EACT;AACA,QAAM,WAAW,OAAO,OAAO,KAAK;AACpC,MAAI,aAAa,QAAQ,MAAM,MAAM;AACnC,YAAQ,aAAa,gDAAgD,YAAY,yBAAyB,QAAQ;AAAA,CAAK;AACvH,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,sBAAsB,WAAmC;AAChE,MAAI,UAAU,eAAe,YAAY,UAAU,eAAe,SAAS;AACzE,WAAO;AAAA,EACT;AACA,QAAM,OAAO,GAAG,UAAU,MAAM;AAAA,EAAK,UAAU,MAAM,GAAG,YAAY;AACpE,SAAO,KAAK,SAAS,QAAQ,KAAK,KAAK,SAAS,OAAO,KAAK,KAAK,SAAS,mBAAmB;AAC/F;AAEA,SAAS,eAAe,SAAwB,WAAkC;AAChF,MAAI,UAAU,cAAc,GAAG;AAC7B,YAAQ,aAAa,WAAW,YAAY;AAAA,CAAuD;AACnG,WAAO;AAAA,EACT;AACA,MAAI,UAAU,eAAe,UAAU;AACrC,YAAQ,aAAa,WAAW;AAChC,WAAO;AAAA,EACT;AACA,MAAI,sBAAsB,SAAS,MAAM,MAAM;AAC7C,YAAQ,aAAa,mIAAmI;AACxJ,WAAO;AAAA,EACT;AACA,QAAM,SAAS,UAAU,OAAO,KAAK,KAAK,QAAQ,UAAU,SAAS;AACrE,UAAQ,aAAa,6BAA6B,MAAM;AAAA,CAAI;AAC5D,SAAO;AACT;AAEA,eAAe,iBAAiB,SAAwB,UAAmC;AACzF,QAAM,WAAW,iBAAiB,QAAQ,mBAAmB,QAAQ;AACrE,MAAI,aAAa,WAAW;AAC1B,YAAQ,aAAa,+CAA+C,QAAQ,iBAAiB,cAAc,QAAQ;AAAA,CAAK;AACxH,WAAO;AAAA,EACT;AACA,MAAI,aAAa,UAAU;AACzB,YAAQ,aAAa,QAAQ,QAAQ,iBAAiB;AAAA,CAAkB;AACxE,WAAO;AAAA,EACT;AACA,UAAQ,aAAa,QAAQ,QAAQ,iBAAiB,OAAO,QAAQ;AAAA,CAAI;AACzE,UAAQ,aAAa,eAAe;AACpC,QAAM,YAAY,MAAM,QAAQ,YAAY,OAAO,YAAY;AAC/D,SAAO,eAAe,SAAS,SAAS;AAC1C;AAGA,eAAsB,gBAAgB,SAAyC;AAC7E,QAAM,UAAU,wBAAwB,QAAQ,YAAY;AAC5D,MAAI,YAAY,MAAM;AACpB,YAAQ,aAAa,OAAO;AAC5B,WAAO;AAAA,EACT;AACA,QAAM,SAAS,MAAM,QAAQ,YAAY,OAAO,SAAS;AACzD,QAAM,WAAW,iBAAiB,QAAQ,OAAO;AACjD,MAAI,aAAa,MAAM;AACrB,WAAO;AAAA,EACT;AACA,SAAO,iBAAiB,SAAS,QAAQ;AAC3C;AAEA,SAAS,oBAA6B;AACpC,SAAO,QAAQ,SAAS,QAAQ;AAClC;AAGO,SAAS,uBAAuB,SAAiB,MAAiD;AACvG,MAAI,kBAAkB,MAAM,MAAM;AAChC,WAAO,mBAAmB,SAAS,IAAI;AAAA,EACzC;AACA,SAAO,oBAAoB,SAAS,IAAI;AAC1C;AAEA,SAAS,oBAAoB,SAAiB,MAAiD;AAC7F,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,QAAI,SAAS;AACb,QAAI,SAAS;AACb,QAAI,UAAU;AACd,UAAM,SAAS,CAAC,WAAgC;AAC9C,UAAI,YAAY,MAAM;AACpB;AAAA,MACF;AACA,gBAAU;AACV,cAAQ,MAAM;AAAA,IAChB;AACA,UAAM,UAAU,KAAK,CAAC,MAAM;AAC5B,UAAM,QAAQ,MAAM,SAAS,CAAC,GAAG,IAAI,GAAG,EAAE,OAAO,CAAC,UAAU,QAAQ,MAAM,EAAE,CAAC;AAC7E,UAAM,QAAQ,GAAG,QAAQ,CAAC,UAAkB;AAC1C,YAAM,OAAO,MAAM,SAAS;AAC5B,gBAAU;AACV,UAAI,YAAY,MAAM;AACpB,gBAAQ,OAAO,MAAM,IAAI;AAAA,MAC3B;AAAA,IACF,CAAC;AACD,UAAM,QAAQ,GAAG,QAAQ,CAAC,UAAkB;AAC1C,YAAM,OAAO,MAAM,SAAS;AAC5B,gBAAU;AACV,UAAI,YAAY,MAAM;AACpB,gBAAQ,OAAO,MAAM,IAAI;AAAA,MAC3B;AAAA,IACF,CAAC;AACD,UAAM,GAAG,SAAS,CAAC,UAAiC;AAClD,aAAO,EAAE,WAAW,KAAK,QAAQ,QAAQ,MAAM,SAAS,YAAY,MAAM,KAAK,CAAC;AAAA,IAClF,CAAC;AACD,UAAM,GAAG,SAAS,CAAC,SAAS;AAC1B,aAAO,EAAE,WAAW,QAAQ,GAAG,QAAQ,OAAO,CAAC;AAAA,IACjD,CAAC;AAAA,EACH,CAAC;AACH;AAEA,eAAe,gBACb,QACA,SACA,OACiB;AACjB,QAAM,SAAS,OAAO,UAAU;AAChC,QAAM,UAAU,IAAI,YAAY;AAChC,MAAI,OAAO;AACX,aAAS;AACP,UAAM,OAAO,MAAM,OAAO,KAAK;AAC/B,QAAI,KAAK,SAAS,MAAM;AACtB,aAAO;AAAA,IACT;AACA,UAAM,QAAQ,QAAQ,OAAO,KAAK,OAAO,EAAE,QAAQ,KAAK,CAAC;AACzD,YAAQ;AACR,QAAI,YAAY,MAAM;AACpB,YAAM,KAAK;AAAA,IACb;AAAA,EACF;AACF;AAEA,SAAS,mBAAmB,SAAiB,MAAiD;AAC5F,QAAM,UAAU,KAAK,CAAC,MAAM;AAC5B,MAAI;AACF,UAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,GAAG,IAAI,GAAG;AAAA,MAC1C,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV,CAAC;AACD,WAAO,QAAQ,IAAI;AAAA,MACjB,gBAAgB,MAAM,QAAQ,SAAS,CAAC,SAAS;AAC/C,gBAAQ,OAAO,MAAM,IAAI;AAAA,MAC3B,CAAC;AAAA,MACD,gBAAgB,MAAM,QAAQ,SAAS,CAAC,SAAS;AAC/C,gBAAQ,OAAO,MAAM,IAAI;AAAA,MAC3B,CAAC;AAAA,MACD,MAAM;AAAA,IACR,CAAC,EAAE,KAAK,CAAC,CAAC,QAAQ,QAAQ,SAAS,OAAO,EAAE,WAAW,QAAQ,OAAO,EAAE;AAAA,EAC1E,SAAS,OAAO;AACd,UAAM,QAAQ;AACd,UAAM,SAAS,OAAO,MAAM,YAAY,WAAW,MAAM,UAAU;AACnE,WAAO,QAAQ,QAAQ,EAAE,WAAW,KAAK,QAAQ,IAAI,QAAQ,YAAY,MAAM,KAAK,CAAC;AAAA,EACvF;AACF;AAEA,eAAsB,WAAW,aAAsC;AACrE,SAAO,gBAAgB;AAAA,IACrB,mBAAmB;AAAA,IACnB,cAAc,oBAAoB,aAAa,QAAQ,KAAK,CAAC,QAAQC,YAAWD,MAAK,KAAK,KAAK,MAAM,CAAC,CAAC;AAAA,IACvG,aAAa;AAAA,IACb,cAAc,CAAC,SAAS;AACtB,cAAQ,OAAO,MAAM,IAAI;AAAA,IAC3B;AAAA,IACA,cAAc,CAAC,SAAS;AACtB,cAAQ,OAAO,MAAM,IAAI;AAAA,IAC3B;AAAA,EACF,CAAC;AACH;;;ACnSA,SAAS,mBAAmB;AAC5B,OAAOE,WAAU;AAMjB,IAAM,YAAY,CAAC,WAAW,YAAY,WAAW,QAAQ;AAC7D,IAAM,aAAa;AAEnB,IAAM,oBAAqG;AAAA,EACzG,QAAQ,EAAE,OAAO,YAAY,UAAU,yBAAyB;AAAA,EAChE,eAAe,EAAE,OAAO,gBAAgB,UAAU,6BAA6B,aAAa,iBAAiB;AAAA,EAC7G,WAAW,EAAE,OAAO,mBAAmB,UAAU,6BAA6B,aAAa,oBAAoB;AACjH;AAgBA,SAAS,wBAAwB,UAA4B;AAC3D,QAAM,MAAMC,MAAK,QAAQ,UAAU,SAAS,SAAS;AACrD,MAAI;AACJ,MAAI;AACF,YAAQ,YAAY,GAAG;AAAA,EACzB,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACA,QAAM,UAAoB,CAAC;AAC3B,aAAW,QAAQ,OAAO;AACxB,QAAI,WAAW,KAAK,IAAI,MAAM,MAAM;AAClC,cAAQ,KAAKA,MAAK,MAAM,KAAK,iBAAiB,IAAI,CAAC;AAAA,IACrD;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,mBAAmB,SAAgD;AACjF,QAAM,WAAoC;AAAA,IACxC,MAAM,QAAQ;AAAA,IACd,MAAM;AAAA,IACN,OAAO,QAAQ;AAAA,IACf,UAAU,QAAQ;AAAA,EACpB;AACA,MAAI,QAAQ,gBAAgB,UAAa,QAAQ,YAAY,SAAS,GAAG;AACvE,aAAS,aAAa,IAAI,QAAQ;AAAA,EACpC;AACA,QAAM,SAAkC;AAAA,IACtC,YAAY,QAAQ;AAAA,IACpB,WAAW,CAAC,QAAQ;AAAA,IACpB,WAAW;AAAA,IACX,SAAS,QAAQ;AAAA,EACnB;AACA,MAAI,QAAQ,UAAU,SAAS,GAAG;AAChC,WAAO,SAAS,IAAI,EAAE,WAAW,QAAQ,WAAW,YAAY,QAAQ,WAAW;AAAA,EACrF;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,KAAa,UAA0B;AAC/D,QAAM,UAAU,IAAI,KAAK;AACzB,SAAO,QAAQ,WAAW,IAAI,WAAW;AAC3C;AAEA,SAAS,WAAW,KAAuC;AACzD,QAAM,UAAU,IAAI,KAAK;AACzB,QAAM,OAAO,QAAQ,WAAW,IAAI,WAAW;AAC/C,MAAI,SAAS,YAAY,SAAS,mBAAmB,SAAS,aAAa;AACzE,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,KAAuB;AAC9C,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,YAAsB,CAAC;AAC7B,aAAW,QAAQ,IAAI,MAAM,GAAG,GAAG;AACjC,UAAM,OAAO,KAAK,KAAK,EAAE,YAAY;AACrC,QAAK,UAAgC,SAAS,IAAI,MAAM,SAAS,KAAK,IAAI,IAAI,MAAM,MAAM;AACxF;AAAA,IACF;AACA,SAAK,IAAI,IAAI;AACb,cAAU,KAAK,IAAI;AAAA,EACrB;AACA,SAAO;AACT;AAGO,SAAS,SAAS,IAAe,QAA6C;AACnF,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,QAAI,UAAU;AACd,UAAM,SAAS,CAAC,UAAoC;AAClD,UAAI,YAAY,MAAM;AACpB;AAAA,MACF;AACA,gBAAU;AACV,SAAG,eAAe,UAAU,SAAS;AACrC,SAAG,eAAe,SAAS,QAAQ;AACnC,cAAQ,KAAK;AAAA,IACf;AACA,UAAM,YAAY,MAAY,OAAO,MAAS;AAC9C,UAAM,WAAW,MAAY,OAAO,MAAS;AAC7C,OAAG,KAAK,UAAU,SAAS;AAC3B,OAAG,KAAK,SAAS,QAAQ;AACzB,OAAG,SAAS,QAAQ,CAAC,WAAW,OAAO,MAAM,CAAC;AAAA,EAChD,CAAC;AACH;AAEA,eAAe,SAAS,KAA2C;AACjE,QAAM,MAAM,MAAM,IAAI,qBAAqB;AAC3C,MAAI,QAAQ,QAAW;AACrB,WAAO;AAAA,EACT;AACA,SAAO,iBAAiB,KAAK,MAAM;AACrC;AAEA,eAAe,aACb,KACAC,aACiG;AACjG,QAAM,WAAW,MAAM,IAAI,2DAA2D;AACtF,MAAI,aAAa,QAAW;AAC1B,WAAO;AAAA,EACT;AACA,MAAI,OAAO,WAAW,QAAQ;AAC9B,MAAI,SAAS,QAAW;AACtB,UAAM,QAAQ,MAAM,IAAI,yEAAyE;AACjG,QAAI,UAAU,QAAW;AACvB,aAAO;AAAA,IACT;AACA,WAAO,WAAW,KAAK,KAAK;AAAA,EAC9B;AACA,QAAM,WAAW,kBAAkB,IAAI;AACvC,QAAM,gBAAgBA,gBAAe,UAAaA,YAAW,SAAS,IAAIA,cAAa,SAAS;AAChG,QAAM,YAAY,MAAM,IAAI,UAAU,aAAa,KAAK;AACxD,MAAI,cAAc,QAAW;AAC3B,WAAO;AAAA,EACT;AACA,QAAM,UAAU,MAAM,IAAI,aAAa,SAAS,QAAQ,KAAK;AAC7D,MAAI,YAAY,QAAW;AACzB,WAAO;AAAA,EACT;AACA,QAAM,cAAc,SAAS,eAAe;AAC5C,QAAM,aAAa,YAAY,WAAW,IAAI,2CAA2C,yBAAyB,WAAW;AAC7H,QAAM,UAAU,MAAM,IAAI,UAAU;AACpC,MAAI,YAAY,QAAW;AACzB,WAAO;AAAA,EACT;AACA,QAAM,cAAc,iBAAiB,SAAS,WAAW;AACzD,SAAO;AAAA,IACL,eAAe;AAAA,IACf,OAAO,iBAAiB,WAAW,aAAa;AAAA,IAChD,UAAU,iBAAiB,SAAS,SAAS,QAAQ;AAAA,IACrD,aAAa,YAAY,WAAW,IAAI,SAAY;AAAA,EACtD;AACF;AAEA,SAAS,eAAe,KAAa,UAAsC;AACzE,QAAM,OAAO,iBAAiB,KAAK,QAAQ;AAC3C,SAAO,gBAAgB,IAAI,MAAM,OAAO,OAAO;AACjD;AAEA,eAAe,cAAc,KAAc,UAAkB,UAA+C;AAC1G,QAAM,QAAQ,MAAM,IAAI,GAAG,QAAQ,mBAAmB,QAAQ,iCAAiC;AAC/F,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,eAAe,OAAO,QAAQ;AAC5C,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,MAAM,IAAI,mDAAmD,QAAQ,KAAK;AACxF,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AACA,SAAO,eAAe,OAAO,QAAQ;AACvC;AAEA,eAAe,YAAY,KAAgG;AACzH,QAAM,MAAM,MAAM,IAAI,sEAAsE;AAC5F,MAAI,QAAQ,QAAW;AACrB,WAAO;AAAA,EACT;AACA,QAAM,YAAY,gBAAgB,GAAG;AACrC,QAAM,aAAqC,CAAC;AAC5C,aAAW,YAAY,WAAW;AAChC,UAAM,OAAO,MAAM,cAAc,KAAK,UAAU,2BAA2B,QAAQ,KAAK,EAAE;AAC1F,QAAI,SAAS,QAAW;AACtB,aAAO;AAAA,IACT;AACA,eAAW,QAAQ,IAAI;AAAA,EACzB;AACA,SAAO,EAAE,WAAW,WAAW;AACjC;AAEA,eAAe,YAAY,UAAkB,KAA6C;AACxF,QAAM,QAAQ,wBAAwB,QAAQ;AAC9C,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO,CAAC;AAAA,EACV;AACA,QAAM,UAAoB,CAAC;AAC3B,aAAW,SAAS,OAAO;AACzB,UAAM,SAAS,MAAM,IAAI,iBAAiB,KAAK,WAAW;AAC1D,QAAI,WAAW,QAAW;AACxB,aAAO;AAAA,IACT;AACA,UAAM,MAAM,OAAO,KAAK,EAAE,YAAY;AACtC,QAAI,QAAQ,OAAO,QAAQ,OAAO;AAChC,cAAQ,KAAK,KAAK;AAAA,IACpB;AAAA,EACF;AACA,SAAO;AACT;AAGA,eAAsB,sBAAsB,UAAkB,KAAcA,aAAwD;AAClI,QAAM,aAAa,MAAM,SAAS,GAAG;AACrC,MAAI,eAAe,QAAW;AAC5B,WAAO;AAAA,EACT;AACA,QAAM,WAAW,MAAM,aAAa,KAAKA,WAAU;AACnD,MAAI,aAAa,QAAW;AAC1B,WAAO;AAAA,EACT;AACA,QAAM,UAAU,MAAM,YAAY,GAAG;AACrC,MAAI,YAAY,QAAW;AACzB,WAAO;AAAA,EACT;AACA,QAAM,UAAU,MAAM,YAAY,UAAU,GAAG;AAC/C,MAAI,YAAY,QAAW;AACzB,WAAO;AAAA,EACT;AACA,SAAO,EAAE,YAAY,GAAG,UAAU,WAAW,QAAQ,WAAW,YAAY,QAAQ,YAAY,QAAQ;AAC1G;;;AH7NA,IAAM,YAAoC;AAAA,EACxC,cAAc;AAAA,EACd,eAAe;AAAA,EACf,WAAW;AAAA,EACX,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,iBAAiB;AAAA,EACjB,eAAe;AACjB;AAEA,IAAM,oBAAkD;AAAA,EACtD,eAAe;AAAA,EACf,WAAW;AAAA,EACX,QAAQ;AACV;AAEA,IAAM,uBAAiE;AAAA,EACrE,eAAe;AAAA,EACf,WAAW;AAAA,EACX,QAAQ;AAAA;AACV;AAEA,SAAS,aAAqB;AAC5B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,cAAc,OAAwB;AAC7C,SAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;AAGA,SAAS,eAAe,MAAc,cAA8B;AAClE,MAAI,SAAS,OAAO;AAClB,WAAO;AAAA,EACT;AACA,MAAI,SAAS,WAAW;AACtB,WAAO;AAAA,EACT;AACA,MAAI,SAAS,QAAQ;AACnB,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,WAAW,MAA4B;AAC9C,QAAM,UAAsB,EAAE,WAAW,CAAC,GAAG,aAAa,CAAC,EAAE;AAC7D,WAAS,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAAG;AACnD,UAAM,MAAM,KAAK,KAAK;AACtB,QAAI,QAAQ,QAAW;AACrB;AAAA,IACF;AACA,QAAI,QAAQ,UAAU;AACpB,cAAQ,OAAO;AACf;AAAA,IACF;AACA,QAAI,QAAQ,aAAa;AACvB,cAAQ,UAAU;AAClB;AAAA,IACF;AACA,QAAI,QAAQ,YAAY;AACtB,YAAMC,SAAQ,KAAK,QAAQ,CAAC;AAC5B,UAAIA,WAAU,QAAW;AACvB,cAAM,IAAI,MAAM,0BAA0B;AAAA,MAC5C;AACA,cAAQ,cAAcA;AACtB,eAAS;AACT;AAAA,IACF;AACA,UAAM,eAAe,UAAU,GAAG;AAClC,QAAI,iBAAiB,QAAW;AAC9B,UAAI,IAAI,WAAW,IAAI,MAAM,MAAM;AACjC,cAAM,IAAI,MAAM,iBAAiB,GAAG,EAAE;AAAA,MACxC;AACA,cAAQ,YAAY,KAAK,GAAG;AAC5B;AAAA,IACF;AACA,UAAM,QAAQ,KAAK,QAAQ,CAAC;AAC5B,QAAI,UAAU,UAAa,MAAM,WAAW,IAAI,MAAM,MAAM;AAC1D,YAAM,IAAI,MAAM,GAAG,GAAG,mBAAmB;AAAA,IAC3C;AACA,YAAQ,UAAU,YAAY,IAAI;AAClC,aAAS;AAAA,EACX;AACA,SAAO;AACT;AAEA,SAAS,aAAa,WAA4D;AAChF,QAAM,aAAa,UAAU,eAAe,KAAK,QAAQ,IAAI,sBAAsB;AACnF,MAAI,eAAe,mBAAmB,eAAe,eAAe,eAAe,UAAU;AAC3F,UAAM,IAAI,MAAM,0BAA0B,UAAU,kDAAkD;AAAA,EACxG;AACA,QAAM,OAAqB;AAC3B,QAAM,QAAQ,UAAU,gBAAgB,KAAK,QAAQ,IAAI;AACzD,MAAI,UAAU,UAAa,MAAM,WAAW,GAAG;AAC7C,UAAM,IAAI,MAAM,kHAAkH;AAAA,EACpI;AACA,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA,UAAU,UAAU,mBAAmB,KAAK,QAAQ,IAAI,iBAAiB,kBAAkB,IAAI;AAAA,IAC/F,aAAa,UAAU,sBAAsB,KAAK,QAAQ,IAAI,oBAAoB,qBAAqB,IAAI;AAAA,EAC7G;AACF;AAEA,SAAS,iBAAiB,aAA8C;AACtE,MAAI;AACF,UAAM,MAAMC,cAAa,aAAa,MAAM;AAC5C,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,MAAM,QAAQ,MAAM,GAAG;AAC1E,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI,MAAM,0BAA0B,WAAW,KAAK,cAAc,KAAK,CAAC,EAAE;AAAA,EAClF;AACF;AAEA,SAAS,wBAAwB,QAAiC,WAAyC;AACzG,QAAM,OAAO,CAAC,iBAAiB,kBAAkB,qBAAqB,sBAAsB;AAC5F,QAAM,cAAc,KAAK,KAAK,CAAC,QAAQ,UAAU,GAAG,MAAM,MAAS;AACnE,MAAI,gBAAgB,OAAO;AACzB;AAAA,EACF;AACA,QAAM,YAAY,OAAO,WAAW;AACpC,MAAI,MAAM,QAAQ,SAAS,MAAM,SAAS,UAAU,WAAW,GAAG;AAChE,WAAO,WAAW,IAAI,CAAC,aAAa,SAAS,CAAC;AAC9C;AAAA,EACF;AACA,QAAM,QAAQ,UAAU,CAAC;AACzB,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,UAAM,IAAI,MAAM,uCAAuC;AAAA,EACzD;AACA,QAAM,WAAW;AACjB,aAAW,OAAO,MAAM;AACtB,UAAM,QAAQ,UAAU,GAAG;AAC3B,QAAI,UAAU,QAAW;AACvB,eAAS,IAAI,QAAQ,aAAa,EAAE,CAAC,IAAI;AAAA,IAC3C;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,QAAiC,WAAyC;AACjG,aAAW,OAAO,CAAC,YAAY,iBAAiB,eAAe,WAAW,GAAG;AAC3E,QAAI,UAAU,GAAG,MAAM,QAAW;AAChC,aAAO,GAAG,IAAI,UAAU,GAAG;AAAA,IAC7B;AAAA,EACF;AACA,MAAI,UAAU,WAAW,MAAM,QAAW;AACxC,UAAM,QAAQ,OAAO,UAAU,WAAW,CAAC;AAC3C,QAAI,OAAO,UAAU,KAAK,MAAM,SAAS,QAAQ,GAAG;AAClD,YAAM,IAAI,MAAM,wCAAwC;AAAA,IAC1D;AACA,WAAO,WAAW,IAAI;AAAA,EACxB;AACA,0BAAwB,QAAQ,SAAS;AAC3C;AAGA,SAAS,uBAAuB,UAAuD;AACrF,QAAM,QAAQ,qBAAqB,QAAQ;AAC3C,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AACA,SAAO,YAAY,KAAK;AAC1B;AAEA,SAAS,aAAa,SAAkC;AACtD,QAAM,OACJ,QAAQ,gBAAgB,SACpB,uBAAuB,YAAY,OAAO,CAAC,KAAK,EAAE,WAAW,CAAC,aAAa,QAAQ,SAAS,CAAC,EAAE,IAC/F,iBAAiB,QAAQ,WAAW;AAC1C,kBAAgB,MAAM,QAAQ,SAAS;AACvC,QAAM,YAAY,KAAK,WAAW;AAClC,MAAI,MAAM,QAAQ,SAAS,MAAM,SAAS,UAAU,WAAW,GAAG;AAChE,UAAM,IAAI,MAAM,kHAAkH;AAAA,EACpI;AACA,SAAO,mBAAmB,IAAI;AAChC;AAGA,SAAS,iBAAiB,SAAqB,MAA2B;AACxE,MAAI;AACF,WAAO,aAAa,OAAO;AAAA,EAC7B,SAAS,OAAO;AACd,UAAM,IAAI,MAAM,eAAe,MAAM,cAAc,KAAK,CAAC,CAAC;AAAA,EAC5D;AACF;AAEA,SAAS,gBAAgB,SAAmC;AAC1D,SAAO,QAAQ,GAAG,CAAC,UAAU;AAC3B,QAAI,MAAM,SAAS,cAAc;AAC/B,cAAQ,OAAO,MAAM;AAAA,cAAiB,MAAM,IAAI,EAAE;AAClD;AAAA,IACF;AACA,QAAI,MAAM,SAAS,iBAAiB;AAClC,YAAM,SAAS,MAAM,OAAO,OAAO,OAAO,OAAO,UAAU,MAAM,OAAO,SAAS,EAAE;AACnF,cAAQ,OAAO,MAAM;AAAA,WAAc,MAAM,KAAK,IAAI,KAAK,MAAM,EAAE;AAC/D;AAAA,IACF;AACA,QAAI,MAAM,SAAS,SAAS;AAC1B,cAAQ,OAAO,MAAM,IAAI;AAAA,IAC3B;AAAA,EACF,CAAC;AACH;AAEA,eAAsB,aAAa,QAAiB,OAAgC;AAClF,QAAM,QAAQ,MAAM,0BAA0B,MAAM;AACpD,QAAM,gBAAgB,gBAAgB,MAAM,MAAM;AAClD,MAAI;AACJ,MAAI;AACF,aAAS,MAAM,MAAM,IAAI,EAAE,MAAM,CAAC;AAAA,EACpC,UAAE;AACA,kBAAc;AAAA,EAChB;AACA,QAAM,QAAQ,OAAO,QAAQ;AAC7B,MAAI,UAAU,UAAa,MAAM,QAAQ,SAAS,GAAG;AACnD,YAAQ,OAAO,MAAM,GAAG,MAAM,OAAO;AAAA,CAAI;AAAA,EAC3C;AACA,MAAI,OAAO,QAAQ,mBAAmB,UAAU;AAC9C,YAAQ,OAAO,MAAM,iCAAiC,OAAO,QAAQ,UAAU;AAAA,CAAU;AACzF,WAAO;AAAA,EACT;AACA,MAAI,OAAO,QAAQ,mBAAmB,WAAW;AAC/C,YAAQ,OAAO,MAAM,sBAAsB;AAC3C,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,eAAe,cAAc,OAAc,OAA8B;AACvE,QAAM,gBAAgB,gBAAgB,MAAM,MAAM;AAClD,MAAI;AACF,UAAM,SAAS,MAAM,MAAM,IAAI,EAAE,MAAM,CAAC;AACxC,UAAM,QAAQ,OAAO,QAAQ;AAC7B,QAAI,UAAU,UAAa,MAAM,QAAQ,SAAS,GAAG;AACnD,cAAQ,OAAO,MAAM,GAAG,MAAM,OAAO;AAAA,CAAI;AAAA,IAC3C;AACA,YAAQ,OAAO,MAAM,UAAU,OAAO,QAAQ,UAAU,aAAa,OAAO,YAAY,YAAY;AAAA,CAAK;AAAA,EAC3G,SAAS,OAAO;AACd,YAAQ,OAAO,MAAM,UAAU,cAAc,KAAK,CAAC;AAAA,CAAI;AAAA,EACzD,UAAE;AACA,kBAAc;AAAA,EAChB;AACF;AAEA,SAASC,UAAS,IAAgC;AAChD,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,WAAW,MAAY,QAAQ,EAAE;AACvC,OAAG,SAAS,MAAM,CAAC,WAAW;AAC5B,SAAG,eAAe,SAAS,QAAQ;AACnC,cAAQ,MAAM;AAAA,IAChB,CAAC;AACD,OAAG,KAAK,SAAS,QAAQ;AAAA,EAC3B,CAAC;AACH;AAEA,eAAsB,SAAS,QAAkC;AAC/D,QAAM,QAAQ,MAAM,0BAA0B,MAAM;AACpD,QAAM,KAAK,gBAAgB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,OAAO,CAAC;AAC3E,MAAI;AACF,eAAS;AACP,YAAM,OAAO,MAAMA,UAAS,EAAE;AAC9B,UAAI,KAAK,KAAK,MAAM,IAAI;AACtB,eAAO;AAAA,MACT;AACA,YAAM,UAAU,KAAK,KAAK;AAC1B,UAAI,YAAY,WAAW,YAAY,SAAS;AAC9C,eAAO;AAAA,MACT;AACA,YAAM,cAAc,OAAO,OAAO;AAAA,IACpC;AAAA,EACF,UAAE;AACA,OAAG,MAAM;AAAA,EACX;AACF;AAEA,SAAS,WAAW,SAAyC;AAC3D,QAAM,QAAQ,QAAQ,UAAU,gBAAgB,KAAK,QAAQ,IAAI;AACjE,MAAI,UAAU,UAAa,MAAM,WAAW,GAAG;AAC7C,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,UAA0B;AACpD,MAAI,SAAS,SAAS,GAAGC,MAAK,GAAG,QAAQA,MAAK,GAAG,aAAa,MAAM,MAAM;AACxE,WAAO,6CAA6C,QAAQ;AAAA,EAC9D;AACA,SAAO,kCAAkC,QAAQ;AACnD;AAEA,SAAS,YAAY,SAA6B;AAChD,SAAO,QAAQ,UAAU,UAAU,KAAK,QAAQ,IAAI;AACtD;AAEA,eAAe,aAAa,UAAkB,MAA8C;AAC1F,QAAM,KAAK,gBAAgB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,OAAO,CAAC;AAC3E,MAAI;AACF,UAAM,UAAU,MAAM,sBAAsB,UAAU,CAAC,WAAW,SAAgB,IAAI,MAAM,GAAG,IAAI;AACnG,QAAI,YAAY,QAAW;AACzB,aAAO;AAAA,IACT;AACA,UAAM,SAAS,kBAAkB,UAAU,mBAAmB,OAAO,CAAC;AACtE,YAAQ,OAAO,MAAM,GAAG,OAAO,OAAO;AAAA,CAAI;AAC1C,WAAO,OAAO;AAAA,EAChB,UAAE;AACA,OAAG,MAAM;AAAA,EACX;AACF;AAEA,eAAe,gBAAgB,SAAqB,UAA+C;AACjG,MAAI,QAAQ,gBAAgB,QAAW;AACrC,WAAO;AAAA,EACT;AACA,QAAM,WAAW,qBAAqB,QAAQ;AAC9C,MAAI,aAAa,QAAW;AAC1B,YAAQ,OAAO,MAAM,GAAG,mBAAmB,QAAQ,CAAC;AAAA,CAAI;AACxD,YAAQ,cAAc;AACtB,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,MAAM,aAAa,UAAU,WAAW,OAAO,CAAC;AAC9D,MAAI,UAAU,aAAa;AACzB,YAAQ,OAAO,MAAM,0CAA0C;AAC/D,WAAO;AAAA,EACT;AACA,UAAQ,cAAc;AACtB,SAAO;AACT;AAEA,eAAe,SAAS,SAAsC;AAC5D,MAAI,QAAQ,MAAM,UAAU,MAAM;AAChC,YAAQ,OAAO,MAAM,4HAA4H;AACjJ,WAAO;AAAA,EACT;AACA,QAAM,WAAW,YAAY,OAAO;AACpC,QAAM,UAAU,MAAM,gBAAgB,SAAS,QAAQ;AACvD,MAAI,YAAY,QAAW;AACzB,WAAO;AAAA,EACT;AACA,SAAO,cAAc,iBAAiB,SAAS,KAAK,CAAC;AACvD;AAEA,SAAS,wBAAwB,QAA0C;AACzE,QAAM,YAAY,OAAO,WAAW;AACpC,QAAM,QAAQ,MAAM,QAAQ,SAAS,MAAM,OAAO,UAAU,CAAC,IAAI;AACjE,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,WAAO;AAAA,EACT;AACA,SAAQ,MAAkC,OAAO,MAAM;AACzD;AAEA,SAAS,SAAS,SAA6B;AAC7C,MAAI,QAAQ,YAAY,SAAS,GAAG;AAClC,UAAM,IAAI,MAAM,+BAA+B;AAAA,EACjD;AACA,QAAM,SAAS,sBAAsB;AACrC,kBAAgB,QAAQ,QAAQ,SAAS;AACzC,QAAM,SAAS,kBAAkB,YAAY,OAAO,GAAG,MAAM;AAC7D,UAAQ,OAAO,MAAM,GAAG,OAAO,OAAO;AAAA,CAAI;AAC1C,MAAI,OAAO,YAAY,QAAQ,wBAAwB,MAAM,MAAM,MAAM;AACvE,YAAQ,OAAO,MAAM,wEAAwE;AAAA,EAC/F;AACA,SAAO;AACT;AAEA,eAAe,cAAc,QAA0D;AACrF,QAAM,EAAE,QAAQ,IAAI,MAAM,OAAO,mBAAU;AAC3C,SAAO,QAAQ,MAAM;AACvB;AAEA,SAAS,kBAAkB,QAAqB,eAAqD;AACnG,MAAI,cAAc,SAAS,GAAG;AAC5B,WAAO;AAAA,EACT;AACA,QAAM,aAAa,OAAO,SAAS,aAAa,CAAC;AACjD,SAAO,WAAW,WAAW,IAAI,CAAC,SAAS,IAAI;AACjD;AAEA,eAAe,kBAAkB,QAAqB,WAAsC;AAC1F,QAAM,EAAE,YAAY,IAAI,MAAM,OAAO,uBAAc;AACnD,SAAO,YAAY,QAAQ,kBAAkB,QAAQ,SAAS,CAAC;AACjE;AAUO,SAAS,aAAa,OAA+B;AAC1D,MAAI,MAAM,QAAQ,MAAM;AACtB,WAAO,MAAM,qBAAqB;AAAA,EACpC;AACA,SAAO,mBAAmB,MAAM,YAAY,MAAM,KAAK;AACzD;AAEA,SAAS,iBAA0B;AACjC,SAAO,aAAa;AAAA,IAClB,KAAK,QAAQ,SAAS,QAAQ;AAAA,IAC9B,kBAAkB,YAAY;AAAA,IAC9B,YAAY,YAAY;AAAA,IACxB,OAAO,QAAQ,KAAK,CAAC;AAAA,EACvB,CAAC;AACH;AAEA,SAAS,mBAAmB,YAAoB,OAAoC;AAClF,MAAI,UAAU,UAAa,UAAU,IAAI;AACvC,WAAO;AAAA,EACT;AACA,QAAM,WAAWA,MAAK,QAAQ,KAAK;AACnC,MAAI,eAAe,cAAc,QAAQ,EAAE,MAAM;AAC/C,WAAO;AAAA,EACT;AACA,SAAO,eAAe,cAAc,UAAU,GAAG,QAAQ;AAC3D;AAEA,SAAS,eAAe,MAAc,OAAwB;AAC5D,MAAIC,YAAW,IAAI,MAAM,SAASA,YAAW,KAAK,MAAM,OAAO;AAC7D,WAAO;AAAA,EACT;AACA,SAAO,aAAa,IAAI,MAAM,aAAa,KAAK;AAClD;AAEA,eAAsB,QAAQ,MAAiC;AAC7D,QAAM,UAAU,WAAW,IAAI;AAC/B,MAAI,QAAQ,SAAS,MAAM;AACzB,YAAQ,OAAO,MAAM,GAAG,WAAW,CAAC;AAAA,CAAI;AACxC,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,YAAY,MAAM;AAC5B,YAAQ,OAAO,MAAM,GAAG,YAAY;AAAA,CAAI;AACxC,WAAO;AAAA,EACT;AACA,QAAM,CAAC,KAAK,IAAI,QAAQ;AACxB,MAAI,UAAU,QAAW;AACvB,WAAO,SAAS,OAAO;AAAA,EACzB;AACA,MAAI,UAAU,QAAQ;AACpB,WAAO,SAAS,OAAO;AAAA,EACzB;AACA,MAAI,UAAU,UAAU;AACtB,YAAQ,OAAO,MAAM,GAAG,gBAAgB,CAAC;AAAA,CAAI;AAC7C,WAAO;AAAA,EACT;AACA,MAAI,UAAU,UAAU;AACtB,QAAI,QAAQ,YAAY,SAAS,GAAG;AAClC,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AACA,WAAO,WAAW,cAAc,YAAY,GAAG,CAAC;AAAA,EAClD;AACA,MAAI,UAAU,QAAQ;AACpB,QAAI,QAAQ,YAAY,SAAS,GAAG;AAClC,YAAM,IAAI,MAAM,kCAAkC;AAAA,IACpD;AACA,WAAO,SAAS,iBAAiB,SAAS,KAAK,CAAC;AAAA,EAClD;AACA,MAAI,UAAU,OAAO;AACnB,WAAO,cAAc,iBAAiB,SAAS,KAAK,CAAC;AAAA,EACvD;AACA,MAAI,UAAU,WAAW;AACvB,WAAO,kBAAkB,iBAAiB,SAAS,KAAK,GAAG,QAAQ,YAAY,MAAM,CAAC,CAAC;AAAA,EACzF;AACA,SAAO,aAAa,iBAAiB,SAAS,UAAU,GAAG,QAAQ,YAAY,KAAK,GAAG,CAAC;AAC1F;AAEA,IAAI,eAAe,MAAM,MAAM;AAC7B,UAAQ,QAAQ,KAAK,MAAM,CAAC,CAAC,EAC1B,KAAK,CAAC,SAAS;AACd,YAAQ,WAAW;AAAA,EACrB,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,YAAQ,OAAO,MAAM,SAAS,cAAc,KAAK,CAAC;AAAA,CAAI;AACtD,YAAQ,OAAO,MAAM,+BAA+B;AACpD,YAAQ,WAAW;AAAA,EACrB,CAAC;AACL;","names":["existsSync","readFileSync","path","existsSync","path","path","existsSync","path","path","model_hint","value","readFileSync","ask_line","path","existsSync"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -270,9 +270,8 @@ declare const agent_config_schema: z.ZodEffects<z.ZodObject<{
|
|
|
270
270
|
}>>;
|
|
271
271
|
log_level: z.ZodDefault<z.ZodEnum<["debug", "info", "warn", "error"]>>;
|
|
272
272
|
}, "strip", z.ZodTypeAny, {
|
|
273
|
-
plugins: string[];
|
|
274
|
-
agent_name: string;
|
|
275
273
|
max_turns: number;
|
|
274
|
+
log_level: "debug" | "info" | "warn" | "error";
|
|
276
275
|
providers: z.objectOutputType<{
|
|
277
276
|
kind: z.ZodEnum<["openai_compat", "anthropic", "ollama"]>;
|
|
278
277
|
name: z.ZodString;
|
|
@@ -284,20 +283,21 @@ declare const agent_config_schema: z.ZodEffects<z.ZodObject<{
|
|
|
284
283
|
/** Injectable fetch, mainly for tests; passes through untouched. */
|
|
285
284
|
fetch_fn: z.ZodOptional<z.ZodType<typeof fetch, z.ZodTypeDef, typeof fetch>>;
|
|
286
285
|
}, z.ZodTypeAny, "passthrough">[];
|
|
286
|
+
agent_name: string;
|
|
287
287
|
tools_enabled: string[] | "all";
|
|
288
288
|
context_budget_tokens: number;
|
|
289
289
|
compress_threshold: number;
|
|
290
290
|
terminal_timeout_ms: number;
|
|
291
|
-
|
|
292
|
-
temperature?: number | undefined;
|
|
293
|
-
max_tokens?: number | undefined;
|
|
294
|
-
system_prompt?: string | undefined;
|
|
291
|
+
plugins: string[];
|
|
295
292
|
work_dir?: string | undefined;
|
|
293
|
+
system_prompt?: string | undefined;
|
|
296
294
|
session_dir?: string | undefined;
|
|
297
295
|
gateway?: {
|
|
298
296
|
platforms: ("webhook" | "telegram" | "discord" | "twitch")[];
|
|
299
297
|
token_envs: Record<string, string>;
|
|
300
298
|
} | undefined;
|
|
299
|
+
temperature?: number | undefined;
|
|
300
|
+
max_tokens?: number | undefined;
|
|
301
301
|
}, {
|
|
302
302
|
providers: z.objectInputType<{
|
|
303
303
|
kind: z.ZodEnum<["openai_compat", "anthropic", "ollama"]>;
|
|
@@ -310,42 +310,42 @@ declare const agent_config_schema: z.ZodEffects<z.ZodObject<{
|
|
|
310
310
|
/** Injectable fetch, mainly for tests; passes through untouched. */
|
|
311
311
|
fetch_fn: z.ZodOptional<z.ZodType<typeof fetch, z.ZodTypeDef, typeof fetch>>;
|
|
312
312
|
}, z.ZodTypeAny, "passthrough">[];
|
|
313
|
-
plugins?: string[] | undefined;
|
|
314
|
-
temperature?: number | undefined;
|
|
315
|
-
max_tokens?: number | undefined;
|
|
316
|
-
agent_name?: string | undefined;
|
|
317
|
-
system_prompt?: string | undefined;
|
|
318
|
-
max_turns?: number | undefined;
|
|
319
313
|
work_dir?: string | undefined;
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
compress_threshold?: number | undefined;
|
|
314
|
+
max_turns?: number | undefined;
|
|
315
|
+
system_prompt?: string | undefined;
|
|
323
316
|
session_dir?: string | undefined;
|
|
324
|
-
|
|
317
|
+
log_level?: "debug" | "info" | "warn" | "error" | undefined;
|
|
325
318
|
gateway?: {
|
|
326
319
|
platforms?: ("webhook" | "telegram" | "discord" | "twitch")[] | undefined;
|
|
327
320
|
token_envs?: Record<string, string> | undefined;
|
|
328
321
|
} | undefined;
|
|
329
|
-
|
|
322
|
+
agent_name?: string | undefined;
|
|
323
|
+
tools_enabled?: string[] | "all" | undefined;
|
|
324
|
+
temperature?: number | undefined;
|
|
325
|
+
max_tokens?: number | undefined;
|
|
326
|
+
context_budget_tokens?: number | undefined;
|
|
327
|
+
compress_threshold?: number | undefined;
|
|
328
|
+
terminal_timeout_ms?: number | undefined;
|
|
329
|
+
plugins?: string[] | undefined;
|
|
330
330
|
}>, {
|
|
331
331
|
work_dir: string;
|
|
332
332
|
providers: ProviderConfig[];
|
|
333
333
|
session_dir: string;
|
|
334
|
-
plugins: string[];
|
|
335
|
-
agent_name: string;
|
|
336
334
|
max_turns: number;
|
|
335
|
+
log_level: "debug" | "info" | "warn" | "error";
|
|
336
|
+
agent_name: string;
|
|
337
337
|
tools_enabled: string[] | "all";
|
|
338
338
|
context_budget_tokens: number;
|
|
339
339
|
compress_threshold: number;
|
|
340
340
|
terminal_timeout_ms: number;
|
|
341
|
-
|
|
342
|
-
temperature?: number | undefined;
|
|
343
|
-
max_tokens?: number | undefined;
|
|
341
|
+
plugins: string[];
|
|
344
342
|
system_prompt?: string | undefined;
|
|
345
343
|
gateway?: {
|
|
346
344
|
platforms: ("webhook" | "telegram" | "discord" | "twitch")[];
|
|
347
345
|
token_envs: Record<string, string>;
|
|
348
346
|
} | undefined;
|
|
347
|
+
temperature?: number | undefined;
|
|
348
|
+
max_tokens?: number | undefined;
|
|
349
349
|
}, {
|
|
350
350
|
providers: z.objectInputType<{
|
|
351
351
|
kind: z.ZodEnum<["openai_compat", "anthropic", "ollama"]>;
|
|
@@ -358,23 +358,23 @@ declare const agent_config_schema: z.ZodEffects<z.ZodObject<{
|
|
|
358
358
|
/** Injectable fetch, mainly for tests; passes through untouched. */
|
|
359
359
|
fetch_fn: z.ZodOptional<z.ZodType<typeof fetch, z.ZodTypeDef, typeof fetch>>;
|
|
360
360
|
}, z.ZodTypeAny, "passthrough">[];
|
|
361
|
-
plugins?: string[] | undefined;
|
|
362
|
-
temperature?: number | undefined;
|
|
363
|
-
max_tokens?: number | undefined;
|
|
364
|
-
agent_name?: string | undefined;
|
|
365
|
-
system_prompt?: string | undefined;
|
|
366
|
-
max_turns?: number | undefined;
|
|
367
361
|
work_dir?: string | undefined;
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
compress_threshold?: number | undefined;
|
|
362
|
+
max_turns?: number | undefined;
|
|
363
|
+
system_prompt?: string | undefined;
|
|
371
364
|
session_dir?: string | undefined;
|
|
372
|
-
|
|
365
|
+
log_level?: "debug" | "info" | "warn" | "error" | undefined;
|
|
373
366
|
gateway?: {
|
|
374
367
|
platforms?: ("webhook" | "telegram" | "discord" | "twitch")[] | undefined;
|
|
375
368
|
token_envs?: Record<string, string> | undefined;
|
|
376
369
|
} | undefined;
|
|
377
|
-
|
|
370
|
+
agent_name?: string | undefined;
|
|
371
|
+
tools_enabled?: string[] | "all" | undefined;
|
|
372
|
+
temperature?: number | undefined;
|
|
373
|
+
max_tokens?: number | undefined;
|
|
374
|
+
context_budget_tokens?: number | undefined;
|
|
375
|
+
compress_threshold?: number | undefined;
|
|
376
|
+
terminal_timeout_ms?: number | undefined;
|
|
377
|
+
plugins?: string[] | undefined;
|
|
378
378
|
}>;
|
|
379
379
|
type AgentConfig = z.infer<typeof agent_config_schema>;
|
|
380
380
|
declare function parse_agent_config(raw: unknown): AgentConfig;
|
|
@@ -581,9 +581,6 @@ declare class HookedToolRunner {
|
|
|
581
581
|
call_run_end(info: RunEndInfo, base: HookContext): Promise<void>;
|
|
582
582
|
}
|
|
583
583
|
|
|
584
|
-
|
|
585
|
-
* Public surface of the lich agent harness. Pure re-exports only.
|
|
586
|
-
*/
|
|
587
|
-
declare const LICH_VERSION = "0.3.0";
|
|
584
|
+
declare const LICH_VERSION: string;
|
|
588
585
|
|
|
589
586
|
export { type AfterToolCallInfo, Agent, type AgentConfig, AgentEmitter, type AgentEvent, type AgentEventHandler, type AgentEvents, type AgentRunOptions, type AgentRunResult, type BeforeToolCallInfo, type BeforeToolCallResult, type ChatOptions, type ChatResult, type HookContext, HookedToolRunner, LICH_VERSION, type LoadedPlugin, type LoopOutcome, type LoopParams, type Message, type Plugin, type PluginHooks, type PluginLoadError, type ProviderConfig, ProviderError, type RunEndInfo, type Tool, type ToolCall, type ToolContext, type ToolDefinition, ToolExecutor, ToolRegistry, type ToolResult, type Usage, create_agent, create_agent_with_plugins, load_plugins, parse_agent_config, plugin_errors_summary, register_builtin_tools, run_agent };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
LICH_VERSION
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6M6OAQGN.js";
|
|
4
4
|
import {
|
|
5
5
|
create_agent_with_plugins,
|
|
6
6
|
truncate_text
|
|
@@ -433,4 +433,4 @@ async function run_tui(config) {
|
|
|
433
433
|
export {
|
|
434
434
|
run_tui
|
|
435
435
|
};
|
|
436
|
-
//# sourceMappingURL=tui-
|
|
436
|
+
//# sourceMappingURL=tui-2VO6LAFM.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moikapy/lich",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Lich — a TypeScript AI agent harness (library + CLI) inspired by Hermes",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"zod": "^3.25.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
+
"@types/bun": "^1.4.2",
|
|
49
50
|
"@types/node": "^22.10.0",
|
|
50
51
|
"@types/react": "^19.0.0",
|
|
51
52
|
"tsup": "^8.3.0",
|
package/dist/chunk-ZVK3MUPC.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Public surface of the lich agent harness. Pure re-exports only.\n */\nexport const LICH_VERSION = \"0.3.0\";\n\nexport { Agent, create_agent, run_agent, create_agent_with_plugins } from \"./agent/agent.js\";\nexport type { AgentRunOptions, AgentRunResult } from \"./agent/agent.js\";\nexport type { AgentConfig } from \"./agent/config.js\";\nexport { parse_agent_config } from \"./agent/config.js\";\nexport { AgentEmitter } from \"./agent/events.js\";\nexport type { AgentEvent, AgentEventHandler, AgentEvents } from \"./agent/events.js\";\nexport type { LoopOutcome, LoopParams } from \"./agent/loop.js\";\nexport type {\n ChatOptions,\n ChatResult,\n Message,\n ProviderConfig,\n ToolCall,\n ToolDefinition,\n Usage,\n} from \"./providers/types.js\";\nexport { ProviderError } from \"./providers/types.js\";\nexport { ToolExecutor } from \"./tools/executor.js\";\nexport { ToolRegistry } from \"./tools/registry.js\";\nexport type { Tool, ToolContext, ToolResult } from \"./tools/types.js\";\nexport { register_builtin_tools } from \"./tools/builtin/index.js\";\nexport { HookedToolRunner } from \"./plugins/hooks.js\";\nexport { load_plugins, plugin_errors_summary } from \"./plugins/loader.js\";\nexport type { LoadedPlugin, PluginLoadError } from \"./plugins/loader.js\";\nexport type {\n AfterToolCallInfo,\n BeforeToolCallInfo,\n BeforeToolCallResult,\n HookContext,\n Plugin,\n PluginHooks,\n RunEndInfo,\n} from \"./plugins/types.js\";"],"mappings":";AAGO,IAAM,eAAe;","names":[]}
|
|
File without changes
|