@gaunt-sloth/core 2.0.0-alpha.4 → 2.0.0-alpha.40
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/README.md +71 -20
- package/dist/config/colour.d.ts +38 -0
- package/dist/config/colour.js +36 -0
- package/dist/config/colour.js.map +1 -0
- package/dist/config/configDiscovery.d.ts +79 -0
- package/dist/config/configDiscovery.js +80 -0
- package/dist/config/configDiscovery.js.map +1 -0
- package/dist/config/defaults.d.ts +21 -21
- package/dist/config/defaults.js +11 -9
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/filesystem-tools.d.ts +41 -0
- package/dist/config/filesystem-tools.js +56 -0
- package/dist/config/filesystem-tools.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 +165 -6
- package/dist/config/loader.js +963 -109
- package/dist/config/loader.js.map +1 -1
- package/dist/config/mouse.d.ts +50 -0
- package/dist/config/mouse.js +44 -0
- package/dist/config/mouse.js.map +1 -0
- package/dist/config/profiles.d.ts +68 -0
- package/dist/config/profiles.js +93 -0
- package/dist/config/profiles.js.map +1 -0
- package/dist/config/providerKeys.d.ts +69 -0
- package/dist/config/providerKeys.js +69 -0
- package/dist/config/providerKeys.js.map +1 -0
- package/dist/config/schema.d.ts +2695 -130
- package/dist/config/schema.js +1385 -68
- package/dist/config/schema.js.map +1 -1
- package/dist/config/shell-policy.d.ts +899 -111
- package/dist/config/shell-policy.js +800 -70
- package/dist/config/shell-policy.js.map +1 -1
- package/dist/config/tool-descriptions.d.ts +211 -0
- package/dist/config/tool-descriptions.js +272 -0
- package/dist/config/tool-descriptions.js.map +1 -0
- package/dist/config/types.d.ts +372 -34
- package/dist/config/types.js +1 -0
- package/dist/config/types.js.map +1 -1
- package/dist/config.d.ts +35 -1
- package/dist/config.js +16 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts +45 -0
- package/dist/constants.js +45 -0
- package/dist/constants.js.map +1 -1
- package/dist/core/GthAbstractAgent.d.ts +190 -11
- package/dist/core/GthAbstractAgent.js +551 -35
- package/dist/core/GthAbstractAgent.js.map +1 -1
- package/dist/core/GthAgentRunner.d.ts +565 -57
- package/dist/core/GthAgentRunner.js +1546 -140
- package/dist/core/GthAgentRunner.js.map +1 -1
- package/dist/core/GthLangChainAgent.d.ts +117 -2
- package/dist/core/GthLangChainAgent.js +644 -18
- package/dist/core/GthLangChainAgent.js.map +1 -1
- package/dist/core/approvals/annotations.d.ts +122 -0
- package/dist/core/approvals/annotations.js +137 -0
- package/dist/core/approvals/annotations.js.map +1 -0
- package/dist/core/approvals/grants.d.ts +216 -0
- package/dist/core/approvals/grants.js +469 -0
- package/dist/core/approvals/grants.js.map +1 -0
- package/dist/core/approvals/matcher.d.ts +202 -0
- package/dist/core/approvals/matcher.js +267 -0
- package/dist/core/approvals/matcher.js.map +1 -0
- package/dist/core/approvals/mcpSubjects.d.ts +40 -0
- package/dist/core/approvals/mcpSubjects.js +99 -0
- package/dist/core/approvals/mcpSubjects.js.map +1 -0
- package/dist/core/approvals/promptHeader.d.ts +28 -0
- package/dist/core/approvals/promptHeader.js +62 -0
- package/dist/core/approvals/promptHeader.js.map +1 -0
- package/dist/core/approvals/toolAnnotationSources.d.ts +105 -0
- package/dist/core/approvals/toolAnnotationSources.js +277 -0
- package/dist/core/approvals/toolAnnotationSources.js.map +1 -0
- package/dist/core/approvals/toolHost.d.ts +46 -0
- package/dist/core/approvals/toolHost.js +108 -0
- package/dist/core/approvals/toolHost.js.map +1 -0
- package/dist/core/debugCapture.d.ts +74 -0
- package/dist/core/debugCapture.js +100 -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/launchBanner.d.ts +127 -0
- package/dist/core/launchBanner.js +414 -0
- package/dist/core/launchBanner.js.map +1 -0
- package/dist/core/modelLabel.d.ts +19 -0
- package/dist/core/modelLabel.js +26 -0
- package/dist/core/modelLabel.js.map +1 -0
- package/dist/core/plainToolIndication.d.ts +15 -0
- package/dist/core/plainToolIndication.js +174 -0
- package/dist/core/plainToolIndication.js.map +1 -0
- package/dist/core/reasoningBlocks.d.ts +65 -0
- package/dist/core/reasoningBlocks.js +103 -0
- package/dist/core/reasoningBlocks.js.map +1 -0
- package/dist/core/refusal.d.ts +53 -0
- package/dist/core/refusal.js +133 -0
- package/dist/core/refusal.js.map +1 -0
- package/dist/core/runHeader.d.ts +38 -0
- package/dist/core/runHeader.js +42 -0
- package/dist/core/runHeader.js.map +1 -0
- package/dist/core/runStats.d.ts +52 -0
- package/dist/core/runStats.js +118 -0
- package/dist/core/runStats.js.map +1 -0
- package/dist/core/shell/ShellCommandFailedError.d.ts +53 -0
- package/dist/core/shell/ShellCommandFailedError.js +67 -0
- package/dist/core/shell/ShellCommandFailedError.js.map +1 -0
- package/dist/core/shell/abstention.d.ts +88 -0
- package/dist/core/shell/abstention.js +184 -0
- package/dist/core/shell/abstention.js.map +1 -0
- package/dist/core/shell/approvalCapture.d.ts +271 -0
- package/dist/core/shell/approvalCapture.js +108 -0
- package/dist/core/shell/approvalCapture.js.map +1 -0
- package/dist/core/shell/approvalStop.d.ts +123 -0
- package/dist/core/shell/approvalStop.js +269 -0
- package/dist/core/shell/approvalStop.js.map +1 -0
- package/dist/core/shell/arity.d.ts +6 -0
- package/dist/core/shell/arity.js +20 -6
- package/dist/core/shell/arity.js.map +1 -1
- package/dist/core/shell/denylist.d.ts +11 -0
- package/dist/core/shell/denylist.js +37 -0
- package/dist/core/shell/denylist.js.map +1 -0
- package/dist/core/shell/escalationSeverity.d.ts +141 -0
- package/dist/core/shell/escalationSeverity.js +89 -0
- package/dist/core/shell/escalationSeverity.js.map +1 -0
- package/dist/core/shell/framing.d.ts +190 -0
- package/dist/core/shell/framing.js +633 -0
- package/dist/core/shell/framing.js.map +1 -0
- package/dist/core/shell/hardline.d.ts +103 -0
- package/dist/core/shell/hardline.js +780 -0
- package/dist/core/shell/hardline.js.map +1 -0
- package/dist/core/shell/negotiation.d.ts +328 -0
- package/dist/core/shell/negotiation.js +488 -0
- package/dist/core/shell/negotiation.js.map +1 -0
- package/dist/core/shell/normalize.d.ts +44 -4
- package/dist/core/shell/normalize.js +61 -7
- package/dist/core/shell/normalize.js.map +1 -1
- package/dist/core/shell/openWorld.d.ts +263 -0
- package/dist/core/shell/openWorld.js +1188 -0
- package/dist/core/shell/openWorld.js.map +1 -0
- package/dist/core/shell/rater.d.ts +873 -0
- package/dist/core/shell/rater.js +1454 -0
- package/dist/core/shell/rater.js.map +1 -0
- package/dist/core/shell/raterModel.d.ts +41 -0
- package/dist/core/shell/raterModel.js +51 -0
- package/dist/core/shell/raterModel.js.map +1 -0
- package/dist/core/shell/raterVocabulary.d.ts +121 -0
- package/dist/core/shell/raterVocabulary.js +116 -0
- package/dist/core/shell/raterVocabulary.js.map +1 -0
- package/dist/core/shell/rejection.d.ts +69 -0
- package/dist/core/shell/rejection.js +38 -0
- package/dist/core/shell/rejection.js.map +1 -0
- package/dist/core/toolCallRepair/grammar.d.ts +41 -0
- package/dist/core/toolCallRepair/grammar.js +116 -0
- package/dist/core/toolCallRepair/grammar.js.map +1 -0
- package/dist/core/toolCallRepair/index.d.ts +2 -0
- package/dist/core/toolCallRepair/index.js +7 -0
- package/dist/core/toolCallRepair/index.js.map +1 -0
- package/dist/core/toolCallRepair/payload.d.ts +36 -0
- package/dist/core/toolCallRepair/payload.js +341 -0
- package/dist/core/toolCallRepair/payload.js.map +1 -0
- package/dist/core/toolCallRepair/promote.d.ts +45 -0
- package/dist/core/toolCallRepair/promote.js +90 -0
- package/dist/core/toolCallRepair/promote.js.map +1 -0
- package/dist/core/toolDisplay.d.ts +123 -0
- package/dist/core/toolDisplay.js +451 -0
- package/dist/core/toolDisplay.js.map +1 -0
- package/dist/core/toolOutputChannel.d.ts +95 -0
- package/dist/core/toolOutputChannel.js +165 -0
- package/dist/core/toolOutputChannel.js.map +1 -0
- package/dist/core/types.d.ts +378 -16
- package/dist/core/types.js.map +1 -1
- package/dist/history/historyFormat.d.ts +28 -0
- package/dist/history/historyFormat.js +127 -0
- package/dist/history/historyFormat.js.map +1 -0
- package/dist/history/historyStore.d.ts +198 -0
- package/dist/history/historyStore.js +482 -0
- package/dist/history/historyStore.js.map +1 -0
- package/dist/history/recordSession.d.ts +37 -0
- package/dist/history/recordSession.js +56 -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 +17 -10
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/configurationPassthrough.d.ts +107 -0
- package/dist/providers/configurationPassthrough.js +148 -0
- package/dist/providers/configurationPassthrough.js.map +1 -0
- 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/geminiSchemaSanitizer.d.ts +55 -0
- package/dist/providers/geminiSchemaSanitizer.js +347 -0
- package/dist/providers/geminiSchemaSanitizer.js.map +1 -0
- package/dist/providers/geminiThinking.d.ts +60 -0
- package/dist/providers/geminiThinking.js +92 -0
- package/dist/providers/geminiThinking.js.map +1 -0
- package/dist/providers/google-genai.d.ts +1 -1
- package/dist/providers/google-genai.js +23 -11
- package/dist/providers/google-genai.js.map +1 -1
- package/dist/providers/groq.d.ts +1 -1
- package/dist/providers/groq.js +17 -10
- package/dist/providers/groq.js.map +1 -1
- package/dist/providers/huggingface.d.ts +25 -0
- package/dist/providers/huggingface.js +69 -0
- package/dist/providers/huggingface.js.map +1 -0
- package/dist/providers/modelCatalog.d.ts +109 -0
- package/dist/providers/modelCatalog.js +245 -0
- package/dist/providers/modelCatalog.js.map +1 -0
- package/dist/providers/modelDiscovery.d.ts +153 -6
- package/dist/providers/modelDiscovery.js +295 -41
- package/dist/providers/modelDiscovery.js.map +1 -1
- package/dist/providers/ollama.d.ts +19 -5
- package/dist/providers/ollama.js +72 -52
- package/dist/providers/ollama.js.map +1 -1
- package/dist/providers/openai.d.ts +1 -1
- package/dist/providers/openai.js +39 -10
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/openrouter.d.ts +27 -5
- package/dist/providers/openrouter.js +88 -36
- package/dist/providers/openrouter.js.map +1 -1
- package/dist/providers/vertexai.d.ts +1 -1
- package/dist/providers/vertexai.js +24 -11
- package/dist/providers/vertexai.js.map +1 -1
- package/dist/providers/xai.d.ts +1 -1
- package/dist/providers/xai.js +25 -10
- package/dist/providers/xai.js.map +1 -1
- package/dist/runtime/askStructured.d.ts +105 -0
- package/dist/runtime/askStructured.js +120 -0
- package/dist/runtime/askStructured.js.map +1 -0
- package/dist/runtime/conversation.d.ts +64 -0
- package/dist/runtime/conversation.js +171 -0
- package/dist/runtime/conversation.js.map +1 -0
- package/dist/runtime/singleShot.d.ts +39 -5
- package/dist/runtime/singleShot.js +115 -36
- package/dist/runtime/singleShot.js.map +1 -1
- package/dist/runtime/structuredOutput.d.ts +104 -0
- package/dist/runtime/structuredOutput.js +393 -0
- package/dist/runtime/structuredOutput.js.map +1 -0
- package/dist/utils/ProgressIndicator.d.ts +21 -0
- package/dist/utils/ProgressIndicator.js +30 -3
- package/dist/utils/ProgressIndicator.js.map +1 -1
- package/dist/utils/aiignoreUtils.js.map +1 -1
- package/dist/utils/binaryOutputUtils.js.map +1 -1
- package/dist/utils/consoleUtils.d.ts +95 -0
- package/dist/utils/consoleUtils.js +112 -2
- package/dist/utils/consoleUtils.js.map +1 -1
- package/dist/utils/crashHandler.d.ts +87 -0
- package/dist/utils/crashHandler.js +128 -0
- package/dist/utils/crashHandler.js.map +1 -0
- package/dist/utils/debugDump.d.ts +134 -0
- package/dist/utils/debugDump.js +381 -0
- package/dist/utils/debugDump.js.map +1 -0
- package/dist/utils/debugUtils.d.ts +13 -4
- package/dist/utils/debugUtils.js +36 -13
- package/dist/utils/debugUtils.js.map +1 -1
- package/dist/utils/displayWidth.d.ts +53 -0
- package/dist/utils/displayWidth.js +195 -0
- package/dist/utils/displayWidth.js.map +1 -0
- package/dist/utils/fileUtils.d.ts +20 -1
- package/dist/utils/fileUtils.js +35 -2
- package/dist/utils/fileUtils.js.map +1 -1
- package/dist/utils/llmUtils.d.ts +39 -8
- package/dist/utils/llmUtils.js +76 -8
- package/dist/utils/llmUtils.js.map +1 -1
- package/dist/utils/redactSecrets.d.ts +63 -0
- package/dist/utils/redactSecrets.js +286 -0
- package/dist/utils/redactSecrets.js.map +1 -0
- package/dist/utils/systemPromptNotes.d.ts +222 -0
- package/dist/utils/systemPromptNotes.js +338 -0
- package/dist/utils/systemPromptNotes.js.map +1 -0
- package/dist/utils/systemUtils.d.ts +18 -1
- package/dist/utils/systemUtils.js +38 -3
- package/dist/utils/systemUtils.js.map +1 -1
- package/dist/utils/toolMatching.d.ts +30 -0
- package/dist/utils/toolMatching.js +44 -0
- package/dist/utils/toolMatching.js.map +1 -0
- package/dist/utils/untrustedText.d.ts +86 -0
- package/dist/utils/untrustedText.js +101 -0
- package/dist/utils/untrustedText.js.map +1 -0
- package/package.json +21 -6
- package/schema/gsloth-config.schema.json +1979 -353
- package/dist/core/shell/allowlist.d.ts +0 -75
- package/dist/core/shell/allowlist.js +0 -187
- package/dist/core/shell/allowlist.js.map +0 -1
- package/dist/core/shell/judge.d.ts +0 -161
- package/dist/core/shell/judge.js +0 -261
- package/dist/core/shell/judge.js.map +0 -1
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module displayWidth
|
|
3
|
+
* The one place this repo answers "how many terminal COLUMNS does this string occupy, and where
|
|
4
|
+
* may I cut it". Everything that fits text to a terminal — the launch banner's field budgets, the
|
|
5
|
+
* tool-display caps — measures and slices through here.
|
|
6
|
+
*
|
|
7
|
+
* ## Why a code-point count is not a width
|
|
8
|
+
*
|
|
9
|
+
* `[...text].length` counts code points, which is right for UTF-16 safety and wrong for layout: a
|
|
10
|
+
* CJK ideograph or an emoji is ONE code point occupying TWO columns. Text measured that way reads
|
|
11
|
+
* as shorter than it renders, escapes whatever budget it was given, and wraps — and a wrapped
|
|
12
|
+
* continuation line starts back at column 0, which is precisely the failure the budgets exist to
|
|
13
|
+
* prevent. So the rule is: a value destined for a fixed column budget is measured with
|
|
14
|
+
* {@link displayWidth} and cut with {@link sliceToWidth} / {@link sliceEndToWidth}, never with
|
|
15
|
+
* `.length`, a spread, or `String.prototype.slice`.
|
|
16
|
+
*
|
|
17
|
+
* ## Why grapheme clusters are the cutting unit
|
|
18
|
+
*
|
|
19
|
+
* Slicing by code point is safe against halving a surrogate pair but not against halving a
|
|
20
|
+
* CLUSTER: a flag, a skin-toned or ZWJ-joined emoji, or a base letter plus its combining mark are
|
|
21
|
+
* several code points that a terminal draws as one glyph, and cutting between them produces
|
|
22
|
+
* mojibake or an orphaned mark. `Intl.Segmenter` gives the same cluster boundaries the width
|
|
23
|
+
* rules below are defined over, so the two agree by construction and a sliced string's width is
|
|
24
|
+
* exactly the sum of the widths of the clusters kept.
|
|
25
|
+
*
|
|
26
|
+
* ## What the slices expect: PLAIN text
|
|
27
|
+
*
|
|
28
|
+
* {@link displayWidth} is ANSI-aware and the slices are NOT, and that asymmetry is a contract
|
|
29
|
+
* rather than an oversight. An escape sequence is not one cluster — the terminal swallows it
|
|
30
|
+
* whole, but `ESC`, `[`, `3`, `5`, `m` segment as five, four of them printable — so the two
|
|
31
|
+
* disagree on an escape-bearing string and a slice can both under-fill its budget and cut inside
|
|
32
|
+
* a sequence. Feed the slices the text a user will read, and colour it afterwards; that is what
|
|
33
|
+
* every caller here does, since both render surfaces map a style tag to their own escapes at the
|
|
34
|
+
* very end. Making the slices ANSI-aware would change what a coloured preview line renders as,
|
|
35
|
+
* which is a decision for whoever needs it and not a silent detail of this module.
|
|
36
|
+
*
|
|
37
|
+
* That asymmetry is also why a slice decides "does the whole string fit?" two different ways. For
|
|
38
|
+
* plain text the cluster walk decides it: the widths of the clusters sum to the width of the
|
|
39
|
+
* string, so walking until the budget is blown answers the question and answers it WITHOUT
|
|
40
|
+
* touching the rest of the input — which is what keeps a megabyte-long preview line from being
|
|
41
|
+
* measured end to end before it is cut at column 200. Only escape-bearing text is measured whole
|
|
42
|
+
* first, because there the two rulers disagree and a coloured string that MEASURES as fitting must
|
|
43
|
+
* be handed back whole rather than cut short by the bytes of its own escapes.
|
|
44
|
+
*
|
|
45
|
+
* ## Why ambiguous-width characters stay NARROW — and the one place they must not
|
|
46
|
+
*
|
|
47
|
+
* `string-width` defaults to treating East-Asian "Ambiguous" characters as one column, and that
|
|
48
|
+
* default is load-bearing here rather than incidental: the sloth face is block elements, the
|
|
49
|
+
* wordmark is box-drawing, and `…` is U+2026 — all Ambiguous. Counting them as two columns would
|
|
50
|
+
* measure the 16-column face at 32 and shatter the layout it anchors. So {@link displayWidth} and
|
|
51
|
+
* {@link sliceToWidth} keep the default, and the specs pin the face at 16 and the wordmark at 19 so
|
|
52
|
+
* a change of that policy fails loudly instead of quietly doubling the art.
|
|
53
|
+
*
|
|
54
|
+
* That default is an **assumption about the reader's terminal**, and it is one this process cannot
|
|
55
|
+
* check: an Ambiguous character occupies one cell or two depending on how the terminal is
|
|
56
|
+
* configured, and several CJK locales — plus an option in xterm, urxvt and mlterm — choose two.
|
|
57
|
+
* For layout art that assumption is free, because being wrong only makes the art look wrong.
|
|
58
|
+
*
|
|
59
|
+
* It is **not** free where a budget is a security boundary. {@link maxDisplayWidth} and
|
|
60
|
+
* {@link sliceToMaxWidth} are the sanctioned exception: they measure Ambiguous as **two** columns,
|
|
61
|
+
* i.e. the widest a terminal can render the string, so text fitted with them fits under *either*
|
|
62
|
+
* policy. Use them wherever a row that overruns its budget would be wrapped by the terminal into a
|
|
63
|
+
* consequence rather than into an untidy screen — `core/shell/framing` frames untrusted text this
|
|
64
|
+
* way, because there a wrapped continuation line starts at column 0 and can forge a dialog's chrome.
|
|
65
|
+
* The cost is under-fill: on a terminal that does render Ambiguous narrow, such a row can stop short
|
|
66
|
+
* of its budget. Under-fill is cosmetic; overrun is not. True Wide characters (CJK ideographs,
|
|
67
|
+
* emoji, fullwidth forms) measure 2 under both, so the common CJK case is unaffected either way.
|
|
68
|
+
*/
|
|
69
|
+
import stringWidth from 'string-width';
|
|
70
|
+
/**
|
|
71
|
+
* Grapheme-cluster boundaries, i.e. what a terminal draws as one glyph. Built once: constructing
|
|
72
|
+
* an `Intl.Segmenter` is expensive relative to the short strings this module handles.
|
|
73
|
+
*/
|
|
74
|
+
const GRAPHEME_SEGMENTER = new Intl.Segmenter(undefined, { granularity: 'grapheme' });
|
|
75
|
+
/**
|
|
76
|
+
* Terminal columns `text` occupies. Zero-width clusters (combining marks, default-ignorables)
|
|
77
|
+
* count 0, wide clusters (CJK, emoji, fullwidth forms) count 2, everything else 1. ANSI escape
|
|
78
|
+
* sequences are not counted, so a pre-coloured string measures as what the user sees — but the
|
|
79
|
+
* slices below do not share that awareness, so do not read this as a licence to feed them one.
|
|
80
|
+
*/
|
|
81
|
+
export function displayWidth(text) {
|
|
82
|
+
return stringWidth(text);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Terminal columns `text` occupies **at most** — the same measurement as {@link displayWidth} but
|
|
86
|
+
* counting East-Asian Ambiguous characters as two columns rather than one, which is the widest any
|
|
87
|
+
* terminal will render them.
|
|
88
|
+
*
|
|
89
|
+
* For a budget that must hold on a terminal whose ambiguous-width policy is unknown, this is the
|
|
90
|
+
* only sound ruler: it is the supremum over the policies a terminal can be configured with, so a
|
|
91
|
+
* string that fits under it fits under all of them. See the module docblock for when to reach for
|
|
92
|
+
* this rather than {@link displayWidth}.
|
|
93
|
+
*/
|
|
94
|
+
export function maxDisplayWidth(text) {
|
|
95
|
+
return stringWidth(text, { ambiguousIsNarrow: false });
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* The first grapheme cluster of `text`, or `''` when it is empty — i.e. the smallest piece a cut
|
|
99
|
+
* can leave behind, for a caller that has to make progress through a string one drawable glyph at
|
|
100
|
+
* a time.
|
|
101
|
+
*/
|
|
102
|
+
export function firstCluster(text) {
|
|
103
|
+
for (const { segment } of GRAPHEME_SEGMENTER.segment(text))
|
|
104
|
+
return segment;
|
|
105
|
+
return '';
|
|
106
|
+
}
|
|
107
|
+
/** The clusters of `text`, in order — the only unit either slice is allowed to cut between. */
|
|
108
|
+
function clusters(text) {
|
|
109
|
+
const out = [];
|
|
110
|
+
for (const { segment } of GRAPHEME_SEGMENTER.segment(text))
|
|
111
|
+
out.push(segment);
|
|
112
|
+
return out;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Whether the whole-string measurement is the only ruler that can answer "does this fit" for
|
|
116
|
+
* `text` — true exactly when it carries an escape introducer (`ESC`, or the one-byte `CSI`), the
|
|
117
|
+
* two characters `string-width` itself strips on. On anything else the cluster widths sum to the
|
|
118
|
+
* whole-string width, so the walk decides the same question incrementally and a pre-measurement
|
|
119
|
+
* would be a second full pass over the input for nothing.
|
|
120
|
+
*/
|
|
121
|
+
function needsWholeStringMeasure(text) {
|
|
122
|
+
return text.includes('\u001B') || text.includes('\u009B');
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* The longest LEADING run of whole clusters whose total width is at most `maxWidth` — i.e. keep
|
|
126
|
+
* the head, lose the tail. Total (never throws): a non-positive `maxWidth` yields `''`.
|
|
127
|
+
*
|
|
128
|
+
* A cluster is kept only if it fits ENTIRELY, so the result can come back one column short of
|
|
129
|
+
* `maxWidth` when the next cluster is two columns wide. That is the point: half a wide glyph
|
|
130
|
+
* cannot be drawn, and spending the column anyway is how text over-runs its budget.
|
|
131
|
+
*
|
|
132
|
+
* The clusters are produced one at a time and the walk stops at the budget, so the cost is the
|
|
133
|
+
* length of the RESULT rather than the length of the input — the input here is a whole tool-output
|
|
134
|
+
* line, which is unbounded.
|
|
135
|
+
*/
|
|
136
|
+
export function sliceToWidth(text, maxWidth) {
|
|
137
|
+
return sliceHeadToWidth(text, maxWidth, displayWidth);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* {@link sliceToWidth} measured by {@link maxDisplayWidth} — the head that fits the budget on any
|
|
141
|
+
* terminal, whatever it does with Ambiguous characters. The cut for a budget that must hold rather
|
|
142
|
+
* than merely look right.
|
|
143
|
+
*/
|
|
144
|
+
export function sliceToMaxWidth(text, maxWidth) {
|
|
145
|
+
return sliceHeadToWidth(text, maxWidth, maxDisplayWidth);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* The head-slice both public cuts are made of, given the ruler to measure with. The ruler is passed
|
|
149
|
+
* rather than chosen here so the whole-string shortcut and the cluster walk can never end up on
|
|
150
|
+
* different ones — measuring the shortcut narrow and the walk wide would hand back a string that
|
|
151
|
+
* overruns the very budget the caller asked to be held to.
|
|
152
|
+
*/
|
|
153
|
+
function sliceHeadToWidth(text, maxWidth, measure) {
|
|
154
|
+
if (maxWidth <= 0)
|
|
155
|
+
return '';
|
|
156
|
+
if (needsWholeStringMeasure(text) && measure(text) <= maxWidth)
|
|
157
|
+
return text;
|
|
158
|
+
let width = 0;
|
|
159
|
+
let kept = '';
|
|
160
|
+
for (const { segment } of GRAPHEME_SEGMENTER.segment(text)) {
|
|
161
|
+
const clusterWidth = measure(segment);
|
|
162
|
+
if (width + clusterWidth > maxWidth)
|
|
163
|
+
break;
|
|
164
|
+
width += clusterWidth;
|
|
165
|
+
kept += segment;
|
|
166
|
+
}
|
|
167
|
+
return kept;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* The longest TRAILING run of whole clusters whose total width is at most `maxWidth` — i.e. keep
|
|
171
|
+
* the tail, lose the head. The mirror of {@link sliceToWidth}, for values whose end is the
|
|
172
|
+
* informative part (a path's leaf directory).
|
|
173
|
+
*
|
|
174
|
+
* This one materialises the clusters: it walks backwards, and cluster boundaries are only
|
|
175
|
+
* derivable from the front. Its callers pass a path or a model id, so the input is a line rather
|
|
176
|
+
* than a file.
|
|
177
|
+
*/
|
|
178
|
+
export function sliceEndToWidth(text, maxWidth) {
|
|
179
|
+
if (maxWidth <= 0)
|
|
180
|
+
return '';
|
|
181
|
+
if (needsWholeStringMeasure(text) && displayWidth(text) <= maxWidth)
|
|
182
|
+
return text;
|
|
183
|
+
const all = clusters(text);
|
|
184
|
+
let width = 0;
|
|
185
|
+
let kept = '';
|
|
186
|
+
for (let index = all.length - 1; index >= 0; index--) {
|
|
187
|
+
const clusterWidth = displayWidth(all[index]);
|
|
188
|
+
if (width + clusterWidth > maxWidth)
|
|
189
|
+
break;
|
|
190
|
+
width += clusterWidth;
|
|
191
|
+
kept = all[index] + kept;
|
|
192
|
+
}
|
|
193
|
+
return kept;
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=displayWidth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"displayWidth.js","sourceRoot":"","sources":["../../src/utils/displayWidth.ts"],"names":[],"mappings":"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"}
|
|
@@ -60,7 +60,26 @@ export declare function readMultipleFilesFromProjectDir(fileNames: string | stri
|
|
|
60
60
|
* package dir.
|
|
61
61
|
*/
|
|
62
62
|
export declare function readFileFromInstallDir(filePath: string, packageDir?: string): string;
|
|
63
|
-
|
|
63
|
+
/**
|
|
64
|
+
* No-clobber write: writes `content` only when `filePath` does not already exist.
|
|
65
|
+
* @returns `true` when the file was written, `false` when it was skipped because it
|
|
66
|
+
* already existed. Callers use the return value to avoid claiming success on a skip.
|
|
67
|
+
*/
|
|
68
|
+
export declare function writeFileIfNotExistsWithMessages(filePath: string, content: string): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Unconditional write: writes (or overwrites) `content` at `filePath`, creating parent
|
|
71
|
+
* directories as needed. Use this only for the config-overwrite path (an explicit user /
|
|
72
|
+
* `--force` decision); the no-clobber {@link writeFileIfNotExistsWithMessages} still guards
|
|
73
|
+
* user-editable preamble files (guidelines / review).
|
|
74
|
+
*/
|
|
75
|
+
export declare function writeFileWithMessages(filePath: string, content: string): void;
|
|
76
|
+
/**
|
|
77
|
+
* Config-file write that honours an overwrite flag.
|
|
78
|
+
* - `force === true` → always (over)writes.
|
|
79
|
+
* - `force === false` → no-clobber (skips + warns when the file already exists).
|
|
80
|
+
* @returns `true` when a write happened, `false` when it was skipped.
|
|
81
|
+
*/
|
|
82
|
+
export declare function writeConfigFileWithMessages(filePath: string, content: string, force?: boolean): boolean;
|
|
64
83
|
export declare function appendToFile(filePath: string, content: string): void;
|
|
65
84
|
export declare function readFileSyncWithMessages(filePath: string, errorMessageIn?: string, noFileMessage?: string): string;
|
|
66
85
|
/**
|
package/dist/utils/fileUtils.js
CHANGED
|
@@ -163,6 +163,11 @@ export function readFileFromInstallDir(filePath, packageDir = corePackageDir) {
|
|
|
163
163
|
throw readFromInstallDirError;
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* No-clobber write: writes `content` only when `filePath` does not already exist.
|
|
168
|
+
* @returns `true` when the file was written, `false` when it was skipped because it
|
|
169
|
+
* already existed. Callers use the return value to avoid claiming success on a skip.
|
|
170
|
+
*/
|
|
166
171
|
export function writeFileIfNotExistsWithMessages(filePath, content) {
|
|
167
172
|
displayInfo(`checking ${filePath} existence`);
|
|
168
173
|
if (!existsSync(filePath)) {
|
|
@@ -173,10 +178,38 @@ export function writeFileIfNotExistsWithMessages(filePath, content) {
|
|
|
173
178
|
}
|
|
174
179
|
writeFileSync(filePath, content);
|
|
175
180
|
displaySuccess(`Created ${filePath}`);
|
|
181
|
+
return true;
|
|
176
182
|
}
|
|
177
|
-
|
|
178
|
-
|
|
183
|
+
displayWarning(`${filePath} already exists`);
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Unconditional write: writes (or overwrites) `content` at `filePath`, creating parent
|
|
188
|
+
* directories as needed. Use this only for the config-overwrite path (an explicit user /
|
|
189
|
+
* `--force` decision); the no-clobber {@link writeFileIfNotExistsWithMessages} still guards
|
|
190
|
+
* user-editable preamble files (guidelines / review).
|
|
191
|
+
*/
|
|
192
|
+
export function writeFileWithMessages(filePath, content) {
|
|
193
|
+
const parentDir = dirname(filePath);
|
|
194
|
+
if (!existsSync(parentDir)) {
|
|
195
|
+
mkdirSync(parentDir, { recursive: true });
|
|
196
|
+
}
|
|
197
|
+
const existed = existsSync(filePath);
|
|
198
|
+
writeFileSync(filePath, content);
|
|
199
|
+
displaySuccess(existed ? `Overwrote ${filePath}` : `Created ${filePath}`);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Config-file write that honours an overwrite flag.
|
|
203
|
+
* - `force === true` → always (over)writes.
|
|
204
|
+
* - `force === false` → no-clobber (skips + warns when the file already exists).
|
|
205
|
+
* @returns `true` when a write happened, `false` when it was skipped.
|
|
206
|
+
*/
|
|
207
|
+
export function writeConfigFileWithMessages(filePath, content, force = false) {
|
|
208
|
+
if (force) {
|
|
209
|
+
writeFileWithMessages(filePath, content);
|
|
210
|
+
return true;
|
|
179
211
|
}
|
|
212
|
+
return writeFileIfNotExistsWithMessages(filePath, content);
|
|
180
213
|
}
|
|
181
214
|
export function appendToFile(filePath, content) {
|
|
182
215
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fileUtils.js","sourceRoot":"","sources":["../../src/utils/fileUtils.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"fileUtils.js","sourceRoot":"","sources":["../../src/utils/fileUtils.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/llmUtils.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RunnableConfig } from '@langchain/core/runnables';
|
|
2
|
-
import { GthConfig } from '#src/config.js';
|
|
2
|
+
import { GthConfig, PromptSegmentName } from '#src/config.js';
|
|
3
|
+
import type { GthCommand } from '#src/core/types.js';
|
|
3
4
|
import { SystemMessage } from '@langchain/core/messages';
|
|
4
5
|
/**
|
|
5
6
|
* Creates new runnable config.
|
|
@@ -8,14 +9,43 @@ import { SystemMessage } from '@langchain/core/messages';
|
|
|
8
9
|
* and in another prototype project where I was importing Gaunt Sloth.
|
|
9
10
|
*/
|
|
10
11
|
export declare function getNewRunnableConfig(recursionLimit?: number): RunnableConfig;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
/** The config slice every prompt-segment read needs. */
|
|
13
|
+
type PromptReadConfig = Pick<GthConfig, 'prompts' | 'identityProfile' | 'noDefaultPrompts'>;
|
|
14
|
+
/**
|
|
15
|
+
* GS2-43 — the single composition point for one prompt segment, honouring the segment's
|
|
16
|
+
* `prompts.<segment>` config:
|
|
17
|
+
* - no setting → the segment's default-named file ({@link PROMPT_SEGMENT_FILES}), falling back
|
|
18
|
+
* to the bundled default unless `noDefaultPrompts` — exactly the pre-GS2-43 behaviour;
|
|
19
|
+
* - a `string` → shorthand for `{ path }`;
|
|
20
|
+
* - `enabled: false` → the segment is dropped entirely (returns `''`), even its bundled default;
|
|
21
|
+
* - `path` + `mode: 'replace'` (default) → the file replaces the built-in segment content;
|
|
22
|
+
* - `path` + `mode: 'append'` → the file content is appended after the built-in content.
|
|
23
|
+
*/
|
|
24
|
+
export declare function readPromptSegment(segment: PromptSegmentName, config: PromptReadConfig): string;
|
|
25
|
+
export declare function readBackstory(config: PromptReadConfig): string;
|
|
26
|
+
export declare function readGuidelines(config: Pick<GthConfig, 'prompts' | 'includeCurrentDateAfterGuidelines' | 'organization' | 'identityProfile' | 'noDefaultPrompts'> | string): string;
|
|
27
|
+
export declare function readReviewInstructions(config: PromptReadConfig | string): string;
|
|
28
|
+
export declare function readSystemPrompt(config: PromptReadConfig): string;
|
|
29
|
+
export declare function readChatPrompt(config: PromptReadConfig): string;
|
|
16
30
|
export declare function buildSystemMessages(config: GthConfig, modePrompt?: string | null): SystemMessage[];
|
|
17
|
-
export declare function readCodePrompt(config:
|
|
18
|
-
export declare function readExecPrompt(config:
|
|
31
|
+
export declare function readCodePrompt(config: PromptReadConfig): string;
|
|
32
|
+
export declare function readExecPrompt(config: PromptReadConfig): string;
|
|
33
|
+
/**
|
|
34
|
+
* GS2-79 — the SINGLE place a command's mode prompt is chosen, for every site that composes a
|
|
35
|
+
* system prompt via {@link buildSystemMessages}: both agent backends and the subagent profiles.
|
|
36
|
+
*
|
|
37
|
+
* It exists because the selection used to be an inline three-branch ternary copied to each of
|
|
38
|
+
* those sites, and a command missing from one copy is silently served the CHAT prompt — the
|
|
39
|
+
* default branch — rather than failing. That is how `review`/`pr` came to compose the chat prompt
|
|
40
|
+
* while the review instructions were smuggled in as a caller-side leading `SystemMessage`, which
|
|
41
|
+
* Anthropic rejects outright ("System messages are only permitted as the first passed message").
|
|
42
|
+
* One function means a new command is wired once, and `review`/`pr` cannot silently fall back to
|
|
43
|
+
* chat again.
|
|
44
|
+
*
|
|
45
|
+
* `review`/`pr` resolve to the REVIEW INSTRUCTIONS (`.gsloth.review.md`), which is what makes a
|
|
46
|
+
* review a review; every command without a mode prompt of its own keeps the chat prompt.
|
|
47
|
+
*/
|
|
48
|
+
export declare function readModePrompt(command: GthCommand | undefined, config: PromptReadConfig): string;
|
|
19
49
|
/**
|
|
20
50
|
* Read a prompt file from the project config dir (honouring identity profiles), falling back
|
|
21
51
|
* to a packaged default unless `noDefaultPrompts` is set. Downstream packages owning their own
|
|
@@ -45,3 +75,4 @@ export declare function formatToolCalls(toolCalls: Array<{
|
|
|
45
75
|
name: string;
|
|
46
76
|
args?: Record<string, unknown>;
|
|
47
77
|
}>, maxLength?: number): string;
|
|
78
|
+
export {};
|
package/dist/utils/llmUtils.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { GSLOTH_BACKSTORY, GSLOTH_CHAT_PROMPT, GSLOTH_CODE_PROMPT, GSLOTH_EXEC_PROMPT, GSLOTH_SYSTEM_PROMPT, } from '#src/constants.js';
|
|
2
|
+
import { GSLOTH_BACKSTORY, GSLOTH_CHAT_PROMPT, GSLOTH_CODE_PROMPT, GSLOTH_EXEC_PROMPT, GSLOTH_SYSTEM_PROMPT, PROJECT_GUIDELINES, PROJECT_REVIEW_INSTRUCTIONS, } from '#src/constants.js';
|
|
3
3
|
import { getGslothConfigReadPath, readFileFromInstallDir } from '#src/utils/fileUtils.js';
|
|
4
4
|
import { existsSync, readFileSync } from 'node:fs';
|
|
5
5
|
import { debugLog } from '#src/utils/debugUtils.js';
|
|
@@ -17,14 +17,54 @@ export function getNewRunnableConfig(recursionLimit = 1000) {
|
|
|
17
17
|
configurable: { thread_id: randomUUID() },
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* GS2-43 — each prompt segment's default-named file. The `prompts.<segment>` config retargets,
|
|
22
|
+
* disables, or composes against these; with no config the segment resolves exactly as before
|
|
23
|
+
* (config-dir/project file of this name, else the bundled default).
|
|
24
|
+
*/
|
|
25
|
+
const PROMPT_SEGMENT_FILES = {
|
|
26
|
+
backstory: GSLOTH_BACKSTORY,
|
|
27
|
+
guidelines: PROJECT_GUIDELINES,
|
|
28
|
+
system: GSLOTH_SYSTEM_PROMPT,
|
|
29
|
+
chat: GSLOTH_CHAT_PROMPT,
|
|
30
|
+
code: GSLOTH_CODE_PROMPT,
|
|
31
|
+
exec: GSLOTH_EXEC_PROMPT,
|
|
32
|
+
review: PROJECT_REVIEW_INSTRUCTIONS,
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* GS2-43 — the single composition point for one prompt segment, honouring the segment's
|
|
36
|
+
* `prompts.<segment>` config:
|
|
37
|
+
* - no setting → the segment's default-named file ({@link PROMPT_SEGMENT_FILES}), falling back
|
|
38
|
+
* to the bundled default unless `noDefaultPrompts` — exactly the pre-GS2-43 behaviour;
|
|
39
|
+
* - a `string` → shorthand for `{ path }`;
|
|
40
|
+
* - `enabled: false` → the segment is dropped entirely (returns `''`), even its bundled default;
|
|
41
|
+
* - `path` + `mode: 'replace'` (default) → the file replaces the built-in segment content;
|
|
42
|
+
* - `path` + `mode: 'append'` → the file content is appended after the built-in content.
|
|
43
|
+
*/
|
|
44
|
+
export function readPromptSegment(segment, config) {
|
|
45
|
+
const setting = config.prompts?.[segment];
|
|
46
|
+
const segmentConfig = typeof setting === 'string' ? { path: setting } : (setting ?? {});
|
|
47
|
+
if (segmentConfig.enabled === false) {
|
|
48
|
+
return '';
|
|
49
|
+
}
|
|
50
|
+
const readBuiltIn = () => readPromptFile(PROMPT_SEGMENT_FILES[segment], config.identityProfile, config.noDefaultPrompts);
|
|
51
|
+
if (!segmentConfig.path) {
|
|
52
|
+
return readBuiltIn();
|
|
53
|
+
}
|
|
54
|
+
const fileContent = readPromptFile(segmentConfig.path, config.identityProfile, config.noDefaultPrompts);
|
|
55
|
+
if (segmentConfig.mode === 'append') {
|
|
56
|
+
return [readBuiltIn(), fileContent].filter(Boolean).join('\n');
|
|
57
|
+
}
|
|
58
|
+
return fileContent;
|
|
59
|
+
}
|
|
20
60
|
export function readBackstory(config) {
|
|
21
|
-
return
|
|
61
|
+
return readPromptSegment('backstory', config);
|
|
22
62
|
}
|
|
23
63
|
export function readGuidelines(config) {
|
|
24
64
|
if (typeof config === 'string') {
|
|
25
65
|
return readPromptFile(config, undefined);
|
|
26
66
|
}
|
|
27
|
-
const guidelines =
|
|
67
|
+
const guidelines = readPromptSegment('guidelines', config);
|
|
28
68
|
if (config.includeCurrentDateAfterGuidelines) {
|
|
29
69
|
const currentDate = new Date();
|
|
30
70
|
const orgName = config.organization?.name;
|
|
@@ -51,13 +91,13 @@ export function readReviewInstructions(config) {
|
|
|
51
91
|
if (typeof config === 'string') {
|
|
52
92
|
return readPromptFile(config, undefined);
|
|
53
93
|
}
|
|
54
|
-
return
|
|
94
|
+
return readPromptSegment('review', config);
|
|
55
95
|
}
|
|
56
96
|
export function readSystemPrompt(config) {
|
|
57
|
-
return
|
|
97
|
+
return readPromptSegment('system', config);
|
|
58
98
|
}
|
|
59
99
|
export function readChatPrompt(config) {
|
|
60
|
-
return
|
|
100
|
+
return readPromptSegment('chat', config);
|
|
61
101
|
}
|
|
62
102
|
export function buildSystemMessages(config, modePrompt) {
|
|
63
103
|
const parts = [readBackstory(config), readGuidelines(config)];
|
|
@@ -70,10 +110,38 @@ export function buildSystemMessages(config, modePrompt) {
|
|
|
70
110
|
return content.trim() ? [new SystemMessage(content)] : [];
|
|
71
111
|
}
|
|
72
112
|
export function readCodePrompt(config) {
|
|
73
|
-
return
|
|
113
|
+
return readPromptSegment('code', config);
|
|
74
114
|
}
|
|
75
115
|
export function readExecPrompt(config) {
|
|
76
|
-
return
|
|
116
|
+
return readPromptSegment('exec', config);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* GS2-79 — the SINGLE place a command's mode prompt is chosen, for every site that composes a
|
|
120
|
+
* system prompt via {@link buildSystemMessages}: both agent backends and the subagent profiles.
|
|
121
|
+
*
|
|
122
|
+
* It exists because the selection used to be an inline three-branch ternary copied to each of
|
|
123
|
+
* those sites, and a command missing from one copy is silently served the CHAT prompt — the
|
|
124
|
+
* default branch — rather than failing. That is how `review`/`pr` came to compose the chat prompt
|
|
125
|
+
* while the review instructions were smuggled in as a caller-side leading `SystemMessage`, which
|
|
126
|
+
* Anthropic rejects outright ("System messages are only permitted as the first passed message").
|
|
127
|
+
* One function means a new command is wired once, and `review`/`pr` cannot silently fall back to
|
|
128
|
+
* chat again.
|
|
129
|
+
*
|
|
130
|
+
* `review`/`pr` resolve to the REVIEW INSTRUCTIONS (`.gsloth.review.md`), which is what makes a
|
|
131
|
+
* review a review; every command without a mode prompt of its own keeps the chat prompt.
|
|
132
|
+
*/
|
|
133
|
+
export function readModePrompt(command, config) {
|
|
134
|
+
switch (command) {
|
|
135
|
+
case 'code':
|
|
136
|
+
return readCodePrompt(config);
|
|
137
|
+
case 'exec':
|
|
138
|
+
return readExecPrompt(config);
|
|
139
|
+
case 'review':
|
|
140
|
+
case 'pr':
|
|
141
|
+
return readReviewInstructions(config);
|
|
142
|
+
default:
|
|
143
|
+
return readChatPrompt(config);
|
|
144
|
+
}
|
|
77
145
|
}
|
|
78
146
|
/**
|
|
79
147
|
* Read a prompt file from the project config dir (honouring identity profiles), falling back
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llmUtils.js","sourceRoot":"","sources":["../../src/utils/llmUtils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"llmUtils.js","sourceRoot":"","sources":["../../src/utils/llmUtils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* GS2-47 — a shared, reusable secret-redaction pass for diagnostic output.
|
|
4
|
+
*
|
|
5
|
+
* Built for `/debug-dump` ({@link file://./debugDump.ts}) but deliberately generic and
|
|
6
|
+
* dependency-free — it takes `env` as a PARAMETER rather than reading `process.env`, so the pass is
|
|
7
|
+
* pure, deterministic in tests, and reusable by GS2-48's crash-report handler (which hard-depends on
|
|
8
|
+
* this module). Nothing here reads ambient process state.
|
|
9
|
+
*
|
|
10
|
+
* DESIGN DECISION (settled by the coordinator, GS2-47): **PATTERN-ONLY** redaction — we do NOT scan
|
|
11
|
+
* for high-entropy strings. Rationale: pattern-only is safe to reason about and near-zero
|
|
12
|
+
* false-positive; entropy scanning catches marginally more but produces false-positive redactions
|
|
13
|
+
* the user has to squint through, degrading the dump's debug value. A high-entropy scanner is a
|
|
14
|
+
* DELIBERATELY-DEFERRED option (a config surface for it could be added later if ever warranted) and
|
|
15
|
+
* is intentionally NOT implemented here.
|
|
16
|
+
*
|
|
17
|
+
* Three techniques, in priority order:
|
|
18
|
+
* 1. [load-bearing] Known-secret VALUE substitution — collect the literal values of secret-named
|
|
19
|
+
* env vars + inline config secrets, then substitute every occurrence across ALL artifacts. This
|
|
20
|
+
* catches a leaked key wherever it surfaces (config, env, transcript, log) with no guessing.
|
|
21
|
+
* 2. Provider key/token PATTERNS — a tight, documented, prefix-anchored set of well-known key
|
|
22
|
+
* shapes plus explicit auth-header contexts. We never blanket-redact long alphanumeric strings.
|
|
23
|
+
* 3. Sensitive config-FIELD masking — mask the VALUES of secret-named config keys while preserving
|
|
24
|
+
* structure (the key stays; only the value becomes the marker).
|
|
25
|
+
*
|
|
26
|
+
* Fail-safe throughout: on any internal error the functions redact MORE (return the marker), never
|
|
27
|
+
* less — a redaction hiccup must never cause raw content to be emitted.
|
|
28
|
+
*/
|
|
29
|
+
/** The visible, greppable placeholder substituted for every redacted secret value. */
|
|
30
|
+
export declare const REDACTED = "<redacted>";
|
|
31
|
+
/**
|
|
32
|
+
* Collect the literal secret VALUES to substitute everywhere (technique 1), from two sources:
|
|
33
|
+
* - process-env vars whose NAME matches {@link SECRET_ENV_NAME_RE}, PLUS the specific var(s) named
|
|
34
|
+
* by any `apiKeyEnvironmentVariable` in the config;
|
|
35
|
+
* - non-empty inline secret field values in the config (technique 3's field names), so a key pasted
|
|
36
|
+
* inline is scrubbed wherever it *also* surfaces (transcript, log, env), not only in config.json.
|
|
37
|
+
*
|
|
38
|
+
* `env` is a PARAMETER — never read ambiently — so the pass is pure, reusable (GS2-48) and
|
|
39
|
+
* deterministic in tests. Values shorter than {@link MIN_SECRET_LITERAL_LENGTH} are skipped. The
|
|
40
|
+
* result is returned longest-first so an overlapping-substring secret can't leave a shorter one
|
|
41
|
+
* partially intact. Never throws (a hostile config getter is swallowed — patterns + structural
|
|
42
|
+
* masking still apply).
|
|
43
|
+
*/
|
|
44
|
+
export declare function collectSecretValues(config: unknown, env: Record<string, string | undefined>): string[];
|
|
45
|
+
/**
|
|
46
|
+
* Redact a STRING: substitute every known literal secret value (technique 1, longest-first), then
|
|
47
|
+
* apply the provider key/auth patterns (technique 2). Never throws — on any error it returns the
|
|
48
|
+
* fully-withheld marker (fail safe: redact MORE, never emit the raw text). Applying it twice is
|
|
49
|
+
* safe (re-redacting already-redacted text is a no-op).
|
|
50
|
+
*/
|
|
51
|
+
export declare function redactText(text: string, secrets: readonly string[]): string;
|
|
52
|
+
/**
|
|
53
|
+
* Deep-redact an arbitrary value for serialization: mask the VALUES of secret-named fields
|
|
54
|
+
* (technique 3 — structure preserved: the key stays, only its value becomes the marker) and run
|
|
55
|
+
* {@link redactText} over every string leaf (techniques 1 + 2). Circular refs are broken; functions
|
|
56
|
+
* and bigints are rendered the way `safeStringify` would, so the result is JSON-safe. Pure — never
|
|
57
|
+
* mutates the input. `apiKeyEnvironmentVariable` is intentionally NOT masked (it is a var name).
|
|
58
|
+
*
|
|
59
|
+
* Intended for the CONFIG artifact (where field-name masking is wanted). Non-config artifacts use
|
|
60
|
+
* {@link redactText} over their stringified form instead (literal + pattern only), so a legitimate
|
|
61
|
+
* `token`/`secret`-named field in tool output is not blanket-masked.
|
|
62
|
+
*/
|
|
63
|
+
export declare function redactValue(value: unknown, secrets: readonly string[]): unknown;
|