@codacy/verity-cli 0.27.2 → 0.28.1-experimental.b7950e1

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/bin/verity.js +314 -124
  2. package/package.json +1 -5
package/bin/verity.js CHANGED
@@ -10328,7 +10328,7 @@ var {
10328
10328
  var import_node_child_process4 = require("node:child_process");
10329
10329
 
10330
10330
  // src/lib/auth.ts
10331
- var import_promises = require("node:fs/promises");
10331
+ var import_promises2 = require("node:fs/promises");
10332
10332
  var import_node_child_process2 = require("node:child_process");
10333
10333
 
10334
10334
  // src/constants.ts
@@ -10473,7 +10473,7 @@ var SECURITY_PATTERNS = [
10473
10473
  /Dockerfile/
10474
10474
  ];
10475
10475
  var PROD_SERVICE_URL = "https://ofcamwrjwrkazqvdchko.supabase.co/functions/v1";
10476
- var DEFAULT_SERVICE_URL = "".length > 0 ? "" : PROD_SERVICE_URL;
10476
+ var DEFAULT_SERVICE_URL = "https://wukeddyzpijoegyajtnc.supabase.co/functions/v1".length > 0 ? "https://wukeddyzpijoegyajtnc.supabase.co/functions/v1" : PROD_SERVICE_URL;
10477
10477
  var GITHUB_CLIENT_ID = "Iv23li88HxAi3ZrbYzWh";
10478
10478
  var GITHUB_DEVICE_CODE_URL = "https://github.com/login/device/code";
10479
10479
  var GITHUB_ACCESS_TOKEN_URL = "https://github.com/login/oauth/access_token";
@@ -10551,6 +10551,13 @@ function rotateIfNeeded(file) {
10551
10551
  }
10552
10552
 
10553
10553
  // src/lib/api-client.ts
10554
+ function describeFetchError(err, url) {
10555
+ const message = err instanceof Error ? err.message : String(err);
10556
+ const cause = err?.cause;
10557
+ const causeBits = [cause?.code, cause?.hostname].filter(Boolean).join(" ");
10558
+ const detail = causeBits || (cause?.message && cause.message !== message ? cause.message : "");
10559
+ return `${message}${detail ? ` (${detail})` : ""} \u2014 could not reach ${url}`;
10560
+ }
10554
10561
  async function apiRequest(options) {
10555
10562
  const {
10556
10563
  method,
@@ -10606,7 +10613,7 @@ async function apiRequest(options) {
10606
10613
  const duration2 = Date.now() - startedAt;
10607
10614
  const isTimeout = err instanceof DOMException && err.name === "TimeoutError";
10608
10615
  const category = isTimeout ? "timeout" : "network";
10609
- const error = isTimeout ? `Request timed out after ${timeout}ms` : `Network error: ${err.message}`;
10616
+ const error = isTimeout ? `Request timed out after ${timeout}ms (${url})` : `Network error: ${describeFetchError(err, url)}`;
10610
10617
  logHttpCall({ ...logBase, duration_ms: duration2, http_status: null, category, error });
10611
10618
  return { ok: false, error, category, http_status: null };
10612
10619
  }
@@ -10665,6 +10672,60 @@ function analyzeRequest(options) {
10665
10672
  });
10666
10673
  }
10667
10674
 
10675
+ // src/lib/service-url.ts
10676
+ var import_promises = require("node:fs/promises");
10677
+ async function serviceUrlFromCredentials() {
10678
+ try {
10679
+ const creds = await (0, import_promises.readFile)(projectPath(CREDENTIALS_FILE), "utf-8");
10680
+ const match = creds.match(/service_url:\s*(https?:\/\/[^\s]+)/);
10681
+ return match ? match[1] : null;
10682
+ } catch {
10683
+ return null;
10684
+ }
10685
+ }
10686
+ async function serviceUrlFromVerityMd() {
10687
+ try {
10688
+ const content = await (0, import_promises.readFile)(projectPath(VERITY_MD_FILE), "utf-8");
10689
+ const boldLine = content.split("\n").find((l) => /\*\*url\*\*/i.test(l));
10690
+ if (boldLine) {
10691
+ const urlMatch = boldLine.match(/https:\/\/[^\s]+/);
10692
+ if (urlMatch) return urlMatch[0];
10693
+ }
10694
+ const plainLine = content.split("\n").find((l) => /(?:url|service)\s*:/i.test(l));
10695
+ if (plainLine) {
10696
+ const urlMatch = plainLine.match(/https:\/\/[^\s]+/);
10697
+ if (urlMatch) return urlMatch[0];
10698
+ }
10699
+ } catch {
10700
+ }
10701
+ return null;
10702
+ }
10703
+ async function resolveServiceUrlDetailed(flagUrl) {
10704
+ if (flagUrl) {
10705
+ return { ok: true, data: { url: flagUrl, source: "flag" } };
10706
+ }
10707
+ const envUrl = process.env.VERITY_SERVICE_URL;
10708
+ if (envUrl) {
10709
+ return { ok: true, data: { url: envUrl, source: "env" } };
10710
+ }
10711
+ const credsUrl = await serviceUrlFromCredentials();
10712
+ if (credsUrl) {
10713
+ return { ok: true, data: { url: credsUrl, source: "credentials" } };
10714
+ }
10715
+ const mdUrl = await serviceUrlFromVerityMd();
10716
+ if (mdUrl) {
10717
+ return { ok: true, data: { url: mdUrl, source: "verity_md" } };
10718
+ }
10719
+ return { ok: false, error: "No Verity service URL found. Run /verity-setup to configure." };
10720
+ }
10721
+ async function resolveServiceUrl(flagUrl) {
10722
+ const result = await resolveServiceUrlDetailed(flagUrl);
10723
+ return result.ok ? { ok: true, data: result.data.url } : result;
10724
+ }
10725
+ function isHealCandidate(resolved) {
10726
+ return (resolved.source === "credentials" || resolved.source === "verity_md") && resolved.url !== DEFAULT_SERVICE_URL;
10727
+ }
10728
+
10668
10729
  // src/lib/auth.ts
10669
10730
  function parseIdentity(content) {
10670
10731
  const idMatch = content.match(/^user_id:\s*(\d+)/m);
@@ -10683,7 +10744,7 @@ async function resolveToken(flagToken) {
10683
10744
  return { ok: true, data: { token: envToken, source: "env" } };
10684
10745
  }
10685
10746
  try {
10686
- const content = await (0, import_promises.readFile)(projectPath(CREDENTIALS_FILE), "utf-8");
10747
+ const content = await (0, import_promises2.readFile)(projectPath(CREDENTIALS_FILE), "utf-8");
10687
10748
  const match = content.match(/token:\s*((?:gate_|verity_)[a-f0-9]+)/);
10688
10749
  if (match) {
10689
10750
  return { ok: true, data: { token: match[1], source: "local", ...parseIdentity(content) } };
@@ -10692,7 +10753,7 @@ async function resolveToken(flagToken) {
10692
10753
  }
10693
10754
  const globalCredentials = `${process.env.HOME}/.verity/credentials`;
10694
10755
  try {
10695
- const content = await (0, import_promises.readFile)(globalCredentials, "utf-8");
10756
+ const content = await (0, import_promises2.readFile)(globalCredentials, "utf-8");
10696
10757
  let remote = "";
10697
10758
  try {
10698
10759
  remote = (0, import_node_child_process2.execSync)("git remote get-url origin", { encoding: "utf-8" }).trim();
@@ -10721,50 +10782,44 @@ async function whoami(token, serviceUrl, verbose) {
10721
10782
  path: "/auth/whoami",
10722
10783
  serviceUrl,
10723
10784
  token,
10724
- verbose
10785
+ verbose,
10786
+ cmd: "whoami"
10725
10787
  });
10726
10788
  }
10727
-
10728
- // src/lib/service-url.ts
10729
- var import_promises2 = require("node:fs/promises");
10730
- async function resolveServiceUrl(flagUrl) {
10731
- if (flagUrl) {
10732
- return { ok: true, data: flagUrl };
10733
- }
10734
- const envUrl = process.env.VERITY_SERVICE_URL;
10735
- if (envUrl) {
10736
- return { ok: true, data: envUrl };
10789
+ async function probeService(serviceUrl, verbose) {
10790
+ const res = await apiRequest({
10791
+ method: "GET",
10792
+ path: "/auth/whoami",
10793
+ serviceUrl,
10794
+ verbose,
10795
+ timeout: 5e3,
10796
+ cmd: "probe"
10797
+ });
10798
+ if (res.ok || res.http_status != null) return { reachable: true };
10799
+ return { reachable: false, dnsDead: /\bENOTFOUND\b/.test(res.error), error: res.error };
10800
+ }
10801
+ async function maybeHealServiceUrl(resolution, verbose) {
10802
+ if (!isHealCandidate(resolution)) {
10803
+ return { serviceUrl: resolution.url, healed: false };
10737
10804
  }
10738
- try {
10739
- const creds = await (0, import_promises2.readFile)(projectPath(CREDENTIALS_FILE), "utf-8");
10740
- const match = creds.match(/service_url:\s*(https?:\/\/[^\s]+)/);
10741
- if (match) {
10742
- return { ok: true, data: match[1] };
10743
- }
10744
- } catch {
10805
+ const probe = await probeService(resolution.url, verbose);
10806
+ if (probe.reachable) {
10807
+ return { serviceUrl: resolution.url, healed: false };
10745
10808
  }
10746
- try {
10747
- const content = await (0, import_promises2.readFile)(projectPath(VERITY_MD_FILE), "utf-8");
10748
- const boldMatch = content.match(/\*\*url\*\*/i);
10749
- if (boldMatch) {
10750
- const lineMatch = content.split("\n").find((l) => /\*\*url\*\*/i.test(l));
10751
- if (lineMatch) {
10752
- const urlMatch = lineMatch.match(/https:\/\/[^\s]+/);
10753
- if (urlMatch) {
10754
- return { ok: true, data: urlMatch[0] };
10755
- }
10756
- }
10757
- }
10758
- const plainLine = content.split("\n").find((l) => /(?:url|service)\s*:/i.test(l));
10759
- if (plainLine) {
10760
- const urlMatch = plainLine.match(/https:\/\/[^\s]+/);
10761
- if (urlMatch) {
10762
- return { ok: true, data: urlMatch[0] };
10763
- }
10809
+ const from = resolution.source === "credentials" ? ".verity/credentials" : "VERITY.md";
10810
+ printWarn(`Your configured Verity service URL is unreachable: ${resolution.url}`);
10811
+ printInfo(` (${probe.error})`);
10812
+ if (probe.dnsDead && (await probeService(DEFAULT_SERVICE_URL, verbose)).reachable) {
10813
+ printInfo(` The hostname no longer exists \u2014 the URL in ${from} is stale (e.g. a retired preview backend).`);
10814
+ printInfo(` Falling back to the default Verity service: ${DEFAULT_SERVICE_URL}`);
10815
+ if (resolution.source === "verity_md") {
10816
+ printWarn(` Note: VERITY.md still contains the stale URL \u2014 update it to ${DEFAULT_SERVICE_URL} and commit.`);
10764
10817
  }
10765
- } catch {
10818
+ return { serviceUrl: DEFAULT_SERVICE_URL, healed: true };
10766
10819
  }
10767
- return { ok: false, error: "No Verity service URL found. Run /verity-setup to configure." };
10820
+ printInfo(" Continuing against the configured URL. If it is stale, log in against the default with:");
10821
+ printInfo(` VERITY_SERVICE_URL=${DEFAULT_SERVICE_URL} verity login`);
10822
+ return { serviceUrl: resolution.url, healed: false };
10768
10823
  }
10769
10824
 
10770
10825
  // src/lib/register.ts
@@ -11185,7 +11240,8 @@ async function registerProject(opts) {
11185
11240
  serviceUrl: opts.serviceUrl,
11186
11241
  body: { project_name: opts.projectName, git_remote_url: opts.remote },
11187
11242
  extraHeaders: { "X-Provider-Token": providerToken },
11188
- verbose: opts.verbose
11243
+ verbose: opts.verbose,
11244
+ cmd: "register"
11189
11245
  });
11190
11246
  if (!result.ok) {
11191
11247
  return { ok: false, error: result.error };
@@ -11321,14 +11377,18 @@ var import_node_path4 = require("node:path");
11321
11377
  function registerLoginCommand(program2) {
11322
11378
  program2.command("login").description("Log in to Verity (link your GitHub identity so runs and memory are saved)").option("--force", "Re-authenticate even if already logged in").action(async (opts) => {
11323
11379
  const globals = program2.opts();
11324
- const urlResult = await resolveServiceUrl(globals.serviceUrl);
11380
+ const urlResult = await resolveServiceUrlDetailed(globals.serviceUrl);
11325
11381
  if (!urlResult.ok) {
11326
11382
  printError(urlResult.error);
11327
11383
  process.exit(1);
11328
11384
  }
11329
- const serviceUrl = urlResult.data;
11385
+ const heal = await maybeHealServiceUrl(urlResult.data, globals.verbose);
11386
+ const serviceUrl = heal.serviceUrl;
11387
+ if (heal.healed) {
11388
+ printInfo(" Completing login re-registers this project and updates .verity/credentials.");
11389
+ }
11330
11390
  const existing = await resolveToken(globals.token);
11331
- if (existing.ok && !opts.force) {
11391
+ if (existing.ok && !opts.force && !heal.healed) {
11332
11392
  if (existing.data.userId != null) {
11333
11393
  printInfo(`Already logged in as ${existing.data.email ?? `user #${existing.data.userId}`}. \u2713`);
11334
11394
  printInfo(" Re-authenticate with: verity login --force");
@@ -11827,7 +11887,7 @@ function registerHooksCommands(program2) {
11827
11887
  }
11828
11888
 
11829
11889
  // src/commands/intent.ts
11830
- var import_node_crypto3 = require("node:crypto");
11890
+ var import_node_crypto4 = require("node:crypto");
11831
11891
 
11832
11892
  // src/lib/conversation-buffer.ts
11833
11893
  var import_promises6 = require("node:fs/promises");
@@ -11946,6 +12006,19 @@ function getRecentCommitMessages() {
11946
12006
  }
11947
12007
  }
11948
12008
 
12009
+ // src/lib/context-identity.ts
12010
+ var import_node_crypto2 = require("node:crypto");
12011
+ function contextIdentity(token, sessionId) {
12012
+ const t = (token ?? "").trim();
12013
+ const s = (sessionId ?? "").trim();
12014
+ const userKey = t.length > 0 ? (0, import_node_crypto2.createHash)("sha256").update(t).digest("hex").slice(0, 12) : "anon";
12015
+ const sessionKey2 = s.length > 0 ? (0, import_node_crypto2.createHash)("sha256").update(s).digest("hex").slice(0, 16) : "_default";
12016
+ return { userKey, sessionKey: sessionKey2, bucket: `${userKey}/${sessionKey2}` };
12017
+ }
12018
+ function sessionScopeKey(token, sessionId) {
12019
+ return contextIdentity(token, sessionId).bucket;
12020
+ }
12021
+
11949
12022
  // src/lib/task-context-buffer.ts
11950
12023
  var import_promises7 = require("node:fs/promises");
11951
12024
  var import_node_fs4 = require("node:fs");
@@ -12233,7 +12306,7 @@ async function retrieveForInjection(promptText, taskFiles = [], budgetTokens = D
12233
12306
  var import_promises9 = require("node:fs/promises");
12234
12307
  var import_node_fs6 = require("node:fs");
12235
12308
  var import_node_path9 = require("node:path");
12236
- var import_node_crypto2 = require("node:crypto");
12309
+ var import_node_crypto3 = require("node:crypto");
12237
12310
 
12238
12311
  // src/lib/glob-match.ts
12239
12312
  function globToRegex(glob) {
@@ -12331,7 +12404,7 @@ async function buildManifest() {
12331
12404
  const fullPath = (0, import_node_path9.join)(memoryDir2(), filePath);
12332
12405
  try {
12333
12406
  const content = await (0, import_promises9.readFile)(fullPath, "utf-8");
12334
- const hash = (0, import_node_crypto2.createHash)("sha256").update(content).digest("hex").slice(0, 16);
12407
+ const hash = (0, import_node_crypto3.createHash)("sha256").update(content).digest("hex").slice(0, 16);
12335
12408
  nodes.push({ path: filePath, content_hash: `sha256:${hash}` });
12336
12409
  } catch {
12337
12410
  }
@@ -12342,7 +12415,7 @@ async function buildManifest() {
12342
12415
  let indexHash = null;
12343
12416
  try {
12344
12417
  const indexContent = await (0, import_promises9.readFile)((0, import_node_path9.join)(memoryDir2(), "index.md"), "utf-8");
12345
- indexHash = `sha256:${(0, import_node_crypto2.createHash)("sha256").update(indexContent).digest("hex").slice(0, 16)}`;
12418
+ indexHash = `sha256:${(0, import_node_crypto3.createHash)("sha256").update(indexContent).digest("hex").slice(0, 16)}`;
12346
12419
  } catch {
12347
12420
  }
12348
12421
  let logLength = 0;
@@ -12354,7 +12427,7 @@ async function buildManifest() {
12354
12427
  return { schema_version: 1, nodes, index_hash: indexHash, log_length: logLength };
12355
12428
  }
12356
12429
  function hashContent(content) {
12357
- return `sha256:${(0, import_node_crypto2.createHash)("sha256").update(content).digest("hex").slice(0, 16)}`;
12430
+ return `sha256:${(0, import_node_crypto3.createHash)("sha256").update(content).digest("hex").slice(0, 16)}`;
12358
12431
  }
12359
12432
  async function readOnDiskNodes() {
12360
12433
  const out = /* @__PURE__ */ new Map();
@@ -12799,7 +12872,10 @@ function registerIntentCommands(program2) {
12799
12872
  if (!prompt) {
12800
12873
  process.exit(0);
12801
12874
  }
12802
- await appendToConversationBuffer(prompt, event.session_id ?? "");
12875
+ const authForScope = await resolveToken(program2.opts().token);
12876
+ const scopeToken = authForScope.ok ? authForScope.data.token : void 0;
12877
+ const scopeSession = event.session_id || process.env.CLAUDE_SESSION_ID || "";
12878
+ await appendToConversationBuffer(prompt, sessionScopeKey(scopeToken, scopeSession));
12803
12879
  try {
12804
12880
  await ensureMemoryDir();
12805
12881
  const injection = await retrieveForInjection(prompt);
@@ -12841,7 +12917,7 @@ async function fireClassify(prompt, sessionId) {
12841
12917
  logEvent("classify_skipped", { reason: "no_service_url", detail: urlResult.error });
12842
12918
  return;
12843
12919
  }
12844
- const promptHash = (0, import_node_crypto3.createHash)("sha256").update(prompt).digest("hex");
12920
+ const promptHash = (0, import_node_crypto4.createHash)("sha256").update(prompt).digest("hex");
12845
12921
  const result = await apiRequest({
12846
12922
  method: "POST",
12847
12923
  path: "/classify-task",
@@ -13499,10 +13575,10 @@ function collectCodeDelta(files, opts) {
13499
13575
 
13500
13576
  // src/lib/debounce.ts
13501
13577
  var import_node_fs9 = require("node:fs");
13502
- var import_node_crypto4 = require("node:crypto");
13578
+ var import_node_crypto5 = require("node:crypto");
13503
13579
  function scopedFile(base, sessionId) {
13504
13580
  if (!sessionId) return base;
13505
- return `${base}.${(0, import_node_crypto4.createHash)("sha1").update(sessionId).digest("hex").slice(0, 12)}`;
13581
+ return `${base}.${(0, import_node_crypto5.createHash)("sha1").update(sessionId).digest("hex").slice(0, 12)}`;
13506
13582
  }
13507
13583
  function checkDebounce(debounceSeconds = DEBOUNCE_SECONDS, sessionId) {
13508
13584
  const file = scopedFile(DEBOUNCE_FILE, sessionId);
@@ -13543,7 +13619,7 @@ function checkMtime(files, bypassForRecentCommits, sessionId) {
13543
13619
  return "No files modified since last analysis";
13544
13620
  }
13545
13621
  function computeContentHash(files) {
13546
- const hash = (0, import_node_crypto4.createHash)("sha1");
13622
+ const hash = (0, import_node_crypto5.createHash)("sha1");
13547
13623
  const sorted = [...files].sort();
13548
13624
  for (const f of sorted) {
13549
13625
  const resolved = resolveFile(f) ?? f;
@@ -13931,14 +14007,14 @@ function cleanStaleSnapshots(dir, keepSet) {
13931
14007
  // src/lib/baseline.ts
13932
14008
  var import_node_fs13 = require("node:fs");
13933
14009
  var import_node_path13 = require("node:path");
13934
- var import_node_crypto5 = require("node:crypto");
14010
+ var import_node_crypto6 = require("node:crypto");
13935
14011
  var BASELINE_VERSION = 1;
13936
14012
  var BASELINE_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
13937
14013
  var MIRROR_MAX_BYTES = 2 * 1024 * 1024;
13938
14014
  var DEFAULT_SESSION_KEY = "_default";
13939
14015
  function sessionKey(sessionId) {
13940
14016
  if (!sessionId) return DEFAULT_SESSION_KEY;
13941
- return (0, import_node_crypto5.createHash)("sha256").update(sessionId).digest("hex").slice(0, 16);
14017
+ return (0, import_node_crypto6.createHash)("sha256").update(sessionId).digest("hex").slice(0, 16);
13942
14018
  }
13943
14019
  function sessionDir(key) {
13944
14020
  return (0, import_node_path13.join)(projectPath(BASELINE_DIR), key);
@@ -14120,13 +14196,57 @@ function pruneOldBaselines() {
14120
14196
  }
14121
14197
  }
14122
14198
 
14199
+ // src/lib/task-context.ts
14200
+ var import_node_child_process9 = require("node:child_process");
14201
+ var CLOSING_RE = /\b(close[sd]?|fix(?:e[sd])?|resolve[sd]?)\b[\s:]*#(\d+)/i;
14202
+ var BRANCH_RE = /(?:^|[/_-])(?:issue|gh|fix)[-_/]?(\d+)\b/i;
14203
+ function parseLinkedIssue(sources) {
14204
+ for (const c of sources.commits ?? []) {
14205
+ const m = CLOSING_RE.exec(c);
14206
+ if (m) return { issue: parseInt(m[2], 10), via: `commit:${m[1].toLowerCase()}` };
14207
+ }
14208
+ if (sources.branch) {
14209
+ const m = BRANCH_RE.exec(sources.branch);
14210
+ if (m) return { issue: parseInt(m[1], 10), via: "branch" };
14211
+ }
14212
+ return null;
14213
+ }
14214
+ function safeExec(cmd, timeout) {
14215
+ try {
14216
+ return (0, import_node_child_process9.execSync)(cmd, { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout }).trim();
14217
+ } catch {
14218
+ return "";
14219
+ }
14220
+ }
14221
+ function defaultGhFetch(issue) {
14222
+ const raw = safeExec(`gh issue view ${issue} --json title,body`, 5e3);
14223
+ if (!raw) return null;
14224
+ try {
14225
+ const j = JSON.parse(raw);
14226
+ return j.title ? { title: j.title, body: j.body ?? "" } : null;
14227
+ } catch {
14228
+ return null;
14229
+ }
14230
+ }
14231
+ function resolveTaskContext(opts) {
14232
+ const branch = opts?.branch ?? safeExec("git rev-parse --abbrev-ref HEAD", 3e3);
14233
+ const commits = opts?.commits ?? safeExec("git log -5 --format=%s%n%b", 3e3).split("\n").map((l) => l.trim()).filter(Boolean);
14234
+ const linked = parseLinkedIssue({ branch, commits });
14235
+ if (!linked) return null;
14236
+ const issue = (opts?.ghFetch ?? defaultGhFetch)(linked.issue);
14237
+ if (!issue) return null;
14238
+ const body = (issue.body ?? "").slice(0, 4e3).trim();
14239
+ const goal = `[#${linked.issue}] ${issue.title}${body ? "\n\n" + body : ""}`;
14240
+ return { number: linked.issue, title: issue.title, goal, via: linked.via };
14241
+ }
14242
+
14123
14243
  // src/lib/offline.ts
14124
14244
  var import_node_fs14 = require("node:fs");
14125
- var import_node_crypto6 = require("node:crypto");
14245
+ var import_node_crypto7 = require("node:crypto");
14126
14246
  function cacheRequest(body) {
14127
14247
  try {
14128
14248
  (0, import_node_fs14.mkdirSync)(CACHE_DIR, { recursive: true });
14129
- const suffix = (0, import_node_crypto6.randomBytes)(4).toString("hex");
14249
+ const suffix = (0, import_node_crypto7.randomBytes)(4).toString("hex");
14130
14250
  const filename = `pending-${Math.floor(Date.now() / 1e3)}-${suffix}.json`;
14131
14251
  (0, import_node_fs14.writeFileSync)(`${CACHE_DIR}/${filename}`, JSON.stringify(body));
14132
14252
  } catch {
@@ -14331,6 +14451,30 @@ function detectAnalysisMode(noFilesChanged, assistantResponse, conversationPromp
14331
14451
  }
14332
14452
  return "standard";
14333
14453
  }
14454
+ var FILE_MUTATE_RE = /(?:^|[\s|&;(`])(?:sed\s+-i|perl\s+-i|awk\b|tee\b|dd\b|cp\b|mv\b|ln\b|install\b|touch\b|patch\b|git\s+(?:apply|am)\b|cargo\s+build|go\s+generate|make\b|--write\b|--fix\b|--in-place\b)|>>?(?![&>])/i;
14455
+ var GIT_PLUMBING_RE = /^\s*git\s+(?:merge|rebase|stash|cherry-pick|revert|pull|fetch|checkout|switch|reset|restore|clean)\b/i;
14456
+ var READ_ONLY_RE = /^\s*(?:git\s+(?:status|diff|log|show|branch|remote|config|rev-parse|ls-files|blame|describe)|ls|cat|head|tail|less|grep|rg|find|pwd|echo|printf|wc|which|type|tree|stat|file|env|printenv|date|whoami)\b/i;
14457
+ var CHAIN_RE = /&&|\||;|\$\(|\x60/;
14458
+ function hasNonEditAuthorship(actionSummary, sessionAuthoredCode) {
14459
+ if (!actionSummary) return sessionAuthoredCode;
14460
+ if ((actionSummary.subagents ?? 0) > 0) return true;
14461
+ if (Object.keys(actionSummary.tool_counts ?? {}).some((t) => t.startsWith("mcp__"))) return true;
14462
+ const commands = actionSummary.commands ?? [];
14463
+ if (commands.some((c) => FILE_MUTATE_RE.test(c))) return true;
14464
+ if (sessionAuthoredCode) {
14465
+ const allSafe = commands.length > 0 && commands.every(
14466
+ (c) => !CHAIN_RE.test(c) && (GIT_PLUMBING_RE.test(c) || READ_ONLY_RE.test(c))
14467
+ );
14468
+ if (!allSafe) return true;
14469
+ }
14470
+ return false;
14471
+ }
14472
+ function scopeToAuthored(files, actionSummary) {
14473
+ if (!actionSummary) return { files, signal: "no-transcript" };
14474
+ const touched = [...actionSummary.files_edited ?? [], ...actionSummary.files_created ?? []];
14475
+ if (touched.length === 0) return { files: [], signal: "none-authored" };
14476
+ return { files: narrowToAgentAuthored(files, actionSummary), signal: "authored" };
14477
+ }
14334
14478
  function narrowToAgentAuthored(files, actionSummary) {
14335
14479
  if (!actionSummary) return files;
14336
14480
  const touched = [
@@ -14533,6 +14677,7 @@ function buildSummary(lines) {
14533
14677
  searches++;
14534
14678
  break;
14535
14679
  case "Agent":
14680
+ case "Task":
14536
14681
  subagents++;
14537
14682
  break;
14538
14683
  case "WebFetch":
@@ -14585,19 +14730,48 @@ function addPath(set, rawPath) {
14585
14730
  function sanitizeCommand(rawCmd) {
14586
14731
  if (typeof rawCmd !== "string" || !rawCmd) return null;
14587
14732
  let cmd = rawCmd.split("\n")[0];
14733
+ let cut = -1;
14734
+ let marker = "";
14588
14735
  for (const sep of [" | ", " > ", " >> ", " 2>", " && ", " ; "]) {
14589
14736
  const idx = cmd.indexOf(sep);
14590
- if (idx > 0) cmd = cmd.slice(0, idx);
14737
+ if (idx > 0 && (cut === -1 || idx < cut)) {
14738
+ cut = idx;
14739
+ marker = sep.trim();
14740
+ }
14591
14741
  }
14742
+ if (cut > -1) cmd = cmd.slice(0, cut);
14592
14743
  if (cmd.length > MAX_COMMAND_CHARS) {
14593
14744
  cmd = cmd.slice(0, MAX_COMMAND_CHARS);
14594
14745
  }
14595
- return cmd.trim() || null;
14746
+ cmd = cmd.trim();
14747
+ if (marker) cmd = cmd ? `${cmd} ${marker}` : marker;
14748
+ return cmd || null;
14596
14749
  }
14597
14750
  function capArray(set, max) {
14598
14751
  return Array.from(set).slice(0, max);
14599
14752
  }
14600
14753
 
14754
+ // src/lib/run-mode.ts
14755
+ function parseAutonomousEnv(raw) {
14756
+ if (raw === void 0) return void 0;
14757
+ const v = raw.trim().toLowerCase();
14758
+ if (v === "") return void 0;
14759
+ if (v === "0" || v === "false" || v === "off" || v === "no") return false;
14760
+ return true;
14761
+ }
14762
+ function resolveRunMode(inputs = {}) {
14763
+ if (inputs.autonomousFlag === true) return "autonomous";
14764
+ if (inputs.autonomousFlag === false) return "interactive";
14765
+ const env = inputs.env ?? process.env;
14766
+ const envDecision = parseAutonomousEnv(env.VERITY_AUTONOMOUS);
14767
+ if (envDecision !== void 0) return envDecision ? "autonomous" : "interactive";
14768
+ const isTTY = inputs.isTTY ?? Boolean(process.stdin?.isTTY);
14769
+ return isTTY ? "interactive" : "autonomous";
14770
+ }
14771
+ function isExplicitlyAutonomous(env = process.env) {
14772
+ return parseAutonomousEnv(env.VERITY_AUTONOMOUS) === true || parseAutonomousEnv(env.CI) === true || parseAutonomousEnv(env.GITHUB_ACTIONS) === true;
14773
+ }
14774
+
14601
14775
  // src/lib/seed-runner.ts
14602
14776
  var import_promises12 = require("node:fs/promises");
14603
14777
  var import_node_fs18 = require("node:fs");
@@ -15012,7 +15186,10 @@ async function runAnalyze(opts, globals) {
15012
15186
  }
15013
15187
  const { assistantMessage: assistantResponse, stopReason, transcriptPath, sessionId } = await readStopHookStdin();
15014
15188
  const actionSummary = transcriptPath ? await extractActionSummary(transcriptPath) : null;
15015
- const baselineSessionId = sessionId || process.env.CLAUDE_SESSION_ID || void 0;
15189
+ const tokenResult = await resolveToken(globals.token);
15190
+ const scopeToken = tokenResult.ok ? tokenResult.data.token : void 0;
15191
+ const rawSessionId = sessionId || process.env.CLAUDE_SESSION_ID || void 0;
15192
+ const baselineSessionId = sessionScopeKey(scopeToken, rawSessionId);
15016
15193
  const baseline = readBaseline(baselineSessionId);
15017
15194
  if (baseline) {
15018
15195
  logEvent("baseline_loaded", {
@@ -15030,7 +15207,7 @@ async function runAnalyze(opts, globals) {
15030
15207
  passAndExit("No analyzable files changed");
15031
15208
  }
15032
15209
  const allForReview = Array.from(/* @__PURE__ */ new Set([...analyzable, ...reviewable]));
15033
- const conversation = await readAndClearConversationBuffer(sessionId ?? void 0);
15210
+ const conversation = await readAndClearConversationBuffer(baselineSessionId);
15034
15211
  const specs = discoverSpecs();
15035
15212
  const plans = discoverPlans();
15036
15213
  const latestPrompt = conversation?.prompts?.[conversation.prompts.length - 1]?.prompt ?? "";
@@ -15044,7 +15221,6 @@ async function runAnalyze(opts, globals) {
15044
15221
  if (isReflectionQuestion(assistantResponse) && !agentAuthoredCodeThisTurn) {
15045
15222
  passAndExit("Reflection-prompt turn \u2014 skipping analysis");
15046
15223
  }
15047
- const tokenResult = await resolveToken(globals.token);
15048
15224
  const urlResult = await resolveServiceUrl(globals.serviceUrl);
15049
15225
  if (!tokenResult.ok || !urlResult.ok) {
15050
15226
  localOnlyAndExit(runLocalStatic(analyzable, securityFiles, baseline, !!opts.skipStatic));
@@ -15138,8 +15314,11 @@ async function runAnalyze(opts, globals) {
15138
15314
  }
15139
15315
  contentHash = hashResult.hash;
15140
15316
  if (analysisMode !== "plan") {
15141
- const agentNarrowed = narrowToAgentAuthored(allForReview, actionSummary);
15142
- const baseForReview = agentNarrowed.length > 0 ? agentNarrowed : allForReview;
15317
+ const scoped = scopeToAuthored(allForReview, actionSummary);
15318
+ if (scoped.signal === "none-authored" && !hasNonEditAuthorship(actionSummary, sessionAuthoredCode)) {
15319
+ passAndExit("No agent-authored code this turn \u2014 working-tree changes were not authored by this session");
15320
+ }
15321
+ const baseForReview = scoped.signal === "authored" && scoped.files.length > 0 ? scoped.files : allForReview;
15143
15322
  const recentForReview = narrowToRecent(baseForReview, baselineSessionId);
15144
15323
  if (!opts.skipStatic && isCodacyAvailable()) {
15145
15324
  let allScannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles]));
@@ -15269,7 +15448,9 @@ async function runAnalyze(opts, globals) {
15269
15448
  if (snapshotResult.has_snapshots && snapshotResult.diffs.length > 0) {
15270
15449
  requestBody.snapshot_diffs = snapshotResult.diffs;
15271
15450
  }
15272
- const hasIntent = (conversation?.prompts?.length ?? 0) > 0 || specs.length > 0 || plans.length > 0 || !!assistantResponse;
15451
+ const noHumanPrompt = (conversation?.prompts?.length ?? 0) === 0;
15452
+ const w4Task = noHumanPrompt && isExplicitlyAutonomous() ? resolveTaskContext() : null;
15453
+ const hasIntent = (conversation?.prompts?.length ?? 0) > 0 || specs.length > 0 || plans.length > 0 || !!assistantResponse || !!w4Task;
15273
15454
  if (hasIntent) {
15274
15455
  const intentContext = {};
15275
15456
  if (conversation && conversation.prompts.length > 0) {
@@ -15284,6 +15465,10 @@ async function runAnalyze(opts, globals) {
15284
15465
  intentContext.recent_commits = conversation.recent_commits;
15285
15466
  }
15286
15467
  }
15468
+ if (w4Task && !intentContext.user_prompt) {
15469
+ intentContext.user_prompt = w4Task.goal;
15470
+ logEvent("w4_issue_anchor", { issue: w4Task.number, via: w4Task.via });
15471
+ }
15287
15472
  if (assistantResponse) {
15288
15473
  const cap = analysisMode === "plan" ? MAX_ASSISTANT_RESPONSE_CHARS_PLAN : MAX_ASSISTANT_RESPONSE_CHARS_DEFAULT;
15289
15474
  intentContext.assistant_response = assistantResponse.length > cap ? assistantResponse.slice(0, cap) : assistantResponse;
@@ -15576,7 +15761,10 @@ function registerBaselineCommands(program2) {
15576
15761
  }
15577
15762
  }
15578
15763
  }
15579
- const result = captureBaseline({ sessionId, source });
15764
+ const authForScope = await resolveToken(program2.opts().token);
15765
+ const scopeToken = authForScope.ok ? authForScope.data.token : void 0;
15766
+ const scopeSession = sessionId || process.env.CLAUDE_SESSION_ID || void 0;
15767
+ const result = captureBaseline({ sessionId: sessionScopeKey(scopeToken, scopeSession), source });
15580
15768
  logEvent("baseline_capture", {
15581
15769
  created: result.created,
15582
15770
  source: source ?? null,
@@ -16022,20 +16210,20 @@ function writeBlockMessage(moment, response) {
16022
16210
  var import_node_fs24 = require("node:fs");
16023
16211
  var import_promises13 = require("node:fs/promises");
16024
16212
  var import_node_path19 = require("node:path");
16025
- var import_node_child_process10 = require("node:child_process");
16213
+ var import_node_child_process11 = require("node:child_process");
16026
16214
  var readline2 = __toESM(require("node:readline/promises"));
16027
16215
 
16028
16216
  // src/commands/migrate.ts
16029
16217
  var import_node_fs23 = require("node:fs");
16030
16218
  var import_node_path18 = require("node:path");
16031
- var import_node_child_process9 = require("node:child_process");
16219
+ var import_node_child_process10 = require("node:child_process");
16032
16220
  var LEGACY_NPM_PACKAGE = "@codacy/gate-cli";
16033
16221
  function defaultNpmRemover(pkg) {
16034
- (0, import_node_child_process9.execSync)(`npm rm -g ${pkg}`, { stdio: "pipe", timeout: 12e4 });
16222
+ (0, import_node_child_process10.execSync)(`npm rm -g ${pkg}`, { stdio: "pipe", timeout: 12e4 });
16035
16223
  }
16036
16224
  function isGitTracked(cwd, relPath) {
16037
16225
  try {
16038
- (0, import_node_child_process9.execSync)(`git ls-files --error-unmatch ${relPath}`, { cwd, stdio: "pipe" });
16226
+ (0, import_node_child_process10.execSync)(`git ls-files --error-unmatch ${relPath}`, { cwd, stdio: "pipe" });
16039
16227
  return true;
16040
16228
  } catch {
16041
16229
  return false;
@@ -16043,7 +16231,7 @@ function isGitTracked(cwd, relPath) {
16043
16231
  }
16044
16232
  function isGitRepo(cwd) {
16045
16233
  try {
16046
- (0, import_node_child_process9.execSync)("git rev-parse --is-inside-work-tree", { cwd, stdio: "pipe" });
16234
+ (0, import_node_child_process10.execSync)("git rev-parse --is-inside-work-tree", { cwd, stdio: "pipe" });
16047
16235
  return true;
16048
16236
  } catch {
16049
16237
  return false;
@@ -16082,7 +16270,7 @@ function migrateProjectDirRename(root, gateDir, verityDir, actions) {
16082
16270
  );
16083
16271
  }
16084
16272
  try {
16085
- (0, import_node_child_process9.execSync)("git mv .gate .verity", { cwd: root, stdio: "pipe" });
16273
+ (0, import_node_child_process10.execSync)("git mv .gate .verity", { cwd: root, stdio: "pipe" });
16086
16274
  actions.push("Moved .gate/ \u2192 .verity/ (git mv, staged)");
16087
16275
  moved = true;
16088
16276
  } catch {
@@ -16161,7 +16349,7 @@ function migrateStandardFile(root, actions) {
16161
16349
  let moved = false;
16162
16350
  if (isGitRepo(root) && isGitTracked(root, "GATE.md")) {
16163
16351
  try {
16164
- (0, import_node_child_process9.execSync)("git mv GATE.md VERITY.md", { cwd: root, stdio: "pipe" });
16352
+ (0, import_node_child_process10.execSync)("git mv GATE.md VERITY.md", { cwd: root, stdio: "pipe" });
16165
16353
  moved = true;
16166
16354
  } catch {
16167
16355
  }
@@ -16217,7 +16405,7 @@ function readFileSyncSafe(path) {
16217
16405
  }
16218
16406
  function hasStagedChanges(root) {
16219
16407
  try {
16220
- (0, import_node_child_process9.execSync)("git diff --cached --quiet", { cwd: root, stdio: "pipe" });
16408
+ (0, import_node_child_process10.execSync)("git diff --cached --quiet", { cwd: root, stdio: "pipe" });
16221
16409
  return false;
16222
16410
  } catch {
16223
16411
  return true;
@@ -16313,30 +16501,47 @@ async function promptYes(question) {
16313
16501
  rl.close();
16314
16502
  }
16315
16503
  }
16316
- async function runOptionalAuth(serviceUrl) {
16317
- const existing = await resolveToken();
16318
- if (existing.ok) {
16319
- const who = await whoami(existing.data.token, serviceUrl);
16320
- if (who.ok && who.data.logged_in) {
16321
- printInfo(`Logged in as ${who.data.email ?? `user #${who.data.user_id}`} \u2713 \u2014 runs & memory sync to Verity.`);
16322
- return;
16504
+ async function confirmExistingLogin(serviceUrl, opts) {
16505
+ const existing = await resolveToken(opts.token);
16506
+ if (!existing.ok) return "drive-login";
16507
+ const who = await whoami(existing.data.token, serviceUrl, opts.verbose);
16508
+ if (who.ok && who.data.logged_in) {
16509
+ printInfo(`Logged in as ${who.data.email ?? `user #${who.data.user_id}`} \u2713 \u2014 runs & memory sync to Verity.`);
16510
+ return "handled";
16511
+ }
16512
+ if (!who.ok) {
16513
+ if (existing.data.userId != null) {
16514
+ printInfo(`Logged in as ${existing.data.email ?? `user #${existing.data.userId}`} (cached \u2014 could not reach the Verity service). \u2713`);
16515
+ } else {
16516
+ printInfo("Could not confirm your login state with the service; continuing with your existing token.");
16517
+ printInfo(` (${who.error})`);
16323
16518
  }
16324
- if (!who.ok) {
16325
- if (existing.data.userId != null) {
16326
- printInfo(`Logged in as ${existing.data.email ?? `user #${existing.data.userId}`} (cached \u2014 could not reach the Verity service). \u2713`);
16327
- } else {
16328
- printInfo("Could not confirm your login state with the service; continuing with your existing token.");
16329
- }
16330
- return;
16519
+ return "handled";
16520
+ }
16521
+ console.log("");
16522
+ printWarn("You are NOT logged in \u2014 this project has only an anonymous token.");
16523
+ printInfo(" The gate still runs, but no runs are saved and Verity keeps no memory of this project.");
16524
+ printInfo(" Log in below to unlock run history, trends, and cloud memory (strongly recommended).");
16525
+ return "drive-login";
16526
+ }
16527
+ async function runOptionalAuth(resolution, opts = {}) {
16528
+ let serviceUrl = resolution?.url ?? DEFAULT_SERVICE_URL;
16529
+ let healed = false;
16530
+ if (resolution) {
16531
+ const heal = await maybeHealServiceUrl(resolution, opts.verbose);
16532
+ serviceUrl = heal.serviceUrl;
16533
+ healed = heal.healed;
16534
+ if (healed) {
16535
+ printInfo(" Log in below to re-register this project and repair .verity/credentials.");
16331
16536
  }
16332
- console.log("");
16333
- printWarn("You are NOT logged in \u2014 this project has only an anonymous token.");
16334
- printInfo(" The gate still runs, but no runs are saved and Verity keeps no memory of this project.");
16335
- printInfo(" Log in below to unlock run history, trends, and cloud memory (strongly recommended).");
16537
+ }
16538
+ if (!healed) {
16539
+ const state = await confirmExistingLogin(serviceUrl, opts);
16540
+ if (state === "handled") return;
16336
16541
  }
16337
16542
  let remote = "";
16338
16543
  try {
16339
- remote = (0, import_node_child_process10.execSync)("git remote get-url origin", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
16544
+ remote = (0, import_node_child_process11.execSync)("git remote get-url origin", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
16340
16545
  } catch {
16341
16546
  }
16342
16547
  const localOnlyNote = () => {
@@ -16369,7 +16574,7 @@ async function runOptionalAuth(serviceUrl) {
16369
16574
  }
16370
16575
  const projectName = parseRemote(remote)?.repo ?? (0, import_node_path19.basename)(process.cwd());
16371
16576
  printInfo("Authenticating with GitHub\u2026");
16372
- const result = await registerProject({ projectName, remote, serviceUrl });
16577
+ const result = await registerProject({ projectName, remote, serviceUrl, verbose: opts.verbose });
16373
16578
  if (result.ok) {
16374
16579
  const who = result.data.email ?? (result.data.userId != null ? `user #${result.data.userId}` : null);
16375
16580
  printInfo(`Logged in${who ? ` as ${who}` : ""} \u2713 \u2014 runs, history, and cloud memory now sync to Verity.`);
@@ -16432,30 +16637,30 @@ function registerInitCommand(program2) {
16432
16637
  }
16433
16638
  printInfo(` Node.js ${nodeVersion} \u2713`);
16434
16639
  try {
16435
- const gitVersion = (0, import_node_child_process10.execSync)("git --version", { encoding: "utf-8" }).trim();
16640
+ const gitVersion = (0, import_node_child_process11.execSync)("git --version", { encoding: "utf-8" }).trim();
16436
16641
  printInfo(` ${gitVersion} \u2713`);
16437
16642
  } catch {
16438
16643
  printError("git is required but not installed. Install from https://git-scm.com");
16439
16644
  process.exit(1);
16440
16645
  }
16441
16646
  try {
16442
- (0, import_node_child_process10.execSync)("which claude", { encoding: "utf-8" });
16647
+ (0, import_node_child_process11.execSync)("which claude", { encoding: "utf-8" });
16443
16648
  printInfo(" Claude Code \u2713");
16444
16649
  } catch {
16445
16650
  printWarn(" Claude Code not found \u2014 hooks will be configured but need Claude Code to run.");
16446
16651
  }
16447
16652
  try {
16448
- (0, import_node_child_process10.execSync)("which codacy-analysis", { encoding: "utf-8", stdio: "pipe" });
16653
+ (0, import_node_child_process11.execSync)("which codacy-analysis", { encoding: "utf-8", stdio: "pipe" });
16449
16654
  printInfo(" @codacy/analysis-cli \u2713");
16450
16655
  } catch {
16451
16656
  printInfo(" Installing @codacy/analysis-cli...");
16452
16657
  try {
16453
- (0, import_node_child_process10.execSync)("npm install -g @codacy/analysis-cli", { encoding: "utf-8", stdio: "pipe", timeout: 12e4 });
16658
+ (0, import_node_child_process11.execSync)("npm install -g @codacy/analysis-cli", { encoding: "utf-8", stdio: "pipe", timeout: 12e4 });
16454
16659
  printInfo(" @codacy/analysis-cli installed \u2713");
16455
16660
  } catch {
16456
16661
  try {
16457
16662
  printWarn(" Retrying with sudo...");
16458
- (0, import_node_child_process10.execSync)("sudo npm install -g @codacy/analysis-cli", { encoding: "utf-8", stdio: "inherit", timeout: 12e4 });
16663
+ (0, import_node_child_process11.execSync)("sudo npm install -g @codacy/analysis-cli", { encoding: "utf-8", stdio: "inherit", timeout: 12e4 });
16459
16664
  printInfo(" @codacy/analysis-cli installed \u2713");
16460
16665
  } catch {
16461
16666
  printWarn(" Could not install @codacy/analysis-cli automatically.");
@@ -16523,8 +16728,11 @@ function registerInitCommand(program2) {
16523
16728
  console.log("");
16524
16729
  try {
16525
16730
  const globals = program2.opts();
16526
- const urlResult = await resolveServiceUrl(globals.serviceUrl);
16527
- await runOptionalAuth(urlResult.ok ? urlResult.data : DEFAULT_SERVICE_URL);
16731
+ const urlResult = await resolveServiceUrlDetailed(globals.serviceUrl);
16732
+ await runOptionalAuth(urlResult.ok ? urlResult.data : null, {
16733
+ token: globals.token,
16734
+ verbose: globals.verbose
16735
+ });
16528
16736
  } catch (err) {
16529
16737
  printWarn(`Authentication step skipped: ${err.message}`);
16530
16738
  }
@@ -16894,24 +17102,6 @@ function registerResetCommand(program2) {
16894
17102
  });
16895
17103
  }
16896
17104
 
16897
- // src/lib/run-mode.ts
16898
- function parseAutonomousEnv(raw) {
16899
- if (raw === void 0) return void 0;
16900
- const v = raw.trim().toLowerCase();
16901
- if (v === "") return void 0;
16902
- if (v === "0" || v === "false" || v === "off" || v === "no") return false;
16903
- return true;
16904
- }
16905
- function resolveRunMode(inputs = {}) {
16906
- if (inputs.autonomousFlag === true) return "autonomous";
16907
- if (inputs.autonomousFlag === false) return "interactive";
16908
- const env = inputs.env ?? process.env;
16909
- const envDecision = parseAutonomousEnv(env.VERITY_AUTONOMOUS);
16910
- if (envDecision !== void 0) return envDecision ? "autonomous" : "interactive";
16911
- const isTTY = inputs.isTTY ?? Boolean(process.stdin?.isTTY);
16912
- return isTTY ? "interactive" : "autonomous";
16913
- }
16914
-
16915
17105
  // src/commands/reflect.ts
16916
17106
  function registerReflectCommand(program2) {
16917
17107
  program2.command("reflect").description("Capture learnings \u2014 auto-extract or submit a human reflection").option("--user-input <text>", "The reflection to record (the agent-drafted or user-confirmed text)").option("--kind <kind>", "Node kind (decision, gotcha, pattern, security, quality, intent, domain, integration)", "gotcha").option("--task-id <id>", "Task to reflect on (defaults to current task)").option("--autonomous", "Record the drafted reflection without a confirm step (auto-detected from TTY / VERITY_AUTONOMOUS when omitted)").action(async (opts) => {
@@ -17273,7 +17463,7 @@ function registerTelemetryCommands(program2) {
17273
17463
  }
17274
17464
 
17275
17465
  // src/cli.ts
17276
- program.name("verity").description("CLI for Verity quality gate service").version("0.27.2").option("--token <token>", "Override authentication token").option("--service-url <url>", "Override service URL").option("--verbose", "Log HTTP requests/responses to stderr");
17466
+ program.name("verity").description("CLI for Verity quality gate service").version("0.28.1-experimental.b7950e1").option("--token <token>", "Override authentication token").option("--service-url <url>", "Override service URL").option("--verbose", "Log HTTP requests/responses to stderr");
17277
17467
  registerAuthCommands(program);
17278
17468
  registerLoginCommand(program);
17279
17469
  registerHooksCommands(program);
package/package.json CHANGED
@@ -1,12 +1,8 @@
1
1
  {
2
2
  "name": "@codacy/verity-cli",
3
- "version": "0.27.2",
3
+ "version": "0.28.1-experimental.b7950e1",
4
4
  "description": "CLI for Verity quality gate service",
5
5
  "homepage": "https://verity.md",
6
- "repository": {
7
- "type": "git",
8
- "url": "git+https://github.com/codacy/verity.git"
9
- },
10
6
  "bugs": {
11
7
  "url": "https://github.com/codacy/verity/issues"
12
8
  },