@gaunt-sloth/core 2.0.0-alpha.9 → 2.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. package/.gsloth.review.md +2 -0
  2. package/README.md +71 -20
  3. package/dist/config/colour.d.ts +38 -0
  4. package/dist/config/colour.js +36 -0
  5. package/dist/config/colour.js.map +1 -0
  6. package/dist/config/configDiscovery.d.ts +79 -0
  7. package/dist/config/configDiscovery.js +80 -0
  8. package/dist/config/configDiscovery.js.map +1 -0
  9. package/dist/config/defaults.d.ts +20 -20
  10. package/dist/config/defaults.js +10 -8
  11. package/dist/config/defaults.js.map +1 -1
  12. package/dist/config/filesystem-tools.d.ts +41 -0
  13. package/dist/config/filesystem-tools.js +56 -0
  14. package/dist/config/filesystem-tools.js.map +1 -0
  15. package/dist/config/loader.d.ts +171 -19
  16. package/dist/config/loader.js +1054 -144
  17. package/dist/config/loader.js.map +1 -1
  18. package/dist/config/mouse.d.ts +50 -0
  19. package/dist/config/mouse.js +44 -0
  20. package/dist/config/mouse.js.map +1 -0
  21. package/dist/config/profiles.d.ts +68 -0
  22. package/dist/config/profiles.js +93 -0
  23. package/dist/config/profiles.js.map +1 -0
  24. package/dist/config/providerKeys.d.ts +69 -0
  25. package/dist/config/providerKeys.js +69 -0
  26. package/dist/config/providerKeys.js.map +1 -0
  27. package/dist/config/schema.d.ts +2671 -138
  28. package/dist/config/schema.js +1361 -85
  29. package/dist/config/schema.js.map +1 -1
  30. package/dist/config/shell-policy.d.ts +899 -111
  31. package/dist/config/shell-policy.js +800 -70
  32. package/dist/config/shell-policy.js.map +1 -1
  33. package/dist/config/tool-descriptions.d.ts +211 -0
  34. package/dist/config/tool-descriptions.js +272 -0
  35. package/dist/config/tool-descriptions.js.map +1 -0
  36. package/dist/config/types.d.ts +352 -41
  37. package/dist/config/types.js +1 -0
  38. package/dist/config/types.js.map +1 -1
  39. package/dist/config.d.ts +35 -1
  40. package/dist/config.js +16 -1
  41. package/dist/config.js.map +1 -1
  42. package/dist/constants.d.ts +28 -1
  43. package/dist/constants.js +28 -1
  44. package/dist/constants.js.map +1 -1
  45. package/dist/core/GthAbstractAgent.d.ts +166 -11
  46. package/dist/core/GthAbstractAgent.js +484 -45
  47. package/dist/core/GthAbstractAgent.js.map +1 -1
  48. package/dist/core/GthAgentRunner.d.ts +543 -57
  49. package/dist/core/GthAgentRunner.js +1494 -140
  50. package/dist/core/GthAgentRunner.js.map +1 -1
  51. package/dist/core/GthLangChainAgent.d.ts +117 -2
  52. package/dist/core/GthLangChainAgent.js +602 -29
  53. package/dist/core/GthLangChainAgent.js.map +1 -1
  54. package/dist/core/approvals/annotations.d.ts +122 -0
  55. package/dist/core/approvals/annotations.js +137 -0
  56. package/dist/core/approvals/annotations.js.map +1 -0
  57. package/dist/core/approvals/grants.d.ts +216 -0
  58. package/dist/core/approvals/grants.js +469 -0
  59. package/dist/core/approvals/grants.js.map +1 -0
  60. package/dist/core/approvals/matcher.d.ts +202 -0
  61. package/dist/core/approvals/matcher.js +267 -0
  62. package/dist/core/approvals/matcher.js.map +1 -0
  63. package/dist/core/approvals/mcpSubjects.d.ts +40 -0
  64. package/dist/core/approvals/mcpSubjects.js +99 -0
  65. package/dist/core/approvals/mcpSubjects.js.map +1 -0
  66. package/dist/core/approvals/promptHeader.d.ts +28 -0
  67. package/dist/core/approvals/promptHeader.js +62 -0
  68. package/dist/core/approvals/promptHeader.js.map +1 -0
  69. package/dist/core/approvals/toolAnnotationSources.d.ts +105 -0
  70. package/dist/core/approvals/toolAnnotationSources.js +277 -0
  71. package/dist/core/approvals/toolAnnotationSources.js.map +1 -0
  72. package/dist/core/approvals/toolHost.d.ts +46 -0
  73. package/dist/core/approvals/toolHost.js +108 -0
  74. package/dist/core/approvals/toolHost.js.map +1 -0
  75. package/dist/core/debugCapture.d.ts +74 -0
  76. package/dist/core/debugCapture.js +100 -0
  77. package/dist/core/debugCapture.js.map +1 -0
  78. package/dist/core/gthLeanAgentFactory.d.ts +4 -4
  79. package/dist/core/gthLeanAgentFactory.js +4 -4
  80. package/dist/core/launchBanner.d.ts +127 -0
  81. package/dist/core/launchBanner.js +414 -0
  82. package/dist/core/launchBanner.js.map +1 -0
  83. package/dist/core/modelLabel.d.ts +19 -0
  84. package/dist/core/modelLabel.js +26 -0
  85. package/dist/core/modelLabel.js.map +1 -0
  86. package/dist/core/plainToolIndication.d.ts +15 -0
  87. package/dist/core/plainToolIndication.js +174 -0
  88. package/dist/core/plainToolIndication.js.map +1 -0
  89. package/dist/core/reasoningBlocks.d.ts +65 -0
  90. package/dist/core/reasoningBlocks.js +103 -0
  91. package/dist/core/reasoningBlocks.js.map +1 -0
  92. package/dist/core/refusal.d.ts +53 -0
  93. package/dist/core/refusal.js +133 -0
  94. package/dist/core/refusal.js.map +1 -0
  95. package/dist/core/runHeader.d.ts +38 -0
  96. package/dist/core/runHeader.js +42 -0
  97. package/dist/core/runHeader.js.map +1 -0
  98. package/dist/core/runStats.d.ts +14 -3
  99. package/dist/core/runStats.js +48 -3
  100. package/dist/core/runStats.js.map +1 -1
  101. package/dist/core/shell/ShellCommandFailedError.d.ts +3 -4
  102. package/dist/core/shell/ShellCommandFailedError.js +3 -4
  103. package/dist/core/shell/ShellCommandFailedError.js.map +1 -1
  104. package/dist/core/shell/abstention.d.ts +88 -0
  105. package/dist/core/shell/abstention.js +184 -0
  106. package/dist/core/shell/abstention.js.map +1 -0
  107. package/dist/core/shell/approvalCapture.d.ts +271 -0
  108. package/dist/core/shell/approvalCapture.js +108 -0
  109. package/dist/core/shell/approvalCapture.js.map +1 -0
  110. package/dist/core/shell/approvalStop.d.ts +123 -0
  111. package/dist/core/shell/approvalStop.js +269 -0
  112. package/dist/core/shell/approvalStop.js.map +1 -0
  113. package/dist/core/shell/arity.d.ts +6 -0
  114. package/dist/core/shell/arity.js +20 -6
  115. package/dist/core/shell/arity.js.map +1 -1
  116. package/dist/core/shell/denylist.d.ts +11 -0
  117. package/dist/core/shell/denylist.js +37 -0
  118. package/dist/core/shell/denylist.js.map +1 -0
  119. package/dist/core/shell/escalationSeverity.d.ts +141 -0
  120. package/dist/core/shell/escalationSeverity.js +89 -0
  121. package/dist/core/shell/escalationSeverity.js.map +1 -0
  122. package/dist/core/shell/framing.d.ts +190 -0
  123. package/dist/core/shell/framing.js +633 -0
  124. package/dist/core/shell/framing.js.map +1 -0
  125. package/dist/core/shell/hardline.d.ts +103 -0
  126. package/dist/core/shell/hardline.js +780 -0
  127. package/dist/core/shell/hardline.js.map +1 -0
  128. package/dist/core/shell/negotiation.d.ts +328 -0
  129. package/dist/core/shell/negotiation.js +488 -0
  130. package/dist/core/shell/negotiation.js.map +1 -0
  131. package/dist/core/shell/normalize.d.ts +44 -4
  132. package/dist/core/shell/normalize.js +61 -7
  133. package/dist/core/shell/normalize.js.map +1 -1
  134. package/dist/core/shell/openWorld.d.ts +263 -0
  135. package/dist/core/shell/openWorld.js +1188 -0
  136. package/dist/core/shell/openWorld.js.map +1 -0
  137. package/dist/core/shell/rater.d.ts +873 -0
  138. package/dist/core/shell/rater.js +1454 -0
  139. package/dist/core/shell/rater.js.map +1 -0
  140. package/dist/core/shell/raterModel.d.ts +41 -0
  141. package/dist/core/shell/raterModel.js +51 -0
  142. package/dist/core/shell/raterModel.js.map +1 -0
  143. package/dist/core/shell/raterVocabulary.d.ts +121 -0
  144. package/dist/core/shell/raterVocabulary.js +116 -0
  145. package/dist/core/shell/raterVocabulary.js.map +1 -0
  146. package/dist/core/shell/rejection.d.ts +69 -0
  147. package/dist/core/shell/rejection.js +38 -0
  148. package/dist/core/shell/rejection.js.map +1 -0
  149. package/dist/core/toolCallRepair/grammar.d.ts +41 -0
  150. package/dist/core/toolCallRepair/grammar.js +116 -0
  151. package/dist/core/toolCallRepair/grammar.js.map +1 -0
  152. package/dist/core/toolCallRepair/index.d.ts +2 -0
  153. package/dist/core/toolCallRepair/index.js +7 -0
  154. package/dist/core/toolCallRepair/index.js.map +1 -0
  155. package/dist/core/toolCallRepair/payload.d.ts +36 -0
  156. package/dist/core/toolCallRepair/payload.js +341 -0
  157. package/dist/core/toolCallRepair/payload.js.map +1 -0
  158. package/dist/core/toolCallRepair/promote.d.ts +45 -0
  159. package/dist/core/toolCallRepair/promote.js +90 -0
  160. package/dist/core/toolCallRepair/promote.js.map +1 -0
  161. package/dist/core/toolDisplay.d.ts +123 -0
  162. package/dist/core/toolDisplay.js +451 -0
  163. package/dist/core/toolDisplay.js.map +1 -0
  164. package/dist/core/toolOutputChannel.d.ts +95 -0
  165. package/dist/core/toolOutputChannel.js +165 -0
  166. package/dist/core/toolOutputChannel.js.map +1 -0
  167. package/dist/core/types.d.ts +349 -16
  168. package/dist/core/types.js.map +1 -1
  169. package/dist/history/historyFormat.d.ts +12 -3
  170. package/dist/history/historyFormat.js +50 -8
  171. package/dist/history/historyFormat.js.map +1 -1
  172. package/dist/history/historyStore.d.ts +77 -0
  173. package/dist/history/historyStore.js +173 -6
  174. package/dist/history/historyStore.js.map +1 -1
  175. package/dist/history/recordSession.d.ts +10 -1
  176. package/dist/history/recordSession.js +27 -0
  177. package/dist/history/recordSession.js.map +1 -1
  178. package/dist/providers/anthropic.js +12 -0
  179. package/dist/providers/anthropic.js.map +1 -1
  180. package/dist/providers/configurationPassthrough.d.ts +107 -0
  181. package/dist/providers/configurationPassthrough.js +148 -0
  182. package/dist/providers/configurationPassthrough.js.map +1 -0
  183. package/dist/providers/geminiSchemaSanitizer.d.ts +55 -0
  184. package/dist/providers/geminiSchemaSanitizer.js +347 -0
  185. package/dist/providers/geminiSchemaSanitizer.js.map +1 -0
  186. package/dist/providers/geminiThinking.d.ts +60 -0
  187. package/dist/providers/geminiThinking.js +92 -0
  188. package/dist/providers/geminiThinking.js.map +1 -0
  189. package/dist/providers/google-genai.js +18 -1
  190. package/dist/providers/google-genai.js.map +1 -1
  191. package/dist/providers/groq.js +12 -0
  192. package/dist/providers/groq.js.map +1 -1
  193. package/dist/providers/huggingface.d.ts +25 -0
  194. package/dist/providers/huggingface.js +69 -0
  195. package/dist/providers/huggingface.js.map +1 -0
  196. package/dist/providers/modelCatalog.d.ts +109 -0
  197. package/dist/providers/modelCatalog.js +245 -0
  198. package/dist/providers/modelCatalog.js.map +1 -0
  199. package/dist/providers/modelDiscovery.d.ts +99 -5
  200. package/dist/providers/modelDiscovery.js +191 -35
  201. package/dist/providers/modelDiscovery.js.map +1 -1
  202. package/dist/providers/ollama.d.ts +18 -4
  203. package/dist/providers/ollama.js +67 -37
  204. package/dist/providers/ollama.js.map +1 -1
  205. package/dist/providers/openai.js +34 -0
  206. package/dist/providers/openai.js.map +1 -1
  207. package/dist/providers/openrouter.d.ts +26 -4
  208. package/dist/providers/openrouter.js +83 -26
  209. package/dist/providers/openrouter.js.map +1 -1
  210. package/dist/providers/vertexai.js +19 -1
  211. package/dist/providers/vertexai.js.map +1 -1
  212. package/dist/providers/xai.js +20 -0
  213. package/dist/providers/xai.js.map +1 -1
  214. package/dist/runtime/askStructured.d.ts +105 -0
  215. package/dist/runtime/askStructured.js +120 -0
  216. package/dist/runtime/askStructured.js.map +1 -0
  217. package/dist/runtime/conversation.d.ts +64 -0
  218. package/dist/runtime/conversation.js +171 -0
  219. package/dist/runtime/conversation.js.map +1 -0
  220. package/dist/runtime/singleShot.d.ts +37 -6
  221. package/dist/runtime/singleShot.js +113 -67
  222. package/dist/runtime/singleShot.js.map +1 -1
  223. package/dist/runtime/structuredOutput.d.ts +104 -0
  224. package/dist/runtime/structuredOutput.js +393 -0
  225. package/dist/runtime/structuredOutput.js.map +1 -0
  226. package/dist/utils/ProgressIndicator.d.ts +21 -0
  227. package/dist/utils/ProgressIndicator.js +30 -3
  228. package/dist/utils/ProgressIndicator.js.map +1 -1
  229. package/dist/utils/aiignoreUtils.js.map +1 -1
  230. package/dist/utils/binaryOutputUtils.js.map +1 -1
  231. package/dist/utils/consoleUtils.d.ts +95 -0
  232. package/dist/utils/consoleUtils.js +112 -2
  233. package/dist/utils/consoleUtils.js.map +1 -1
  234. package/dist/utils/crashHandler.d.ts +87 -0
  235. package/dist/utils/crashHandler.js +128 -0
  236. package/dist/utils/crashHandler.js.map +1 -0
  237. package/dist/utils/debugDump.d.ts +134 -0
  238. package/dist/utils/debugDump.js +381 -0
  239. package/dist/utils/debugDump.js.map +1 -0
  240. package/dist/utils/debugUtils.d.ts +13 -4
  241. package/dist/utils/debugUtils.js +36 -13
  242. package/dist/utils/debugUtils.js.map +1 -1
  243. package/dist/utils/displayWidth.d.ts +53 -0
  244. package/dist/utils/displayWidth.js +195 -0
  245. package/dist/utils/displayWidth.js.map +1 -0
  246. package/dist/utils/fileUtils.js.map +1 -1
  247. package/dist/utils/globalConfigUtils.d.ts +14 -2
  248. package/dist/utils/globalConfigUtils.js +22 -4
  249. package/dist/utils/globalConfigUtils.js.map +1 -1
  250. package/dist/utils/llmUtils.d.ts +39 -8
  251. package/dist/utils/llmUtils.js +76 -8
  252. package/dist/utils/llmUtils.js.map +1 -1
  253. package/dist/utils/redactSecrets.d.ts +63 -0
  254. package/dist/utils/redactSecrets.js +286 -0
  255. package/dist/utils/redactSecrets.js.map +1 -0
  256. package/dist/utils/systemPromptNotes.d.ts +222 -0
  257. package/dist/utils/systemPromptNotes.js +338 -0
  258. package/dist/utils/systemPromptNotes.js.map +1 -0
  259. package/dist/utils/systemUtils.d.ts +18 -1
  260. package/dist/utils/systemUtils.js +38 -3
  261. package/dist/utils/systemUtils.js.map +1 -1
  262. package/dist/utils/toolMatching.d.ts +30 -0
  263. package/dist/utils/toolMatching.js +44 -0
  264. package/dist/utils/toolMatching.js.map +1 -0
  265. package/dist/utils/untrustedText.d.ts +86 -0
  266. package/dist/utils/untrustedText.js +101 -0
  267. package/dist/utils/untrustedText.js.map +1 -0
  268. package/package.json +21 -7
  269. package/schema/gsloth-config.schema.json +1921 -326
  270. package/dist/core/shell/allowlist.d.ts +0 -75
  271. package/dist/core/shell/allowlist.js +0 -187
  272. package/dist/core/shell/allowlist.js.map +0 -1
  273. package/dist/core/shell/judge.d.ts +0 -161
  274. package/dist/core/shell/judge.js +0 -261
  275. package/dist/core/shell/judge.js.map +0 -1
package/.gsloth.review.md CHANGED
@@ -8,6 +8,8 @@ Please categorize your feedback (e.g., "Bug," "Suggestion," "Nitpick").
8
8
  Important! In the end, conclude if you would recommend approving this PR or not.
9
9
  Use ✅⚠️❌ symbols to highlight your feedback appropriately.
10
10
 
11
+ Important! Do not speculate about version numbers of dependencies and workflows, specifically about versions which you think do not exist yet — you have knowledge cut-off, and you can't know which versions were released since then.
12
+
11
13
  Finish with a short 1-2 sentence summary that captures the overall state of the review.
12
14
 
13
15
  Thank you for your thorough review!
package/README.md CHANGED
@@ -1,34 +1,85 @@
1
1
  # @gaunt-sloth/core
2
2
 
3
- Core utilities and types for Gaunt Sloth.
3
+ The foundation layer of Gaunt Sloth: the configuration system (`GthConfig`, config discovery and
4
+ loading, the JSON schema), the LLM provider factory (anthropic, deepseek, google-genai, groq,
5
+ huggingface, ollama, openai, openrouter, vertexai, xai, fake), the lean LangChain agent runtime
6
+ (`GthAgentRunner`), session history, and the shared utility modules (`consoleUtils`,
7
+ `systemUtils`, `fileUtils`, `llmUtils`, …).
4
8
 
5
- ## Contents
9
+ **When to depend on this package** — you are embedding a piece of Gaunt Sloth (or building your
10
+ own front-end on its infrastructure) and need its config resolution and provider wiring without
11
+ the CLI. Every other `@gaunt-sloth/*` package builds on it. If you just want to use Gaunt Sloth
12
+ from the terminal, install the [`gaunt-sloth`](https://www.npmjs.com/package/gaunt-sloth) app
13
+ instead.
6
14
 
7
- - Configuration system (`GthConfig`, `RawGthConfig`, config loading and post-processing)
8
- - Agent infrastructure: `GthLangChainAgent`, `GthAgentRunner`
9
- - LLM provider wrappers: anthropic, deepseek, google-genai, groq, openai, openrouter, vertexai, xai, fake
10
- - Utility modules: `consoleUtils`, `debugUtils`, `fileUtils`, `llmUtils`, `systemUtils`, `stringUtils`, `aiignoreUtils`, `binaryOutputUtils`, `vertexaiUtils`, `globalConfigUtils`, `ProgressIndicator`
11
- - State and artifact storage: `artifactStore`
12
- - Shared constants and types
15
+ ## Installation
13
16
 
14
- AI vendor packages are not direct dependencies. Each vendor package is an optional peer dependency, resolved at runtime by whichever consumer (e.g. `gaunt-sloth`) pulls them in.
17
+ AI vendor packages are optional peer dependencies install the provider(s) your configuration
18
+ uses alongside core:
15
19
 
16
- ## Dependencies
17
-
18
- No other `@gaunt-sloth/*` packages.
20
+ ```bash
21
+ npm install @gaunt-sloth/core @langchain/anthropic
22
+ ```
19
23
 
20
- ## Exports
24
+ ## Embedding: resolve config into a live model
21
25
 
22
- All modules are exported via the `./` export map pattern (`./*.js`), e.g.:
26
+ I want my script to honour the user's `.gsloth.config.*` (provider, model, API keys) instead of
27
+ hard-coding a vendor SDK. With a `.gsloth.config.json` such as
28
+ `{ "llm": { "type": "anthropic", "model": "claude-sonnet-4-5" } }` in the working directory:
23
29
 
24
30
  ```js
25
- import { GthAgentRunner } from '@gaunt-sloth/core/agentRunner.js';
26
- import { display } from '@gaunt-sloth/core/utils/consoleUtils.js';
31
+ import { initConfig } from '@gaunt-sloth/core';
32
+
33
+ const config = await initConfig({}); // discovers .gsloth.config.* up-tree from cwd
34
+ // config.llm is a live LangChain chat model built from that config
35
+ const response = await config.llm.invoke('Say hello');
36
+ console.log(response.text);
27
37
  ```
28
38
 
39
+ When the configured provider has no API key anywhere — not in `llm.apiKey`, not in
40
+ `llm.apiKeyEnvironmentVariable`, not in any variable that provider accepts — `initConfig` rejects
41
+ with a `MissingProviderKeyError` carrying `provider` and `envVars`, so a caller running several
42
+ configs can report which one lacked a secret and carry on with the rest. Use
43
+ `isMissingProviderKeyError(error)` to recognise it.
44
+
45
+ All config keys (providers, prompts, tools, per-command settings) are documented in
46
+ [the configuration guide](https://github.com/pukeko-robotics/gaunt-sloth/blob/main/docs/configuration/index.md).
47
+
48
+ ## Exports
49
+
50
+ - `@gaunt-sloth/core` (the root export) is the public API: config
51
+ (`initConfig`, `GthConfig`, defaults), constants, core types, the lean agent factory, model
52
+ discovery, and session history.
53
+ - **A type the Zod schema declares is re-exported, so a value you can set is a value you can name.**
54
+ Some types in this package's public surface are declared by the schema rather than beside the
55
+ interface that uses them; those are re-exported from the root and from
56
+ `@gaunt-sloth/core/config.js` — `GthOutputHeaderRung`, the type of `GthConfig`'s `output.header`,
57
+ and `RawConfigValidationResult`, the interface `ConfigLayerValidationReport` extends. The schema's
58
+ runtime surface (`rawGthConfigSchema`, `generateConfigJsonSchema`, `validateRawGthConfig`,
59
+ `KNOWN_TOP_LEVEL_KEYS`, the deprecation scanners) is validator internals and is not part of the
60
+ root export; reach it through the deep path below if you need it.
61
+ - **The approval and shell types are covered by the same rule, so a typed `ToolApprovalCallback`
62
+ needs no deep path.** Everything a `PendingToolInterrupt` hands that callback, and the tool
63
+ annotations `GthAgentInterface` reports, can be named from the root and from
64
+ `@gaunt-sloth/core/core/types.js`: `ApprovalSubject` with its `ShellApprovalSubject`,
65
+ `ToolApprovalSubject` and `McpToolApprovalSubject` variants, the rater's `ShellSafetyVerdict`,
66
+ `RaterOutcome` and `RaterNegotiationRound`, and `DeclaredToolAnnotations`. What
67
+ `GthAgentInterface` takes beyond those is config and follows the bullet above — `GthConfig` is
68
+ named from the root, not from that deep path.
69
+ These stay declared under `core/approvals/` and `core/shell/`, beside the code that decides them,
70
+ and the runtime surface there — the matcher and rater functions, and the closed vocabularies those
71
+ types are derived from — is not part of the root export.
72
+ - `@gaunt-sloth/core/<path>.js` deep paths (e.g. `@gaunt-sloth/core/config.js`,
73
+ `@gaunt-sloth/core/utils/consoleUtils.js`) mirror the internal `dist/` layout 1:1 and are a
74
+ deliberate part of the contract — the other `@gaunt-sloth/*` packages and downstream consumers
75
+ import them directly. They are supported at your own risk: internal files can move between
76
+ alpha/minor versions without a deprecation cycle. Prefer the root export where it suffices.
77
+
78
+ This package ships no binaries.
79
+
29
80
  ## Related packages
30
81
 
31
- - [`@gaunt-sloth/core`](../core) — Core utilities, config, and agent infrastructure (this package)
32
- - [`@gaunt-sloth/agent`](../agent) — Agent runtime: built-in tools, filesystem toolkit, middleware registry, API server, AG-UI, MCP, and A2A integration
33
- - [`@gaunt-sloth/review`](../review) — Review and Q&A modules with standalone CLI
34
- - [`gaunt-sloth`](../app) — Main CLI application
82
+ - [`@gaunt-sloth/agent`](https://www.npmjs.com/package/@gaunt-sloth/agent) — Agent runtime: built-in tools, filesystem toolkit, middleware registry, API server, AG-UI, MCP, and A2A integration ([source](https://github.com/pukeko-robotics/gaunt-sloth/tree/main/packages/agent))
83
+ - [`@gaunt-sloth/review`](https://www.npmjs.com/package/@gaunt-sloth/review) — Review engine with content/requirement sources (GitHub, Jira, file, text) and standalone CLI ([source](https://github.com/pukeko-robotics/gaunt-sloth/tree/main/packages/review))
84
+ - [`@gaunt-sloth/batch`](https://www.npmjs.com/package/@gaunt-sloth/batch) — Batch / eval / workflow runtime ([source](https://github.com/pukeko-robotics/gaunt-sloth/tree/main/packages/batch))
85
+ - [`gaunt-sloth`](https://www.npmjs.com/package/gaunt-sloth) — Main CLI application ([source](https://github.com/pukeko-robotics/gaunt-sloth/tree/main/packages/app))
@@ -0,0 +1,38 @@
1
+ /**
2
+ * CFG-30 — the single place that decides whether Gaunt Sloth emits ANSI colour.
3
+ *
4
+ * Everything this decision depends on arrives as an argument: no `process.env`, no `stdout`, no
5
+ * config merge. That keeps the ladder unit-testable rung by rung without touching process globals,
6
+ * and keeps the one mutation site ({@link setUseColour}, called from `mergeConfig`) unchanged.
7
+ */
8
+ /** Everything the colour decision depends on. See {@link resolveUseColour}. */
9
+ export interface UseColourInput {
10
+ /**
11
+ * Raw `FORCE_COLOR` environment value; `undefined` when the variable is not set at all.
12
+ * The empty string is a SET value (`FORCE_COLOR=` on the command line) and means colour on.
13
+ */
14
+ forceColor?: string;
15
+ /** Raw `NO_COLOR` environment value; `undefined` when the variable is not set at all. */
16
+ noColor?: string;
17
+ /**
18
+ * `useColour` as the user actually wrote it — read from the RAW config, BEFORE `DEFAULT_CONFIG`
19
+ * is merged in. `undefined` means the user set nothing, which is what rung 3 tests for; after the
20
+ * default merge an explicit `true` is indistinguishable from the default `true`, so this value
21
+ * must be captured pre-merge or the rung collapses.
22
+ */
23
+ explicitUseColour?: boolean;
24
+ /** Whether stdout is a terminal. Rung 4's auto-detection; stdout, not stdin. */
25
+ stdoutIsTTY: boolean;
26
+ }
27
+ /**
28
+ * Resolve the effective colour setting from the four-rung precedence ladder, highest wins:
29
+ *
30
+ * 1. `FORCE_COLOR` is set — `"0"` or `"false"` turn colour OFF, ANY other value (including the
31
+ * empty string) turns it ON. This rung outranks everything below it, `NO_COLOR` included.
32
+ * 2. `NO_COLOR` is set and non-empty — colour OFF (the no-color.org convention: the variable's
33
+ * presence is the signal, its value is not, but an empty value does not count as set).
34
+ * 3. `useColour` was set explicitly in config — use it verbatim.
35
+ * 4. Otherwise auto-detect — colour ON when stdout is a terminal, OFF when it is piped or
36
+ * redirected, so captured output stays clean without any configuration.
37
+ */
38
+ export declare function resolveUseColour(input: UseColourInput): boolean;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * CFG-30 — the single place that decides whether Gaunt Sloth emits ANSI colour.
3
+ *
4
+ * Everything this decision depends on arrives as an argument: no `process.env`, no `stdout`, no
5
+ * config merge. That keeps the ladder unit-testable rung by rung without touching process globals,
6
+ * and keeps the one mutation site ({@link setUseColour}, called from `mergeConfig`) unchanged.
7
+ */
8
+ /**
9
+ * Resolve the effective colour setting from the four-rung precedence ladder, highest wins:
10
+ *
11
+ * 1. `FORCE_COLOR` is set — `"0"` or `"false"` turn colour OFF, ANY other value (including the
12
+ * empty string) turns it ON. This rung outranks everything below it, `NO_COLOR` included.
13
+ * 2. `NO_COLOR` is set and non-empty — colour OFF (the no-color.org convention: the variable's
14
+ * presence is the signal, its value is not, but an empty value does not count as set).
15
+ * 3. `useColour` was set explicitly in config — use it verbatim.
16
+ * 4. Otherwise auto-detect — colour ON when stdout is a terminal, OFF when it is piped or
17
+ * redirected, so captured output stays clean without any configuration.
18
+ */
19
+ export function resolveUseColour(input) {
20
+ // Rung 1 — FORCE_COLOR, the deliberate "I know what I am doing" override. Checked first so a
21
+ // user can force colour through a NO_COLOR inherited from their shell profile or a CI image.
22
+ if (input.forceColor !== undefined) {
23
+ return !(input.forceColor === '0' || input.forceColor === 'false');
24
+ }
25
+ // Rung 2 — NO_COLOR (no-color.org), honoured by chalk, ripgrep, fd and delta.
26
+ if (input.noColor !== undefined && input.noColor !== '') {
27
+ return false;
28
+ }
29
+ // Rung 3 — the user's own config. Only reachable with an explicit value, never the default.
30
+ if (input.explicitUseColour !== undefined) {
31
+ return input.explicitUseColour;
32
+ }
33
+ // Rung 4 — auto-detect.
34
+ return input.stdoutIsTTY;
35
+ }
36
+ //# sourceMappingURL=colour.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colour.js","sourceRoot":"","sources":["../../src/config/colour.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsBH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAqB;IACpD,6FAA6F;IAC7F,6FAA6F;IAC7F,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACnC,OAAO,CAAC,CAAC,KAAK,CAAC,UAAU,KAAK,GAAG,IAAI,KAAK,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC;IACrE,CAAC;IAED,8EAA8E;IAC9E,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,KAAK,EAAE,EAAE,CAAC;QACxD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,4FAA4F;IAC5F,IAAI,KAAK,CAAC,iBAAiB,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC,iBAAiB,CAAC;IACjC,CAAC;IAED,wBAAwB;IACxB,OAAO,KAAK,CAAC,WAAW,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * The catchable error a config **load** raises when the configuration itself cannot be used. The
4
+ * cases, all one class on purpose:
5
+ *
6
+ * - an explicitly-named identity profile (or an `extends` base) that resolves to no config;
7
+ * - a `--config` path that does not exist;
8
+ * - a config layer present but malformed — a removed pre-2.0 shape, a bad approvals rule grammar,
9
+ * a schema mismatch, an unresolvable `approvals.rater`;
10
+ * - a config that read fine but names no usable model — no `llm` block, no `llm.type`, an
11
+ * `llm.type` with no provider module, or a provider module that cannot build from a JSON spec;
12
+ * - a provider instance that could not be constructed for a reason other than a missing API key
13
+ * (that one is {@link MissingProviderKeyError}, which carries the key details);
14
+ * - no configuration file anywhere at all.
15
+ *
16
+ * Deliberately dependency-free (no imports beyond types) so the config barrel, the loader and
17
+ * downstream consumers can all reach it without an import cycle — the same shape
18
+ * `providerKeys.ts` uses for {@link MissingProviderKeyError}.
19
+ *
20
+ * **Why this is an error object and not a process exit.** Loading configuration is a *library*
21
+ * operation, and a library that terminates the process denies every caller the chance to classify
22
+ * the failure. `gth eval` in particular distinguishes a **harness** error (exit 2 — the suite could
23
+ * not be evaluated) from a **product** failure (exit 1 — the SUT ran and failed); a `process.exit(1)`
24
+ * inside config discovery collapses that contract, reporting a typo in `--judge` exactly as it
25
+ * reports a genuine regression. Callers that legitimately want to terminate — the CLI entry points —
26
+ * catch it at their top level, where the exit code is chosen deliberately.
27
+ *
28
+ * One class covers every case above on purpose: no caller needs to tell them apart (all of them mean
29
+ * "this configuration cannot be used"), and the fields carry whichever detail applies. Sub-classing
30
+ * per case would only push the callers back to the marker-list problem this class exists to end —
31
+ * a consumer that wants the underlying failure reads `cause`.
32
+ */
33
+ /** What a config load knows about the configuration it could not use. */
34
+ export interface ConfigDiscoveryDetails {
35
+ /**
36
+ * The explicitly-requested identity profile that did not resolve, when that is the failure.
37
+ * Undefined for a malformed-config failure, which is about a file rather than a profile name.
38
+ */
39
+ identityProfile?: string | undefined;
40
+ /**
41
+ * Human-readable source of the offending config layer (e.g. `.gsloth.config.json`,
42
+ * `.gsloth.config.json (global)`, `<name> (extends base)`), when a layer was read and rejected.
43
+ */
44
+ sourceLabel?: string | undefined;
45
+ }
46
+ /**
47
+ * A configuration could not be used: a named identity profile has no config, or a config layer is
48
+ * malformed.
49
+ *
50
+ * Thrown (never exited on) by the config loader, so `gth eval`, `gth batch`, the AG-UI/ACP servers
51
+ * and any embedding consumer can classify the failure and choose their own exit code.
52
+ */
53
+ export declare class ConfigDiscoveryError extends Error implements ConfigDiscoveryDetails {
54
+ /** Duck-typed marker so {@link isConfigDiscoveryError} works across duplicated module copies. */
55
+ readonly gthConfigDiscoveryError: true;
56
+ readonly identityProfile: string | undefined;
57
+ readonly sourceLabel: string | undefined;
58
+ constructor(message: string, details?: ConfigDiscoveryDetails, options?: {
59
+ cause?: unknown;
60
+ });
61
+ /**
62
+ * Serialize the machine-readable half. `JSON.stringify(error)` would otherwise drop `message`
63
+ * (an Error's `message` is a non-enumerable own property), which is exactly the field a report
64
+ * consumer shows a human next to the profile or the file that failed.
65
+ */
66
+ toJSON(): {
67
+ name: string;
68
+ message: string;
69
+ } & ConfigDiscoveryDetails;
70
+ }
71
+ /**
72
+ * True when `value` is a {@link ConfigDiscoveryError}.
73
+ *
74
+ * Duck-typed on the marker property rather than `instanceof` on purpose: a consumer that ends up
75
+ * with two copies of `@gaunt-sloth/core` on disk (a `file:` dep, a hoisting split) would fail an
76
+ * `instanceof` check against a genuinely-correct error and mis-handle a config failure as an
77
+ * unexpected crash — exactly the distinction this error exists to make.
78
+ */
79
+ export declare function isConfigDiscoveryError(value: unknown): value is ConfigDiscoveryError;
@@ -0,0 +1,80 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * The catchable error a config **load** raises when the configuration itself cannot be used. The
4
+ * cases, all one class on purpose:
5
+ *
6
+ * - an explicitly-named identity profile (or an `extends` base) that resolves to no config;
7
+ * - a `--config` path that does not exist;
8
+ * - a config layer present but malformed — a removed pre-2.0 shape, a bad approvals rule grammar,
9
+ * a schema mismatch, an unresolvable `approvals.rater`;
10
+ * - a config that read fine but names no usable model — no `llm` block, no `llm.type`, an
11
+ * `llm.type` with no provider module, or a provider module that cannot build from a JSON spec;
12
+ * - a provider instance that could not be constructed for a reason other than a missing API key
13
+ * (that one is {@link MissingProviderKeyError}, which carries the key details);
14
+ * - no configuration file anywhere at all.
15
+ *
16
+ * Deliberately dependency-free (no imports beyond types) so the config barrel, the loader and
17
+ * downstream consumers can all reach it without an import cycle — the same shape
18
+ * `providerKeys.ts` uses for {@link MissingProviderKeyError}.
19
+ *
20
+ * **Why this is an error object and not a process exit.** Loading configuration is a *library*
21
+ * operation, and a library that terminates the process denies every caller the chance to classify
22
+ * the failure. `gth eval` in particular distinguishes a **harness** error (exit 2 — the suite could
23
+ * not be evaluated) from a **product** failure (exit 1 — the SUT ran and failed); a `process.exit(1)`
24
+ * inside config discovery collapses that contract, reporting a typo in `--judge` exactly as it
25
+ * reports a genuine regression. Callers that legitimately want to terminate — the CLI entry points —
26
+ * catch it at their top level, where the exit code is chosen deliberately.
27
+ *
28
+ * One class covers every case above on purpose: no caller needs to tell them apart (all of them mean
29
+ * "this configuration cannot be used"), and the fields carry whichever detail applies. Sub-classing
30
+ * per case would only push the callers back to the marker-list problem this class exists to end —
31
+ * a consumer that wants the underlying failure reads `cause`.
32
+ */
33
+ /** Marker property carried by every {@link ConfigDiscoveryError}; see {@link isConfigDiscoveryError}. */
34
+ const CONFIG_DISCOVERY_MARKER = 'gthConfigDiscoveryError';
35
+ /**
36
+ * A configuration could not be used: a named identity profile has no config, or a config layer is
37
+ * malformed.
38
+ *
39
+ * Thrown (never exited on) by the config loader, so `gth eval`, `gth batch`, the AG-UI/ACP servers
40
+ * and any embedding consumer can classify the failure and choose their own exit code.
41
+ */
42
+ export class ConfigDiscoveryError extends Error {
43
+ /** Duck-typed marker so {@link isConfigDiscoveryError} works across duplicated module copies. */
44
+ gthConfigDiscoveryError = true;
45
+ identityProfile;
46
+ sourceLabel;
47
+ constructor(message, details = {}, options) {
48
+ super(message, options);
49
+ this.name = 'ConfigDiscoveryError';
50
+ this.identityProfile = details.identityProfile;
51
+ this.sourceLabel = details.sourceLabel;
52
+ }
53
+ /**
54
+ * Serialize the machine-readable half. `JSON.stringify(error)` would otherwise drop `message`
55
+ * (an Error's `message` is a non-enumerable own property), which is exactly the field a report
56
+ * consumer shows a human next to the profile or the file that failed.
57
+ */
58
+ toJSON() {
59
+ return {
60
+ name: this.name,
61
+ message: this.message,
62
+ identityProfile: this.identityProfile,
63
+ sourceLabel: this.sourceLabel,
64
+ };
65
+ }
66
+ }
67
+ /**
68
+ * True when `value` is a {@link ConfigDiscoveryError}.
69
+ *
70
+ * Duck-typed on the marker property rather than `instanceof` on purpose: a consumer that ends up
71
+ * with two copies of `@gaunt-sloth/core` on disk (a `file:` dep, a hoisting split) would fail an
72
+ * `instanceof` check against a genuinely-correct error and mis-handle a config failure as an
73
+ * unexpected crash — exactly the distinction this error exists to make.
74
+ */
75
+ export function isConfigDiscoveryError(value) {
76
+ return (typeof value === 'object' &&
77
+ value !== null &&
78
+ value[CONFIG_DISCOVERY_MARKER] === true);
79
+ }
80
+ //# sourceMappingURL=configDiscovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configDiscovery.js","sourceRoot":"","sources":["../../src/config/configDiscovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,yGAAyG;AACzG,MAAM,uBAAuB,GAAG,yBAAyB,CAAC;AAgB1D;;;;;;GAMG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C,iGAAiG;IACxF,uBAAuB,GAAG,IAAa,CAAC;IACxC,eAAe,CAAqB;IACpC,WAAW,CAAqB;IAEzC,YACE,OAAe,EACf,OAAO,GAA2B,EAAE,EACpC,OAA6B;QAE7B,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;QAC/C,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IACzC,CAAC;IAED;;;;OAIG;IACH,MAAM;QACJ,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,CAAC;IACJ,CAAC;CACF;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAc;IACnD,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACb,KAAiC,CAAC,uBAAuB,CAAC,KAAK,IAAI,CACrE,CAAC;AACJ,CAAC"}
@@ -1,22 +1,21 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Default Gaunt Sloth configuration ({@link DEFAULT_CONFIG}). Extracted verbatim from
4
+ * the former `config.ts` god-file; values are unchanged.
5
+ */
1
6
  import { StatusLevel } from '#src/core/types.js';
2
7
  /**
3
8
  * Default config
4
9
  */
5
10
  export declare const DEFAULT_CONFIG: {
6
- readonly contentSource: "file";
7
- readonly requirementSource: "file";
8
- /**
9
- * Path to project-specific guidelines.
10
- * The default is `.gsloth.guidelines.md`; this config may be used to point Gaunt Sloth to a different file,
11
- * for example, to AGENTS.md
12
- */
13
- readonly projectGuidelines: ".gsloth.guidelines.md";
11
+ readonly contentSource: 'file';
12
+ readonly requirementSource: 'file';
14
13
  /**
15
14
  * Whether to include the current date in the project review instructions or not.
16
15
  */
17
16
  readonly includeCurrentDateAfterGuidelines: false;
18
- readonly projectReviewInstructions: ".gsloth.review.md";
19
- readonly filesystem: "none";
17
+ readonly filesystem: 'none';
18
+ readonly builtInTools: string[];
20
19
  readonly debugLog: false;
21
20
  readonly consoleLevel: StatusLevel.INFO;
22
21
  /**
@@ -30,8 +29,8 @@ export declare const DEFAULT_CONFIG: {
30
29
  */
31
30
  readonly commands: {
32
31
  readonly pr: {
33
- readonly contentSource: "github";
34
- readonly requirementSource: "github";
32
+ readonly contentSource: 'github';
33
+ readonly requirementSource: 'github';
35
34
  readonly rating: {
36
35
  readonly enabled: true;
37
36
  readonly passThreshold: 6;
@@ -50,24 +49,24 @@ export declare const DEFAULT_CONFIG: {
50
49
  };
51
50
  };
52
51
  readonly ask: {
53
- readonly filesystem: "read";
52
+ readonly filesystem: 'read';
54
53
  };
55
54
  readonly chat: {
56
- readonly filesystem: "read";
55
+ readonly filesystem: 'read';
57
56
  };
58
57
  readonly code: {
59
- readonly filesystem: "all";
58
+ readonly filesystem: 'all';
60
59
  };
61
60
  readonly exec: {
62
- readonly filesystem: "all";
61
+ readonly filesystem: 'all';
63
62
  };
64
63
  readonly api: {
65
- readonly filesystem: "read";
64
+ readonly filesystem: 'read';
66
65
  readonly port: 3000;
67
66
  readonly cors: {
68
- readonly allowOrigin: "http://localhost:3000";
69
- readonly allowMethods: "POST, GET, OPTIONS";
70
- readonly allowHeaders: "Content-Type, Accept";
67
+ readonly allowOrigin: 'http://localhost:3000';
68
+ readonly allowMethods: 'POST, GET, OPTIONS';
69
+ readonly allowHeaders: 'Content-Type, Accept';
71
70
  };
72
71
  };
73
72
  };
@@ -75,6 +74,7 @@ export declare const DEFAULT_CONFIG: {
75
74
  readonly writeOutputToFile: false;
76
75
  readonly writeBinaryOutputsToFile: true;
77
76
  readonly useColour: true;
77
+ readonly useMouse: true;
78
78
  readonly streamSessionInferenceLog: true;
79
79
  readonly canInterruptInferenceWithEsc: true;
80
80
  readonly aiignore: {
@@ -3,7 +3,6 @@
3
3
  * Default Gaunt Sloth configuration ({@link DEFAULT_CONFIG}). Extracted verbatim from
4
4
  * the former `config.ts` god-file; values are unchanged.
5
5
  */
6
- import { PROJECT_GUIDELINES, PROJECT_REVIEW_INSTRUCTIONS } from '#src/constants.js';
7
6
  import { StatusLevel } from '#src/core/types.js';
8
7
  /**
9
8
  * Default config
@@ -11,18 +10,20 @@ import { StatusLevel } from '#src/core/types.js';
11
10
  export const DEFAULT_CONFIG = {
12
11
  contentSource: 'file',
13
12
  requirementSource: 'file',
14
- /**
15
- * Path to project-specific guidelines.
16
- * The default is `.gsloth.guidelines.md`; this config may be used to point Gaunt Sloth to a different file,
17
- * for example, to AGENTS.md
18
- */
19
- projectGuidelines: PROJECT_GUIDELINES,
13
+ // GS2-43: prompt segments (backstory/guidelines/system/chat/code/exec/review) are configured
14
+ // via the optional `prompts` object and DEFAULTED AT THE READ SITE (`readPromptSegment` falls
15
+ // back to each segment's default-named file), so `prompts` is intentionally absent here.
20
16
  /**
21
17
  * Whether to include the current date in the project review instructions or not.
22
18
  */
23
19
  includeCurrentDateAfterGuidelines: false,
24
- projectReviewInstructions: PROJECT_REVIEW_INSTRUCTIONS,
25
20
  filesystem: 'none',
21
+ // Enabled built-in tools. `gth_checklist` (the lean agent's planning/todo tool) and `gth_grep`
22
+ // (the permission-light content-search tool, GS2-51) are on by default across commands; a user
23
+ // `builtInTools` setting replaces this set entirely. Both are named to coexist with the deep
24
+ // backend's own `write_todos`/`grep` built-ins. Cast keeps it a mutable `string[]` under the
25
+ // surrounding `as const`.
26
+ builtInTools: ['gth_checklist', 'gth_grep'],
26
27
  debugLog: false,
27
28
  consoleLevel: StatusLevel.INFO, // Default to INFO level, not debug
28
29
  /**
@@ -81,6 +82,7 @@ export const DEFAULT_CONFIG = {
81
82
  writeOutputToFile: false,
82
83
  writeBinaryOutputsToFile: true,
83
84
  useColour: true,
85
+ useMouse: true,
84
86
  streamSessionInferenceLog: true,
85
87
  canInterruptInferenceWithEsc: true,
86
88
  aiignore: {
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGjD;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,aAAa,EAAE,MAAM;IACrB,iBAAiB,EAAE,MAAM;IACzB;;;;OAIG;IACH,iBAAiB,EAAE,kBAAkB;IACrC;;OAEG;IACH,iCAAiC,EAAE,KAAK;IACxC,yBAAyB,EAAE,2BAA2B;IACtD,UAAU,EAAE,MAAM;IAClB,QAAQ,EAAE,KAAK;IACf,YAAY,EAAE,WAAW,CAAC,IAAI,EAAE,mCAAmC;IACnE;;;;;;;;OAQG;IACH,QAAQ,EAAE;QACR,EAAE,EAAE;YACF,aAAa,EAAE,QAAQ;YACvB,iBAAiB,EAAE,QAAQ;YAC3B,MAAM,EAAE;gBACN,OAAO,EAAE,IAAI;gBACb,aAAa,EAAE,CAAC;gBAChB,SAAS,EAAE,CAAC;gBACZ,SAAS,EAAE,EAAE;gBACb,iBAAiB,EAAE,IAAI;aACxB;SACF;QACD,MAAM,EAAE;YACN,MAAM,EAAE;gBACN,OAAO,EAAE,IAAI;gBACb,aAAa,EAAE,CAAC;gBAChB,SAAS,EAAE,CAAC;gBACZ,SAAS,EAAE,EAAE;gBACb,iBAAiB,EAAE,IAAI;aACxB;SACF;QACD,GAAG,EAAE;YACH,UAAU,EAAE,MAAM;SACnB;QACD,IAAI,EAAE;YACJ,UAAU,EAAE,MAAM;SACnB;QACD,IAAI,EAAE;YACJ,UAAU,EAAE,KAAK;SAClB;QACD,IAAI,EAAE;YACJ,UAAU,EAAE,KAAK;SAClB;QACD,GAAG,EAAE;YACH,UAAU,EAAE,MAAM;YAClB,IAAI,EAAE,IAAI;YACV,IAAI,EAAE;gBACJ,WAAW,EAAE,uBAAuB;gBACpC,YAAY,EAAE,oBAAoB;gBAClC,YAAY,EAAE,sBAAsB;aACrC;SACF;KACF;IACD,YAAY,EAAE,IAAI;IAClB,iBAAiB,EAAE,KAAK;IACxB,wBAAwB,EAAE,IAAI;IAC9B,SAAS,EAAE,IAAI;IACf,yBAAyB,EAAE,IAAI;IAC/B,4BAA4B,EAAE,IAAI;IAClC,QAAQ,EAAE;QACR,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,SAAS;KACpB;CACO,CAAC;AAEX;;;GAGG;AACH,oEAAoE;AACpE,cAA2B,CAAC"}
1
+ {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGjD;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,aAAa,EAAE,MAAM;IACrB,iBAAiB,EAAE,MAAM;IACzB,6FAA6F;IAC7F,8FAA8F;IAC9F,yFAAyF;IACzF;;OAEG;IACH,iCAAiC,EAAE,KAAK;IACxC,UAAU,EAAE,MAAM;IAClB,+FAA+F;IAC/F,+FAA+F;IAC/F,6FAA6F;IAC7F,6FAA6F;IAC7F,0BAA0B;IAC1B,YAAY,EAAE,CAAC,eAAe,EAAE,UAAU,CAAa;IACvD,QAAQ,EAAE,KAAK;IACf,YAAY,EAAE,WAAW,CAAC,IAAI,EAAE,mCAAmC;IACnE;;;;;;;;OAQG;IACH,QAAQ,EAAE;QACR,EAAE,EAAE;YACF,aAAa,EAAE,QAAQ;YACvB,iBAAiB,EAAE,QAAQ;YAC3B,MAAM,EAAE;gBACN,OAAO,EAAE,IAAI;gBACb,aAAa,EAAE,CAAC;gBAChB,SAAS,EAAE,CAAC;gBACZ,SAAS,EAAE,EAAE;gBACb,iBAAiB,EAAE,IAAI;aACxB;SACF;QACD,MAAM,EAAE;YACN,MAAM,EAAE;gBACN,OAAO,EAAE,IAAI;gBACb,aAAa,EAAE,CAAC;gBAChB,SAAS,EAAE,CAAC;gBACZ,SAAS,EAAE,EAAE;gBACb,iBAAiB,EAAE,IAAI;aACxB;SACF;QACD,GAAG,EAAE;YACH,UAAU,EAAE,MAAM;SACnB;QACD,IAAI,EAAE;YACJ,UAAU,EAAE,MAAM;SACnB;QACD,IAAI,EAAE;YACJ,UAAU,EAAE,KAAK;SAClB;QACD,IAAI,EAAE;YACJ,UAAU,EAAE,KAAK;SAClB;QACD,GAAG,EAAE;YACH,UAAU,EAAE,MAAM;YAClB,IAAI,EAAE,IAAI;YACV,IAAI,EAAE;gBACJ,WAAW,EAAE,uBAAuB;gBACpC,YAAY,EAAE,oBAAoB;gBAClC,YAAY,EAAE,sBAAsB;aACrC;SACF;KACF;IACD,YAAY,EAAE,IAAI;IAClB,iBAAiB,EAAE,KAAK;IACxB,wBAAwB,EAAE,IAAI;IAC9B,SAAS,EAAE,IAAI;IACf,QAAQ,EAAE,IAAI;IACd,yBAAyB,EAAE,IAAI;IAC/B,4BAA4B,EAAE,IAAI;IAClC,QAAQ,EAAE;QACR,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,SAAS;KACpB;CACO,CAAC;AAEX;;;GAGG;AACH,oEAAoE;AACpE,cAA2B,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * The single interpretation of the `filesystem` config value: **which filesystem tools it
4
+ * registers**.
5
+ *
6
+ * `filesystem` is a union — `'all'`, `'read'`, `'none'`, or a `string[]` of tool names — so any
7
+ * two-value check ("is it `read` or `none`?") is wrong by construction. The toolkit filter in
8
+ * `@gaunt-sloth/agent` (`filterFilesystemTools`) and the system-prompt notes in this package both
9
+ * need the answer, and they must never derive it separately: a prompt that names a tool the filter
10
+ * did not register tells the model to call something that does not exist. {@link
11
+ * isFilesystemToolRegistered} is that one derivation; both call it.
12
+ */
13
+ import { type BuiltInToolAccess } from '#src/config/tool-descriptions.js';
14
+ /** The `filesystem` config union: an allow-list of tool names, or one of the three modes. */
15
+ export type FilesystemToolsConfig = string[] | 'all' | 'read' | 'none';
16
+ /**
17
+ * The filesystem tool that creates a file from supplied content.
18
+ *
19
+ * Exported as a constant because prompt text names it literally: the note telling the model how to
20
+ * write a commit message interpolates this, so the name the model is told and the name the
21
+ * registration check asks about cannot drift apart.
22
+ */
23
+ export declare const WRITE_FILE_TOOL_NAME = "write_file";
24
+ /**
25
+ * Whether a filesystem tool is registered under the given `filesystem` config.
26
+ *
27
+ * `access` is the tool's own read/write class — the runtime `gthFileSystemType` the toolkit stamps
28
+ * on each tool, or {@link BUILT_IN_TOOL_ACCESS} for a caller that has only a name. A tool with no
29
+ * class is never covered by `'read'`; it can still be named explicitly in the array form.
30
+ *
31
+ * The array form is an allow-list of tool NAMES which may also carry the `'read'` and `'all'`
32
+ * keywords, so `['read', 'write_file']` means "every read tool, plus write_file". A value that is
33
+ * neither a known mode nor an array leaves the toolset unrestricted, matching the filter's own
34
+ * fallback, so an absent or malformed value never silently strips the model's tools.
35
+ */
36
+ export declare function isFilesystemToolRegistered(filesystemConfig: FilesystemToolsConfig | undefined, toolName: string | undefined, access: BuiltInToolAccess | undefined): boolean;
37
+ /**
38
+ * Whether {@link WRITE_FILE_TOOL_NAME} is registered under the given `filesystem` config — the
39
+ * question the commit-message guidance asks before it names the tool.
40
+ */
41
+ export declare function isWriteFileToolRegistered(filesystemConfig: FilesystemToolsConfig | undefined): boolean;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * The single interpretation of the `filesystem` config value: **which filesystem tools it
4
+ * registers**.
5
+ *
6
+ * `filesystem` is a union — `'all'`, `'read'`, `'none'`, or a `string[]` of tool names — so any
7
+ * two-value check ("is it `read` or `none`?") is wrong by construction. The toolkit filter in
8
+ * `@gaunt-sloth/agent` (`filterFilesystemTools`) and the system-prompt notes in this package both
9
+ * need the answer, and they must never derive it separately: a prompt that names a tool the filter
10
+ * did not register tells the model to call something that does not exist. {@link
11
+ * isFilesystemToolRegistered} is that one derivation; both call it.
12
+ */
13
+ import { BUILT_IN_TOOL_ACCESS } from '#src/config/tool-descriptions.js';
14
+ /**
15
+ * The filesystem tool that creates a file from supplied content.
16
+ *
17
+ * Exported as a constant because prompt text names it literally: the note telling the model how to
18
+ * write a commit message interpolates this, so the name the model is told and the name the
19
+ * registration check asks about cannot drift apart.
20
+ */
21
+ export const WRITE_FILE_TOOL_NAME = 'write_file';
22
+ /**
23
+ * Whether a filesystem tool is registered under the given `filesystem` config.
24
+ *
25
+ * `access` is the tool's own read/write class — the runtime `gthFileSystemType` the toolkit stamps
26
+ * on each tool, or {@link BUILT_IN_TOOL_ACCESS} for a caller that has only a name. A tool with no
27
+ * class is never covered by `'read'`; it can still be named explicitly in the array form.
28
+ *
29
+ * The array form is an allow-list of tool NAMES which may also carry the `'read'` and `'all'`
30
+ * keywords, so `['read', 'write_file']` means "every read tool, plus write_file". A value that is
31
+ * neither a known mode nor an array leaves the toolset unrestricted, matching the filter's own
32
+ * fallback, so an absent or malformed value never silently strips the model's tools.
33
+ */
34
+ export function isFilesystemToolRegistered(filesystemConfig, toolName, access) {
35
+ if (filesystemConfig === 'none')
36
+ return false;
37
+ if (filesystemConfig === 'all')
38
+ return true;
39
+ if (filesystemConfig === 'read')
40
+ return access === 'read';
41
+ if (!Array.isArray(filesystemConfig))
42
+ return true;
43
+ if (filesystemConfig.includes('all'))
44
+ return true;
45
+ if (filesystemConfig.includes('read') && access === 'read')
46
+ return true;
47
+ return filesystemConfig.some((name) => name !== 'read' && name !== 'all' && name === toolName && !!toolName);
48
+ }
49
+ /**
50
+ * Whether {@link WRITE_FILE_TOOL_NAME} is registered under the given `filesystem` config — the
51
+ * question the commit-message guidance asks before it names the tool.
52
+ */
53
+ export function isWriteFileToolRegistered(filesystemConfig) {
54
+ return isFilesystemToolRegistered(filesystemConfig, WRITE_FILE_TOOL_NAME, BUILT_IN_TOOL_ACCESS[WRITE_FILE_TOOL_NAME]);
55
+ }
56
+ //# sourceMappingURL=filesystem-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem-tools.js","sourceRoot":"","sources":["../../src/config/filesystem-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,oBAAoB,EAA0B,MAAM,kCAAkC,CAAC;AAKhG;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,YAAY,CAAC;AAEjD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,0BAA0B,CACxC,gBAAmD,EACnD,QAA4B,EAC5B,MAAqC;IAErC,IAAI,gBAAgB,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IAC9C,IAAI,gBAAgB,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,gBAAgB,KAAK,MAAM;QAAE,OAAO,MAAM,KAAK,MAAM,CAAC;IAC1D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC;QAAE,OAAO,IAAI,CAAC;IAClD,IAAI,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAClD,IAAI,gBAAgB,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IACxE,OAAO,gBAAgB,CAAC,IAAI,CAC1B,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAC/E,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CACvC,gBAAmD;IAEnD,OAAO,0BAA0B,CAC/B,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,CAAC,oBAAoB,CAAC,CAC3C,CAAC;AACJ,CAAC"}