@moikapy/lich 0.6.0 → 0.7.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.
Files changed (39) hide show
  1. package/CHANGELOG.md +75 -1
  2. package/README.md +59 -7
  3. package/dist/{chunk-JC2G3XH2.js → chunk-CVX7LZWC.js} +2 -2
  4. package/dist/chunk-PZNYVGD4.js +58 -0
  5. package/dist/chunk-PZNYVGD4.js.map +1 -0
  6. package/dist/{chunk-7HLVKVIG.js → chunk-WNFBIX4E.js} +1344 -162
  7. package/dist/chunk-WNFBIX4E.js.map +1 -0
  8. package/dist/cli.js +246 -18
  9. package/dist/cli.js.map +1 -1
  10. package/dist/{gateway-RJFZJEUZ.js → gateway-44QTIJTJ.js} +108 -49
  11. package/dist/gateway-44QTIJTJ.js.map +1 -0
  12. package/dist/index.d.ts +288 -154
  13. package/dist/index.js +5 -3
  14. package/dist/{tui-LOUJVZ6A.js → tui-MEJGEILU.js} +25 -10
  15. package/dist/tui-MEJGEILU.js.map +1 -0
  16. package/docs/.vitepress/config.mts +4 -0
  17. package/docs/architecture/overview.md +30 -18
  18. package/docs/architecture/plugins.md +1 -1
  19. package/docs/architecture/tools.md +36 -4
  20. package/docs/getting-started.md +7 -6
  21. package/docs/index.md +5 -4
  22. package/docs/user-guide/cli.md +21 -8
  23. package/docs/user-guide/games.md +1 -1
  24. package/docs/user-guide/gateway.md +70 -16
  25. package/docs/user-guide/godot.md +3 -1
  26. package/docs/user-guide/library.md +4 -2
  27. package/docs/user-guide/plugins.md +2 -2
  28. package/docs/user-guide/redot.md +93 -0
  29. package/docs/user-guide/tui.md +2 -2
  30. package/examples/game_bridge/README.md +2 -0
  31. package/optional-mcps/godot/manifest.json +6 -0
  32. package/optional-mcps/redot/manifest.json +18 -0
  33. package/package.json +2 -1
  34. package/dist/chunk-6M6OAQGN.js +0 -17
  35. package/dist/chunk-6M6OAQGN.js.map +0 -1
  36. package/dist/chunk-7HLVKVIG.js.map +0 -1
  37. package/dist/gateway-RJFZJEUZ.js.map +0 -1
  38. package/dist/tui-LOUJVZ6A.js.map +0 -1
  39. /package/dist/{chunk-JC2G3XH2.js.map → chunk-CVX7LZWC.js.map} +0 -0
package/dist/index.d.ts CHANGED
@@ -23,107 +23,6 @@ interface JsonSchemaObject {
23
23
  additionalProperties?: boolean;
24
24
  }
25
25
 
26
- interface ToolResult {
27
- ok: boolean;
28
- output: string;
29
- error?: string;
30
- }
31
- interface ToolContext {
32
- work_dir: string;
33
- env: Record<string, string>;
34
- signal?: AbortSignal;
35
- }
36
- interface Tool {
37
- name: string;
38
- description: string;
39
- parameters: JsonSchemaObject;
40
- /** Per-tool executor timeout override in ms; unset tools get the 30s default. */
41
- timeout_ms?: number;
42
- execute(args: Record<string, unknown>, context: ToolContext): Promise<ToolResult>;
43
- }
44
- interface Toolset {
45
- name: string;
46
- tools: Tool[];
47
- }
48
-
49
- /**
50
- * Plugin surface: user-authored tools and lifecycle hooks loaded at startup.
51
- *
52
- * A plugin is a plain object exported from a TS/JS module. Hooks observe and
53
- * (in the case of before_tool_call) veto tool executions; tools merge into the
54
- * agent registry after builtin filtering.
55
- */
56
-
57
- /** Runtime info handed to every hook call. */
58
- interface HookContext {
59
- work_dir: string;
60
- /**
61
- * This plugin's own per-run state sub-map. Every hook invocation receives
62
- * a ctx exposing only the invoking plugin's bag; the bag is swapped fresh
63
- * at each run start. Absent only on hand-built contexts outside the runner.
64
- */
65
- state?: Map<string, unknown>;
66
- }
67
- /** Argument passed to before_tool_call hooks. */
68
- interface BeforeToolCallInfo {
69
- tool_name: string;
70
- args: Record<string, unknown>;
71
- }
72
- /** Return value that vetoes a tool call; other hooks still run. */
73
- interface BeforeToolCallResult {
74
- block?: boolean;
75
- reason?: string;
76
- }
77
- /** Argument passed to after_tool_call hooks. */
78
- interface AfterToolCallInfo extends BeforeToolCallInfo {
79
- result_summary: string;
80
- /** Structured executor outcome; gate on this, never parse result_summary. */
81
- ok: boolean;
82
- error?: string;
83
- }
84
- interface RunEndInfo {
85
- stopped_reason: string;
86
- turns_used: number;
87
- }
88
- /** Optional lifecycle hooks a plugin may implement. All hooks are awaited. */
89
- interface PluginHooks {
90
- before_tool_call?(info: BeforeToolCallInfo, ctx: HookContext): Promise<BeforeToolCallResult | void> | BeforeToolCallResult | void;
91
- after_tool_call?(info: AfterToolCallInfo, ctx: HookContext): Promise<void> | void;
92
- on_run_start?(info: {
93
- input_chars: number;
94
- }, ctx: HookContext): Promise<void> | void;
95
- on_run_end?(info: RunEndInfo, ctx: HookContext): Promise<void> | void;
96
- }
97
- /** A user plugin: required unique name, optional tools and hooks. */
98
- interface Plugin {
99
- name: string;
100
- version?: string;
101
- tools?: Tool[];
102
- hooks?: PluginHooks;
103
- }
104
-
105
- /** A successfully loaded plugin plus the entry path it came from. */
106
- interface LoadedPlugin {
107
- plugin: Plugin;
108
- entry: string;
109
- }
110
- /** One failed entry: the specifier and why it failed. */
111
- interface PluginLoadError {
112
- entry: string;
113
- error_message: string;
114
- }
115
- /**
116
- * Load plugins from explicit entry paths (relative to `base_dir` or absolute).
117
- * Broken imports, missing exports, and duplicate names become error entries;
118
- * nothing is thrown for a bad plugin.
119
- */
120
- declare function load_plugins(entries: readonly string[], base_dir: string): Promise<{
121
- plugins: LoadedPlugin[];
122
- errors: PluginLoadError[];
123
- }>;
124
- /** Joined one-liner per load error, for a single warn log. */
125
- declare function plugin_errors_summary(errors: readonly PluginLoadError[]): string;
126
-
127
26
  type FinishReason = "stop" | "tool_calls" | "length" | "error" | "unknown";
128
27
  type ProviderErrorKind = "rate_limit" | "network" | "auth" | "overflow" | "bad_request" | "unknown";
129
28
  interface ToolCall {
@@ -261,19 +160,73 @@ declare const agent_config_schema: z.ZodEffects<z.ZodObject<{
261
160
  platforms: z.ZodDefault<z.ZodArray<z.ZodEnum<["webhook", "telegram", "discord", "twitch"]>, "many">>;
262
161
  /** Env-var names that hold tokens. Never store the secrets themselves. */
263
162
  token_envs: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
163
+ /** Per-platform user ids allowed to talk to the bot (default-deny on public platforms). */
164
+ allowed_users: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
165
+ /** Per-platform chat/channel ids allowed (default-deny on public platforms). */
166
+ allowed_chats: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString, "many">>>;
167
+ /** Tool allowlist for the gateway agent; defaults to a read-only safe subset. */
168
+ tools_enabled: z.ZodDefault<z.ZodUnion<[z.ZodLiteral<"all">, z.ZodArray<z.ZodString, "many">]>>;
264
169
  }, "strip", z.ZodTypeAny, {
170
+ tools_enabled: string[] | "all";
265
171
  platforms: ("webhook" | "telegram" | "discord" | "twitch")[];
266
172
  token_envs: Record<string, string>;
173
+ allowed_users: Record<string, string[]>;
174
+ allowed_chats: Record<string, string[]>;
267
175
  }, {
176
+ tools_enabled?: string[] | "all" | undefined;
268
177
  platforms?: ("webhook" | "telegram" | "discord" | "twitch")[] | undefined;
269
178
  token_envs?: Record<string, string> | undefined;
179
+ allowed_users?: Record<string, string[]> | undefined;
180
+ allowed_chats?: Record<string, string[]> | undefined;
270
181
  }>>;
271
182
  log_level: z.ZodDefault<z.ZodEnum<["debug", "info", "warn", "error"]>>;
272
183
  theme: z.ZodDefault<z.ZodString>;
184
+ /** Named MCP servers. Each entry is stdio or loopback http. Default off. */
185
+ mcp_servers: z.ZodOptional<z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodObject<{
186
+ enabled: z.ZodDefault<z.ZodBoolean>;
187
+ command: z.ZodString;
188
+ args: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
189
+ env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
190
+ }, "strict", z.ZodTypeAny, {
191
+ enabled: boolean;
192
+ command: string;
193
+ args: string[];
194
+ env?: Record<string, string> | undefined;
195
+ }, {
196
+ command: string;
197
+ enabled?: boolean | undefined;
198
+ args?: string[] | undefined;
199
+ env?: Record<string, string> | undefined;
200
+ }>, z.ZodObject<{
201
+ enabled: z.ZodDefault<z.ZodBoolean>;
202
+ url: z.ZodString;
203
+ }, "strict", z.ZodTypeAny, {
204
+ url: string;
205
+ enabled: boolean;
206
+ }, {
207
+ url: string;
208
+ enabled?: boolean | undefined;
209
+ }>]>>, Record<string, {
210
+ enabled: boolean;
211
+ command: string;
212
+ args: string[];
213
+ env?: Record<string, string> | undefined;
214
+ } | {
215
+ url: string;
216
+ enabled: boolean;
217
+ }>, Record<string, {
218
+ command: string;
219
+ enabled?: boolean | undefined;
220
+ args?: string[] | undefined;
221
+ env?: Record<string, string> | undefined;
222
+ } | {
223
+ url: string;
224
+ enabled?: boolean | undefined;
225
+ }>>>;
273
226
  }, "strip", z.ZodTypeAny, {
274
- plugins: string[];
275
- agent_name: string;
276
227
  max_turns: number;
228
+ log_level: "debug" | "info" | "warn" | "error";
229
+ theme: string;
277
230
  providers: z.objectOutputType<{
278
231
  kind: z.ZodEnum<["openai_compat", "anthropic", "ollama"]>;
279
232
  name: z.ZodString;
@@ -285,21 +238,33 @@ declare const agent_config_schema: z.ZodEffects<z.ZodObject<{
285
238
  /** Injectable fetch, mainly for tests; passes through untouched. */
286
239
  fetch_fn: z.ZodOptional<z.ZodType<typeof fetch, z.ZodTypeDef, typeof fetch>>;
287
240
  }, z.ZodTypeAny, "passthrough">[];
241
+ agent_name: string;
288
242
  tools_enabled: string[] | "all";
289
243
  context_budget_tokens: number;
290
244
  compress_threshold: number;
291
245
  terminal_timeout_ms: number;
292
- log_level: "debug" | "info" | "warn" | "error";
293
- theme: string;
294
- temperature?: number | undefined;
295
- max_tokens?: number | undefined;
296
- system_prompt?: string | undefined;
246
+ plugins: string[];
297
247
  work_dir?: string | undefined;
248
+ system_prompt?: string | undefined;
298
249
  session_dir?: string | undefined;
299
250
  gateway?: {
251
+ tools_enabled: string[] | "all";
300
252
  platforms: ("webhook" | "telegram" | "discord" | "twitch")[];
301
253
  token_envs: Record<string, string>;
254
+ allowed_users: Record<string, string[]>;
255
+ allowed_chats: Record<string, string[]>;
302
256
  } | undefined;
257
+ temperature?: number | undefined;
258
+ max_tokens?: number | undefined;
259
+ mcp_servers?: Record<string, {
260
+ enabled: boolean;
261
+ command: string;
262
+ args: string[];
263
+ env?: Record<string, string> | undefined;
264
+ } | {
265
+ url: string;
266
+ enabled: boolean;
267
+ }> | undefined;
303
268
  }, {
304
269
  providers: z.objectInputType<{
305
270
  kind: z.ZodEnum<["openai_compat", "anthropic", "ollama"]>;
@@ -312,44 +277,68 @@ declare const agent_config_schema: z.ZodEffects<z.ZodObject<{
312
277
  /** Injectable fetch, mainly for tests; passes through untouched. */
313
278
  fetch_fn: z.ZodOptional<z.ZodType<typeof fetch, z.ZodTypeDef, typeof fetch>>;
314
279
  }, z.ZodTypeAny, "passthrough">[];
315
- plugins?: string[] | undefined;
316
- temperature?: number | undefined;
317
- max_tokens?: number | undefined;
318
- agent_name?: string | undefined;
319
- system_prompt?: string | undefined;
320
- max_turns?: number | undefined;
321
280
  work_dir?: string | undefined;
322
- tools_enabled?: string[] | "all" | undefined;
323
- context_budget_tokens?: number | undefined;
324
- compress_threshold?: number | undefined;
281
+ max_turns?: number | undefined;
282
+ system_prompt?: string | undefined;
325
283
  session_dir?: string | undefined;
326
- terminal_timeout_ms?: number | undefined;
284
+ log_level?: "debug" | "info" | "warn" | "error" | undefined;
285
+ theme?: string | undefined;
327
286
  gateway?: {
287
+ tools_enabled?: string[] | "all" | undefined;
328
288
  platforms?: ("webhook" | "telegram" | "discord" | "twitch")[] | undefined;
329
289
  token_envs?: Record<string, string> | undefined;
290
+ allowed_users?: Record<string, string[]> | undefined;
291
+ allowed_chats?: Record<string, string[]> | undefined;
330
292
  } | undefined;
331
- log_level?: "debug" | "info" | "warn" | "error" | undefined;
332
- theme?: string | undefined;
293
+ agent_name?: string | undefined;
294
+ tools_enabled?: string[] | "all" | undefined;
295
+ temperature?: number | undefined;
296
+ max_tokens?: number | undefined;
297
+ context_budget_tokens?: number | undefined;
298
+ compress_threshold?: number | undefined;
299
+ terminal_timeout_ms?: number | undefined;
300
+ plugins?: string[] | undefined;
301
+ mcp_servers?: Record<string, {
302
+ command: string;
303
+ enabled?: boolean | undefined;
304
+ args?: string[] | undefined;
305
+ env?: Record<string, string> | undefined;
306
+ } | {
307
+ url: string;
308
+ enabled?: boolean | undefined;
309
+ }> | undefined;
333
310
  }>, {
334
311
  work_dir: string;
335
312
  providers: ProviderConfig[];
336
313
  session_dir: string;
337
- plugins: string[];
338
- agent_name: string;
339
314
  max_turns: number;
315
+ log_level: "debug" | "info" | "warn" | "error";
316
+ theme: string;
317
+ agent_name: string;
340
318
  tools_enabled: string[] | "all";
341
319
  context_budget_tokens: number;
342
320
  compress_threshold: number;
343
321
  terminal_timeout_ms: number;
344
- log_level: "debug" | "info" | "warn" | "error";
345
- theme: string;
346
- temperature?: number | undefined;
347
- max_tokens?: number | undefined;
322
+ plugins: string[];
348
323
  system_prompt?: string | undefined;
349
324
  gateway?: {
325
+ tools_enabled: string[] | "all";
350
326
  platforms: ("webhook" | "telegram" | "discord" | "twitch")[];
351
327
  token_envs: Record<string, string>;
328
+ allowed_users: Record<string, string[]>;
329
+ allowed_chats: Record<string, string[]>;
352
330
  } | undefined;
331
+ temperature?: number | undefined;
332
+ max_tokens?: number | undefined;
333
+ mcp_servers?: Record<string, {
334
+ enabled: boolean;
335
+ command: string;
336
+ args: string[];
337
+ env?: Record<string, string> | undefined;
338
+ } | {
339
+ url: string;
340
+ enabled: boolean;
341
+ }> | undefined;
353
342
  }, {
354
343
  providers: z.objectInputType<{
355
344
  kind: z.ZodEnum<["openai_compat", "anthropic", "ollama"]>;
@@ -362,28 +351,175 @@ declare const agent_config_schema: z.ZodEffects<z.ZodObject<{
362
351
  /** Injectable fetch, mainly for tests; passes through untouched. */
363
352
  fetch_fn: z.ZodOptional<z.ZodType<typeof fetch, z.ZodTypeDef, typeof fetch>>;
364
353
  }, z.ZodTypeAny, "passthrough">[];
365
- plugins?: string[] | undefined;
366
- temperature?: number | undefined;
367
- max_tokens?: number | undefined;
368
- agent_name?: string | undefined;
369
- system_prompt?: string | undefined;
370
- max_turns?: number | undefined;
371
354
  work_dir?: string | undefined;
372
- tools_enabled?: string[] | "all" | undefined;
373
- context_budget_tokens?: number | undefined;
374
- compress_threshold?: number | undefined;
355
+ max_turns?: number | undefined;
356
+ system_prompt?: string | undefined;
375
357
  session_dir?: string | undefined;
376
- terminal_timeout_ms?: number | undefined;
358
+ log_level?: "debug" | "info" | "warn" | "error" | undefined;
359
+ theme?: string | undefined;
377
360
  gateway?: {
361
+ tools_enabled?: string[] | "all" | undefined;
378
362
  platforms?: ("webhook" | "telegram" | "discord" | "twitch")[] | undefined;
379
363
  token_envs?: Record<string, string> | undefined;
364
+ allowed_users?: Record<string, string[]> | undefined;
365
+ allowed_chats?: Record<string, string[]> | undefined;
380
366
  } | undefined;
381
- log_level?: "debug" | "info" | "warn" | "error" | undefined;
382
- theme?: string | undefined;
367
+ agent_name?: string | undefined;
368
+ tools_enabled?: string[] | "all" | undefined;
369
+ temperature?: number | undefined;
370
+ max_tokens?: number | undefined;
371
+ context_budget_tokens?: number | undefined;
372
+ compress_threshold?: number | undefined;
373
+ terminal_timeout_ms?: number | undefined;
374
+ plugins?: string[] | undefined;
375
+ mcp_servers?: Record<string, {
376
+ command: string;
377
+ enabled?: boolean | undefined;
378
+ args?: string[] | undefined;
379
+ env?: Record<string, string> | undefined;
380
+ } | {
381
+ url: string;
382
+ enabled?: boolean | undefined;
383
+ }> | undefined;
383
384
  }>;
384
385
  type AgentConfig = z.infer<typeof agent_config_schema>;
385
386
  declare function parse_agent_config(raw: unknown): AgentConfig;
386
387
 
388
+ interface ToolResult {
389
+ ok: boolean;
390
+ output: string;
391
+ error?: string;
392
+ }
393
+ interface ToolContext {
394
+ work_dir: string;
395
+ env: Record<string, string>;
396
+ signal?: AbortSignal;
397
+ }
398
+ interface Tool {
399
+ name: string;
400
+ description: string;
401
+ parameters: JsonSchemaObject;
402
+ /** Per-tool executor timeout override in ms; unset tools get the 30s default. */
403
+ timeout_ms?: number;
404
+ execute(args: Record<string, unknown>, context: ToolContext): Promise<ToolResult>;
405
+ }
406
+ interface Toolset {
407
+ name: string;
408
+ tools: Tool[];
409
+ }
410
+
411
+ /**
412
+ * Name-keyed registry of tools and toolsets. Registration rejects duplicate
413
+ * tool names so conflicting builtins fail loudly at startup.
414
+ */
415
+ declare class ToolRegistry {
416
+ private readonly tools;
417
+ register(tool: Tool): void;
418
+ register_toolset(toolset: Toolset): void;
419
+ get(name: string): Tool | undefined;
420
+ has(name: string): boolean;
421
+ list(): Tool[];
422
+ /** Map registered tools onto the provider-facing wire shape. */
423
+ definitions(): ToolDefinition[];
424
+ }
425
+
426
+ interface LineChild {
427
+ write_line(line: string): void;
428
+ read_line(): Promise<string | undefined>;
429
+ stop(): void;
430
+ failed(): string | undefined;
431
+ }
432
+ type LineSpawner = (command: string, args: readonly string[], env?: Record<string, string>) => LineChild;
433
+
434
+ /**
435
+ * Discover tools/list for each enabled server and register mcp_<server>_<tool>.
436
+ * tools_enabled filters them. An empty allowlist never connects.
437
+ */
438
+
439
+ interface McpRuntime {
440
+ spawn?: LineSpawner;
441
+ fetch_fn?: typeof fetch;
442
+ env_path?: string;
443
+ }
444
+
445
+ /**
446
+ * Plugin surface: user-authored tools and lifecycle hooks loaded at startup.
447
+ *
448
+ * A plugin is a plain object exported from a TS/JS module. Hooks observe and
449
+ * (in the case of before_tool_call) veto tool executions; tools merge into the
450
+ * agent registry after builtin filtering.
451
+ */
452
+
453
+ /** Runtime info handed to every hook call. */
454
+ interface HookContext {
455
+ work_dir: string;
456
+ /**
457
+ * This plugin's own per-run state sub-map. Every hook invocation receives
458
+ * a ctx exposing only the invoking plugin's bag; the bag is swapped fresh
459
+ * at each run start. Absent only on hand-built contexts outside the runner.
460
+ */
461
+ state?: Map<string, unknown>;
462
+ }
463
+ /** Argument passed to before_tool_call hooks. */
464
+ interface BeforeToolCallInfo {
465
+ tool_name: string;
466
+ args: Record<string, unknown>;
467
+ }
468
+ /** Return value that vetoes a tool call; other hooks still run. */
469
+ interface BeforeToolCallResult {
470
+ block?: boolean;
471
+ reason?: string;
472
+ }
473
+ /** Argument passed to after_tool_call hooks. */
474
+ interface AfterToolCallInfo extends BeforeToolCallInfo {
475
+ result_summary: string;
476
+ /** Structured executor outcome; gate on this, never parse result_summary. */
477
+ ok: boolean;
478
+ error?: string;
479
+ }
480
+ interface RunEndInfo {
481
+ stopped_reason: string;
482
+ turns_used: number;
483
+ }
484
+ /** Optional lifecycle hooks a plugin may implement. All hooks are awaited. */
485
+ interface PluginHooks {
486
+ before_tool_call?(info: BeforeToolCallInfo, ctx: HookContext): Promise<BeforeToolCallResult | void> | BeforeToolCallResult | void;
487
+ after_tool_call?(info: AfterToolCallInfo, ctx: HookContext): Promise<void> | void;
488
+ on_run_start?(info: {
489
+ input_chars: number;
490
+ }, ctx: HookContext): Promise<void> | void;
491
+ on_run_end?(info: RunEndInfo, ctx: HookContext): Promise<void> | void;
492
+ }
493
+ /** A user plugin: required unique name, optional tools and hooks. */
494
+ interface Plugin {
495
+ name: string;
496
+ version?: string;
497
+ tools?: Tool[];
498
+ hooks?: PluginHooks;
499
+ }
500
+
501
+ /** A successfully loaded plugin plus the entry path it came from. */
502
+ interface LoadedPlugin {
503
+ plugin: Plugin;
504
+ entry: string;
505
+ }
506
+ /** One failed entry: the specifier and why it failed. */
507
+ interface PluginLoadError {
508
+ entry: string;
509
+ error_message: string;
510
+ }
511
+ /**
512
+ * Load plugins from explicit entry paths (relative to `base_dir` or absolute).
513
+ * Broken imports, missing exports, and duplicate names become error entries;
514
+ * nothing is thrown for a bad plugin.
515
+ */
516
+ declare function load_plugins(entries: readonly string[], base_dir: string): Promise<{
517
+ plugins: LoadedPlugin[];
518
+ errors: PluginLoadError[];
519
+ }>;
520
+ /** Joined one-liner per load error, for a single warn log. */
521
+ declare function plugin_errors_summary(errors: readonly PluginLoadError[]): string;
522
+
387
523
  /**
388
524
  * Typed event emitter for the agent loop.
389
525
  *
@@ -492,8 +628,18 @@ declare class Agent {
492
628
  private readonly registry;
493
629
  private readonly executor;
494
630
  private readonly hook_runner;
495
- constructor(config: AgentConfig, plugins?: readonly LoadedPlugin[]);
631
+ private readonly mcp_runtime;
632
+ private mcp_sessions;
633
+ private mcp_attach;
634
+ constructor(config: AgentConfig, plugins?: readonly LoadedPlugin[], runtime?: {
635
+ mcp?: McpRuntime;
636
+ });
496
637
  run(options: AgentRunOptions): Promise<AgentRunResult>;
638
+ /** Close MCP sessions so stdio children do not keep the event loop alive. */
639
+ close(): void;
640
+ /** tools/list once, before the model sees definitions. Empty allowlists never connect. */
641
+ private attach_mcp_once;
642
+ private do_attach_mcp;
497
643
  /** Per-run deps: the built-once ToolContext threads through every tool execution. */
498
644
  private loop_deps;
499
645
  /** Best-effort on_run_start fan-out; hook errors are logged, never fatal. */
@@ -511,20 +657,8 @@ declare function run_agent(raw_config: unknown, input: string, options?: {
511
657
  label?: string;
512
658
  }): Promise<AgentRunResult>;
513
659
 
514
- /**
515
- * Name-keyed registry of tools and toolsets. Registration rejects duplicate
516
- * tool names so conflicting builtins fail loudly at startup.
517
- */
518
- declare class ToolRegistry {
519
- private readonly tools;
520
- register(tool: Tool): void;
521
- register_toolset(toolset: Toolset): void;
522
- get(name: string): Tool | undefined;
523
- has(name: string): boolean;
524
- list(): Tool[];
525
- /** Map registered tools onto the provider-facing wire shape. */
526
- definitions(): ToolDefinition[];
527
- }
660
+ /** Write the client entry. The user sets enabled. Godot has nothing to write. */
661
+ declare function catalog_client_entry(name: string, substitutes?: Record<string, string>): Record<string, unknown> | string;
528
662
 
529
663
  interface ExecutorDefaults {
530
664
  work_dir?: string;
@@ -588,4 +722,4 @@ declare class HookedToolRunner {
588
722
 
589
723
  declare const LICH_VERSION: string;
590
724
 
591
- 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 };
725
+ 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, catalog_client_entry, 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,7 @@
1
1
  import {
2
- LICH_VERSION
3
- } from "./chunk-6M6OAQGN.js";
2
+ LICH_VERSION,
3
+ catalog_client_entry
4
+ } from "./chunk-PZNYVGD4.js";
4
5
  import {
5
6
  Agent,
6
7
  AgentEmitter,
@@ -15,7 +16,7 @@ import {
15
16
  plugin_errors_summary,
16
17
  register_builtin_tools,
17
18
  run_agent
18
- } from "./chunk-7HLVKVIG.js";
19
+ } from "./chunk-WNFBIX4E.js";
19
20
  export {
20
21
  Agent,
21
22
  AgentEmitter,
@@ -24,6 +25,7 @@ export {
24
25
  ProviderError,
25
26
  ToolExecutor,
26
27
  ToolRegistry,
28
+ catalog_client_entry,
27
29
  create_agent,
28
30
  create_agent_with_plugins,
29
31
  load_plugins,
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  fill_template,
3
3
  load_theme
4
- } from "./chunk-JC2G3XH2.js";
4
+ } from "./chunk-CVX7LZWC.js";
5
5
  import {
6
6
  LICH_VERSION
7
- } from "./chunk-6M6OAQGN.js";
7
+ } from "./chunk-PZNYVGD4.js";
8
8
  import {
9
9
  create_agent_with_plugins,
10
10
  truncate_text
11
- } from "./chunk-7HLVKVIG.js";
11
+ } from "./chunk-WNFBIX4E.js";
12
12
 
13
13
  // src/tui.tsx
14
14
  import { render } from "ink";
@@ -242,6 +242,9 @@ function CommandBar({ busy, on_submit }) {
242
242
  const [recall_ring, set_recall_ring] = useState2([]);
243
243
  const [recall_index, set_recall_index] = useState2(void 0);
244
244
  const submit_buffer = () => {
245
+ if (busy === true) {
246
+ return;
247
+ }
245
248
  const text = buffer.trim();
246
249
  set_buffer("");
247
250
  set_recall_index(void 0);
@@ -254,6 +257,14 @@ function CommandBar({ busy, on_submit }) {
254
257
  if (recall_ring.length === 0) {
255
258
  return;
256
259
  }
260
+ if (direction === -1 && recall_index === 0) {
261
+ set_recall_index(void 0);
262
+ set_buffer("");
263
+ return;
264
+ }
265
+ if (direction === -1 && recall_index === void 0) {
266
+ return;
267
+ }
257
268
  const current = recall_index ?? -direction;
258
269
  const next = Math.min(Math.max(current + direction, 0), recall_ring.length - 1);
259
270
  set_recall_index(next);
@@ -265,11 +276,11 @@ function CommandBar({ busy, on_submit }) {
265
276
  return;
266
277
  }
267
278
  if (key.upArrow === true) {
268
- walk_recall(-1);
279
+ walk_recall(1);
269
280
  return;
270
281
  }
271
282
  if (key.downArrow === true) {
272
- walk_recall(1);
283
+ walk_recall(-1);
273
284
  return;
274
285
  }
275
286
  if (key.backspace === true || key.delete === true) {
@@ -427,12 +438,16 @@ function TuiApp({ agent, theme }) {
427
438
  import { jsx as jsx5 } from "react/jsx-runtime";
428
439
  async function run_tui(config) {
429
440
  const agent = await create_agent_with_plugins(config);
430
- const theme = load_theme(config.theme);
431
- const instance = render(/* @__PURE__ */ jsx5(TuiApp, { agent, theme }));
432
- await instance.waitUntilExit();
433
- return 0;
441
+ try {
442
+ const theme = load_theme(config.theme);
443
+ const instance = render(/* @__PURE__ */ jsx5(TuiApp, { agent, theme }));
444
+ await instance.waitUntilExit();
445
+ return 0;
446
+ } finally {
447
+ agent.close();
448
+ }
434
449
  }
435
450
  export {
436
451
  run_tui
437
452
  };
438
- //# sourceMappingURL=tui-LOUJVZ6A.js.map
453
+ //# sourceMappingURL=tui-MEJGEILU.js.map