veefore 1.6.0 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/veefore.mjs +84 -8
  2. package/package.json +1 -1
package/dist/veefore.mjs CHANGED
@@ -4376,13 +4376,13 @@ function findGuardedKeys(sources) {
4376
4376
  }
4377
4377
  function dynamicCheckpointKeys(text, file) {
4378
4378
  const found = [];
4379
- const calls = /(?:\b)[A-Za-z_$]*[cC]heckpoint\(\s*([A-Za-z_$][\w$]*(?:\s*(?:\?\.|\.)\s*[A-Za-z_$][\w$]*)+)\s*[,)]/g;
4379
+ const calls = /(?<![\w$.])[A-Za-z_$]*[cC]heckpoint\(\s*([A-Za-z_$][\w$]*(?:\s*(?:\?\.|\.)\s*[A-Za-z_$][\w$]*)*)\s*[,)]/g;
4380
4380
  for (const call of text.matchAll(calls)) {
4381
4381
  const expression = (call[1] ?? "").replace(/\s+/g, "");
4382
4382
  if (expression === "") continue;
4383
4383
  const head = text.slice(Math.max(0, (call.index ?? 0) - 600), call.index ?? 0);
4384
4384
  const [object, ...rest] = expression.split(".");
4385
- if (object === void 0 || rest.length === 0) continue;
4385
+ if (object === void 0) continue;
4386
4386
  const access = rest.map((part) => `\\s*(?:\\?\\.|\\.)\\s*${escapeRegex(part)}`).join("");
4387
4387
  const pattern = new RegExp(
4388
4388
  `(?<![\\w$.])${escapeRegex(object)}${access}\\s*={2,3}\\s*['"\`]([a-z][a-z0-9_]*)['"\`]`,
@@ -6866,7 +6866,7 @@ function planCheckpoints(files, read, toolKeys) {
6866
6866
  const placed = [];
6867
6867
  for (const [at, { keys, site }] of sites) {
6868
6868
  if (/^\s*(?:await\s+)?[A-Za-z_$]*[cC]heckpoint\(/.test(source.slice(at, at + 200))) continue;
6869
- const many = keys.length > 1;
6869
+ const many = keys.length > 1 || site.shared === true;
6870
6870
  const keyExpression = many && site.keyExpression ? site.keyExpression : quote(keys[0] ?? "");
6871
6871
  if (many && !site.keyExpression) continue;
6872
6872
  const args = site.argsExpression ? `, ${site.argsExpression}` : "";
@@ -6892,6 +6892,58 @@ ${blockIndent(source, at)}await ${alias}(${keyExpression}${args});`
6892
6892
  }
6893
6893
  return plans;
6894
6894
  }
6895
+ function planCheckpointRepairs(files, read, toolKeys) {
6896
+ const plans = [];
6897
+ const known = new Set(toolKeys);
6898
+ for (const file of files) {
6899
+ if (file.endsWith(".py") || !JS_EXTENSIONS.test(file)) continue;
6900
+ const source = read(file);
6901
+ if (source === null || !/[cC]heckpoint\(/.test(source)) continue;
6902
+ const structure = readStructure(source);
6903
+ const lineOf = lineLocator2(source);
6904
+ const edits = [];
6905
+ const placed = [];
6906
+ const calls = /(?<![\w$.])([A-Za-z_$]*[cC]heckpoint)\(\s*(['"`])([a-z][a-z0-9_]*)\2/g;
6907
+ for (const match of source.matchAll(calls)) {
6908
+ const key = match[3];
6909
+ if (!known.has(key)) continue;
6910
+ const at = match.index ?? 0;
6911
+ const group = enclosing(structure.parens, at).find(
6912
+ (candidate) => BRANCH_KEYWORDS.has(candidate.name)
6913
+ );
6914
+ const head = group ?? innermostBranchAbove(source, structure, at);
6915
+ if (!head) continue;
6916
+ const compared = comparedKeyExpression(source, head, key);
6917
+ if (!compared) continue;
6918
+ const served = branchKeys(source, head, compared);
6919
+ if (served.length < 2 || !served.includes(key)) continue;
6920
+ const keyStart = at + match[0].indexOf(match[2], match[1].length);
6921
+ edits.push({ start: keyStart, end: keyStart + (key.length + 2), text: compared });
6922
+ for (const served_key of served) {
6923
+ placed.push({ key: served_key, line: lineOf(at), shape: "branch", dynamic: true });
6924
+ }
6925
+ }
6926
+ if (edits.length === 0) continue;
6927
+ plans.push({ file, before: source, after: applyEdits(source, edits), placed });
6928
+ }
6929
+ return plans;
6930
+ }
6931
+ function innermostBranchAbove(source, structure, at) {
6932
+ const body = innermost(
6933
+ structure.blocks.filter((block) => !block.fn),
6934
+ at
6935
+ );
6936
+ if (!body) return null;
6937
+ return structure.parens.filter((group) => BRANCH_KEYWORDS.has(group.name) && group.close < body.open).sort((a, b) => b.close - a.close)[0] ?? null;
6938
+ }
6939
+ function comparedKeyExpression(source, head, key) {
6940
+ const text = source.slice(head.open, head.close);
6941
+ const pattern = new RegExp(
6942
+ `(?<![\\w$.])([A-Za-z_$][\\w$]*(?:\\s*(?:\\?\\.|\\.)\\s*[A-Za-z_$][\\w$]*)*)\\s*={2,3}\\s*['"\`]${escapeForRegex(key)}['"\`]`
6943
+ );
6944
+ const found = pattern.exec(text);
6945
+ return found ? found[1].replace(/\s+/g, "") : null;
6946
+ }
6895
6947
  function checkpointSite(source, key, structure) {
6896
6948
  const quoted = `['"\`]${escapeForRegex(key)}['"\`]`;
6897
6949
  const usable = (at) => awaitAllowed(structure, at) === true;
@@ -6924,11 +6976,13 @@ function checkpointSite(source, key, structure) {
6924
6976
  const compared = comparedExpression(source, at);
6925
6977
  const loop = group.name === "for" ? loopVariable(source, group.open) : null;
6926
6978
  const subject = loop ?? compared?.object ?? null;
6979
+ const served = compared ? branchKeys(source, group, compared.expression) : [];
6927
6980
  return {
6928
6981
  at: insertAt,
6929
6982
  shape: group.name === "if" ? "branch" : "loop",
6930
6983
  argsExpression: subject ? argumentsOf(source, subject) : enclosingArguments(source, structure, insertAt),
6931
- keyExpression: loop ? `${loop}.name` : compared?.expression ?? null
6984
+ keyExpression: loop ? `${loop}.name` : compared?.expression ?? null,
6985
+ shared: served.length > 1
6932
6986
  };
6933
6987
  }
6934
6988
  const declaration = new RegExp(
@@ -6995,9 +7049,22 @@ function positiveComparison(source, at) {
6995
7049
  }
6996
7050
  function comparedExpression(source, at) {
6997
7051
  const before = source.slice(Math.max(0, at - 160), at);
6998
- const match = /([A-Za-z_$][\w$]*)\s*(?:\?\.|\.)\s*([A-Za-z_$][\w$]*)\s*={2,3}\s*$/.exec(before);
6999
- if (!match) return null;
7000
- return { object: match[1], expression: `${match[1]}.${match[2]}` };
7052
+ const member = /([A-Za-z_$][\w$]*)\s*(?:\?\.|\.)\s*([A-Za-z_$][\w$]*)\s*={2,3}\s*$/.exec(before);
7053
+ if (member) return { object: member[1], expression: `${member[1]}.${member[2]}` };
7054
+ const bare = /(?<![\w$.])([A-Za-z_$][\w$]*)\s*={2,3}\s*$/.exec(before);
7055
+ if (bare) return { object: null, expression: bare[1] };
7056
+ return null;
7057
+ }
7058
+ function branchKeys(source, group, expression) {
7059
+ const head = source.slice(group.open, group.close);
7060
+ const [object, ...rest] = expression.split(".");
7061
+ if (object === void 0) return [];
7062
+ const access = rest.map((part) => `\\s*(?:\\?\\.|\\.)\\s*${escapeForRegex(part)}`).join("");
7063
+ const pattern = new RegExp(
7064
+ `(?<![\\w$.])${escapeForRegex(object)}${access}\\s*={2,3}\\s*['"\`]([a-z][a-z0-9_]*)['"\`]`,
7065
+ "g"
7066
+ );
7067
+ return [...new Set([...head.matchAll(pattern)].map((match) => match[1]))];
7001
7068
  }
7002
7069
  function switchKey(source, at) {
7003
7070
  const before = source.slice(Math.max(0, at - 4e3), at);
@@ -7511,6 +7578,15 @@ async function integrate(root, toolKeys, options) {
7511
7578
  dispatch = [];
7512
7579
  }
7513
7580
  }
7581
+ const repaired = applyCheckpoints(
7582
+ plan,
7583
+ planCheckpointRepairs(sourceFiles, (file) => currentText(root, plan, file), toolKeys)
7584
+ );
7585
+ if (repaired.size > 0 && !options.quiet) {
7586
+ out(
7587
+ `${symbol.warn} Corrected a guard that named one tool in a block that runs several: ${style.bold([...repaired].join(", "))} ${style.grey("(it now carries the key your code read)")}`
7588
+ );
7589
+ }
7514
7590
  if (dispatch.length > 0 && checkpointUsable(root, options.quiet === true)) {
7515
7591
  const placed = applyCheckpoints(
7516
7592
  plan,
@@ -8821,7 +8897,7 @@ import { homedir as homedir2 } from "node:os";
8821
8897
  import path12 from "node:path";
8822
8898
 
8823
8899
  // src/version.ts
8824
- var CLI_VERSION = "1.6.0";
8900
+ var CLI_VERSION = "1.6.1";
8825
8901
 
8826
8902
  // src/panel.ts
8827
8903
  function welcomeSource(flags = {}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veefore",
3
- "version": "1.6.0",
3
+ "version": "1.6.1",
4
4
  "description": "Veefore command line: sign in, scan an agent project, set it up and protect its tools.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://veefore.com",