@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.
@@ -17506,7 +17506,7 @@ var require_package2 = __commonJS({
17506
17506
  module2.exports = {
17507
17507
  name: "@aws-sdk/client-bedrock-runtime",
17508
17508
  description: "AWS SDK for JavaScript Bedrock Runtime Client for Node.js, Browser and React Native",
17509
- version: "3.999.0",
17509
+ version: "3.1000.0",
17510
17510
  scripts: {
17511
17511
  build: "concurrently 'yarn:build:types' 'yarn:build:es' && yarn build:cjs",
17512
17512
  "build:cjs": "node ../../scripts/compilation/inline client-bedrock-runtime",
@@ -17517,7 +17517,11 @@ var require_package2 = __commonJS({
17517
17517
  clean: "premove dist-cjs dist-es dist-types tsconfig.cjs.tsbuildinfo tsconfig.es.tsbuildinfo tsconfig.types.tsbuildinfo",
17518
17518
  "extract:docs": "api-extractor run --local",
17519
17519
  "generate:client": "node ../../scripts/generate-clients/single-service --solo bedrock-runtime",
17520
- "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs"
17520
+ test: "yarn g:vitest run --passWithNoTests",
17521
+ "test:index": "tsc --noEmit ./test/index-types.ts && node ./test/index-objects.spec.mjs",
17522
+ "test:integration": "yarn g:vitest run --passWithNoTests -c vitest.config.integ.mts",
17523
+ "test:integration:watch": "yarn g:vitest run --passWithNoTests -c vitest.config.integ.mts",
17524
+ "test:watch": "yarn g:vitest watch --passWithNoTests"
17521
17525
  },
17522
17526
  main: "./dist-cjs/index.js",
17523
17527
  types: "./dist-types/index.d.ts",
@@ -17536,7 +17540,7 @@ var require_package2 = __commonJS({
17536
17540
  "@aws-sdk/middleware-user-agent": "^3.972.15",
17537
17541
  "@aws-sdk/middleware-websocket": "^3.972.10",
17538
17542
  "@aws-sdk/region-config-resolver": "^3.972.6",
17539
- "@aws-sdk/token-providers": "3.999.0",
17543
+ "@aws-sdk/token-providers": "3.1000.0",
17540
17544
  "@aws-sdk/types": "^3.973.4",
17541
17545
  "@aws-sdk/util-endpoints": "^3.996.3",
17542
17546
  "@aws-sdk/util-user-agent-browser": "^3.972.6",
@@ -17573,12 +17577,14 @@ var require_package2 = __commonJS({
17573
17577
  tslib: "^2.6.2"
17574
17578
  },
17575
17579
  devDependencies: {
17580
+ "@smithy/snapshot-testing": "^1.0.7",
17576
17581
  "@tsconfig/node20": "20.1.8",
17577
17582
  "@types/node": "^20.14.8",
17578
17583
  concurrently: "7.0.0",
17579
17584
  "downlevel-dts": "0.10.1",
17580
17585
  premove: "4.0.0",
17581
- typescript: "~5.8.3"
17586
+ typescript: "~5.8.3",
17587
+ vitest: "^4.0.17"
17582
17588
  },
17583
17589
  engines: {
17584
17590
  node: ">=20.0.0"
@@ -19580,9 +19586,9 @@ var init_sso_oidc = __esm({
19580
19586
  }
19581
19587
  });
19582
19588
 
19583
- // node_modules/@aws-sdk/token-providers/dist-cjs/index.js
19589
+ // node_modules/@aws-sdk/credential-provider-sso/node_modules/@aws-sdk/token-providers/dist-cjs/index.js
19584
19590
  var require_dist_cjs56 = __commonJS({
19585
- "node_modules/@aws-sdk/token-providers/dist-cjs/index.js"(exports2) {
19591
+ "node_modules/@aws-sdk/credential-provider-sso/node_modules/@aws-sdk/token-providers/dist-cjs/index.js"(exports2) {
19586
19592
  "use strict";
19587
19593
  var client = (init_client(), __toCommonJS(client_exports));
19588
19594
  var httpAuthSchemes = (init_httpAuthSchemes2(), __toCommonJS(httpAuthSchemes_exports));
@@ -23415,8 +23421,155 @@ var require_dist_cjs63 = __commonJS({
23415
23421
  }
23416
23422
  });
23417
23423
 
23418
- // node_modules/@smithy/eventstream-serde-node/dist-cjs/index.js
23424
+ // node_modules/@aws-sdk/token-providers/dist-cjs/index.js
23419
23425
  var require_dist_cjs64 = __commonJS({
23426
+ "node_modules/@aws-sdk/token-providers/dist-cjs/index.js"(exports2) {
23427
+ "use strict";
23428
+ var client = (init_client(), __toCommonJS(client_exports));
23429
+ var httpAuthSchemes = (init_httpAuthSchemes2(), __toCommonJS(httpAuthSchemes_exports));
23430
+ var propertyProvider = require_dist_cjs24();
23431
+ var sharedIniFileLoader = require_dist_cjs42();
23432
+ var node_fs = require("node:fs");
23433
+ var fromEnvSigningName = ({ logger: logger2, signingName } = {}) => async () => {
23434
+ logger2?.debug?.("@aws-sdk/token-providers - fromEnvSigningName");
23435
+ if (!signingName) {
23436
+ throw new propertyProvider.TokenProviderError("Please pass 'signingName' to compute environment variable key", { logger: logger2 });
23437
+ }
23438
+ const bearerTokenKey = httpAuthSchemes.getBearerTokenEnvKey(signingName);
23439
+ if (!(bearerTokenKey in process.env)) {
23440
+ throw new propertyProvider.TokenProviderError(`Token not present in '${bearerTokenKey}' environment variable`, { logger: logger2 });
23441
+ }
23442
+ const token = { token: process.env[bearerTokenKey] };
23443
+ client.setTokenFeature(token, "BEARER_SERVICE_ENV_VARS", "3");
23444
+ return token;
23445
+ };
23446
+ var EXPIRE_WINDOW_MS = 5 * 60 * 1e3;
23447
+ var REFRESH_MESSAGE = `To refresh this SSO session run 'aws sso login' with the corresponding profile.`;
23448
+ var getSsoOidcClient = async (ssoRegion, init = {}, callerClientConfig) => {
23449
+ const { SSOOIDCClient: SSOOIDCClient2 } = await Promise.resolve().then(() => (init_sso_oidc(), sso_oidc_exports));
23450
+ const coalesce = (prop) => init.clientConfig?.[prop] ?? init.parentClientConfig?.[prop] ?? callerClientConfig?.[prop];
23451
+ const ssoOidcClient = new SSOOIDCClient2(Object.assign({}, init.clientConfig ?? {}, {
23452
+ region: ssoRegion ?? init.clientConfig?.region,
23453
+ logger: coalesce("logger"),
23454
+ userAgentAppId: coalesce("userAgentAppId")
23455
+ }));
23456
+ return ssoOidcClient;
23457
+ };
23458
+ var getNewSsoOidcToken = async (ssoToken, ssoRegion, init = {}, callerClientConfig) => {
23459
+ const { CreateTokenCommand: CreateTokenCommand2 } = await Promise.resolve().then(() => (init_sso_oidc(), sso_oidc_exports));
23460
+ const ssoOidcClient = await getSsoOidcClient(ssoRegion, init, callerClientConfig);
23461
+ return ssoOidcClient.send(new CreateTokenCommand2({
23462
+ clientId: ssoToken.clientId,
23463
+ clientSecret: ssoToken.clientSecret,
23464
+ refreshToken: ssoToken.refreshToken,
23465
+ grantType: "refresh_token"
23466
+ }));
23467
+ };
23468
+ var validateTokenExpiry = (token) => {
23469
+ if (token.expiration && token.expiration.getTime() < Date.now()) {
23470
+ throw new propertyProvider.TokenProviderError(`Token is expired. ${REFRESH_MESSAGE}`, false);
23471
+ }
23472
+ };
23473
+ var validateTokenKey = (key, value, forRefresh = false) => {
23474
+ if (typeof value === "undefined") {
23475
+ throw new propertyProvider.TokenProviderError(`Value not present for '${key}' in SSO Token${forRefresh ? ". Cannot refresh" : ""}. ${REFRESH_MESSAGE}`, false);
23476
+ }
23477
+ };
23478
+ var { writeFile: writeFile2 } = node_fs.promises;
23479
+ var writeSSOTokenToFile = (id, ssoToken) => {
23480
+ const tokenFilepath = sharedIniFileLoader.getSSOTokenFilepath(id);
23481
+ const tokenString = JSON.stringify(ssoToken, null, 2);
23482
+ return writeFile2(tokenFilepath, tokenString);
23483
+ };
23484
+ var lastRefreshAttemptTime = /* @__PURE__ */ new Date(0);
23485
+ var fromSso = (init = {}) => async ({ callerClientConfig } = {}) => {
23486
+ init.logger?.debug("@aws-sdk/token-providers - fromSso");
23487
+ const profiles = await sharedIniFileLoader.parseKnownFiles(init);
23488
+ const profileName = sharedIniFileLoader.getProfileName({
23489
+ profile: init.profile ?? callerClientConfig?.profile
23490
+ });
23491
+ const profile = profiles[profileName];
23492
+ if (!profile) {
23493
+ throw new propertyProvider.TokenProviderError(`Profile '${profileName}' could not be found in shared credentials file.`, false);
23494
+ } else if (!profile["sso_session"]) {
23495
+ throw new propertyProvider.TokenProviderError(`Profile '${profileName}' is missing required property 'sso_session'.`);
23496
+ }
23497
+ const ssoSessionName = profile["sso_session"];
23498
+ const ssoSessions = await sharedIniFileLoader.loadSsoSessionData(init);
23499
+ const ssoSession = ssoSessions[ssoSessionName];
23500
+ if (!ssoSession) {
23501
+ throw new propertyProvider.TokenProviderError(`Sso session '${ssoSessionName}' could not be found in shared credentials file.`, false);
23502
+ }
23503
+ for (const ssoSessionRequiredKey of ["sso_start_url", "sso_region"]) {
23504
+ if (!ssoSession[ssoSessionRequiredKey]) {
23505
+ throw new propertyProvider.TokenProviderError(`Sso session '${ssoSessionName}' is missing required property '${ssoSessionRequiredKey}'.`, false);
23506
+ }
23507
+ }
23508
+ ssoSession["sso_start_url"];
23509
+ const ssoRegion = ssoSession["sso_region"];
23510
+ let ssoToken;
23511
+ try {
23512
+ ssoToken = await sharedIniFileLoader.getSSOTokenFromFile(ssoSessionName);
23513
+ } catch (e5) {
23514
+ throw new propertyProvider.TokenProviderError(`The SSO session token associated with profile=${profileName} was not found or is invalid. ${REFRESH_MESSAGE}`, false);
23515
+ }
23516
+ validateTokenKey("accessToken", ssoToken.accessToken);
23517
+ validateTokenKey("expiresAt", ssoToken.expiresAt);
23518
+ const { accessToken, expiresAt } = ssoToken;
23519
+ const existingToken = { token: accessToken, expiration: new Date(expiresAt) };
23520
+ if (existingToken.expiration.getTime() - Date.now() > EXPIRE_WINDOW_MS) {
23521
+ return existingToken;
23522
+ }
23523
+ if (Date.now() - lastRefreshAttemptTime.getTime() < 30 * 1e3) {
23524
+ validateTokenExpiry(existingToken);
23525
+ return existingToken;
23526
+ }
23527
+ validateTokenKey("clientId", ssoToken.clientId, true);
23528
+ validateTokenKey("clientSecret", ssoToken.clientSecret, true);
23529
+ validateTokenKey("refreshToken", ssoToken.refreshToken, true);
23530
+ try {
23531
+ lastRefreshAttemptTime.setTime(Date.now());
23532
+ const newSsoOidcToken = await getNewSsoOidcToken(ssoToken, ssoRegion, init, callerClientConfig);
23533
+ validateTokenKey("accessToken", newSsoOidcToken.accessToken);
23534
+ validateTokenKey("expiresIn", newSsoOidcToken.expiresIn);
23535
+ const newTokenExpiration = new Date(Date.now() + newSsoOidcToken.expiresIn * 1e3);
23536
+ try {
23537
+ await writeSSOTokenToFile(ssoSessionName, {
23538
+ ...ssoToken,
23539
+ accessToken: newSsoOidcToken.accessToken,
23540
+ expiresAt: newTokenExpiration.toISOString(),
23541
+ refreshToken: newSsoOidcToken.refreshToken
23542
+ });
23543
+ } catch (error2) {
23544
+ }
23545
+ return {
23546
+ token: newSsoOidcToken.accessToken,
23547
+ expiration: newTokenExpiration
23548
+ };
23549
+ } catch (error2) {
23550
+ validateTokenExpiry(existingToken);
23551
+ return existingToken;
23552
+ }
23553
+ };
23554
+ var fromStatic = ({ token, logger: logger2 }) => async () => {
23555
+ logger2?.debug("@aws-sdk/token-providers - fromStatic");
23556
+ if (!token || !token.token) {
23557
+ throw new propertyProvider.TokenProviderError(`Please pass a valid token to fromStatic`, false);
23558
+ }
23559
+ return token;
23560
+ };
23561
+ var nodeProvider = (init = {}) => propertyProvider.memoize(propertyProvider.chain(fromSso(init), async () => {
23562
+ throw new propertyProvider.TokenProviderError("Could not load token from any providers", false);
23563
+ }), (token) => token.expiration !== void 0 && token.expiration.getTime() - Date.now() < 3e5, (token) => token.expiration !== void 0);
23564
+ exports2.fromEnvSigningName = fromEnvSigningName;
23565
+ exports2.fromSso = fromSso;
23566
+ exports2.fromStatic = fromStatic;
23567
+ exports2.nodeProvider = nodeProvider;
23568
+ }
23569
+ });
23570
+
23571
+ // node_modules/@smithy/eventstream-serde-node/dist-cjs/index.js
23572
+ var require_dist_cjs65 = __commonJS({
23420
23573
  "node_modules/@smithy/eventstream-serde-node/dist-cjs/index.js"(exports2) {
23421
23574
  "use strict";
23422
23575
  var eventstreamSerdeUniversal = require_dist_cjs35();
@@ -26098,11 +26251,11 @@ var require_runtimeConfig = __commonJS({
26098
26251
  var core_1 = (init_dist_es2(), __toCommonJS(dist_es_exports2));
26099
26252
  var credential_provider_node_1 = require_dist_cjs62();
26100
26253
  var eventstream_handler_node_1 = require_dist_cjs63();
26101
- var token_providers_1 = require_dist_cjs56();
26254
+ var token_providers_1 = require_dist_cjs64();
26102
26255
  var util_user_agent_node_1 = require_dist_cjs51();
26103
26256
  var config_resolver_1 = require_dist_cjs39();
26104
26257
  var core_2 = (init_dist_es(), __toCommonJS(dist_es_exports));
26105
- var eventstream_serde_node_1 = require_dist_cjs64();
26258
+ var eventstream_serde_node_1 = require_dist_cjs65();
26106
26259
  var hash_node_1 = require_dist_cjs52();
26107
26260
  var middleware_retry_1 = require_dist_cjs47();
26108
26261
  var node_config_provider_1 = require_dist_cjs43();
@@ -26174,7 +26327,7 @@ var require_runtimeConfig = __commonJS({
26174
26327
  });
26175
26328
 
26176
26329
  // node_modules/@aws-sdk/client-bedrock-runtime/dist-cjs/index.js
26177
- var require_dist_cjs65 = __commonJS({
26330
+ var require_dist_cjs66 = __commonJS({
26178
26331
  "node_modules/@aws-sdk/client-bedrock-runtime/dist-cjs/index.js"(exports2) {
26179
26332
  "use strict";
26180
26333
  var middlewareEventstream = require_dist_cjs3();
@@ -27019,13 +27172,13 @@ var import_client_bedrock_runtime, import_client_bedrock_runtime2, import_client
27019
27172
  var init_dist3 = __esm({
27020
27173
  "node_modules/@ai-sdk/amazon-bedrock/dist/index.mjs"() {
27021
27174
  init_dist2();
27022
- import_client_bedrock_runtime = __toESM(require_dist_cjs65(), 1);
27175
+ import_client_bedrock_runtime = __toESM(require_dist_cjs66(), 1);
27023
27176
  init_dist();
27024
- import_client_bedrock_runtime2 = __toESM(require_dist_cjs65(), 1);
27177
+ import_client_bedrock_runtime2 = __toESM(require_dist_cjs66(), 1);
27025
27178
  init_dist();
27026
27179
  init_dist();
27027
27180
  init_dist2();
27028
- import_client_bedrock_runtime3 = __toESM(require_dist_cjs65(), 1);
27181
+ import_client_bedrock_runtime3 = __toESM(require_dist_cjs66(), 1);
27029
27182
  generateFileId = createIdGenerator({ prefix: "file", size: 16 });
27030
27183
  BedrockChatLanguageModel = class {
27031
27184
  constructor(modelId, settings, config) {
@@ -36872,6 +37025,11 @@ Example: <extract><targets>${displayPath}</targets></extract>`;
36872
37025
  if (!replace_all && occurrences > 1) {
36873
37026
  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).`;
36874
37027
  }
37028
+ const oldLines = matchTarget.split("\n").length;
37029
+ const newLines = new_string.split("\n").length;
37030
+ if (oldLines >= 20 && newLines < oldLines * 0.5) {
37031
+ 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.`;
37032
+ }
36875
37033
  let newContent;
36876
37034
  if (replace_all) {
36877
37035
  newContent = content.replaceAll(matchTarget, new_string);
@@ -40251,6 +40409,122 @@ var init_bashPermissions = __esm({
40251
40409
  });
40252
40410
 
40253
40411
  // src/agent/bashExecutor.js
40412
+ function splitCommandComponents(command) {
40413
+ const parts = [];
40414
+ let current2 = "";
40415
+ let inQuote = false;
40416
+ let quoteChar = "";
40417
+ for (let i5 = 0; i5 < command.length; i5++) {
40418
+ const c5 = command[i5];
40419
+ const next = command[i5 + 1] || "";
40420
+ if (c5 === "\\" && !inQuote) {
40421
+ current2 += c5 + next;
40422
+ i5++;
40423
+ continue;
40424
+ }
40425
+ if (inQuote && quoteChar === '"' && c5 === "\\" && next) {
40426
+ current2 += c5 + next;
40427
+ i5++;
40428
+ continue;
40429
+ }
40430
+ if (!inQuote && (c5 === '"' || c5 === "'")) {
40431
+ inQuote = true;
40432
+ quoteChar = c5;
40433
+ current2 += c5;
40434
+ continue;
40435
+ }
40436
+ if (inQuote && c5 === quoteChar) {
40437
+ inQuote = false;
40438
+ current2 += c5;
40439
+ continue;
40440
+ }
40441
+ if (!inQuote) {
40442
+ if (c5 === "&" && next === "&" || c5 === "|" && next === "|") {
40443
+ if (current2.trim()) parts.push(current2.trim());
40444
+ current2 = "";
40445
+ i5++;
40446
+ continue;
40447
+ }
40448
+ if (c5 === "|" || c5 === ";") {
40449
+ if (current2.trim()) parts.push(current2.trim());
40450
+ current2 = "";
40451
+ continue;
40452
+ }
40453
+ }
40454
+ current2 += c5;
40455
+ }
40456
+ if (current2.trim()) parts.push(current2.trim());
40457
+ return parts;
40458
+ }
40459
+ function checkSingleCommandInteractive(command) {
40460
+ let effective = command.trim();
40461
+ while (/^\w+=\S*\s/.test(effective)) {
40462
+ effective = effective.replace(/^\w+=\S*\s+/, "");
40463
+ }
40464
+ const parts = effective.split(/\s+/);
40465
+ const base2 = parts[0];
40466
+ const args = parts.slice(1);
40467
+ if (["vi", "vim", "nvim", "nano", "emacs", "pico", "joe", "mcedit"].includes(base2)) {
40468
+ return `'${base2}' is an interactive editor and cannot run without a terminal. Use non-interactive file manipulation commands instead.`;
40469
+ }
40470
+ if (["less", "more"].includes(base2)) {
40471
+ return `'${base2}' is an interactive pager. Use 'cat', 'head', or 'tail' instead.`;
40472
+ }
40473
+ if (base2 === "git") {
40474
+ const sub = args[0];
40475
+ if (sub === "commit") {
40476
+ const hasNonInteractiveFlag = args.some(
40477
+ (a5) => a5 === "-m" || a5.startsWith("--message") || a5 === "-C" || a5 === "-c" || a5.startsWith("--fixup") || a5.startsWith("--squash") || a5 === "--allow-empty-message" || a5 === "--no-edit"
40478
+ );
40479
+ if (!hasNonInteractiveFlag) {
40480
+ return `Interactive command: 'git commit' opens an editor for the commit message. Use 'git commit -m "your message"' instead.`;
40481
+ }
40482
+ }
40483
+ if (sub === "rebase" && (args.includes("--continue") || args.includes("--skip"))) {
40484
+ 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.";
40485
+ }
40486
+ if (sub === "rebase" && (args.includes("-i") || args.includes("--interactive"))) {
40487
+ return "Interactive command: 'git rebase -i' requires an interactive editor. Interactive rebase cannot run without a terminal.";
40488
+ }
40489
+ if (sub === "merge" && !args.includes("--no-edit") && !args.includes("--no-commit") && !args.includes("--ff-only")) {
40490
+ return "Interactive command: 'git merge' may open an editor for the merge commit message. Add '--no-edit' to accept the default message.";
40491
+ }
40492
+ if (sub === "cherry-pick" && !args.includes("--no-edit")) {
40493
+ return "Interactive command: 'git cherry-pick' may open an editor. Add '--no-edit' to accept the default message.";
40494
+ }
40495
+ if (sub === "revert" && !args.includes("--no-edit")) {
40496
+ return "Interactive command: 'git revert' opens an editor. Add '--no-edit' to accept the default message.";
40497
+ }
40498
+ if (sub === "tag" && args.includes("-a") && !args.some((a5) => a5 === "-m" || a5.startsWith("--message"))) {
40499
+ return `Interactive command: 'git tag -a' opens an editor for the tag message. Use 'git tag -a <name> -m "message"' instead.`;
40500
+ }
40501
+ if (sub === "add" && (args.includes("-i") || args.includes("--interactive") || args.includes("-p") || args.includes("--patch"))) {
40502
+ return "Interactive command: 'git add -i/-p' requires interactive input. Use 'git add <files>' to stage specific files instead.";
40503
+ }
40504
+ }
40505
+ if (["python", "python3", "node", "irb", "ghci", "lua", "R", "ruby"].includes(base2) && args.length === 0) {
40506
+ return `Interactive command: '${base2}' without arguments starts an interactive REPL. Provide a script file or use '-c'/'--eval' for inline code.`;
40507
+ }
40508
+ if (base2 === "mysql" && !args.some((a5) => a5 === "-e" || a5.startsWith("--execute"))) {
40509
+ return `Interactive command: 'mysql' without -e flag starts an interactive session. Use 'mysql -e "SQL QUERY"' instead.`;
40510
+ }
40511
+ if (base2 === "psql" && !args.some((a5) => a5 === "-c" || a5.startsWith("--command") || a5 === "-f" || a5.startsWith("--file"))) {
40512
+ return `Interactive command: 'psql' without -c flag starts an interactive session. Use 'psql -c "SQL QUERY"' instead.`;
40513
+ }
40514
+ if (["top", "htop", "btop", "nmon"].includes(base2)) {
40515
+ return `Interactive command: '${base2}' is an interactive TUI tool. Use 'ps aux' or 'top -b -n 1' for non-interactive process listing.`;
40516
+ }
40517
+ return null;
40518
+ }
40519
+ function checkInteractiveCommand(command) {
40520
+ if (!command || typeof command !== "string") return null;
40521
+ const components = splitCommandComponents(command.trim());
40522
+ for (const component of components) {
40523
+ const result = checkSingleCommandInteractive(component);
40524
+ if (result) return result;
40525
+ }
40526
+ return null;
40527
+ }
40254
40528
  async function executeBashCommand(command, options = {}) {
40255
40529
  const {
40256
40530
  workingDirectory = process.cwd(),
@@ -40280,6 +40554,24 @@ async function executeBashCommand(command, options = {}) {
40280
40554
  };
40281
40555
  }
40282
40556
  const startTime = Date.now();
40557
+ const interactiveError = checkInteractiveCommand(command);
40558
+ if (interactiveError) {
40559
+ if (debug) {
40560
+ console.log(`[BashExecutor] Blocked interactive command: "${command}"`);
40561
+ console.log(`[BashExecutor] Reason: ${interactiveError}`);
40562
+ }
40563
+ return {
40564
+ success: false,
40565
+ error: interactiveError,
40566
+ stdout: "",
40567
+ stderr: interactiveError,
40568
+ exitCode: 1,
40569
+ command,
40570
+ workingDirectory: cwd,
40571
+ duration: 0,
40572
+ interactive: true
40573
+ };
40574
+ }
40283
40575
  if (debug) {
40284
40576
  console.log(`[BashExecutor] Executing command: "${command}"`);
40285
40577
  console.log(`[BashExecutor] Working directory: "${cwd}"`);
@@ -40290,6 +40582,8 @@ async function executeBashCommand(command, options = {}) {
40290
40582
  ...process.env,
40291
40583
  ...env
40292
40584
  };
40585
+ if (!processEnv.GIT_EDITOR) processEnv.GIT_EDITOR = "true";
40586
+ if (!processEnv.GIT_TERMINAL_PROMPT) processEnv.GIT_TERMINAL_PROMPT = "0";
40293
40587
  const isComplex = isComplexCommand(command);
40294
40588
  let cmd, cmdArgs, useShell;
40295
40589
  if (isComplex) {
@@ -40324,20 +40618,32 @@ async function executeBashCommand(command, options = {}) {
40324
40618
  // stdin ignored, capture stdout/stderr
40325
40619
  shell: useShell,
40326
40620
  // false for security
40621
+ detached: true,
40622
+ // new session — no controlling terminal
40327
40623
  windowsHide: true
40328
40624
  });
40329
40625
  let stdout = "";
40330
40626
  let stderr = "";
40331
40627
  let killed = false;
40332
40628
  let timeoutHandle;
40629
+ const killProcessGroup = (signal) => {
40630
+ try {
40631
+ if (child.pid) process.kill(-child.pid, signal);
40632
+ } catch {
40633
+ try {
40634
+ child.kill(signal);
40635
+ } catch {
40636
+ }
40637
+ }
40638
+ };
40333
40639
  if (timeout > 0) {
40334
40640
  timeoutHandle = setTimeout(() => {
40335
40641
  if (!killed) {
40336
40642
  killed = true;
40337
- child.kill("SIGTERM");
40643
+ killProcessGroup("SIGTERM");
40338
40644
  setTimeout(() => {
40339
40645
  if (child.exitCode === null) {
40340
- child.kill("SIGKILL");
40646
+ killProcessGroup("SIGKILL");
40341
40647
  }
40342
40648
  }, 5e3);
40343
40649
  }
@@ -40350,7 +40656,7 @@ async function executeBashCommand(command, options = {}) {
40350
40656
  } else {
40351
40657
  if (!killed) {
40352
40658
  killed = true;
40353
- child.kill("SIGTERM");
40659
+ killProcessGroup("SIGTERM");
40354
40660
  }
40355
40661
  }
40356
40662
  });
@@ -40361,7 +40667,7 @@ async function executeBashCommand(command, options = {}) {
40361
40667
  } else {
40362
40668
  if (!killed) {
40363
40669
  killed = true;
40364
- child.kill("SIGTERM");
40670
+ killProcessGroup("SIGTERM");
40365
40671
  }
40366
40672
  }
40367
40673
  });
@@ -66267,7 +66573,6 @@ var init_reg_exp = __esm({
66267
66573
  // node_modules/chevrotain/lib/src/scan/lexer.js
66268
66574
  function analyzeTokenTypes(tokenTypes, options) {
66269
66575
  options = defaults_default(options, {
66270
- useSticky: SUPPORT_STICKY,
66271
66576
  debug: false,
66272
66577
  safeMode: false,
66273
66578
  positionTracking: "full",
@@ -66316,7 +66621,7 @@ function analyzeTokenTypes(tokenTypes, options) {
66316
66621
  ], regExpSource[1])) {
66317
66622
  return regExpSource[1];
66318
66623
  } else {
66319
- return options.useSticky ? addStickyFlag(currPattern) : addStartOfInput(currPattern);
66624
+ return addStickyFlag(currPattern);
66320
66625
  }
66321
66626
  } else if (isFunction_default(currPattern)) {
66322
66627
  hasCustom = true;
@@ -66330,7 +66635,7 @@ function analyzeTokenTypes(tokenTypes, options) {
66330
66635
  } else {
66331
66636
  const escapedRegExpString = currPattern.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
66332
66637
  const wrappedRegExp = new RegExp(escapedRegExpString);
66333
- return options.useSticky ? addStickyFlag(wrappedRegExp) : addStartOfInput(wrappedRegExp);
66638
+ return addStickyFlag(wrappedRegExp);
66334
66639
  }
66335
66640
  } else {
66336
66641
  throw Error("non exhaustive match");
@@ -66734,10 +67039,6 @@ function noMetaChar(regExp) {
66734
67039
  function usesLookAheadOrBehind(regExp) {
66735
67040
  return /(\(\?=)|(\(\?!)|(\(\?<=)|(\(\?<!)/.test(regExp.source);
66736
67041
  }
66737
- function addStartOfInput(pattern) {
66738
- const flags = pattern.ignoreCase ? "i" : "";
66739
- return new RegExp(`^(?:${pattern.source})`, flags);
66740
- }
66741
67042
  function addStickyFlag(pattern) {
66742
67043
  const flags = pattern.ignoreCase ? "iy" : "y";
66743
67044
  return new RegExp(`${pattern.source}`, flags);
@@ -66926,7 +67227,7 @@ function initCharCodeToOptimizedIndexMap() {
66926
67227
  }
66927
67228
  }
66928
67229
  }
66929
- var PATTERN, DEFAULT_MODE, MODES, SUPPORT_STICKY, end_of_input, start_of_input, LineTerminatorOptimizedTester, minOptimizationVal, charCodeToOptimizedIdxMap;
67230
+ var PATTERN, DEFAULT_MODE, MODES, end_of_input, start_of_input, LineTerminatorOptimizedTester, minOptimizationVal, charCodeToOptimizedIdxMap;
66930
67231
  var init_lexer = __esm({
66931
67232
  "node_modules/chevrotain/lib/src/scan/lexer.js"() {
66932
67233
  init_api3();
@@ -66938,7 +67239,6 @@ var init_lexer = __esm({
66938
67239
  PATTERN = "PATTERN";
66939
67240
  DEFAULT_MODE = "defaultMode";
66940
67241
  MODES = "modes";
66941
- SUPPORT_STICKY = typeof new RegExp("(?:)").sticky === "boolean";
66942
67242
  end_of_input = /[^\\][$]/;
66943
67243
  start_of_input = /[^\\[][\^]|^\^/;
66944
67244
  LineTerminatorOptimizedTester = {
@@ -67254,13 +67554,6 @@ var init_lexer_public = __esm({
67254
67554
  PRINT_WARNING(warningDescriptor.message);
67255
67555
  });
67256
67556
  this.TRACE_INIT("Choosing sub-methods implementations", () => {
67257
- if (SUPPORT_STICKY) {
67258
- this.chopInput = identity_default;
67259
- this.match = this.matchWithTest;
67260
- } else {
67261
- this.updateLastIndex = noop_default;
67262
- this.match = this.matchWithExec;
67263
- }
67264
67557
  if (hasOnlySingleMode) {
67265
67558
  this.handleModes = noop_default;
67266
67559
  }
@@ -67323,7 +67616,7 @@ var init_lexer_public = __esm({
67323
67616
  // this method also used quite a bit of `!` none null assertions because it is too optimized
67324
67617
  // for `tsc` to always understand it is "safe"
67325
67618
  tokenizeInternal(text, initialMode) {
67326
- let i5, j5, k5, matchAltImage, longerAlt, matchedImage, payload2, altPayload, imageLength, group, tokType, newToken, errLength, droppedChar, msg, match2;
67619
+ let i5, j5, k5, matchAltImage, longerAlt, matchedImage, payload2, altPayload, imageLength, group, tokType, newToken, errLength, msg, match2;
67327
67620
  const orgText = text;
67328
67621
  const orgLength = orgText.length;
67329
67622
  let offset2 = 0;
@@ -67342,19 +67635,7 @@ var init_lexer_public = __esm({
67342
67635
  const modeStack = [];
67343
67636
  const emptyArray = [];
67344
67637
  Object.freeze(emptyArray);
67345
- let getPossiblePatterns;
67346
- function getPossiblePatternsSlow() {
67347
- return patternIdxToConfig;
67348
- }
67349
- function getPossiblePatternsOptimized(charCode) {
67350
- const optimizedCharIdx = charCodeToOptimizedIndex(charCode);
67351
- const possiblePatterns = currCharCodeToPatternIdxToConfig[optimizedCharIdx];
67352
- if (possiblePatterns === void 0) {
67353
- return emptyArray;
67354
- } else {
67355
- return possiblePatterns;
67356
- }
67357
- }
67638
+ let isOptimizedMode = false;
67358
67639
  const pop_mode = (popToken) => {
67359
67640
  if (modeStack.length === 1 && // if we have both a POP_MODE and a PUSH_MODE this is in-fact a "transition"
67360
67641
  // So no error should occur.
@@ -67375,9 +67656,9 @@ var init_lexer_public = __esm({
67375
67656
  currModePatternsLength = patternIdxToConfig.length;
67376
67657
  const modeCanBeOptimized = this.canModeBeOptimized[newMode] && this.config.safeMode === false;
67377
67658
  if (currCharCodeToPatternIdxToConfig && modeCanBeOptimized) {
67378
- getPossiblePatterns = getPossiblePatternsOptimized;
67659
+ isOptimizedMode = true;
67379
67660
  } else {
67380
- getPossiblePatterns = getPossiblePatternsSlow;
67661
+ isOptimizedMode = false;
67381
67662
  }
67382
67663
  }
67383
67664
  };
@@ -67389,9 +67670,9 @@ var init_lexer_public = __esm({
67389
67670
  currModePatternsLength = patternIdxToConfig.length;
67390
67671
  const modeCanBeOptimized = this.canModeBeOptimized[newMode] && this.config.safeMode === false;
67391
67672
  if (currCharCodeToPatternIdxToConfig && modeCanBeOptimized) {
67392
- getPossiblePatterns = getPossiblePatternsOptimized;
67673
+ isOptimizedMode = true;
67393
67674
  } else {
67394
- getPossiblePatterns = getPossiblePatternsSlow;
67675
+ isOptimizedMode = false;
67395
67676
  }
67396
67677
  }
67397
67678
  push_mode.call(this, initialMode);
@@ -67399,8 +67680,16 @@ var init_lexer_public = __esm({
67399
67680
  const recoveryEnabled = this.config.recoveryEnabled;
67400
67681
  while (offset2 < orgLength) {
67401
67682
  matchedImage = null;
67683
+ imageLength = -1;
67402
67684
  const nextCharCode = orgText.charCodeAt(offset2);
67403
- const chosenPatternIdxToConfig = getPossiblePatterns(nextCharCode);
67685
+ let chosenPatternIdxToConfig;
67686
+ if (isOptimizedMode) {
67687
+ const optimizedCharIdx = charCodeToOptimizedIndex(nextCharCode);
67688
+ const possiblePatterns = currCharCodeToPatternIdxToConfig[optimizedCharIdx];
67689
+ chosenPatternIdxToConfig = possiblePatterns !== void 0 ? possiblePatterns : emptyArray;
67690
+ } else {
67691
+ chosenPatternIdxToConfig = patternIdxToConfig;
67692
+ }
67404
67693
  const chosenPatternsLength = chosenPatternIdxToConfig.length;
67405
67694
  for (i5 = 0; i5 < chosenPatternsLength; i5++) {
67406
67695
  currConfig = chosenPatternIdxToConfig[i5];
@@ -67409,12 +67698,14 @@ var init_lexer_public = __esm({
67409
67698
  const singleCharCode = currConfig.short;
67410
67699
  if (singleCharCode !== false) {
67411
67700
  if (nextCharCode === singleCharCode) {
67701
+ imageLength = 1;
67412
67702
  matchedImage = currPattern;
67413
67703
  }
67414
67704
  } else if (currConfig.isCustom === true) {
67415
67705
  match2 = currPattern.exec(orgText, offset2, matchedTokens, groups);
67416
67706
  if (match2 !== null) {
67417
67707
  matchedImage = match2[0];
67708
+ imageLength = matchedImage.length;
67418
67709
  if (match2.payload !== void 0) {
67419
67710
  payload2 = match2.payload;
67420
67711
  }
@@ -67422,12 +67713,13 @@ var init_lexer_public = __esm({
67422
67713
  matchedImage = null;
67423
67714
  }
67424
67715
  } else {
67425
- this.updateLastIndex(currPattern, offset2);
67426
- matchedImage = this.match(currPattern, text, offset2);
67716
+ currPattern.lastIndex = offset2;
67717
+ imageLength = this.matchLength(currPattern, text, offset2);
67427
67718
  }
67428
- if (matchedImage !== null) {
67719
+ if (imageLength !== -1) {
67429
67720
  longerAlt = currConfig.longerAlt;
67430
67721
  if (longerAlt !== void 0) {
67722
+ matchedImage = text.substring(offset2, offset2 + imageLength);
67431
67723
  const longerAltLength = longerAlt.length;
67432
67724
  for (k5 = 0; k5 < longerAltLength; k5++) {
67433
67725
  const longerAltConfig = patternIdxToConfig[longerAlt[k5]];
@@ -67444,11 +67736,12 @@ var init_lexer_public = __esm({
67444
67736
  matchAltImage = null;
67445
67737
  }
67446
67738
  } else {
67447
- this.updateLastIndex(longerAltPattern, offset2);
67739
+ longerAltPattern.lastIndex = offset2;
67448
67740
  matchAltImage = this.match(longerAltPattern, text, offset2);
67449
67741
  }
67450
67742
  if (matchAltImage && matchAltImage.length > matchedImage.length) {
67451
67743
  matchedImage = matchAltImage;
67744
+ imageLength = matchAltImage.length;
67452
67745
  payload2 = altPayload;
67453
67746
  currConfig = longerAltConfig;
67454
67747
  break;
@@ -67458,10 +67751,10 @@ var init_lexer_public = __esm({
67458
67751
  break;
67459
67752
  }
67460
67753
  }
67461
- if (matchedImage !== null) {
67462
- imageLength = matchedImage.length;
67754
+ if (imageLength !== -1) {
67463
67755
  group = currConfig.group;
67464
67756
  if (group !== void 0) {
67757
+ matchedImage = matchedImage !== null ? matchedImage : text.substring(offset2, offset2 + imageLength);
67465
67758
  tokType = currConfig.tokenTypeIdx;
67466
67759
  newToken = this.createTokenInstance(matchedImage, offset2, tokType, currConfig.tokenType, line, column, imageLength);
67467
67760
  this.handlePayload(newToken, payload2);
@@ -67471,15 +67764,13 @@ var init_lexer_public = __esm({
67471
67764
  groups[group].push(newToken);
67472
67765
  }
67473
67766
  }
67474
- text = this.chopInput(text, imageLength);
67475
- offset2 = offset2 + imageLength;
67476
- column = this.computeNewColumn(column, imageLength);
67477
67767
  if (trackLines === true && currConfig.canLineTerminator === true) {
67478
67768
  let numOfLTsInMatch = 0;
67479
67769
  let foundTerminator;
67480
67770
  let lastLTEndOffset;
67481
67771
  lineTerminatorPattern.lastIndex = 0;
67482
67772
  do {
67773
+ matchedImage = matchedImage !== null ? matchedImage : text.substring(offset2, offset2 + imageLength);
67483
67774
  foundTerminator = lineTerminatorPattern.test(matchedImage);
67484
67775
  if (foundTerminator === true) {
67485
67776
  lastLTEndOffset = lineTerminatorPattern.lastIndex - 1;
@@ -67490,8 +67781,13 @@ var init_lexer_public = __esm({
67490
67781
  line = line + numOfLTsInMatch;
67491
67782
  column = imageLength - lastLTEndOffset;
67492
67783
  this.updateTokenEndLineColumnLocation(newToken, group, lastLTEndOffset, numOfLTsInMatch, line, column, imageLength);
67784
+ } else {
67785
+ column = this.computeNewColumn(column, imageLength);
67493
67786
  }
67787
+ } else {
67788
+ column = this.computeNewColumn(column, imageLength);
67494
67789
  }
67790
+ offset2 = offset2 + imageLength;
67495
67791
  this.handleModes(currConfig, pop_mode, push_mode, newToken);
67496
67792
  } else {
67497
67793
  const errorStartOffset = offset2;
@@ -67499,7 +67795,6 @@ var init_lexer_public = __esm({
67499
67795
  const errorColumn = column;
67500
67796
  let foundResyncPoint = recoveryEnabled === false;
67501
67797
  while (foundResyncPoint === false && offset2 < orgLength) {
67502
- text = this.chopInput(text, 1);
67503
67798
  offset2++;
67504
67799
  for (j5 = 0; j5 < currModePatternsLength; j5++) {
67505
67800
  const currConfig2 = patternIdxToConfig[j5];
@@ -67512,7 +67807,7 @@ var init_lexer_public = __esm({
67512
67807
  } else if (currConfig2.isCustom === true) {
67513
67808
  foundResyncPoint = currPattern.exec(orgText, offset2, matchedTokens, groups) !== null;
67514
67809
  } else {
67515
- this.updateLastIndex(currPattern, offset2);
67810
+ currPattern.lastIndex = offset2;
67516
67811
  foundResyncPoint = currPattern.exec(text) !== null;
67517
67812
  }
67518
67813
  if (foundResyncPoint === true) {
@@ -67555,12 +67850,6 @@ var init_lexer_public = __esm({
67555
67850
  push_mode.call(this, config.push);
67556
67851
  }
67557
67852
  }
67558
- chopInput(text, length) {
67559
- return text.substring(length);
67560
- }
67561
- updateLastIndex(regExp, newLastIndex) {
67562
- regExp.lastIndex = newLastIndex;
67563
- }
67564
67853
  // TODO: decrease this under 600 characters? inspect stripping comments option in TSC compiler
67565
67854
  updateTokenEndLineColumnLocation(newToken, group, lastLTIdx, numOfLTsInMatch, line, column, imageLength) {
67566
67855
  let lastCharIsLT, fixForEndingInLT;
@@ -67623,16 +67912,19 @@ var init_lexer_public = __esm({
67623
67912
  token.payload = payload2;
67624
67913
  }
67625
67914
  }
67626
- matchWithTest(pattern, text, offset2) {
67915
+ match(pattern, text, offset2) {
67627
67916
  const found = pattern.test(text);
67628
67917
  if (found === true) {
67629
67918
  return text.substring(offset2, pattern.lastIndex);
67630
67919
  }
67631
67920
  return null;
67632
67921
  }
67633
- matchWithExec(pattern, text) {
67634
- const regExpArray = pattern.exec(text);
67635
- return regExpArray !== null ? regExpArray[0] : null;
67922
+ matchLength(pattern, text, offset2) {
67923
+ const found = pattern.test(text);
67924
+ if (found === true) {
67925
+ return pattern.lastIndex - offset2;
67926
+ }
67927
+ return -1;
67636
67928
  }
67637
67929
  };
67638
67930
  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.";
@@ -67824,12 +68116,20 @@ For Further details.`;
67824
68116
  return errMsg;
67825
68117
  },
67826
68118
  buildAlternationAmbiguityError(options) {
67827
- const pathMsg = map_default(options.prefixPath, (currtok) => tokenLabel2(currtok)).join(", ");
67828
68119
  const occurrence = options.alternation.idx === 0 ? "" : options.alternation.idx;
68120
+ const isEmptyPath = options.prefixPath.length === 0;
67829
68121
  let currMessage = `Ambiguous Alternatives Detected: <${options.ambiguityIndices.join(" ,")}> in <OR${occurrence}> inside <${options.topLevelRule.name}> Rule,
67830
- <${pathMsg}> may appears as a prefix path in all these alternatives.
67831
68122
  `;
67832
- currMessage = currMessage + `See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES
68123
+ if (isEmptyPath) {
68124
+ currMessage += `These alternatives are all empty (match no tokens), making them indistinguishable.
68125
+ Only the last alternative may be empty.
68126
+ `;
68127
+ } else {
68128
+ const pathMsg = map_default(options.prefixPath, (currtok) => tokenLabel2(currtok)).join(", ");
68129
+ currMessage += `<${pathMsg}> may appears as a prefix path in all these alternatives.
68130
+ `;
68131
+ }
68132
+ currMessage += `See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES
67833
68133
  For Further details.`;
67834
68134
  return currMessage;
67835
68135
  },
@@ -74332,7 +74632,7 @@ function validateFlowchart(text, options = {}) {
74332
74632
  const byLine = /* @__PURE__ */ new Map();
74333
74633
  const collect = (arr) => {
74334
74634
  for (const e5 of arr || []) {
74335
- if (e5 && (e5.code === "FL-LABEL-PARENS-UNQUOTED" || e5.code === "FL-LABEL-AT-IN-UNQUOTED" || e5.code === "FL-LABEL-QUOTE-IN-UNQUOTED")) {
74635
+ if (e5 && (e5.code === "FL-LABEL-PARENS-UNQUOTED" || e5.code === "FL-LABEL-AT-IN-UNQUOTED" || e5.code === "FL-LABEL-QUOTE-IN-UNQUOTED" || e5.code === "FL-LABEL-SLASH-UNQUOTED")) {
74336
74636
  const ln = e5.line ?? 0;
74337
74637
  const col = e5.column ?? 1;
74338
74638
  const list2 = byLine.get(ln) || [];
@@ -74415,6 +74715,7 @@ function validateFlowchart(text, options = {}) {
74415
74715
  const hasAt = seg.includes("@");
74416
74716
  const hasQuote = seg.includes('"');
74417
74717
  const isSingleQuoted = /^'[^]*'$/.test(trimmed);
74718
+ const hasLeadingSlash = lsp === "/" || lsp === "\\";
74418
74719
  if (!covered && !isQuoted && !isParenWrapped && hasParens) {
74419
74720
  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: &#40; and &#41;.' });
74420
74721
  existing.push({ start: startCol, end: endCol });
@@ -74425,6 +74726,11 @@ function validateFlowchart(text, options = {}) {
74425
74726
  existing.push({ start: startCol, end: endCol });
74426
74727
  byLine.set(ln, existing);
74427
74728
  }
74729
+ if (!covered && !isQuoted && !isSlashPair && hasLeadingSlash) {
74730
+ 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 &#47; / &#92; for literal slashes.' });
74731
+ existing.push({ start: startCol, end: endCol });
74732
+ byLine.set(ln, existing);
74733
+ }
74428
74734
  if (!covered && !isQuoted && !isSlashPair && hasQuote && !isSingleQuoted) {
74429
74735
  errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-QUOTE-IN-UNQUOTED", message: "Quotes are not allowed inside unquoted node labels. Use &quot; for quotes or wrap the entire label in quotes.", hint: 'Example: C["HTML Output: data-trigger-visibility=&quot;true&quot;"]' });
74430
74736
  existing.push({ start: startCol, end: endCol });
@@ -77433,7 +77739,7 @@ function computeFixes(text, errors, level = "safe") {
77433
77739
  }
77434
77740
  continue;
77435
77741
  }
77436
- if (is("FL-LABEL-PARENS-UNQUOTED", e5) || is("FL-LABEL-AT-IN-UNQUOTED", e5)) {
77742
+ if (is("FL-LABEL-PARENS-UNQUOTED", e5) || is("FL-LABEL-AT-IN-UNQUOTED", e5) || is("FL-LABEL-SLASH-UNQUOTED", e5)) {
77437
77743
  if (level === "safe" || level === "all") {
77438
77744
  if (patchedLines.has(e5.line))
77439
77745
  continue;
@@ -98728,6 +99034,7 @@ If the solution is clear, you can jump to implementation right away. If not, ask
98728
99034
  - Avoid implementing special cases when a general approach works
98729
99035
  - Never expose secrets, API keys, or credentials in generated code. Never log sensitive information.
98730
99036
  - 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.
99037
+ - 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.
98731
99038
  - After every significant change, verify the project still builds and passes linting. Do not wait until the end to discover breakage.
98732
99039
 
98733
99040
  # After Implementation
@@ -98738,11 +99045,33 @@ If the solution is clear, you can jump to implementation right away. If not, ask
98738
99045
 
98739
99046
  # GitHub Integration
98740
99047
  - Use the \`gh\` CLI for all GitHub operations: issues, pull requests, checks, releases.
98741
- - To create a pull request: commit your changes, push the branch, then use \`gh pr create --title "..." --body "..."\`.
98742
99048
  - To view issues or PRs: \`gh issue view <number>\`, \`gh pr view <number>\`.
98743
99049
  - If given a GitHub URL, use \`gh\` to fetch the relevant information rather than guessing.
98744
99050
  - Always return the pull request URL to the user after creating one.
98745
- - 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.`,
99051
+ - 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.
99052
+
99053
+ # Pull Request Creation
99054
+ - Commit your changes, push the branch, then use \`gh pr create --title "..." --body "..."\`.
99055
+ - **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:\`.
99056
+ - **PR body**: MUST follow this structure:
99057
+
99058
+ \`\`\`
99059
+ ## Problem / Task
99060
+ <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.>
99061
+
99062
+ ## Changes
99063
+ <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.>
99064
+
99065
+ ## Testing
99066
+ <What tests were added, modified, or run. Include:
99067
+ - New test names and what they verify
99068
+ - Whether existing tests still pass
99069
+ - Manual verification steps if applicable
99070
+ - Commands used to validate (e.g. \`make test\`, \`npm test\`)>
99071
+ \`\`\`
99072
+
99073
+ - 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").
99074
+ - 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.`,
98746
99075
  "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.
98747
99076
 
98748
99077
  When troubleshooting:
@@ -112007,6 +112336,7 @@ Follow these instructions carefully:
112007
112336
  * For rewriting entire functions/classes/methods, use the symbol parameter instead (no exact text matching needed).
112008
112337
  * 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.' : ""}
112009
112338
  * 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.
112339
+ * 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.
112010
112340
  - Use 'create' for new files or complete file rewrites.
112011
112341
  - If an edit fails, read the error message \u2014 it tells you exactly how to fix the call and retry.
112012
112342
  - 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.` : ""}