@gaunt-sloth/core 2.0.0-alpha.3 → 2.0.0-alpha.4

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/dist/config.d.ts CHANGED
@@ -1,828 +1,25 @@
1
- import { StatusLevel } from '#src/core/types.js';
2
- import type { GthCommand } from '#src/core/types.js';
3
- import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
4
- import type { BaseToolkit, StructuredToolInterface } from '@langchain/core/tools';
5
1
  /**
6
- * This is a processed Gaunt Sloth config ready to be passed down into components.
2
+ * @packageDocumentation
3
+ * Gaunt Sloth Configuration.
7
4
  *
8
- * Default values can be found in {@link DEFAULT_CONFIG}
9
- */
10
- export interface GthConfig {
11
- llm: BaseChatModel;
12
- /**
13
- * Binary format support configuration.
14
- * Disabled by default unless explicitly configured.
15
- */
16
- binaryFormats?: false | BinaryFormatConfig[];
17
- /**
18
- * Content Provider. Provider used to fetch content (usually diff) for `review` or `pr` command.
19
- *
20
- * {@link DEFAULT_CONFIG#contentProvider}
21
- */
22
- /**
23
- * Content source type. Preferred name for contentProvider.
24
- */
25
- contentSource: string;
26
- /**
27
- * Requirement source type. Preferred name for requirementsProvider.
28
- */
29
- requirementSource: string;
30
- /**
31
- * @deprecated Use contentSource instead
32
- */
33
- contentProvider: string;
34
- /**
35
- * @deprecated Use requirementSource instead
36
- */
37
- requirementsProvider: string;
38
- /**
39
- * Path to project-specific guidelines.
40
- * The default is `.gsloth.guidelines.md`; this config may be used to point Gaunt Sloth to a different file,
41
- * for example, to AGENTS.md
42
- */
43
- projectGuidelines: string;
44
- /**
45
- * Separate identity profile.
46
- * May include separate identity, guidelines and command protocol,
47
- * making gsloth behave as an agent different from default profile behaviour.
48
- * for example, `devops` profile to detect changes such as properties and environment variables.
49
- * Custom config can still win over this one.
50
- * This setting requires .gsloth/.gsloth-settings directory to exist.
51
- */
52
- identityProfile?: string;
53
- /**
54
- * Whether to include the current date in the project review instructions or not.
55
- */
56
- includeCurrentDateAfterGuidelines: boolean;
57
- /**
58
- * Organisation name, locale and timezone.
59
- * Only used with {@link includeCurrentDateAfterGuidelines}.
60
- * timeZone and locale should be in format supported by Intl.DateTimeFormat
61
- */
62
- organization?: {
63
- name?: string;
64
- locale?: string;
65
- timezone?: string;
66
- };
67
- projectReviewInstructions: string;
68
- /**
69
- * If true, only use user-provided system prompts. Do not fall back to the
70
- * bundled `.gsloth.*.md` prompt files shipped with the installation.
71
- * This applies to all `.gsloth.*.md` files (backstory, system, chat, code, guidelines, review).
72
- */
73
- noDefaultPrompts?: boolean;
74
- filesystem: string[] | 'all' | 'read' | 'none';
75
- builtInTools?: string[];
76
- tools?: StructuredToolInterface[] | BaseToolkit[] | ServerTool[];
77
- /**
78
- * Restrict the agent to this allow-list of tool names, applied after every tool source
79
- * (filesystem, built-in, custom, MCP, A2A, and `tools`) is resolved. This is the only knob
80
- * that can gate MCP and A2A tools, which have no per-source override of their own.
81
- *
82
- * - omitted/undefined: no filtering, all resolved tools remain available.
83
- * - non-empty array: keep only tools whose name is in the list.
84
- * - empty array `[]`: disable every tool. MCP servers are not even contacted (no OAuth),
85
- * which is useful for agents that only need to reason over the prompt (e.g. the review
86
- * agent).
87
- *
88
- * Can be overridden per command via `commands.<command>.allowedTools`.
89
- */
90
- allowedTools?: string[];
91
- /**
92
- * Middleware configuration for LangChain v1.
93
- * Middleware provides hooks to intercept and control agent execution at critical points.
94
- *
95
- * Middleware can be:
96
- * - Predefined middleware (string or config object) - works in both JSON and JS configs
97
- * - Custom middleware objects - only available in JS configs
98
- *
99
- * Example (JSON config):
100
- * ```json
101
- * {
102
- * "middleware": [
103
- * "summarization",
104
- * { "name": "anthropic-prompt-caching", "ttl": "5m" }
105
- * ]
106
- * }
107
- * ```
108
- *
109
- * Example (JS config):
110
- * ```js
111
- * {
112
- * middleware: [
113
- * "summarization",
114
- * { beforeModel: (state) => { /* custom logic *\/ return state; } }
115
- * ]
116
- * }
117
- * ```
118
- *
119
- * Available predefined middleware:
120
- * - `anthropic-prompt-caching`: Reduces API costs by caching prompts (Anthropic only)
121
- * - `summarization`: Condenses conversation history when approaching token limits
122
- */
123
- middleware?: unknown[];
124
- /**
125
- * Stream output. Some models do not support streaming. Set value to `false` for them.
126
- *
127
- * {@link DEFAULT_CONFIG#streamOutput}
128
- */
129
- streamOutput: boolean;
130
- /**
131
- * Should the output be written to md file.
132
- * (e.g. gth_2025-07-26_22-59-06_REVIEW.md).
133
- * Can be set to false with `-wn` or `-w0`
134
- * Can be set to a specific filename or path by passing a string:
135
- * - Bare filenames (e.g. `"review.md"`) are placed in `.gsloth/` when it exists, otherwise project root
136
- * - Paths with separators (e.g. `"./review.md"` or `"reviews/last.md"`) are always relative to project root
137
- * Please note the string does not accept absolute path, but allows to exit project with `..` if necessary.
138
- */
139
- writeOutputToFile: boolean | string;
140
- /**
141
- * Whether binary model outputs should be written to files instead of printed inline.
142
- * When enabled, supported binary content blocks are materialized as `gth_*.<ext>` files.
143
- */
144
- writeBinaryOutputsToFile: boolean;
145
- /**
146
- * Use colour in output
147
- */
148
- useColour: boolean;
149
- /**
150
- * Stream session log instead of writing it when inference streaming is complete.
151
- * (only works when {@link streamOutput} is true)
152
- */
153
- streamSessionInferenceLog: boolean;
154
- /**
155
- * Allow inference to be interrupted with esc. Only has an effect in TTY mode.
156
- */
157
- canInterruptInferenceWithEsc: boolean;
158
- /**
159
- * Log messages and events to gaunt-sloth.log,
160
- * use llm.verbose or `gth --verbose` as more intrusive option, setting verbose to LangChain / LangGraph
161
- */
162
- debugLog?: boolean;
163
- /**
164
- * LangGraph recursion limit for an agent run — the maximum number of
165
- * super-steps (model ↔ tool round-trips) before the graph throws. Defaults to
166
- * 1000, which suits long coding chains; embodied / tight-loop consumers can
167
- * lower it so a stuck run fails fast and visibly instead of grinding.
168
- */
169
- recursionLimit?: number;
170
- /**
171
- * Console logging level. Only messages at or above this level will be displayed.
172
- * Valid values: 'debug', 'info', 'display', 'success', 'warning', 'error', 'stream'
173
- * Default: 'info' (not debug)
174
- */
175
- consoleLevel?: StatusLevel;
176
- customTools?: CustomToolsConfig;
177
- requirementSourceConfig?: Record<string, unknown>;
178
- contentSourceConfig?: Record<string, unknown>;
179
- /** @deprecated Use requirementSourceConfig instead */
180
- requirementsProviderConfig?: Record<string, unknown>;
181
- /** @deprecated Use contentSourceConfig instead */
182
- contentProviderConfig?: Record<string, unknown>;
183
- /**
184
- * MCP (Model Context Protocol) server connections.
185
- * Allows connecting to external MCP servers including those requiring OAuth.
186
- * @see {@link https://modelcontextprotocol.io/}
187
- */
188
- mcpServers?: Record<string, unknown>;
189
- /**
190
- * A2A (Agent-to-Agent) protocol agents configuration.
191
- * Enables delegation of tasks to external AI agents.
192
- * Each agent becomes available as a tool named `a2a_agent_<agentId>`.
193
- * @experimental This feature is experimental and may change.
194
- * @see {@link https://a2a-protocol.org/}
195
- */
196
- a2aAgents?: Record<string, unknown>;
197
- builtInToolsConfig?: BuiltInToolsConfig;
198
- aiignore?: {
199
- enabled?: boolean;
200
- patterns?: string[];
201
- };
202
- commands?: {
203
- pr?: PrCommandConfig;
204
- review?: {
205
- contentSource?: string;
206
- requirementSource?: string;
207
- /** @deprecated Use requirementSource instead */
208
- requirementsProvider?: string;
209
- /** @deprecated Use contentSource instead */
210
- contentProvider?: string;
211
- filesystem?: string[] | 'all' | 'read' | 'none';
212
- builtInTools?: string[];
213
- customTools?: CustomToolsConfig | false;
214
- /** See {@link GthConfig.allowedTools}. Empty array disables all tools for the review agent. */
215
- allowedTools?: string[];
216
- rating?: RatingConfig;
217
- binaryFormats?: false | BinaryFormatConfig[];
218
- };
219
- ask?: {
220
- filesystem?: string[] | 'all' | 'read' | 'none';
221
- builtInTools?: string[];
222
- customTools?: CustomToolsConfig | false;
223
- /** See {@link GthConfig.allowedTools}. */
224
- allowedTools?: string[];
225
- /**
226
- * Dev tools (run commands etc.) for `ask --write` runs. Normally inherited from
227
- * `commands.exec` / `commands.code` by the `--write` flag rather than set directly.
228
- */
229
- devTools?: GthDevToolsConfig;
230
- binaryFormats?: false | BinaryFormatConfig[];
231
- };
232
- chat?: {
233
- filesystem?: string[] | 'all' | 'read' | 'none';
234
- builtInTools?: string[];
235
- customTools?: CustomToolsConfig | false;
236
- /** See {@link GthConfig.allowedTools}. */
237
- allowedTools?: string[];
238
- binaryFormats?: false | BinaryFormatConfig[];
239
- };
240
- code?: {
241
- filesystem?: string[] | 'all' | 'read' | 'none';
242
- builtInTools?: string[];
243
- customTools?: CustomToolsConfig | false;
244
- /** See {@link GthConfig.allowedTools}. */
245
- allowedTools?: string[];
246
- devTools?: GthDevToolsConfig;
247
- binaryFormats?: false | BinaryFormatConfig[];
248
- };
249
- /**
250
- * `gth exec` — prompt-as-script runtime. Like `code`, an exec run may need to actually
251
- * do the job (read/write files, run commands), so it carries the same tool/filesystem knobs.
252
- */
253
- exec?: {
254
- filesystem?: string[] | 'all' | 'read' | 'none';
255
- builtInTools?: string[];
256
- customTools?: CustomToolsConfig | false;
257
- /** See {@link GthConfig.allowedTools}. */
258
- allowedTools?: string[];
259
- devTools?: GthDevToolsConfig;
260
- binaryFormats?: false | BinaryFormatConfig[];
261
- };
262
- api?: {
263
- filesystem?: string[] | 'all' | 'read' | 'none';
264
- builtInTools?: string[];
265
- port?: number;
266
- cors?: {
267
- allowOrigin?: string;
268
- allowMethods?: string;
269
- allowHeaders?: string;
270
- };
271
- };
272
- };
273
- modelDisplayName?: string;
274
- /**
275
- * Transient (runtime-only) extra filesystem roots the agent is allowed to read/write for
276
- * THIS run, in addition to the cwd sandbox. Populated by `gth exec --allow-dir <path>`
277
- * (repeatable); never persisted to a config file. When set, the deep agent's
278
- * {@link FilesystemBackend} drops `virtualMode` (so absolute paths and `..` resolve on the
279
- * real filesystem) and access is constrained to cwd + these dirs via permission allow-rules.
280
- * Removing the cwd-only sandbox is a guardrail removal, so callers announce it loudly.
281
- */
282
- allowDirs?: string[];
283
- /**
284
- * Transient (runtime-only) flag set by `gth ask --write`: opt `ask` into the same
285
- * "do-the-job" filesystem + dev tools that `exec`/`code` get, so a question can act
286
- * (read/write files, run commands) rather than only chat. Never persisted to a config file.
287
- */
288
- askWriteMode?: boolean;
289
- }
290
- /**
291
- * `gth pr` command configuration.
5
+ * Refer to {@link GthConfig} to find all possible configuration properties.
292
6
  *
293
- * Declared as a named interface (rather than inline in {@link GthConfig}) so that downstream
294
- * packages can extend it with their own command features via TypeScript module augmentation
295
- * (`declare module '@gaunt-sloth/core/config.js'`), keeping those features' types out of core.
296
- * For example, the assistant package merges its PR discovery config (`discovery`) into this
297
- * interface.
298
- */
299
- export interface PrCommandConfig {
300
- contentSource?: string;
301
- requirementSource?: string;
302
- /** @deprecated Use contentSource instead */
303
- contentProvider?: string;
304
- /** @deprecated Use requirementSource instead */
305
- requirementsProvider?: string;
306
- filesystem?: string[] | 'all' | 'read' | 'none';
307
- builtInTools?: string[];
308
- customTools?: CustomToolsConfig | false;
309
- /** See {@link GthConfig.allowedTools}. Empty array disables all tools for `gth pr`'s review agent. */
310
- allowedTools?: string[];
311
- logWorkForReviewInSeconds?: number;
312
- rating?: RatingConfig;
313
- binaryFormats?: false | BinaryFormatConfig[];
314
- }
315
- /**
316
- * Server tools such as Anthropic Web Search.
317
- * These tools are meant to be magic objects like
318
- * `{"type": "web_search_20250305", "name": "web_search", "max_uses": 10}`,
319
- * AI Provider does the rest of the magic on their side.
320
- */
321
- export interface ServerTool extends Record<string, unknown> {
322
- type: string;
323
- name?: string;
324
- }
325
- /**
326
- * Raw, unprocessed Gaunt Sloth config.
327
- */
328
- export type ConsoleLevelInput = StatusLevel | keyof typeof StatusLevel | Lowercase<keyof typeof StatusLevel>;
329
- export interface RawGthConfig extends Omit<GthConfig, 'llm' | 'consoleLevel'> {
330
- llm: LLMConfig;
331
- consoleLevel?: ConsoleLevelInput;
332
- }
333
- export type BinaryFormatType = 'image' | 'file' | 'audio' | 'video' | 'binary';
334
- export interface BinaryFormatConfig {
335
- /**
336
- * The type/category of binary format.
337
- */
338
- type: BinaryFormatType;
339
- /**
340
- * List of allowed extensions for this type (without leading dot).
341
- */
342
- extensions: string[];
343
- /**
344
- * Maximum file size in bytes. Defaults to 10MB when omitted.
345
- */
346
- maxSize?: number;
347
- /**
348
- * Optional MIME type overrides for extensions not in the default mapping.
349
- */
350
- mimeTypes?: Record<string, string>;
351
- }
352
- export type CustomToolsConfig = Record<string, CustomCommandConfig>;
353
- export type BuiltInToolsConfig = Record<string, unknown>;
354
- /**
355
- * Configuration for review rating feature.
356
- * Allows configuring automated review scoring with pass/fail thresholds.
357
- */
358
- export interface RatingConfig {
359
- /**
360
- * Enable or disable review rating.
361
- * @default true
362
- */
363
- enabled?: boolean;
364
- /**
365
- * Minimum score (0-10) required to pass the review.
366
- * @default 6
367
- */
368
- passThreshold?: number;
369
- /**
370
- * Highest allowed value on the rating scale.
371
- * @default 10
372
- */
373
- maxRating?: number;
374
- /**
375
- * Lowest allowed value on the rating scale.
376
- * @default 0
377
- */
378
- minRating?: number;
379
- /**
380
- * Exit with error code 1 when review fails (below threshold).
381
- * When false, exits normally (code 0) regardless of rating.
382
- * @default true
383
- */
384
- errorOnReviewFail?: boolean;
385
- }
386
- /**
387
- * Validation checks that can be skipped for custom command parameters.
388
- * Use with the `allow` property to bypass specific security checks.
7
+ * Refer to {@link DEFAULT_CONFIG} for default configuration.
389
8
  *
390
- * - `absolute-paths`: Allow absolute paths (e.g. `/dev/ttyUSB0`)
391
- * - `directory-traversal`: Allow `..` in paths
392
- * - `shell-injection`: Allow shell metacharacters (`|`, `&`, `;`, etc.)
393
- * - `null-bytes`: Allow null bytes in values
394
- */
395
- export type ValidationCheck = 'absolute-paths' | 'directory-traversal' | 'shell-injection' | 'null-bytes';
396
- /**
397
- * Configuration for a custom command parameter.
398
- * Parameters allow the model to provide dynamic values to commands.
399
- */
400
- export interface CustomCommandParameter {
401
- /**
402
- * Description of the parameter shown to the model.
403
- */
404
- description: string;
405
- /**
406
- * Optional list of validation checks to skip for this parameter's value.
407
- * Use when this parameter legitimately requires values that would normally be blocked.
408
- * For example, `["absolute-paths"]` allows values like `/dev/ttyUSB0` for this parameter.
409
- *
410
- * Available checks: `absolute-paths`, `directory-traversal`, `shell-injection`, `null-bytes`
411
- */
412
- allow?: ValidationCheck[];
413
- }
414
- /**
415
- * Configuration for a custom command.
416
- * Custom commands can be executed with or without parameters.
417
- */
418
- export interface CustomCommandConfig {
419
- /**
420
- * The shell command to execute.
421
- * Can include placeholders like ${paramName} that will be replaced with parameter values.
422
- * If no placeholder is present and parameters are provided, they are appended to the command.
423
- */
424
- command: string;
425
- /**
426
- * Description of what this command does, shown to the model.
427
- */
428
- description: string;
429
- /**
430
- * Optional parameters that the model can provide when calling this command.
431
- * Each parameter has a name (the key) and a description.
432
- * Parameters are validated for security (no shell injection, directory traversal, etc.).
433
- */
434
- parameters?: Record<string, CustomCommandParameter>;
435
- /**
436
- * Optional timeout in seconds.
437
- * When set, the command will be killed if it exceeds this duration.
438
- * When omitted, no timeout is applied.
439
- */
440
- timeout?: number;
441
- }
442
- /**
443
- * Config for {@link GthDevToolkit}.
444
- * Tools are not applied when config is not provided.
445
- * Only available in `code`/`exec` mode (and `ask --write`).
446
- */
447
- export interface GthDevToolsConfig {
448
- /**
449
- * Optional shell command to run tests.
450
- * Not applied when config is not provided.
451
- */
452
- run_tests?: string;
453
- /**
454
- * Optional shell command to run static analysis (lint).
455
- * Not applied when config is not provided.
456
- */
457
- run_lint?: string;
458
- /**
459
- * Optional shell command to run the build.
460
- * Not applied when config is not provided.
461
- */
462
- run_build?: string;
463
- /**
464
- * Optional shell command to run a single test file.
465
- * Supports command interpolation with the `${testPath}` placeholder.
466
- * Example: "npm test -- ${testPath}" or "jest ${testPath}"
467
- * Example: "npm test" - the test will simply be appended
468
- * Not applied when config is not provided.
469
- */
470
- run_single_test?: string;
471
- /**
472
- * Opt-in general-purpose shell tool (`run_shell_command`). Unlike the fixed
473
- * `run_*` commands above, this lets the agent run ARBITRARY shell commands it
474
- * composes itself — the agentic-coding escape hatch the deep agent otherwise
475
- * lacks (it can read/write files but not run commands).
476
- *
477
- * EXT-12 — default: ON in `code` mode, OFF elsewhere. When this is ABSENT/undefined,
478
- * `code` mode emits the tool (still GATED behind the per-command approval prompt — the
479
- * absent-config default NEVER implies yolo); `exec` / `ask --write` keep it OFF. An
480
- * EXPLICIT value always wins: `shell: false` (or `{ enabled: false }`) is a hard escape
481
- * hatch that fully disables it even in `code`. Accepts a bare boolean or an
482
- * `{ enabled }` object for symmetry with future per-tool options.
483
- *
484
- * Because the model chooses the command, every invocation is gated behind a
485
- * per-command human confirmation dialog (LangChain `humanInTheLoopMiddleware`,
486
- * wired via deepagents' `interruptOn`) UNLESS {@link shellYolo} bypasses it.
487
- * The confirmation — not string-filtering — is the guardrail, so the command
488
- * is passed through verbatim (pipes / `$` / `;` are all legitimate).
489
- *
490
- * The object form also tunes the EXT-9 Tier-1 hardening applied to every run
491
- * (these have safe defaults so bare `shell: true` is already hardened):
492
- * - `timeout`: per-command wall-clock limit in MILLISECONDS before the child
493
- * (and its process group) is killed. Default {@link SHELL_DEFAULT_TIMEOUT_MS}.
494
- * - `maxOutputBytes`: byte budget for the captured output returned to the model
495
- * (head + tail window; the middle is dropped and the full output spilled to a
496
- * temp file). Default {@link SHELL_DEFAULT_MAX_OUTPUT_BYTES}. Live terminal
497
- * streaming is never capped.
498
- *
499
- * A hardcoded hardline blocklist of catastrophic commands (rm -rf /, mkfs, dd
500
- * to a block device, fork bomb, shutdown/reboot, …) is refused even under
501
- * {@link shellYolo}; that floor is not configurable.
502
- *
503
- * Example: `{ "shell": true }`,
504
- * `{ "shell": { "enabled": true, "timeout": 300000, "maxOutputBytes": 200000 } }`.
505
- *
506
- * The object form additionally accepts EXT-9 Tier-2 allow-list knobs:
507
- * - `allowlist`: master switch for the scoped approval allow-list (session +
508
- * persisted `always`). Default `true` — once a command is approved at `session`/
509
- * `always` scope, flag-variants of the same classified operation auto-approve
510
- * without re-prompting. Set `false` to require fresh approval for every command.
511
- * - `persistAllowlist`: whether `always`-scoped approvals are written to the project
512
- * allow-list file (`.gsloth/.gsloth-settings/shell-allowlist.json`). Default `true`.
513
- * When `false`, an `always` decision behaves like `session` (in-memory only).
514
- *
515
- * The object form also accepts the EXT-10 LLM-as-judge safety gate (default OFF):
516
- * - `judge`: an opt-in, tiered auto-approve pre-filter that vets each `run_shell_command`
517
- * with a lightweight judge model BEFORE the human prompt. It auto-approves clearly-safe
518
- * commands (fatigue reducer), escalates the rest to the existing human prompt, and may
519
- * reject clearly-catastrophic ones. Default OFF because it costs one LLM call per command.
520
- * Accepts a bare boolean (`judge: true` → defaults: auto-approve low, escalate medium/high,
521
- * judge model = `config.llm`) or an object:
522
- * - `enabled`: turn the gate on.
523
- * - `autoApproveLow`: auto-approve `low`-risk, statically-resolvable commands. Default true.
524
- * - `blockHigh`: reject clearly-catastrophic (`high` + destructive) verdicts WITHOUT
525
- * prompting. Default false (conservative; EXT-9's hardline floor already refuses truly
526
- * catastrophic commands at exec time).
527
- * - `model`: an optional separate (e.g. cheaper) judge model config. Defaults to `config.llm`.
528
- * Hardening (always on when the judge runs): the command is normalized + XML-tagged as
529
- * UNTRUSTED input in the judge prompt; a judge throw/timeout/parse-failure fails CLOSED
530
- * (escalate, never auto-approve); commands whose target can't be statically resolved
531
- * (shell composition / substitution / redirection) and interpreter+script invocations that
532
- * leak ALL_CAPS env vars are NEVER auto-approved.
533
- */
534
- shell?: boolean | {
535
- enabled?: boolean;
536
- timeout?: number;
537
- maxOutputBytes?: number;
538
- allowlist?: boolean;
539
- persistAllowlist?: boolean;
540
- judge?: boolean | {
541
- enabled?: boolean;
542
- autoApproveLow?: boolean;
543
- blockHigh?: boolean;
544
- model?: LLMConfig;
545
- };
546
- };
547
- /**
548
- * Opt-out of the per-command confirmation dialog for {@link shell}
549
- * (`run_shell_command`) — the explicit "yolo" bypass. When `true` AND `shell`
550
- * is enabled, the shell tool runs without any approval interrupt: the model's
551
- * commands execute immediately. Dangerous by design; off by default.
552
- *
553
- * Example: `{ "shell": true, "shellYolo": true }`.
554
- */
555
- shellYolo?: boolean;
556
- }
557
- /**
558
- * Default per-command shell timeout (ms) when {@link GthDevToolsConfig.shell}
559
- * does not specify one. ~120s suits typical build/test/git steps without
560
- * hanging the agent forever on a stuck command.
561
- */
562
- export declare const SHELL_DEFAULT_TIMEOUT_MS = 120000;
563
- /**
564
- * Default byte budget for shell output captured into the ToolMessage returned to
565
- * the model (head + tail window). ~100KB keeps a noisy log from blowing the
566
- * context window; the full output is spilled to a temp file when this is exceeded.
567
- */
568
- export declare const SHELL_DEFAULT_MAX_OUTPUT_BYTES = 100000;
569
- /**
570
- * Normalize the {@link GthDevToolsConfig.shell} opt-in (bare boolean or
571
- * `{ enabled }`) to a plain boolean. Centralized so the toolkit (tool emission)
572
- * and the deep agent (interrupt wiring) agree on what "shell enabled" means.
9
+ * Some config params can be overriden from command line, see {@link CommandLineConfigOverrides}
573
10
  *
574
- * EXT-12 default-resolution: an EXPLICIT value always wins (a bare boolean, or the
575
- * object form's `enabled`), so `shell: false` / `{ enabled: false }` remains a hard
576
- * escape hatch that fully disables the tool. Only when `shell` is ABSENT/undefined does
577
- * the per-mode default apply: in `code` mode the shell tool is ON by default (still
578
- * gated — the per-command approval interrupt is wired separately and is NOT bypassed by
579
- * this), and OFF everywhere else (`exec`, `ask --write`, …) to preserve prior behaviour.
580
- * The default is `code`-mode only because `code` is the interactive agentic-coding surface
581
- * where a TTY can answer the approval prompt; the absent-config default never implies yolo.
11
+ * This module is the **public barrel** for the configuration system. The implementation
12
+ * is split into focused modules under `config/`:
13
+ * - `config/types.ts` the configuration type surface.
14
+ * - `config/shell-policy.ts` {@link GthDevToolsConfig} + the shell/dev-tools resolvers.
15
+ * - `config/defaults.ts` {@link DEFAULT_CONFIG}.
16
+ * - `config/loader.ts` discovery + the layered load/merge pipeline.
17
+ * - `config/schema.ts` the Zod schema (single source of truth) + JSON-Schema generator.
582
18
  *
583
- * @param command The active command, so the absent-config default can be scoped to `code`.
584
- * Omit (or pass a non-`code` command) to keep the historical OFF-by-default behaviour.
585
- */
586
- export declare function isShellToolEnabled(devTools: GthDevToolsConfig | undefined, command?: GthCommand | undefined): boolean;
587
- /**
588
- * Resolve the per-command shell timeout (ms) from config, falling back to
589
- * {@link SHELL_DEFAULT_TIMEOUT_MS}. Only the object form can override it; a bare
590
- * `shell: true` uses the default. Non-positive / non-finite values are ignored.
591
- */
592
- export declare function getShellTimeoutMs(devTools: GthDevToolsConfig | undefined): number;
593
- /**
594
- * Resolve the captured-output byte budget from config, falling back to
595
- * {@link SHELL_DEFAULT_MAX_OUTPUT_BYTES}. Only the object form can override it.
596
- * Non-positive / non-finite values are ignored.
597
- */
598
- export declare function getShellMaxOutputBytes(devTools: GthDevToolsConfig | undefined): number;
599
- /**
600
- * Whether the EXT-9 Tier-2 scoped allow-list is active. Default `true`; only the object
601
- * form's `allowlist: false` disables it (a bare `shell: true` keeps it on). When off, the
602
- * runner prompts for every `run_shell_command` regardless of prior approvals.
603
- */
604
- export declare function isShellAllowlistEnabled(devTools: GthDevToolsConfig | undefined): boolean;
605
- /**
606
- * Whether `always`-scoped approvals are persisted to the project allow-list file. Default
607
- * `true`; only the object form's `persistAllowlist: false` disables persistence (an
608
- * `always` decision then behaves as `session`).
609
- */
610
- export declare function isShellAllowlistPersisted(devTools: GthDevToolsConfig | undefined): boolean;
611
- /**
612
- * Resolved settings for the EXT-10 LLM-as-judge safety gate.
613
- */
614
- export interface ShellJudgeSettings {
615
- /** Whether the judge gate runs at all. */
616
- enabled: boolean;
617
- /** Auto-approve `low`-risk, statically-resolvable commands (the fatigue reducer). */
618
- autoApproveLow: boolean;
619
- /** Reject clearly-catastrophic (`high` + destructive) verdicts without prompting. */
620
- blockHigh: boolean;
621
- /** Optional separate judge model config; when absent the runner uses `config.llm`. */
622
- model?: LLMConfig;
623
- }
624
- /**
625
- * Whether the EXT-10 LLM-as-judge safety gate is enabled for the given dev-tools config.
626
- * Default OFF (only the object form's `judge` truthy enables it), mirroring
627
- * {@link isShellToolEnabled}. A bare `shell: true` keeps the judge OFF — it costs an LLM call
628
- * per command and must be opted into explicitly.
629
- */
630
- export declare function isShellJudgeEnabled(devTools: GthDevToolsConfig | undefined): boolean;
631
- /**
632
- * Resolve the EXT-10 judge gate settings from a dev-tools config, applying safe defaults
633
- * (auto-approve low, do NOT block high). `enabled` reflects {@link isShellJudgeEnabled}.
634
- */
635
- export declare function getShellJudgeSettings(devTools: GthDevToolsConfig | undefined): ShellJudgeSettings;
636
- /**
637
- * Resolve the {@link GthDevToolsConfig} that applies to the active command, mirroring the
638
- * per-command selection in `builtInToolsConfig.getDefaultTools` (which is what actually emits
639
- * the dev tools) and `GthDeepAgent.getEffectiveDevToolsConfig`: `exec` → `commands.exec`,
640
- * `ask --write` → `commands.ask`, `code` → `commands.code`; `undefined` elsewhere (the
641
- * toolkit is inert there). Shared in core so the runner's allow-list gate stays in lockstep
642
- * with where the shell tool is actually emitted.
643
- */
644
- export declare function getEffectiveDevToolsConfig(config: Pick<GthConfig, 'commands' | 'askWriteMode'> | undefined, command: GthCommand | undefined): GthDevToolsConfig | undefined;
645
- export interface LLMConfig extends Record<string, unknown> {
646
- type: string;
647
- model: string;
648
- configuration: Record<string, unknown>;
649
- apiKeyEnvironmentVariable?: string;
650
- }
651
- export declare const availableDefaultConfigs: readonly ["vertexai", "anthropic", "groq", "deepseek", "openai", "google-genai", "xai", "openrouter", "ollama"];
652
- export type ConfigType = (typeof availableDefaultConfigs)[number];
653
- export interface CommandLineConfigOverrides {
654
- /**
655
- * Custom config path
656
- */
657
- customConfigPath?: string;
658
- /**
659
- * Set LangChain/LangGraph to verbose mode,
660
- * causing LangChain/LangGraph to log many details to the console.
661
- * debugLog from config.ts may be a less intrusive option.
662
- */
663
- verbose?: boolean;
664
- /**
665
- * Should the output be written to md file.
666
- * (e.g. gth_2025-07-26_22-59-06_REVIEW.md).
667
- * Can be set to false with `-wn` or `-w0`
668
- * Can be set to a specific filename or path by passing a string:
669
- * - Bare filenames (e.g. `"review.md"`) are placed in `.gsloth/` when it exists, otherwise project root
670
- * - Paths with separators (e.g. `"./review.md"` or `"reviews/last.md"`) are always relative to project root
671
- * Please note the string does not accept absolute path, but allows to exit project with `..` if necessary.
672
- */
673
- writeOutputToFile?: boolean | string;
674
- /**
675
- * Separate identity profile.
676
- * May include separate identity, guidelines and command protocol,
677
- * making gsloth behave as an agent different from default profile behaviour.
678
- * for example, `devops` profile to detect changes such as properties and environment variables.
679
- * Custom config can still win over this one.
680
- * This setting requires .gsloth/.gsloth-settings directory to exist.
681
- * Important to note that the profile directory substitutes the entire config directory,
682
- * in the case if some prompt files are missing - a file from the installation directory will be used.
683
- */
684
- identityProfile?: string;
685
- /**
686
- * Interactive TUI activation override for chat/code sessions.
687
- * - `true` (`--tui`): force the Ink TUI on where the terminal supports it (also overrides
688
- * the CI auto-off heuristic).
689
- * - `false` (`--no-tui`): force the plain readline session.
690
- * - `undefined` (default): auto-detect from the terminal.
691
- * The decision itself lives in `gaunt-sloth`'s `shouldUseTui`; this only carries the flag.
692
- */
693
- tui?: boolean;
694
- }
695
- /**
696
- * Default config
697
- */
698
- export declare const DEFAULT_CONFIG: {
699
- readonly contentSource: "file";
700
- readonly requirementSource: "file";
701
- readonly contentProvider: "file";
702
- readonly requirementsProvider: "file";
703
- /**
704
- * Path to project-specific guidelines.
705
- * The default is `.gsloth.guidelines.md`; this config may be used to point Gaunt Sloth to a different file,
706
- * for example, to AGENTS.md
707
- */
708
- readonly projectGuidelines: ".gsloth.guidelines.md";
709
- /**
710
- * Whether to include the current date in the project review instructions or not.
711
- */
712
- readonly includeCurrentDateAfterGuidelines: false;
713
- readonly projectReviewInstructions: ".gsloth.review.md";
714
- readonly filesystem: "none";
715
- readonly debugLog: false;
716
- readonly consoleLevel: StatusLevel.INFO;
717
- /**
718
- * Default provider for both requirements and content is GitHub.
719
- * It needs GitHub CLI (gh).
720
- *
721
- * `github` content provider uses `gh pr diff NN` internally. {@link src/providers/ghPrDiffProvider.ts!}
722
- *
723
- *
724
- * `github` requirements provider `gh issue view NN` internally
725
- */
726
- readonly commands: {
727
- readonly pr: {
728
- readonly contentSource: "github";
729
- readonly requirementSource: "github";
730
- readonly contentProvider: "github";
731
- readonly requirementsProvider: "github";
732
- readonly rating: {
733
- readonly enabled: true;
734
- readonly passThreshold: 6;
735
- readonly minRating: 0;
736
- readonly maxRating: 10;
737
- readonly errorOnReviewFail: true;
738
- };
739
- };
740
- readonly review: {
741
- readonly rating: {
742
- readonly enabled: true;
743
- readonly passThreshold: 6;
744
- readonly minRating: 0;
745
- readonly maxRating: 10;
746
- readonly errorOnReviewFail: true;
747
- };
748
- };
749
- readonly ask: {
750
- readonly filesystem: "read";
751
- };
752
- readonly chat: {
753
- readonly filesystem: "read";
754
- };
755
- readonly code: {
756
- readonly filesystem: "all";
757
- };
758
- readonly exec: {
759
- readonly filesystem: "all";
760
- };
761
- readonly api: {
762
- readonly filesystem: "read";
763
- readonly port: 3000;
764
- readonly cors: {
765
- readonly allowOrigin: "http://localhost:3000";
766
- readonly allowMethods: "POST, GET, OPTIONS";
767
- readonly allowHeaders: "Content-Type, Accept";
768
- };
769
- };
770
- };
771
- readonly streamOutput: true;
772
- readonly writeOutputToFile: true;
773
- readonly writeBinaryOutputsToFile: true;
774
- readonly useColour: true;
775
- readonly streamSessionInferenceLog: true;
776
- readonly canInterruptInferenceWithEsc: true;
777
- readonly aiignore: {
778
- readonly enabled: true;
779
- readonly patterns: undefined;
780
- };
781
- };
782
- /**
783
- * Loads the global gsloth config (if present) from the global `~/.gsloth` folder.
784
- *
785
- * Precedence support: the returned raw config is intended to act as the BASE that the
786
- * project config (and CLI overrides) merge on top of, so any value here is the lowest
787
- * user-controlled layer (still above {@link DEFAULT_CONFIG}).
788
- *
789
- * Lookup order within the global folder, first match wins:
790
- * `.gsloth.config.json` -> `.gsloth.config.js` -> `.gsloth.config.mjs`
791
- *
792
- * Absence of every variant is a no-op: returns `undefined` so behaviour is unchanged.
793
- *
794
- * NOTE: secrets (API keys) may live in this file; this function must never log its
795
- * contents. Only non-sensitive diagnostics (the resolved path / parse failure) are emitted.
796
- *
797
- * @returns The raw global config object, or `undefined` when no global config exists.
798
- */
799
- export declare function loadGlobalRawConfig(): Promise<Partial<RawGthConfig> | undefined>;
800
- /**
801
- * Returns true when a project-level config file (json/js/mjs) exists for the given
802
- * overrides. Honours `customConfigPath` and the active identity profile so the check
803
- * matches exactly what {@link initConfig} would attempt to load.
804
- *
805
- * This is the project half of CFG-10's "is any config present?" detection; the global
806
- * half is {@link loadGlobalRawConfig} (used by {@link hasAnyConfig}).
807
- */
808
- export declare function hasProjectConfig(commandLineConfigOverrides: CommandLineConfigOverrides): boolean;
809
- /**
810
- * CFG-10 — true when ANY usable configuration is present, either a project config file
811
- * (json/js/mjs) or a standalone global config (`~/.gsloth/.gsloth.config.*`). When this
812
- * returns false the caller should run the first-run dialog instead of erroring.
813
- *
814
- * Reuses CFG-8's project + global detection so the two paths can never disagree.
815
- */
816
- export declare function hasAnyConfig(commandLineConfigOverrides: CommandLineConfigOverrides): Promise<boolean>;
817
- /**
818
- * Initialize configuration by loading from available config files
819
- * @returns The loaded GthConfig
820
- */
821
- export declare function initConfig(commandLineConfigOverrides: CommandLineConfigOverrides): Promise<GthConfig>;
822
- /**
823
- * Process JSON LLM config by creating the appropriate LLM instance
824
- * @param jsonConfig - The parsed JSON config
825
- * @param commandLineConfigOverrides - command line config overrides
826
- * @returns Promise<GthConfig>
19
+ * Every name that was previously exported from `config.ts` is re-exported here, so the
20
+ * public import path `@gaunt-sloth/core/config.js` (and `#src/config.js`) is unchanged.
827
21
  */
828
- export declare function tryJsonConfig(jsonConfig: RawGthConfig, commandLineConfigOverrides: CommandLineConfigOverrides): Promise<GthConfig>;
22
+ export * from '#src/config/types.js';
23
+ export * from '#src/config/shell-policy.js';
24
+ export * from '#src/config/defaults.js';
25
+ export * from '#src/config/loader.js';