@gaunt-sloth/core 2.0.0-alpha.0 → 2.0.0-alpha.10
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/.gsloth.code.md +10 -0
- package/LICENSE +7 -0
- package/README.md +3 -4
- package/dist/config/defaults.d.ts +85 -0
- package/dist/config/defaults.js +101 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/jsonc.d.ts +12 -0
- package/dist/config/jsonc.js +41 -0
- package/dist/config/jsonc.js.map +1 -0
- package/dist/config/loader.d.ts +109 -0
- package/dist/config/loader.js +663 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +509 -0
- package/dist/config/schema.js +349 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/config/shell-policy.d.ts +212 -0
- package/dist/config/shell-policy.js +142 -0
- package/dist/config/shell-policy.js.map +1 -0
- package/dist/config/types.d.ts +490 -0
- package/dist/config/types.js +12 -0
- package/dist/config/types.js.map +1 -0
- package/dist/config.d.ts +18 -647
- package/dist/config.js +15 -516
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts +24 -0
- package/dist/constants.js +24 -0
- package/dist/constants.js.map +1 -1
- package/dist/core/GthAbstractAgent.d.ts +57 -1
- package/dist/core/GthAbstractAgent.js +171 -4
- package/dist/core/GthAbstractAgent.js.map +1 -1
- package/dist/core/GthAgentRunner.d.ts +168 -1
- package/dist/core/GthAgentRunner.js +380 -4
- package/dist/core/GthAgentRunner.js.map +1 -1
- package/dist/core/GthLangChainAgent.js +94 -5
- package/dist/core/GthLangChainAgent.js.map +1 -1
- package/dist/core/debugCapture.d.ts +59 -0
- package/dist/core/debugCapture.js +101 -0
- package/dist/core/debugCapture.js.map +1 -0
- package/dist/core/gthLeanAgentFactory.d.ts +9 -0
- package/dist/core/gthLeanAgentFactory.js +10 -0
- package/dist/core/gthLeanAgentFactory.js.map +1 -0
- package/dist/core/runStats.d.ts +41 -0
- package/dist/core/runStats.js +73 -0
- package/dist/core/runStats.js.map +1 -0
- package/dist/core/shell/ShellCommandFailedError.d.ts +54 -0
- package/dist/core/shell/ShellCommandFailedError.js +68 -0
- package/dist/core/shell/ShellCommandFailedError.js.map +1 -0
- package/dist/core/shell/allowlist.d.ts +75 -0
- package/dist/core/shell/allowlist.js +187 -0
- package/dist/core/shell/allowlist.js.map +1 -0
- package/dist/core/shell/arity.d.ts +75 -0
- package/dist/core/shell/arity.js +313 -0
- package/dist/core/shell/arity.js.map +1 -0
- package/dist/core/shell/judge.d.ts +161 -0
- package/dist/core/shell/judge.js +261 -0
- package/dist/core/shell/judge.js.map +1 -0
- package/dist/core/shell/normalize.d.ts +27 -0
- package/dist/core/shell/normalize.js +53 -0
- package/dist/core/shell/normalize.js.map +1 -0
- package/dist/core/types.d.ts +104 -0
- package/dist/core/types.js.map +1 -1
- package/dist/history/historyFormat.d.ts +19 -0
- package/dist/history/historyFormat.js +85 -0
- package/dist/history/historyFormat.js.map +1 -0
- package/dist/history/historyStore.d.ts +121 -0
- package/dist/history/historyStore.js +315 -0
- package/dist/history/historyStore.js.map +1 -0
- package/dist/history/recordSession.d.ts +28 -0
- package/dist/history/recordSession.js +29 -0
- package/dist/history/recordSession.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/providers/anthropic.d.ts +1 -1
- package/dist/providers/anthropic.js +5 -10
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/deepseek.d.ts +1 -1
- package/dist/providers/deepseek.js +5 -10
- package/dist/providers/deepseek.js.map +1 -1
- package/dist/providers/google-genai.d.ts +1 -1
- package/dist/providers/google-genai.js +5 -10
- package/dist/providers/google-genai.js.map +1 -1
- package/dist/providers/groq.d.ts +1 -1
- package/dist/providers/groq.js +5 -10
- package/dist/providers/groq.js.map +1 -1
- package/dist/providers/modelDiscovery.d.ts +54 -1
- package/dist/providers/modelDiscovery.js +106 -8
- package/dist/providers/modelDiscovery.js.map +1 -1
- package/dist/providers/ollama.d.ts +1 -1
- package/dist/providers/ollama.js +5 -15
- package/dist/providers/ollama.js.map +1 -1
- package/dist/providers/openai.d.ts +1 -1
- package/dist/providers/openai.js +5 -10
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/openrouter.d.ts +1 -1
- package/dist/providers/openrouter.js +7 -12
- package/dist/providers/openrouter.js.map +1 -1
- package/dist/providers/vertexai.d.ts +1 -1
- package/dist/providers/vertexai.js +5 -10
- package/dist/providers/vertexai.js.map +1 -1
- package/dist/providers/xai.d.ts +1 -1
- package/dist/providers/xai.js +5 -10
- package/dist/providers/xai.js.map +1 -1
- package/dist/runtime/singleShot.d.ts +5 -2
- package/dist/runtime/singleShot.js +36 -3
- package/dist/runtime/singleShot.js.map +1 -1
- package/dist/utils/fileUtils.d.ts +24 -2
- package/dist/utils/fileUtils.js +54 -12
- package/dist/utils/fileUtils.js.map +1 -1
- package/dist/utils/systemUtils.d.ts +31 -0
- package/dist/utils/systemUtils.js +38 -0
- package/dist/utils/systemUtils.js.map +1 -1
- package/package.json +16 -11
- package/schema/gsloth-config.schema.json +1579 -0
package/.gsloth.code.md
CHANGED
|
@@ -16,6 +16,16 @@ You have access to the entire project directory and can:
|
|
|
16
16
|
- Create new files and directories as needed
|
|
17
17
|
- Execute commands to run tests, build the project or run static analysis (lint)
|
|
18
18
|
|
|
19
|
+
## File paths
|
|
20
|
+
|
|
21
|
+
- Paths are real absolute filesystem paths — there is no virtual root. The current
|
|
22
|
+
working directory is provided to you separately; do NOT assume it is `/`.
|
|
23
|
+
- The filesystem tools (`ls`/`glob`/`read_file`/`write_file`/`edit_file`/`grep`) and
|
|
24
|
+
`run_shell_command` share the same real paths. A path that works in the shell works
|
|
25
|
+
in the filesystem tools and vice versa.
|
|
26
|
+
- Relative paths resolve against the working directory. Check the current directory
|
|
27
|
+
before filesystem operations and prefer absolute paths when unsure.
|
|
28
|
+
|
|
19
29
|
Focus on writing clean, maintainable code that follows the project's established patterns and conventions. Always test your changes when possible and explain what you're doing and why.
|
|
20
30
|
|
|
21
31
|
## Running tests
|
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright 2025-present Andrew Kondratev
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ Core utilities and types for Gaunt Sloth.
|
|
|
11
11
|
- State and artifact storage: `artifactStore`
|
|
12
12
|
- Shared constants and types
|
|
13
13
|
|
|
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
|
|
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.
|
|
15
15
|
|
|
16
16
|
## Dependencies
|
|
17
17
|
|
|
@@ -29,7 +29,6 @@ import { display } from '@gaunt-sloth/core/utils/consoleUtils.js';
|
|
|
29
29
|
## Related packages
|
|
30
30
|
|
|
31
31
|
- [`@gaunt-sloth/core`](../core) — Core utilities, config, and agent infrastructure (this package)
|
|
32
|
-
- [`@gaunt-sloth/
|
|
33
|
-
- [`@gaunt-sloth/api`](../api) — API server, AG-UI, MCP, and A2A integration
|
|
32
|
+
- [`@gaunt-sloth/agent`](../agent) — Agent runtime: built-in tools, filesystem toolkit, middleware registry, API server, AG-UI, MCP, and A2A integration
|
|
34
33
|
- [`@gaunt-sloth/review`](../review) — Review and Q&A modules with standalone CLI
|
|
35
|
-
- [`gaunt-sloth
|
|
34
|
+
- [`gaunt-sloth`](../app) — Main CLI application
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { StatusLevel } from '#src/core/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Default config
|
|
4
|
+
*/
|
|
5
|
+
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";
|
|
14
|
+
/**
|
|
15
|
+
* Whether to include the current date in the project review instructions or not.
|
|
16
|
+
*/
|
|
17
|
+
readonly includeCurrentDateAfterGuidelines: false;
|
|
18
|
+
readonly projectReviewInstructions: ".gsloth.review.md";
|
|
19
|
+
readonly filesystem: "none";
|
|
20
|
+
readonly builtInTools: string[];
|
|
21
|
+
readonly debugLog: false;
|
|
22
|
+
readonly consoleLevel: StatusLevel.INFO;
|
|
23
|
+
/**
|
|
24
|
+
* Default source for both requirements and content is GitHub.
|
|
25
|
+
* It needs GitHub CLI (gh).
|
|
26
|
+
*
|
|
27
|
+
* `github` content source uses `gh pr diff NN` internally. {@link src/sources/ghPrDiffSource.ts!}
|
|
28
|
+
*
|
|
29
|
+
*
|
|
30
|
+
* `github` requirement source uses `gh issue view NN` internally
|
|
31
|
+
*/
|
|
32
|
+
readonly commands: {
|
|
33
|
+
readonly pr: {
|
|
34
|
+
readonly contentSource: "github";
|
|
35
|
+
readonly requirementSource: "github";
|
|
36
|
+
readonly rating: {
|
|
37
|
+
readonly enabled: true;
|
|
38
|
+
readonly passThreshold: 6;
|
|
39
|
+
readonly minRating: 0;
|
|
40
|
+
readonly maxRating: 10;
|
|
41
|
+
readonly errorOnReviewFail: true;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
readonly review: {
|
|
45
|
+
readonly rating: {
|
|
46
|
+
readonly enabled: true;
|
|
47
|
+
readonly passThreshold: 6;
|
|
48
|
+
readonly minRating: 0;
|
|
49
|
+
readonly maxRating: 10;
|
|
50
|
+
readonly errorOnReviewFail: true;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
readonly ask: {
|
|
54
|
+
readonly filesystem: "read";
|
|
55
|
+
};
|
|
56
|
+
readonly chat: {
|
|
57
|
+
readonly filesystem: "read";
|
|
58
|
+
};
|
|
59
|
+
readonly code: {
|
|
60
|
+
readonly filesystem: "all";
|
|
61
|
+
};
|
|
62
|
+
readonly exec: {
|
|
63
|
+
readonly filesystem: "all";
|
|
64
|
+
};
|
|
65
|
+
readonly api: {
|
|
66
|
+
readonly filesystem: "read";
|
|
67
|
+
readonly port: 3000;
|
|
68
|
+
readonly cors: {
|
|
69
|
+
readonly allowOrigin: "http://localhost:3000";
|
|
70
|
+
readonly allowMethods: "POST, GET, OPTIONS";
|
|
71
|
+
readonly allowHeaders: "Content-Type, Accept";
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
readonly streamOutput: true;
|
|
76
|
+
readonly writeOutputToFile: false;
|
|
77
|
+
readonly writeBinaryOutputsToFile: true;
|
|
78
|
+
readonly useColour: true;
|
|
79
|
+
readonly streamSessionInferenceLog: true;
|
|
80
|
+
readonly canInterruptInferenceWithEsc: true;
|
|
81
|
+
readonly aiignore: {
|
|
82
|
+
readonly enabled: true;
|
|
83
|
+
readonly patterns: undefined;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
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
|
+
*/
|
|
6
|
+
import { PROJECT_GUIDELINES, PROJECT_REVIEW_INSTRUCTIONS } from '#src/constants.js';
|
|
7
|
+
import { StatusLevel } from '#src/core/types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Default config
|
|
10
|
+
*/
|
|
11
|
+
export const DEFAULT_CONFIG = {
|
|
12
|
+
contentSource: 'file',
|
|
13
|
+
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,
|
|
20
|
+
/**
|
|
21
|
+
* Whether to include the current date in the project review instructions or not.
|
|
22
|
+
*/
|
|
23
|
+
includeCurrentDateAfterGuidelines: false,
|
|
24
|
+
projectReviewInstructions: PROJECT_REVIEW_INSTRUCTIONS,
|
|
25
|
+
filesystem: 'none',
|
|
26
|
+
// Enabled built-in tools. `gth_checklist` (the lean agent's planning/todo tool) is on by
|
|
27
|
+
// default across commands; a user `builtInTools` setting replaces this set entirely.
|
|
28
|
+
// Cast keeps it a mutable `string[]` under the surrounding `as const`.
|
|
29
|
+
builtInTools: ['gth_checklist'],
|
|
30
|
+
debugLog: false,
|
|
31
|
+
consoleLevel: StatusLevel.INFO, // Default to INFO level, not debug
|
|
32
|
+
/**
|
|
33
|
+
* Default source for both requirements and content is GitHub.
|
|
34
|
+
* It needs GitHub CLI (gh).
|
|
35
|
+
*
|
|
36
|
+
* `github` content source uses `gh pr diff NN` internally. {@link src/sources/ghPrDiffSource.ts!}
|
|
37
|
+
*
|
|
38
|
+
*
|
|
39
|
+
* `github` requirement source uses `gh issue view NN` internally
|
|
40
|
+
*/
|
|
41
|
+
commands: {
|
|
42
|
+
pr: {
|
|
43
|
+
contentSource: 'github',
|
|
44
|
+
requirementSource: 'github',
|
|
45
|
+
rating: {
|
|
46
|
+
enabled: true,
|
|
47
|
+
passThreshold: 6,
|
|
48
|
+
minRating: 0,
|
|
49
|
+
maxRating: 10,
|
|
50
|
+
errorOnReviewFail: true,
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
review: {
|
|
54
|
+
rating: {
|
|
55
|
+
enabled: true,
|
|
56
|
+
passThreshold: 6,
|
|
57
|
+
minRating: 0,
|
|
58
|
+
maxRating: 10,
|
|
59
|
+
errorOnReviewFail: true,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
ask: {
|
|
63
|
+
filesystem: 'read',
|
|
64
|
+
},
|
|
65
|
+
chat: {
|
|
66
|
+
filesystem: 'read',
|
|
67
|
+
},
|
|
68
|
+
code: {
|
|
69
|
+
filesystem: 'all',
|
|
70
|
+
},
|
|
71
|
+
exec: {
|
|
72
|
+
filesystem: 'all',
|
|
73
|
+
},
|
|
74
|
+
api: {
|
|
75
|
+
filesystem: 'read',
|
|
76
|
+
port: 3000,
|
|
77
|
+
cors: {
|
|
78
|
+
allowOrigin: 'http://localhost:3000',
|
|
79
|
+
allowMethods: 'POST, GET, OPTIONS',
|
|
80
|
+
allowHeaders: 'Content-Type, Accept',
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
streamOutput: true,
|
|
85
|
+
writeOutputToFile: false,
|
|
86
|
+
writeBinaryOutputsToFile: true,
|
|
87
|
+
useColour: true,
|
|
88
|
+
streamSessionInferenceLog: true,
|
|
89
|
+
canInterruptInferenceWithEsc: true,
|
|
90
|
+
aiignore: {
|
|
91
|
+
enabled: true,
|
|
92
|
+
patterns: undefined,
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Needed DEFAULT_CONFIG to be plain const to be picked up by typedoc,
|
|
97
|
+
* this cast here is just for typecheck.
|
|
98
|
+
*/
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
100
|
+
DEFAULT_CONFIG;
|
|
101
|
+
//# sourceMappingURL=defaults.js.map
|
|
@@ -0,0 +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,yFAAyF;IACzF,qFAAqF;IACrF,uEAAuE;IACvE,YAAY,EAAE,CAAC,eAAe,CAAa;IAC3C,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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a JSONC string (JSON + comments + trailing commas) into a value.
|
|
3
|
+
*
|
|
4
|
+
* On success returns the parsed value. On a structural error (anything `JSON.parse`
|
|
5
|
+
* would also reject, e.g. a missing brace or a dangling property) it throws a `SyntaxError`
|
|
6
|
+
* whose message names the first problem and its 0-based character offset, so the loader's
|
|
7
|
+
* existing "Failed to read config …" diagnostics stay actionable.
|
|
8
|
+
*
|
|
9
|
+
* @param text The file contents.
|
|
10
|
+
* @param sourceLabel Optional human-readable source name, included in the error message.
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseJsonc(text: string, sourceLabel?: string): unknown;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* JSONC (JSON-with-comments) parsing for on-disk `.gsloth.config.json` files.
|
|
4
|
+
*
|
|
5
|
+
* The loader historically `JSON.parse`d config files, which rejects the two things
|
|
6
|
+
* hand-edited config files most want: `//` / `/* … */` comments and trailing commas.
|
|
7
|
+
* This wraps Microsoft's zero-dependency `jsonc-parser` so a plain `.json` config may
|
|
8
|
+
* carry both, while a genuinely malformed file still fails with a clear, located error
|
|
9
|
+
* (rather than silently returning `undefined`).
|
|
10
|
+
*
|
|
11
|
+
* `jsonc-parser` is used over a hand-rolled comment-stripper because stripping comments
|
|
12
|
+
* with a regex mishandles `//` / `/*` sequences that appear *inside* string values and
|
|
13
|
+
* escaped quotes; the tokenizer here respects string boundaries correctly. It has no
|
|
14
|
+
* transitive dependencies and is the same parser VS Code uses for its settings files.
|
|
15
|
+
*/
|
|
16
|
+
import { parse as parseJsoncTree, printParseErrorCode } from 'jsonc-parser';
|
|
17
|
+
/**
|
|
18
|
+
* Parse a JSONC string (JSON + comments + trailing commas) into a value.
|
|
19
|
+
*
|
|
20
|
+
* On success returns the parsed value. On a structural error (anything `JSON.parse`
|
|
21
|
+
* would also reject, e.g. a missing brace or a dangling property) it throws a `SyntaxError`
|
|
22
|
+
* whose message names the first problem and its 0-based character offset, so the loader's
|
|
23
|
+
* existing "Failed to read config …" diagnostics stay actionable.
|
|
24
|
+
*
|
|
25
|
+
* @param text The file contents.
|
|
26
|
+
* @param sourceLabel Optional human-readable source name, included in the error message.
|
|
27
|
+
*/
|
|
28
|
+
export function parseJsonc(text, sourceLabel) {
|
|
29
|
+
const errors = [];
|
|
30
|
+
const value = parseJsoncTree(text, errors, {
|
|
31
|
+
allowTrailingComma: true,
|
|
32
|
+
disallowComments: false,
|
|
33
|
+
});
|
|
34
|
+
if (errors.length > 0) {
|
|
35
|
+
const first = errors[0];
|
|
36
|
+
const where = sourceLabel ? ` in ${sourceLabel}` : '';
|
|
37
|
+
throw new SyntaxError(`Invalid JSON/JSONC${where}: ${printParseErrorCode(first.error)} at offset ${first.offset}.`);
|
|
38
|
+
}
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=jsonc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonc.js","sourceRoot":"","sources":["../../src/config/jsonc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,KAAK,IAAI,cAAc,EAAmB,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAE7F;;;;;;;;;;GAUG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,WAAoB;IAC3D,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE;QACzC,kBAAkB,EAAE,IAAI;QACxB,gBAAgB,EAAE,KAAK;KACxB,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,OAAO,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,WAAW,CACnB,qBAAqB,KAAK,KAAK,mBAAmB,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,KAAK,CAAC,MAAM,GAAG,CAC7F,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { type RawConfigValidationResult } from '#src/config/schema.js';
|
|
2
|
+
import type { CommandLineConfigOverrides, ConsoleLevelInput, GthConfig, RawGthConfig } from '#src/config/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Find THE project config by walking up from cwd toward a stop boundary, returning the FIRST
|
|
5
|
+
* match (first-match-win: nearest dir, then format precedence within that dir — NOT a merged
|
|
6
|
+
* stack). Detection ({@link hasProjectConfig}/{@link hasAnyConfig}) and loading ({@link initConfig})
|
|
7
|
+
* both go through this, so they can never disagree.
|
|
8
|
+
*
|
|
9
|
+
* Stop boundary — the dir is SEARCHED, then ascent stops at: a dir containing `.git` (the git
|
|
10
|
+
* root), the user's home dir, or the filesystem root — whichever comes first. So a config IN the
|
|
11
|
+
* git root (or home) is found; a config ABOVE it is not.
|
|
12
|
+
*
|
|
13
|
+
* A `customConfigPath` override wins outright (no walking).
|
|
14
|
+
*
|
|
15
|
+
* @returns the matched `{ dir, path }`, or `undefined` when no project config exists within the
|
|
16
|
+
* boundary.
|
|
17
|
+
*/
|
|
18
|
+
export declare function findProjectConfigPath(commandLineConfigOverrides: CommandLineConfigOverrides): {
|
|
19
|
+
dir: string;
|
|
20
|
+
path: string;
|
|
21
|
+
} | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Loads the global gsloth config (if present) from the global `~/.gsloth` folder.
|
|
24
|
+
*
|
|
25
|
+
* Precedence support: the returned raw config is intended to act as the BASE that the
|
|
26
|
+
* project config (and CLI overrides) merge on top of, so any value here is the lowest
|
|
27
|
+
* user-controlled layer (still above {@link DEFAULT_CONFIG}).
|
|
28
|
+
*
|
|
29
|
+
* Lookup order within the global folder, first match wins:
|
|
30
|
+
* `.gsloth.config.json` -> `.gsloth.config.js` -> `.gsloth.config.mjs`
|
|
31
|
+
*
|
|
32
|
+
* Absence of every variant is a no-op: returns `undefined` so behaviour is unchanged.
|
|
33
|
+
*
|
|
34
|
+
* NOTE: secrets (API keys) may live in this file; this function must never log its
|
|
35
|
+
* contents. Only non-sensitive diagnostics (the resolved path / parse failure) are emitted.
|
|
36
|
+
*
|
|
37
|
+
* @returns The raw global config object, or `undefined` when no global config exists.
|
|
38
|
+
*/
|
|
39
|
+
export declare function loadGlobalRawConfig(): Promise<Partial<RawGthConfig> | undefined>;
|
|
40
|
+
/**
|
|
41
|
+
* ORDERING INVARIANT (GS2-11): detection ({@link hasProjectConfig}/{@link hasAnyConfig}) MUST run
|
|
42
|
+
* before {@link initConfig} in a given process. Both resolve cwd-level candidates via
|
|
43
|
+
* `getGslothConfigReadPath`, which reads `getProjectDir()`; {@link initConfig} clears `projectDir`
|
|
44
|
+
* at the start of its run, so detection stays cwd-correct as long as it precedes initConfig (it
|
|
45
|
+
* does: startSession calls hasAnyConfig before any initConfig, and the ACP/agent path calls
|
|
46
|
+
* initConfig directly without detection). Calling detection AFTER an initConfig with a changed cwd
|
|
47
|
+
* in a long-lived process would read a stale projectDir (currently unreachable). If that call
|
|
48
|
+
* order is ever introduced, decouple discovery's cwd-branch from `getProjectDir()`.
|
|
49
|
+
*/
|
|
50
|
+
/**
|
|
51
|
+
* Returns true when a project-level config file (json/js/mjs) exists for the given
|
|
52
|
+
* overrides. Honours `customConfigPath` and the active identity profile so the check
|
|
53
|
+
* matches exactly what {@link initConfig} would attempt to load.
|
|
54
|
+
*
|
|
55
|
+
* This is the project half of CFG-10's "is any config present?" detection; the global
|
|
56
|
+
* half is {@link loadGlobalRawConfig} (used by {@link hasAnyConfig}).
|
|
57
|
+
*/
|
|
58
|
+
export declare function hasProjectConfig(commandLineConfigOverrides: CommandLineConfigOverrides): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* CFG-10 — true when ANY usable configuration is present, either a project config file
|
|
61
|
+
* (json/js/mjs) or a standalone global config (`~/.gsloth/.gsloth.config.*`). When this
|
|
62
|
+
* returns false the caller should run the first-run dialog instead of erroring.
|
|
63
|
+
*
|
|
64
|
+
* Reuses CFG-8's project + global detection so the two paths can never disagree.
|
|
65
|
+
*/
|
|
66
|
+
export declare function hasAnyConfig(commandLineConfigOverrides: CommandLineConfigOverrides): Promise<boolean>;
|
|
67
|
+
/**
|
|
68
|
+
* Initialize configuration by loading from available config files
|
|
69
|
+
* @returns The loaded GthConfig
|
|
70
|
+
*/
|
|
71
|
+
export declare function initConfig(commandLineConfigOverrides: CommandLineConfigOverrides): Promise<GthConfig>;
|
|
72
|
+
/**
|
|
73
|
+
* Process JSON LLM config by creating the appropriate LLM instance
|
|
74
|
+
* @param jsonConfig - The parsed JSON config
|
|
75
|
+
* @param commandLineConfigOverrides - command line config overrides
|
|
76
|
+
* @returns Promise<GthConfig>
|
|
77
|
+
*/
|
|
78
|
+
export declare function tryJsonConfig(jsonConfig: RawGthConfig, commandLineConfigOverrides: CommandLineConfigOverrides): Promise<GthConfig>;
|
|
79
|
+
/**
|
|
80
|
+
* Resolve a fully-merged {@link GthConfig} from a partial config + CLI overrides WITHOUT
|
|
81
|
+
* any global side effects (a pure transform). It deep-merges defaults, applies CLI overrides,
|
|
82
|
+
* resolves the numeric `consoleLevel` (warning + defaulting to INFO on an invalid value), and
|
|
83
|
+
* computes `canInterruptInferenceWithEsc`. The process-global setters (`setUseColour` /
|
|
84
|
+
* `setConsoleLevel`) are applied separately by {@link mergeConfig}, so this function can be
|
|
85
|
+
* reasoned about and reused without touching global state.
|
|
86
|
+
*/
|
|
87
|
+
export declare function resolveConfig(partialConfig: Omit<Partial<GthConfig>, 'consoleLevel'> & {
|
|
88
|
+
consoleLevel?: ConsoleLevelInput;
|
|
89
|
+
}, commandLineConfigOverrides: CommandLineConfigOverrides): GthConfig;
|
|
90
|
+
/**
|
|
91
|
+
* The outcome of `gth config validate`: whether a config was found, where, and whether it
|
|
92
|
+
* validates. Pure/read-side — it neither builds an LLM nor mutates process globals, so it can
|
|
93
|
+
* report a verdict without the run-path's side effects. The command layer turns this into
|
|
94
|
+
* console output + an exit code.
|
|
95
|
+
*/
|
|
96
|
+
export interface ConfigValidationReport extends RawConfigValidationResult {
|
|
97
|
+
/** False when no project or global config exists within the discovery boundary. */
|
|
98
|
+
found: boolean;
|
|
99
|
+
/** The resolved config path (or `"<name> (global)"`) when one was found. */
|
|
100
|
+
sourceLabel?: string;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Locate and validate the effective raw config against the schema WITHOUT building the LLM
|
|
104
|
+
* or merging defaults (the read-side of GS2-1). Honours `--config`, up-tree discovery, and
|
|
105
|
+
* the identity profile via {@link findProjectConfigPath}, falling back to a standalone global
|
|
106
|
+
* config (CFG-8 order) when no project config exists. A JSONC/module parse failure is thrown
|
|
107
|
+
* to the caller (surfaced as a clear "invalid config" error + non-zero exit).
|
|
108
|
+
*/
|
|
109
|
+
export declare function validateConfig(commandLineConfigOverrides: CommandLineConfigOverrides): Promise<ConfigValidationReport>;
|