@probelabs/probe 0.6.0-rc263 → 0.6.0-rc265
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/bin/binaries/probe-v0.6.0-rc265-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc265-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc265-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc265-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc265-x86_64-unknown-linux-musl.tar.gz +0 -0
- package/build/agent/ProbeAgent.js +1 -0
- package/build/agent/bashExecutor.js +233 -7
- package/build/agent/index.js +244 -67
- package/build/agent/shared/prompts.js +25 -2
- package/build/tools/edit.js +7 -0
- package/cjs/agent/ProbeAgent.cjs +410 -80
- package/cjs/index.cjs +410 -80
- package/package.json +2 -2
- package/src/agent/ProbeAgent.js +1 -0
- package/src/agent/bashExecutor.js +233 -7
- package/src/agent/shared/prompts.js +25 -2
- package/src/tools/edit.js +7 -0
- package/bin/binaries/probe-v0.6.0-rc263-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc263-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc263-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc263-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc263-x86_64-unknown-linux-musl.tar.gz +0 -0
package/build/agent/index.js
CHANGED
|
@@ -9553,6 +9553,11 @@ Example: <extract><targets>${displayPath}</targets></extract>`;
|
|
|
9553
9553
|
if (!replace_all && occurrences > 1) {
|
|
9554
9554
|
return `Error editing file: Multiple occurrences found - the old_string appears ${occurrences} times in ${file_path}. To fix: (1) Set replace_all=true to replace all occurrences, or (2) Include more surrounding lines in old_string to make the match unique (add the full line or adjacent lines for context).`;
|
|
9555
9555
|
}
|
|
9556
|
+
const oldLines = matchTarget.split("\n").length;
|
|
9557
|
+
const newLines = new_string.split("\n").length;
|
|
9558
|
+
if (oldLines >= 20 && newLines < oldLines * 0.5) {
|
|
9559
|
+
return `Error editing file: Edit scope too large \u2014 replacing ${oldLines} lines with ${newLines} lines risks accidental content deletion. To fix: (1) Use line-targeted editing (start_line/end_line) instead to constrain scope, or (2) Split into smaller, focused edits that each target only the lines you intend to change.`;
|
|
9560
|
+
}
|
|
9556
9561
|
let newContent;
|
|
9557
9562
|
if (replace_all) {
|
|
9558
9563
|
newContent = content.replaceAll(matchTarget, new_string);
|
|
@@ -12935,6 +12940,122 @@ var init_bashPermissions = __esm({
|
|
|
12935
12940
|
import { spawn as spawn2 } from "child_process";
|
|
12936
12941
|
import { resolve as resolve3, join } from "path";
|
|
12937
12942
|
import { existsSync as existsSync2 } from "fs";
|
|
12943
|
+
function splitCommandComponents(command) {
|
|
12944
|
+
const parts = [];
|
|
12945
|
+
let current2 = "";
|
|
12946
|
+
let inQuote = false;
|
|
12947
|
+
let quoteChar = "";
|
|
12948
|
+
for (let i = 0; i < command.length; i++) {
|
|
12949
|
+
const c = command[i];
|
|
12950
|
+
const next = command[i + 1] || "";
|
|
12951
|
+
if (c === "\\" && !inQuote) {
|
|
12952
|
+
current2 += c + next;
|
|
12953
|
+
i++;
|
|
12954
|
+
continue;
|
|
12955
|
+
}
|
|
12956
|
+
if (inQuote && quoteChar === '"' && c === "\\" && next) {
|
|
12957
|
+
current2 += c + next;
|
|
12958
|
+
i++;
|
|
12959
|
+
continue;
|
|
12960
|
+
}
|
|
12961
|
+
if (!inQuote && (c === '"' || c === "'")) {
|
|
12962
|
+
inQuote = true;
|
|
12963
|
+
quoteChar = c;
|
|
12964
|
+
current2 += c;
|
|
12965
|
+
continue;
|
|
12966
|
+
}
|
|
12967
|
+
if (inQuote && c === quoteChar) {
|
|
12968
|
+
inQuote = false;
|
|
12969
|
+
current2 += c;
|
|
12970
|
+
continue;
|
|
12971
|
+
}
|
|
12972
|
+
if (!inQuote) {
|
|
12973
|
+
if (c === "&" && next === "&" || c === "|" && next === "|") {
|
|
12974
|
+
if (current2.trim()) parts.push(current2.trim());
|
|
12975
|
+
current2 = "";
|
|
12976
|
+
i++;
|
|
12977
|
+
continue;
|
|
12978
|
+
}
|
|
12979
|
+
if (c === "|" || c === ";") {
|
|
12980
|
+
if (current2.trim()) parts.push(current2.trim());
|
|
12981
|
+
current2 = "";
|
|
12982
|
+
continue;
|
|
12983
|
+
}
|
|
12984
|
+
}
|
|
12985
|
+
current2 += c;
|
|
12986
|
+
}
|
|
12987
|
+
if (current2.trim()) parts.push(current2.trim());
|
|
12988
|
+
return parts;
|
|
12989
|
+
}
|
|
12990
|
+
function checkSingleCommandInteractive(command) {
|
|
12991
|
+
let effective = command.trim();
|
|
12992
|
+
while (/^\w+=\S*\s/.test(effective)) {
|
|
12993
|
+
effective = effective.replace(/^\w+=\S*\s+/, "");
|
|
12994
|
+
}
|
|
12995
|
+
const parts = effective.split(/\s+/);
|
|
12996
|
+
const base2 = parts[0];
|
|
12997
|
+
const args = parts.slice(1);
|
|
12998
|
+
if (["vi", "vim", "nvim", "nano", "emacs", "pico", "joe", "mcedit"].includes(base2)) {
|
|
12999
|
+
return `'${base2}' is an interactive editor and cannot run without a terminal. Use non-interactive file manipulation commands instead.`;
|
|
13000
|
+
}
|
|
13001
|
+
if (["less", "more"].includes(base2)) {
|
|
13002
|
+
return `'${base2}' is an interactive pager. Use 'cat', 'head', or 'tail' instead.`;
|
|
13003
|
+
}
|
|
13004
|
+
if (base2 === "git") {
|
|
13005
|
+
const sub = args[0];
|
|
13006
|
+
if (sub === "commit") {
|
|
13007
|
+
const hasNonInteractiveFlag = args.some(
|
|
13008
|
+
(a) => a === "-m" || a.startsWith("--message") || a === "-C" || a === "-c" || a.startsWith("--fixup") || a.startsWith("--squash") || a === "--allow-empty-message" || a === "--no-edit"
|
|
13009
|
+
);
|
|
13010
|
+
if (!hasNonInteractiveFlag) {
|
|
13011
|
+
return `Interactive command: 'git commit' opens an editor for the commit message. Use 'git commit -m "your message"' instead.`;
|
|
13012
|
+
}
|
|
13013
|
+
}
|
|
13014
|
+
if (sub === "rebase" && (args.includes("--continue") || args.includes("--skip"))) {
|
|
13015
|
+
return "Interactive command: 'git rebase --continue' opens an editor. Set environment variable GIT_EDITOR=true to accept default messages, e.g. pass env: {GIT_EDITOR: 'true'} or prepend GIT_EDITOR=true to the command.";
|
|
13016
|
+
}
|
|
13017
|
+
if (sub === "rebase" && (args.includes("-i") || args.includes("--interactive"))) {
|
|
13018
|
+
return "Interactive command: 'git rebase -i' requires an interactive editor. Interactive rebase cannot run without a terminal.";
|
|
13019
|
+
}
|
|
13020
|
+
if (sub === "merge" && !args.includes("--no-edit") && !args.includes("--no-commit") && !args.includes("--ff-only")) {
|
|
13021
|
+
return "Interactive command: 'git merge' may open an editor for the merge commit message. Add '--no-edit' to accept the default message.";
|
|
13022
|
+
}
|
|
13023
|
+
if (sub === "cherry-pick" && !args.includes("--no-edit")) {
|
|
13024
|
+
return "Interactive command: 'git cherry-pick' may open an editor. Add '--no-edit' to accept the default message.";
|
|
13025
|
+
}
|
|
13026
|
+
if (sub === "revert" && !args.includes("--no-edit")) {
|
|
13027
|
+
return "Interactive command: 'git revert' opens an editor. Add '--no-edit' to accept the default message.";
|
|
13028
|
+
}
|
|
13029
|
+
if (sub === "tag" && args.includes("-a") && !args.some((a) => a === "-m" || a.startsWith("--message"))) {
|
|
13030
|
+
return `Interactive command: 'git tag -a' opens an editor for the tag message. Use 'git tag -a <name> -m "message"' instead.`;
|
|
13031
|
+
}
|
|
13032
|
+
if (sub === "add" && (args.includes("-i") || args.includes("--interactive") || args.includes("-p") || args.includes("--patch"))) {
|
|
13033
|
+
return "Interactive command: 'git add -i/-p' requires interactive input. Use 'git add <files>' to stage specific files instead.";
|
|
13034
|
+
}
|
|
13035
|
+
}
|
|
13036
|
+
if (["python", "python3", "node", "irb", "ghci", "lua", "R", "ruby"].includes(base2) && args.length === 0) {
|
|
13037
|
+
return `Interactive command: '${base2}' without arguments starts an interactive REPL. Provide a script file or use '-c'/'--eval' for inline code.`;
|
|
13038
|
+
}
|
|
13039
|
+
if (base2 === "mysql" && !args.some((a) => a === "-e" || a.startsWith("--execute"))) {
|
|
13040
|
+
return `Interactive command: 'mysql' without -e flag starts an interactive session. Use 'mysql -e "SQL QUERY"' instead.`;
|
|
13041
|
+
}
|
|
13042
|
+
if (base2 === "psql" && !args.some((a) => a === "-c" || a.startsWith("--command") || a === "-f" || a.startsWith("--file"))) {
|
|
13043
|
+
return `Interactive command: 'psql' without -c flag starts an interactive session. Use 'psql -c "SQL QUERY"' instead.`;
|
|
13044
|
+
}
|
|
13045
|
+
if (["top", "htop", "btop", "nmon"].includes(base2)) {
|
|
13046
|
+
return `Interactive command: '${base2}' is an interactive TUI tool. Use 'ps aux' or 'top -b -n 1' for non-interactive process listing.`;
|
|
13047
|
+
}
|
|
13048
|
+
return null;
|
|
13049
|
+
}
|
|
13050
|
+
function checkInteractiveCommand(command) {
|
|
13051
|
+
if (!command || typeof command !== "string") return null;
|
|
13052
|
+
const components = splitCommandComponents(command.trim());
|
|
13053
|
+
for (const component of components) {
|
|
13054
|
+
const result = checkSingleCommandInteractive(component);
|
|
13055
|
+
if (result) return result;
|
|
13056
|
+
}
|
|
13057
|
+
return null;
|
|
13058
|
+
}
|
|
12938
13059
|
async function executeBashCommand(command, options = {}) {
|
|
12939
13060
|
const {
|
|
12940
13061
|
workingDirectory = process.cwd(),
|
|
@@ -12964,6 +13085,24 @@ async function executeBashCommand(command, options = {}) {
|
|
|
12964
13085
|
};
|
|
12965
13086
|
}
|
|
12966
13087
|
const startTime = Date.now();
|
|
13088
|
+
const interactiveError = checkInteractiveCommand(command);
|
|
13089
|
+
if (interactiveError) {
|
|
13090
|
+
if (debug) {
|
|
13091
|
+
console.log(`[BashExecutor] Blocked interactive command: "${command}"`);
|
|
13092
|
+
console.log(`[BashExecutor] Reason: ${interactiveError}`);
|
|
13093
|
+
}
|
|
13094
|
+
return {
|
|
13095
|
+
success: false,
|
|
13096
|
+
error: interactiveError,
|
|
13097
|
+
stdout: "",
|
|
13098
|
+
stderr: interactiveError,
|
|
13099
|
+
exitCode: 1,
|
|
13100
|
+
command,
|
|
13101
|
+
workingDirectory: cwd,
|
|
13102
|
+
duration: 0,
|
|
13103
|
+
interactive: true
|
|
13104
|
+
};
|
|
13105
|
+
}
|
|
12967
13106
|
if (debug) {
|
|
12968
13107
|
console.log(`[BashExecutor] Executing command: "${command}"`);
|
|
12969
13108
|
console.log(`[BashExecutor] Working directory: "${cwd}"`);
|
|
@@ -12974,6 +13113,8 @@ async function executeBashCommand(command, options = {}) {
|
|
|
12974
13113
|
...process.env,
|
|
12975
13114
|
...env
|
|
12976
13115
|
};
|
|
13116
|
+
if (!processEnv.GIT_EDITOR) processEnv.GIT_EDITOR = "true";
|
|
13117
|
+
if (!processEnv.GIT_TERMINAL_PROMPT) processEnv.GIT_TERMINAL_PROMPT = "0";
|
|
12977
13118
|
const isComplex = isComplexCommand(command);
|
|
12978
13119
|
let cmd, cmdArgs, useShell;
|
|
12979
13120
|
if (isComplex) {
|
|
@@ -13008,20 +13149,32 @@ async function executeBashCommand(command, options = {}) {
|
|
|
13008
13149
|
// stdin ignored, capture stdout/stderr
|
|
13009
13150
|
shell: useShell,
|
|
13010
13151
|
// false for security
|
|
13152
|
+
detached: true,
|
|
13153
|
+
// new session — no controlling terminal
|
|
13011
13154
|
windowsHide: true
|
|
13012
13155
|
});
|
|
13013
13156
|
let stdout = "";
|
|
13014
13157
|
let stderr = "";
|
|
13015
13158
|
let killed = false;
|
|
13016
13159
|
let timeoutHandle;
|
|
13160
|
+
const killProcessGroup = (signal) => {
|
|
13161
|
+
try {
|
|
13162
|
+
if (child.pid) process.kill(-child.pid, signal);
|
|
13163
|
+
} catch {
|
|
13164
|
+
try {
|
|
13165
|
+
child.kill(signal);
|
|
13166
|
+
} catch {
|
|
13167
|
+
}
|
|
13168
|
+
}
|
|
13169
|
+
};
|
|
13017
13170
|
if (timeout > 0) {
|
|
13018
13171
|
timeoutHandle = setTimeout(() => {
|
|
13019
13172
|
if (!killed) {
|
|
13020
13173
|
killed = true;
|
|
13021
|
-
|
|
13174
|
+
killProcessGroup("SIGTERM");
|
|
13022
13175
|
setTimeout(() => {
|
|
13023
13176
|
if (child.exitCode === null) {
|
|
13024
|
-
|
|
13177
|
+
killProcessGroup("SIGKILL");
|
|
13025
13178
|
}
|
|
13026
13179
|
}, 5e3);
|
|
13027
13180
|
}
|
|
@@ -13034,7 +13187,7 @@ async function executeBashCommand(command, options = {}) {
|
|
|
13034
13187
|
} else {
|
|
13035
13188
|
if (!killed) {
|
|
13036
13189
|
killed = true;
|
|
13037
|
-
|
|
13190
|
+
killProcessGroup("SIGTERM");
|
|
13038
13191
|
}
|
|
13039
13192
|
}
|
|
13040
13193
|
});
|
|
@@ -13045,7 +13198,7 @@ async function executeBashCommand(command, options = {}) {
|
|
|
13045
13198
|
} else {
|
|
13046
13199
|
if (!killed) {
|
|
13047
13200
|
killed = true;
|
|
13048
|
-
|
|
13201
|
+
killProcessGroup("SIGTERM");
|
|
13049
13202
|
}
|
|
13050
13203
|
}
|
|
13051
13204
|
});
|
|
@@ -39381,7 +39534,6 @@ var init_reg_exp = __esm({
|
|
|
39381
39534
|
// node_modules/chevrotain/lib/src/scan/lexer.js
|
|
39382
39535
|
function analyzeTokenTypes(tokenTypes, options) {
|
|
39383
39536
|
options = defaults_default(options, {
|
|
39384
|
-
useSticky: SUPPORT_STICKY,
|
|
39385
39537
|
debug: false,
|
|
39386
39538
|
safeMode: false,
|
|
39387
39539
|
positionTracking: "full",
|
|
@@ -39430,7 +39582,7 @@ function analyzeTokenTypes(tokenTypes, options) {
|
|
|
39430
39582
|
], regExpSource[1])) {
|
|
39431
39583
|
return regExpSource[1];
|
|
39432
39584
|
} else {
|
|
39433
|
-
return
|
|
39585
|
+
return addStickyFlag(currPattern);
|
|
39434
39586
|
}
|
|
39435
39587
|
} else if (isFunction_default(currPattern)) {
|
|
39436
39588
|
hasCustom = true;
|
|
@@ -39444,7 +39596,7 @@ function analyzeTokenTypes(tokenTypes, options) {
|
|
|
39444
39596
|
} else {
|
|
39445
39597
|
const escapedRegExpString = currPattern.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
|
|
39446
39598
|
const wrappedRegExp = new RegExp(escapedRegExpString);
|
|
39447
|
-
return
|
|
39599
|
+
return addStickyFlag(wrappedRegExp);
|
|
39448
39600
|
}
|
|
39449
39601
|
} else {
|
|
39450
39602
|
throw Error("non exhaustive match");
|
|
@@ -39848,10 +40000,6 @@ function noMetaChar(regExp) {
|
|
|
39848
40000
|
function usesLookAheadOrBehind(regExp) {
|
|
39849
40001
|
return /(\(\?=)|(\(\?!)|(\(\?<=)|(\(\?<!)/.test(regExp.source);
|
|
39850
40002
|
}
|
|
39851
|
-
function addStartOfInput(pattern) {
|
|
39852
|
-
const flags = pattern.ignoreCase ? "i" : "";
|
|
39853
|
-
return new RegExp(`^(?:${pattern.source})`, flags);
|
|
39854
|
-
}
|
|
39855
40003
|
function addStickyFlag(pattern) {
|
|
39856
40004
|
const flags = pattern.ignoreCase ? "iy" : "y";
|
|
39857
40005
|
return new RegExp(`${pattern.source}`, flags);
|
|
@@ -40040,7 +40188,7 @@ function initCharCodeToOptimizedIndexMap() {
|
|
|
40040
40188
|
}
|
|
40041
40189
|
}
|
|
40042
40190
|
}
|
|
40043
|
-
var PATTERN, DEFAULT_MODE, MODES,
|
|
40191
|
+
var PATTERN, DEFAULT_MODE, MODES, end_of_input, start_of_input, LineTerminatorOptimizedTester, minOptimizationVal, charCodeToOptimizedIdxMap;
|
|
40044
40192
|
var init_lexer = __esm({
|
|
40045
40193
|
"node_modules/chevrotain/lib/src/scan/lexer.js"() {
|
|
40046
40194
|
init_api3();
|
|
@@ -40052,7 +40200,6 @@ var init_lexer = __esm({
|
|
|
40052
40200
|
PATTERN = "PATTERN";
|
|
40053
40201
|
DEFAULT_MODE = "defaultMode";
|
|
40054
40202
|
MODES = "modes";
|
|
40055
|
-
SUPPORT_STICKY = typeof new RegExp("(?:)").sticky === "boolean";
|
|
40056
40203
|
end_of_input = /[^\\][$]/;
|
|
40057
40204
|
start_of_input = /[^\\[][\^]|^\^/;
|
|
40058
40205
|
LineTerminatorOptimizedTester = {
|
|
@@ -40368,13 +40515,6 @@ var init_lexer_public = __esm({
|
|
|
40368
40515
|
PRINT_WARNING(warningDescriptor.message);
|
|
40369
40516
|
});
|
|
40370
40517
|
this.TRACE_INIT("Choosing sub-methods implementations", () => {
|
|
40371
|
-
if (SUPPORT_STICKY) {
|
|
40372
|
-
this.chopInput = identity_default;
|
|
40373
|
-
this.match = this.matchWithTest;
|
|
40374
|
-
} else {
|
|
40375
|
-
this.updateLastIndex = noop_default;
|
|
40376
|
-
this.match = this.matchWithExec;
|
|
40377
|
-
}
|
|
40378
40518
|
if (hasOnlySingleMode) {
|
|
40379
40519
|
this.handleModes = noop_default;
|
|
40380
40520
|
}
|
|
@@ -40437,7 +40577,7 @@ var init_lexer_public = __esm({
|
|
|
40437
40577
|
// this method also used quite a bit of `!` none null assertions because it is too optimized
|
|
40438
40578
|
// for `tsc` to always understand it is "safe"
|
|
40439
40579
|
tokenizeInternal(text, initialMode) {
|
|
40440
|
-
let i, j, k, matchAltImage, longerAlt, matchedImage, payload, altPayload, imageLength, group, tokType, newToken, errLength,
|
|
40580
|
+
let i, j, k, matchAltImage, longerAlt, matchedImage, payload, altPayload, imageLength, group, tokType, newToken, errLength, msg, match2;
|
|
40441
40581
|
const orgText = text;
|
|
40442
40582
|
const orgLength = orgText.length;
|
|
40443
40583
|
let offset2 = 0;
|
|
@@ -40456,19 +40596,7 @@ var init_lexer_public = __esm({
|
|
|
40456
40596
|
const modeStack = [];
|
|
40457
40597
|
const emptyArray = [];
|
|
40458
40598
|
Object.freeze(emptyArray);
|
|
40459
|
-
let
|
|
40460
|
-
function getPossiblePatternsSlow() {
|
|
40461
|
-
return patternIdxToConfig;
|
|
40462
|
-
}
|
|
40463
|
-
function getPossiblePatternsOptimized(charCode) {
|
|
40464
|
-
const optimizedCharIdx = charCodeToOptimizedIndex(charCode);
|
|
40465
|
-
const possiblePatterns = currCharCodeToPatternIdxToConfig[optimizedCharIdx];
|
|
40466
|
-
if (possiblePatterns === void 0) {
|
|
40467
|
-
return emptyArray;
|
|
40468
|
-
} else {
|
|
40469
|
-
return possiblePatterns;
|
|
40470
|
-
}
|
|
40471
|
-
}
|
|
40599
|
+
let isOptimizedMode = false;
|
|
40472
40600
|
const pop_mode = (popToken) => {
|
|
40473
40601
|
if (modeStack.length === 1 && // if we have both a POP_MODE and a PUSH_MODE this is in-fact a "transition"
|
|
40474
40602
|
// So no error should occur.
|
|
@@ -40489,9 +40617,9 @@ var init_lexer_public = __esm({
|
|
|
40489
40617
|
currModePatternsLength = patternIdxToConfig.length;
|
|
40490
40618
|
const modeCanBeOptimized = this.canModeBeOptimized[newMode] && this.config.safeMode === false;
|
|
40491
40619
|
if (currCharCodeToPatternIdxToConfig && modeCanBeOptimized) {
|
|
40492
|
-
|
|
40620
|
+
isOptimizedMode = true;
|
|
40493
40621
|
} else {
|
|
40494
|
-
|
|
40622
|
+
isOptimizedMode = false;
|
|
40495
40623
|
}
|
|
40496
40624
|
}
|
|
40497
40625
|
};
|
|
@@ -40503,9 +40631,9 @@ var init_lexer_public = __esm({
|
|
|
40503
40631
|
currModePatternsLength = patternIdxToConfig.length;
|
|
40504
40632
|
const modeCanBeOptimized = this.canModeBeOptimized[newMode] && this.config.safeMode === false;
|
|
40505
40633
|
if (currCharCodeToPatternIdxToConfig && modeCanBeOptimized) {
|
|
40506
|
-
|
|
40634
|
+
isOptimizedMode = true;
|
|
40507
40635
|
} else {
|
|
40508
|
-
|
|
40636
|
+
isOptimizedMode = false;
|
|
40509
40637
|
}
|
|
40510
40638
|
}
|
|
40511
40639
|
push_mode.call(this, initialMode);
|
|
@@ -40513,8 +40641,16 @@ var init_lexer_public = __esm({
|
|
|
40513
40641
|
const recoveryEnabled = this.config.recoveryEnabled;
|
|
40514
40642
|
while (offset2 < orgLength) {
|
|
40515
40643
|
matchedImage = null;
|
|
40644
|
+
imageLength = -1;
|
|
40516
40645
|
const nextCharCode = orgText.charCodeAt(offset2);
|
|
40517
|
-
|
|
40646
|
+
let chosenPatternIdxToConfig;
|
|
40647
|
+
if (isOptimizedMode) {
|
|
40648
|
+
const optimizedCharIdx = charCodeToOptimizedIndex(nextCharCode);
|
|
40649
|
+
const possiblePatterns = currCharCodeToPatternIdxToConfig[optimizedCharIdx];
|
|
40650
|
+
chosenPatternIdxToConfig = possiblePatterns !== void 0 ? possiblePatterns : emptyArray;
|
|
40651
|
+
} else {
|
|
40652
|
+
chosenPatternIdxToConfig = patternIdxToConfig;
|
|
40653
|
+
}
|
|
40518
40654
|
const chosenPatternsLength = chosenPatternIdxToConfig.length;
|
|
40519
40655
|
for (i = 0; i < chosenPatternsLength; i++) {
|
|
40520
40656
|
currConfig = chosenPatternIdxToConfig[i];
|
|
@@ -40523,12 +40659,14 @@ var init_lexer_public = __esm({
|
|
|
40523
40659
|
const singleCharCode = currConfig.short;
|
|
40524
40660
|
if (singleCharCode !== false) {
|
|
40525
40661
|
if (nextCharCode === singleCharCode) {
|
|
40662
|
+
imageLength = 1;
|
|
40526
40663
|
matchedImage = currPattern;
|
|
40527
40664
|
}
|
|
40528
40665
|
} else if (currConfig.isCustom === true) {
|
|
40529
40666
|
match2 = currPattern.exec(orgText, offset2, matchedTokens, groups);
|
|
40530
40667
|
if (match2 !== null) {
|
|
40531
40668
|
matchedImage = match2[0];
|
|
40669
|
+
imageLength = matchedImage.length;
|
|
40532
40670
|
if (match2.payload !== void 0) {
|
|
40533
40671
|
payload = match2.payload;
|
|
40534
40672
|
}
|
|
@@ -40536,12 +40674,13 @@ var init_lexer_public = __esm({
|
|
|
40536
40674
|
matchedImage = null;
|
|
40537
40675
|
}
|
|
40538
40676
|
} else {
|
|
40539
|
-
|
|
40540
|
-
|
|
40677
|
+
currPattern.lastIndex = offset2;
|
|
40678
|
+
imageLength = this.matchLength(currPattern, text, offset2);
|
|
40541
40679
|
}
|
|
40542
|
-
if (
|
|
40680
|
+
if (imageLength !== -1) {
|
|
40543
40681
|
longerAlt = currConfig.longerAlt;
|
|
40544
40682
|
if (longerAlt !== void 0) {
|
|
40683
|
+
matchedImage = text.substring(offset2, offset2 + imageLength);
|
|
40545
40684
|
const longerAltLength = longerAlt.length;
|
|
40546
40685
|
for (k = 0; k < longerAltLength; k++) {
|
|
40547
40686
|
const longerAltConfig = patternIdxToConfig[longerAlt[k]];
|
|
@@ -40558,11 +40697,12 @@ var init_lexer_public = __esm({
|
|
|
40558
40697
|
matchAltImage = null;
|
|
40559
40698
|
}
|
|
40560
40699
|
} else {
|
|
40561
|
-
|
|
40700
|
+
longerAltPattern.lastIndex = offset2;
|
|
40562
40701
|
matchAltImage = this.match(longerAltPattern, text, offset2);
|
|
40563
40702
|
}
|
|
40564
40703
|
if (matchAltImage && matchAltImage.length > matchedImage.length) {
|
|
40565
40704
|
matchedImage = matchAltImage;
|
|
40705
|
+
imageLength = matchAltImage.length;
|
|
40566
40706
|
payload = altPayload;
|
|
40567
40707
|
currConfig = longerAltConfig;
|
|
40568
40708
|
break;
|
|
@@ -40572,10 +40712,10 @@ var init_lexer_public = __esm({
|
|
|
40572
40712
|
break;
|
|
40573
40713
|
}
|
|
40574
40714
|
}
|
|
40575
|
-
if (
|
|
40576
|
-
imageLength = matchedImage.length;
|
|
40715
|
+
if (imageLength !== -1) {
|
|
40577
40716
|
group = currConfig.group;
|
|
40578
40717
|
if (group !== void 0) {
|
|
40718
|
+
matchedImage = matchedImage !== null ? matchedImage : text.substring(offset2, offset2 + imageLength);
|
|
40579
40719
|
tokType = currConfig.tokenTypeIdx;
|
|
40580
40720
|
newToken = this.createTokenInstance(matchedImage, offset2, tokType, currConfig.tokenType, line, column, imageLength);
|
|
40581
40721
|
this.handlePayload(newToken, payload);
|
|
@@ -40585,15 +40725,13 @@ var init_lexer_public = __esm({
|
|
|
40585
40725
|
groups[group].push(newToken);
|
|
40586
40726
|
}
|
|
40587
40727
|
}
|
|
40588
|
-
text = this.chopInput(text, imageLength);
|
|
40589
|
-
offset2 = offset2 + imageLength;
|
|
40590
|
-
column = this.computeNewColumn(column, imageLength);
|
|
40591
40728
|
if (trackLines === true && currConfig.canLineTerminator === true) {
|
|
40592
40729
|
let numOfLTsInMatch = 0;
|
|
40593
40730
|
let foundTerminator;
|
|
40594
40731
|
let lastLTEndOffset;
|
|
40595
40732
|
lineTerminatorPattern.lastIndex = 0;
|
|
40596
40733
|
do {
|
|
40734
|
+
matchedImage = matchedImage !== null ? matchedImage : text.substring(offset2, offset2 + imageLength);
|
|
40597
40735
|
foundTerminator = lineTerminatorPattern.test(matchedImage);
|
|
40598
40736
|
if (foundTerminator === true) {
|
|
40599
40737
|
lastLTEndOffset = lineTerminatorPattern.lastIndex - 1;
|
|
@@ -40604,8 +40742,13 @@ var init_lexer_public = __esm({
|
|
|
40604
40742
|
line = line + numOfLTsInMatch;
|
|
40605
40743
|
column = imageLength - lastLTEndOffset;
|
|
40606
40744
|
this.updateTokenEndLineColumnLocation(newToken, group, lastLTEndOffset, numOfLTsInMatch, line, column, imageLength);
|
|
40745
|
+
} else {
|
|
40746
|
+
column = this.computeNewColumn(column, imageLength);
|
|
40607
40747
|
}
|
|
40748
|
+
} else {
|
|
40749
|
+
column = this.computeNewColumn(column, imageLength);
|
|
40608
40750
|
}
|
|
40751
|
+
offset2 = offset2 + imageLength;
|
|
40609
40752
|
this.handleModes(currConfig, pop_mode, push_mode, newToken);
|
|
40610
40753
|
} else {
|
|
40611
40754
|
const errorStartOffset = offset2;
|
|
@@ -40613,7 +40756,6 @@ var init_lexer_public = __esm({
|
|
|
40613
40756
|
const errorColumn = column;
|
|
40614
40757
|
let foundResyncPoint = recoveryEnabled === false;
|
|
40615
40758
|
while (foundResyncPoint === false && offset2 < orgLength) {
|
|
40616
|
-
text = this.chopInput(text, 1);
|
|
40617
40759
|
offset2++;
|
|
40618
40760
|
for (j = 0; j < currModePatternsLength; j++) {
|
|
40619
40761
|
const currConfig2 = patternIdxToConfig[j];
|
|
@@ -40626,7 +40768,7 @@ var init_lexer_public = __esm({
|
|
|
40626
40768
|
} else if (currConfig2.isCustom === true) {
|
|
40627
40769
|
foundResyncPoint = currPattern.exec(orgText, offset2, matchedTokens, groups) !== null;
|
|
40628
40770
|
} else {
|
|
40629
|
-
|
|
40771
|
+
currPattern.lastIndex = offset2;
|
|
40630
40772
|
foundResyncPoint = currPattern.exec(text) !== null;
|
|
40631
40773
|
}
|
|
40632
40774
|
if (foundResyncPoint === true) {
|
|
@@ -40669,12 +40811,6 @@ var init_lexer_public = __esm({
|
|
|
40669
40811
|
push_mode.call(this, config.push);
|
|
40670
40812
|
}
|
|
40671
40813
|
}
|
|
40672
|
-
chopInput(text, length) {
|
|
40673
|
-
return text.substring(length);
|
|
40674
|
-
}
|
|
40675
|
-
updateLastIndex(regExp, newLastIndex) {
|
|
40676
|
-
regExp.lastIndex = newLastIndex;
|
|
40677
|
-
}
|
|
40678
40814
|
// TODO: decrease this under 600 characters? inspect stripping comments option in TSC compiler
|
|
40679
40815
|
updateTokenEndLineColumnLocation(newToken, group, lastLTIdx, numOfLTsInMatch, line, column, imageLength) {
|
|
40680
40816
|
let lastCharIsLT, fixForEndingInLT;
|
|
@@ -40737,16 +40873,19 @@ var init_lexer_public = __esm({
|
|
|
40737
40873
|
token.payload = payload;
|
|
40738
40874
|
}
|
|
40739
40875
|
}
|
|
40740
|
-
|
|
40876
|
+
match(pattern, text, offset2) {
|
|
40741
40877
|
const found = pattern.test(text);
|
|
40742
40878
|
if (found === true) {
|
|
40743
40879
|
return text.substring(offset2, pattern.lastIndex);
|
|
40744
40880
|
}
|
|
40745
40881
|
return null;
|
|
40746
40882
|
}
|
|
40747
|
-
|
|
40748
|
-
const
|
|
40749
|
-
|
|
40883
|
+
matchLength(pattern, text, offset2) {
|
|
40884
|
+
const found = pattern.test(text);
|
|
40885
|
+
if (found === true) {
|
|
40886
|
+
return pattern.lastIndex - offset2;
|
|
40887
|
+
}
|
|
40888
|
+
return -1;
|
|
40750
40889
|
}
|
|
40751
40890
|
};
|
|
40752
40891
|
Lexer.SKIPPED = "This marks a skipped Token pattern, this means each token identified by it will be consumed and then thrown into oblivion, this can be used to for example to completely ignore whitespace.";
|
|
@@ -40938,12 +41077,20 @@ For Further details.`;
|
|
|
40938
41077
|
return errMsg;
|
|
40939
41078
|
},
|
|
40940
41079
|
buildAlternationAmbiguityError(options) {
|
|
40941
|
-
const pathMsg = map_default(options.prefixPath, (currtok) => tokenLabel2(currtok)).join(", ");
|
|
40942
41080
|
const occurrence = options.alternation.idx === 0 ? "" : options.alternation.idx;
|
|
41081
|
+
const isEmptyPath = options.prefixPath.length === 0;
|
|
40943
41082
|
let currMessage = `Ambiguous Alternatives Detected: <${options.ambiguityIndices.join(" ,")}> in <OR${occurrence}> inside <${options.topLevelRule.name}> Rule,
|
|
40944
|
-
<${pathMsg}> may appears as a prefix path in all these alternatives.
|
|
40945
41083
|
`;
|
|
40946
|
-
|
|
41084
|
+
if (isEmptyPath) {
|
|
41085
|
+
currMessage += `These alternatives are all empty (match no tokens), making them indistinguishable.
|
|
41086
|
+
Only the last alternative may be empty.
|
|
41087
|
+
`;
|
|
41088
|
+
} else {
|
|
41089
|
+
const pathMsg = map_default(options.prefixPath, (currtok) => tokenLabel2(currtok)).join(", ");
|
|
41090
|
+
currMessage += `<${pathMsg}> may appears as a prefix path in all these alternatives.
|
|
41091
|
+
`;
|
|
41092
|
+
}
|
|
41093
|
+
currMessage += `See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES
|
|
40947
41094
|
For Further details.`;
|
|
40948
41095
|
return currMessage;
|
|
40949
41096
|
},
|
|
@@ -47446,7 +47593,7 @@ function validateFlowchart(text, options = {}) {
|
|
|
47446
47593
|
const byLine = /* @__PURE__ */ new Map();
|
|
47447
47594
|
const collect = (arr) => {
|
|
47448
47595
|
for (const e of arr || []) {
|
|
47449
|
-
if (e && (e.code === "FL-LABEL-PARENS-UNQUOTED" || e.code === "FL-LABEL-AT-IN-UNQUOTED" || e.code === "FL-LABEL-QUOTE-IN-UNQUOTED")) {
|
|
47596
|
+
if (e && (e.code === "FL-LABEL-PARENS-UNQUOTED" || e.code === "FL-LABEL-AT-IN-UNQUOTED" || e.code === "FL-LABEL-QUOTE-IN-UNQUOTED" || e.code === "FL-LABEL-SLASH-UNQUOTED")) {
|
|
47450
47597
|
const ln = e.line ?? 0;
|
|
47451
47598
|
const col = e.column ?? 1;
|
|
47452
47599
|
const list = byLine.get(ln) || [];
|
|
@@ -47529,6 +47676,7 @@ function validateFlowchart(text, options = {}) {
|
|
|
47529
47676
|
const hasAt = seg.includes("@");
|
|
47530
47677
|
const hasQuote = seg.includes('"');
|
|
47531
47678
|
const isSingleQuoted = /^'[^]*'$/.test(trimmed);
|
|
47679
|
+
const hasLeadingSlash = lsp === "/" || lsp === "\\";
|
|
47532
47680
|
if (!covered && !isQuoted && !isParenWrapped && hasParens) {
|
|
47533
47681
|
errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-PARENS-UNQUOTED", message: "Parentheses inside an unquoted label are not supported by Mermaid.", hint: 'Wrap the label in quotes, e.g., A["Mark (X)"] \u2014 or replace ( and ) with HTML entities: ( and ).' });
|
|
47534
47682
|
existing.push({ start: startCol, end: endCol });
|
|
@@ -47539,6 +47687,11 @@ function validateFlowchart(text, options = {}) {
|
|
|
47539
47687
|
existing.push({ start: startCol, end: endCol });
|
|
47540
47688
|
byLine.set(ln, existing);
|
|
47541
47689
|
}
|
|
47690
|
+
if (!covered && !isQuoted && !isSlashPair && hasLeadingSlash) {
|
|
47691
|
+
errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-SLASH-UNQUOTED", message: "Leading / or \\ inside an unquoted label is treated as a shape marker by Mermaid.", hint: 'Wrap the label in quotes, e.g., F["/dev/tty unavailable"], or use / / \ for literal slashes.' });
|
|
47692
|
+
existing.push({ start: startCol, end: endCol });
|
|
47693
|
+
byLine.set(ln, existing);
|
|
47694
|
+
}
|
|
47542
47695
|
if (!covered && !isQuoted && !isSlashPair && hasQuote && !isSingleQuoted) {
|
|
47543
47696
|
errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-QUOTE-IN-UNQUOTED", message: "Quotes are not allowed inside unquoted node labels. Use " for quotes or wrap the entire label in quotes.", hint: 'Example: C["HTML Output: data-trigger-visibility="true""]' });
|
|
47544
47697
|
existing.push({ start: startCol, end: endCol });
|
|
@@ -50547,7 +50700,7 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
50547
50700
|
}
|
|
50548
50701
|
continue;
|
|
50549
50702
|
}
|
|
50550
|
-
if (is("FL-LABEL-PARENS-UNQUOTED", e) || is("FL-LABEL-AT-IN-UNQUOTED", e)) {
|
|
50703
|
+
if (is("FL-LABEL-PARENS-UNQUOTED", e) || is("FL-LABEL-AT-IN-UNQUOTED", e) || is("FL-LABEL-SLASH-UNQUOTED", e)) {
|
|
50551
50704
|
if (level === "safe" || level === "all") {
|
|
50552
50705
|
if (patchedLines.has(e.line))
|
|
50553
50706
|
continue;
|
|
@@ -71842,6 +71995,7 @@ If the solution is clear, you can jump to implementation right away. If not, ask
|
|
|
71842
71995
|
- Avoid implementing special cases when a general approach works
|
|
71843
71996
|
- Never expose secrets, API keys, or credentials in generated code. Never log sensitive information.
|
|
71844
71997
|
- Do not surprise the user with unrequested changes. Do what was asked, including reasonable follow-up actions, but do not refactor surrounding code or add features that were not requested.
|
|
71998
|
+
- When editing files, keep edits focused and minimal. For changes spanning more than a few lines, prefer line-targeted editing (start_line/end_line) over text replacement (old_string) \u2014 it constrains scope and prevents accidental removal of adjacent content. Never include unrelated sections in an edit operation.
|
|
71845
71999
|
- After every significant change, verify the project still builds and passes linting. Do not wait until the end to discover breakage.
|
|
71846
72000
|
|
|
71847
72001
|
# After Implementation
|
|
@@ -71852,11 +72006,33 @@ If the solution is clear, you can jump to implementation right away. If not, ask
|
|
|
71852
72006
|
|
|
71853
72007
|
# GitHub Integration
|
|
71854
72008
|
- Use the \`gh\` CLI for all GitHub operations: issues, pull requests, checks, releases.
|
|
71855
|
-
- To create a pull request: commit your changes, push the branch, then use \`gh pr create --title "..." --body "..."\`.
|
|
71856
72009
|
- To view issues or PRs: \`gh issue view <number>\`, \`gh pr view <number>\`.
|
|
71857
72010
|
- If given a GitHub URL, use \`gh\` to fetch the relevant information rather than guessing.
|
|
71858
72011
|
- Always return the pull request URL to the user after creating one.
|
|
71859
|
-
- When checking GitHub Actions, only read logs of failed jobs \u2014 do not waste time on successful ones. Use \`gh run view <run-id> --log-failed\` to fetch only the relevant output
|
|
72012
|
+
- When checking GitHub Actions, only read logs of failed jobs \u2014 do not waste time on successful ones. Use \`gh run view <run-id> --log-failed\` to fetch only the relevant output.
|
|
72013
|
+
|
|
72014
|
+
# Pull Request Creation
|
|
72015
|
+
- Commit your changes, push the branch, then use \`gh pr create --title "..." --body "..."\`.
|
|
72016
|
+
- **PR title**: Keep it short (under 72 characters). Use imperative mood describing the change (e.g. "Add retry logic for API calls", "Fix race condition in cache invalidation"). Prefix with the type of change when useful: \`fix:\`, \`feat:\`, \`refactor:\`, \`docs:\`, \`test:\`, \`chore:\`.
|
|
72017
|
+
- **PR body**: MUST follow this structure:
|
|
72018
|
+
|
|
72019
|
+
\`\`\`
|
|
72020
|
+
## Problem / Task
|
|
72021
|
+
<What problem is being solved or what task was requested. If there is a linked issue, reference it with #number. Be specific about the root cause or motivation.>
|
|
72022
|
+
|
|
72023
|
+
## Changes
|
|
72024
|
+
<Concise list of what was actually changed. Describe each meaningful change \u2014 files modified, logic added/removed, and why. Do NOT just list filenames; explain what each change does.>
|
|
72025
|
+
|
|
72026
|
+
## Testing
|
|
72027
|
+
<What tests were added, modified, or run. Include:
|
|
72028
|
+
- New test names and what they verify
|
|
72029
|
+
- Whether existing tests still pass
|
|
72030
|
+
- Manual verification steps if applicable
|
|
72031
|
+
- Commands used to validate (e.g. \`make test\`, \`npm test\`)>
|
|
72032
|
+
\`\`\`
|
|
72033
|
+
|
|
72034
|
+
- If the task originated from a GitHub issue, always reference it in the PR body (e.g. "Fixes #123" or "Closes #123") so the issue is automatically closed on merge. If it originated from an external ticket system (Jira, Linear, etc.), include the ticket ID and link in the Problem / Task section (e.g. "Resolves PROJ-456").
|
|
72035
|
+
- Do not leave the PR body empty or vague. Every PR must clearly communicate what was done and why so reviewers can understand the change without reading every line of diff.`,
|
|
71860
72036
|
"support": `You are ProbeChat Support, a specialized AI assistant focused on helping developers troubleshoot issues and solve problems. Your primary function is to help users diagnose errors, understand unexpected behaviors, and find solutions using the provided code analysis tools.
|
|
71861
72037
|
|
|
71862
72038
|
When troubleshooting:
|
|
@@ -85122,6 +85298,7 @@ Follow these instructions carefully:
|
|
|
85122
85298
|
* For rewriting entire functions/classes/methods, use the symbol parameter instead (no exact text matching needed).
|
|
85123
85299
|
* For editing specific lines from search/extract output, use start_line (and optionally end_line) with the line numbers shown in the output.${this.hashLines ? ' Line references include content hashes (e.g. "42:ab") for integrity verification.' : ""}
|
|
85124
85300
|
* For editing inside large functions: first use extract with the symbol target (e.g. "file.js#myFunction") to see the function with line numbers${this.hashLines ? " and hashes" : ""}, then use start_line/end_line to surgically edit specific lines within it.
|
|
85301
|
+
* IMPORTANT: Keep old_string as small as possible \u2014 include only the lines you need to change plus minimal context for uniqueness. For replacing large blocks (10+ lines), prefer line-targeted editing with start_line/end_line to constrain scope.
|
|
85125
85302
|
- Use 'create' for new files or complete file rewrites.
|
|
85126
85303
|
- If an edit fails, read the error message \u2014 it tells you exactly how to fix the call and retry.
|
|
85127
85304
|
- The system tracks which files you've seen via search/extract. If you try to edit a file you haven't read, or one that changed since you last read it, the edit will fail with instructions to re-read first. Always use extract before editing to ensure you have current file content.` : ""}
|
|
@@ -87,6 +87,7 @@ If the solution is clear, you can jump to implementation right away. If not, ask
|
|
|
87
87
|
- Avoid implementing special cases when a general approach works
|
|
88
88
|
- Never expose secrets, API keys, or credentials in generated code. Never log sensitive information.
|
|
89
89
|
- Do not surprise the user with unrequested changes. Do what was asked, including reasonable follow-up actions, but do not refactor surrounding code or add features that were not requested.
|
|
90
|
+
- When editing files, keep edits focused and minimal. For changes spanning more than a few lines, prefer line-targeted editing (start_line/end_line) over text replacement (old_string) — it constrains scope and prevents accidental removal of adjacent content. Never include unrelated sections in an edit operation.
|
|
90
91
|
- After every significant change, verify the project still builds and passes linting. Do not wait until the end to discover breakage.
|
|
91
92
|
|
|
92
93
|
# After Implementation
|
|
@@ -97,11 +98,33 @@ If the solution is clear, you can jump to implementation right away. If not, ask
|
|
|
97
98
|
|
|
98
99
|
# GitHub Integration
|
|
99
100
|
- Use the \`gh\` CLI for all GitHub operations: issues, pull requests, checks, releases.
|
|
100
|
-
- To create a pull request: commit your changes, push the branch, then use \`gh pr create --title "..." --body "..."\`.
|
|
101
101
|
- To view issues or PRs: \`gh issue view <number>\`, \`gh pr view <number>\`.
|
|
102
102
|
- If given a GitHub URL, use \`gh\` to fetch the relevant information rather than guessing.
|
|
103
103
|
- Always return the pull request URL to the user after creating one.
|
|
104
|
-
- When checking GitHub Actions, only read logs of failed jobs — do not waste time on successful ones. Use \`gh run view <run-id> --log-failed\` to fetch only the relevant output
|
|
104
|
+
- When checking GitHub Actions, only read logs of failed jobs — do not waste time on successful ones. Use \`gh run view <run-id> --log-failed\` to fetch only the relevant output.
|
|
105
|
+
|
|
106
|
+
# Pull Request Creation
|
|
107
|
+
- Commit your changes, push the branch, then use \`gh pr create --title "..." --body "..."\`.
|
|
108
|
+
- **PR title**: Keep it short (under 72 characters). Use imperative mood describing the change (e.g. "Add retry logic for API calls", "Fix race condition in cache invalidation"). Prefix with the type of change when useful: \`fix:\`, \`feat:\`, \`refactor:\`, \`docs:\`, \`test:\`, \`chore:\`.
|
|
109
|
+
- **PR body**: MUST follow this structure:
|
|
110
|
+
|
|
111
|
+
\`\`\`
|
|
112
|
+
## Problem / Task
|
|
113
|
+
<What problem is being solved or what task was requested. If there is a linked issue, reference it with #number. Be specific about the root cause or motivation.>
|
|
114
|
+
|
|
115
|
+
## Changes
|
|
116
|
+
<Concise list of what was actually changed. Describe each meaningful change — files modified, logic added/removed, and why. Do NOT just list filenames; explain what each change does.>
|
|
117
|
+
|
|
118
|
+
## Testing
|
|
119
|
+
<What tests were added, modified, or run. Include:
|
|
120
|
+
- New test names and what they verify
|
|
121
|
+
- Whether existing tests still pass
|
|
122
|
+
- Manual verification steps if applicable
|
|
123
|
+
- Commands used to validate (e.g. \`make test\`, \`npm test\`)>
|
|
124
|
+
\`\`\`
|
|
125
|
+
|
|
126
|
+
- If the task originated from a GitHub issue, always reference it in the PR body (e.g. "Fixes #123" or "Closes #123") so the issue is automatically closed on merge. If it originated from an external ticket system (Jira, Linear, etc.), include the ticket ID and link in the Problem / Task section (e.g. "Resolves PROJ-456").
|
|
127
|
+
- Do not leave the PR body empty or vague. Every PR must clearly communicate what was done and why so reviewers can understand the change without reading every line of diff.`,
|
|
105
128
|
|
|
106
129
|
'support': `You are ProbeChat Support, a specialized AI assistant focused on helping developers troubleshoot issues and solve problems. Your primary function is to help users diagnose errors, understand unexpected behaviors, and find solutions using the provided code analysis tools.
|
|
107
130
|
|