@mrciphersmith/keryx 0.2.147 → 0.2.150

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/cli.js +117 -18
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -30207,15 +30207,49 @@ ${shown.join(`
30207
30207
  const risk = toolByName.get(call.name)?.definition.risk;
30208
30208
  const isPureReadTool = risk === "read" && !DURABLE_READ_TOOL_NAMES.has(call.name);
30209
30209
  if (!isPureReadTool && untrustedContentSeen) {
30210
- const result = {
30211
- output: "tool blocked: external web content cannot authorize further tool calls in this turn",
30212
- isError: true
30213
- };
30214
- io.onToolResult?.(call.name, result);
30215
- history.push({ role: "tool", content: result.output, provenance: "tool", toolCallId: call.id, ts: now() });
30216
- io.onHistoryChange?.("tool");
30217
- gateBlockedAny = true;
30218
- continue;
30210
+ const approver = io.requestApproval;
30211
+ if (deps.unattended === true || approver === undefined) {
30212
+ const result = {
30213
+ output: "tool blocked: external web content cannot authorize further tool calls in this turn",
30214
+ isError: true
30215
+ };
30216
+ io.onToolResult?.(call.name, result);
30217
+ history.push({ role: "tool", content: result.output, provenance: "tool", toolCallId: call.id, ts: now() });
30218
+ io.onHistoryChange?.("tool");
30219
+ gateBlockedAny = true;
30220
+ continue;
30221
+ }
30222
+ const taintFingerprint = toolCallHash(call.name, call.input);
30223
+ let taintApproved;
30224
+ try {
30225
+ const response = await approver(call.name, call.input, {
30226
+ fingerprint: taintFingerprint,
30227
+ destructive: risk === "destructive",
30228
+ untrustedOrigin: true
30229
+ });
30230
+ taintApproved = isApprovalFor(response, taintFingerprint);
30231
+ } catch (err) {
30232
+ const result = {
30233
+ output: `${call.name} not executed: the approval prompt failed (${err instanceof Error ? err.message : String(err)})`,
30234
+ isError: true
30235
+ };
30236
+ io.onToolResult?.(call.name, result);
30237
+ history.push({ role: "tool", content: result.output, provenance: "tool", toolCallId: call.id, ts: now() });
30238
+ io.onHistoryChange?.("tool");
30239
+ gateBlockedAny = true;
30240
+ continue;
30241
+ }
30242
+ if (!taintApproved) {
30243
+ const result = {
30244
+ output: "tool blocked: external web content cannot authorize this call, and the user did not authorize it either",
30245
+ isError: true
30246
+ };
30247
+ io.onToolResult?.(call.name, result);
30248
+ history.push({ role: "tool", content: result.output, provenance: "tool", toolCallId: call.id, ts: now() });
30249
+ io.onHistoryChange?.("tool");
30250
+ gateBlockedAny = true;
30251
+ continue;
30252
+ }
30219
30253
  }
30220
30254
  io.onToolCall?.(call.name, call.input);
30221
30255
  const reservation = reservationByCallId.get(call.id) ?? reserveToolAttempt(budget, call.name, call.input);
@@ -51463,7 +51497,7 @@ import path47 from "path";
51463
51497
  // package.json
51464
51498
  var package_default = {
51465
51499
  name: "@mrciphersmith/keryx",
51466
- version: "0.2.147",
51500
+ version: "0.2.150",
51467
51501
  description: "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
51468
51502
  private: false,
51469
51503
  publishConfig: {
@@ -88755,6 +88789,9 @@ function renderUseToolApprovalLines(description, meta) {
88755
88789
  if (meta?.destructive === true) {
88756
88790
  lines.push(" this tool is treated as destructive \u2014 it is a third party's code");
88757
88791
  }
88792
+ if (meta?.untrustedOrigin === true) {
88793
+ lines.push(" \u26A0 follows untrusted external content \u2014 that content cannot authorize this call");
88794
+ }
88758
88795
  return lines;
88759
88796
  }
88760
88797
  function summariseUseToolApproval(description) {
@@ -92578,6 +92615,9 @@ async function runGoalCommand(params) {
92578
92615
  init_metaproject_adapter();
92579
92616
  import { spawnSync as spawnSync3 } from "child_process";
92580
92617
 
92618
+ // src/tui/sidebar-metrics.ts
92619
+ var SIDEBAR_WIDTH = 34;
92620
+
92581
92621
  // src/tui/transcript-blocks.ts
92582
92622
  var EVICTED_BLOCK_TEXT = "(output no longer retained)";
92583
92623
  var UNKNOWN_BLOCK_TEXT = "(no such block)";
@@ -93512,7 +93552,6 @@ function modalBodyRows(panelHeight) {
93512
93552
  return Math.max(1, panelHeight - MODAL_CHROME_ROWS);
93513
93553
  }
93514
93554
  var CLOSE_HINT = "[x] esc";
93515
- var UNMEASURED_SIDEBAR_WIDTH = 30;
93516
93555
  function resolveModalAvailableWidth(chrome) {
93517
93556
  const rWidth = chrome.renderer.width;
93518
93557
  const mainWidth = chrome.main?.width ?? 0;
@@ -93520,7 +93559,7 @@ function resolveModalAvailableWidth(chrome) {
93520
93559
  return Math.min(rWidth, mainWidth);
93521
93560
  }
93522
93561
  if (chrome.sidebar !== undefined) {
93523
- const sidebarWidth = chrome.sidebar.width > 0 ? chrome.sidebar.width : UNMEASURED_SIDEBAR_WIDTH;
93562
+ const sidebarWidth = chrome.sidebar.width > 0 ? chrome.sidebar.width : SIDEBAR_WIDTH;
93524
93563
  return Math.max(20, rWidth - sidebarWidth);
93525
93564
  }
93526
93565
  return rWidth;
@@ -95585,7 +95624,6 @@ var COMPOSER_MIN_ROWS = 1;
95585
95624
  var COMPOSER_MAX_ROWS = 6;
95586
95625
  var COMPOSER_BORDER_ROWS = 2;
95587
95626
  var MENU_HEIGHT = 10;
95588
- var SIDEBAR_WIDTH = 30;
95589
95627
  var SIDEBAR_BORDER_LEFT = 1;
95590
95628
  var SIDEBAR_PADDING_LEFT = 2;
95591
95629
  var SIDEBAR_PADDING_RIGHT = 1;
@@ -104090,6 +104128,7 @@ function attachUsageIo(io, chrome) {
104090
104128
  totalOut = 0;
104091
104129
  chrome.setHeaderMeta("\u21910 \u21930");
104092
104130
  chrome.setContextTotal(0);
104131
+ chrome.setUsage?.(0, 0);
104093
104132
  }
104094
104133
  });
104095
104134
  }
@@ -105758,6 +105797,12 @@ async function launchTuiAgentShell(opts) {
105758
105797
  };
105759
105798
  const approvalContext = createApprovalContextLoader(opts.session?.cwd ?? process.cwd());
105760
105799
  io.requestApproval = async (tool, inputJson, meta) => {
105800
+ if (meta?.untrustedOrigin === true) {
105801
+ transcript.add(new otui.TextRenderable(r, {
105802
+ id: `ap${uid++}`,
105803
+ content: otui.t`${otui.yellow("\u26A0 follows untrusted external content \u2014 it cannot authorize this call; your answer does")}`
105804
+ }));
105805
+ }
105761
105806
  if (tool === "spawn_subagent") {
105762
105807
  let mode = "read_only";
105763
105808
  let taskPreview = inputJson;
@@ -109717,6 +109762,13 @@ ${GUTTER}${style.dim(formatReasoningOneLiner({
109717
109762
  },
109718
109763
  requestApproval: async (tool, input, meta) => {
109719
109764
  stopSpinner();
109765
+ if (meta?.untrustedOrigin === true) {
109766
+ out(`
109767
+ ${GUTTER}${style.red("\u26A0 this call follows untrusted external content in this turn")}
109768
+ `);
109769
+ out(`${GUTTER}${style.dim("that content cannot authorize it \u2014 only your answer can")}
109770
+ `);
109771
+ }
109720
109772
  if (tool === "apply_patch") {
109721
109773
  const patch = extractPatchText(input);
109722
109774
  out(`
@@ -118206,6 +118258,16 @@ async function main() {
118206
118258
  }
118207
118259
  const route = CLI_ROUTES[command];
118208
118260
  if (route) {
118261
+ if (shouldInterceptHelp(command, args.slice(1))) {
118262
+ const usage = groupUsage(command);
118263
+ console.log(usage === undefined ? `keryx ${VERSION2}
118264
+
118265
+ ${USAGE_BODY}` : `keryx ${command} \u2014 usage:
118266
+
118267
+ ${usage}
118268
+ `);
118269
+ return;
118270
+ }
118209
118271
  await route(args.slice(1));
118210
118272
  return;
118211
118273
  }
@@ -118213,10 +118275,7 @@ async function main() {
118213
118275
  printHelp25();
118214
118276
  process.exitCode = 1;
118215
118277
  }
118216
- function printHelp25() {
118217
- console.log(`keryx ${VERSION2}
118218
-
118219
- Usage:
118278
+ var USAGE_BODY = `Usage:
118220
118279
  keryx Show CLI usage
118221
118280
  keryx shell [-c|--continue] [-r|--resume [id]] [--provider <p>] [--model <m>] [--base-url <url>] [--agent|--chat] [--tui|--no-tui]
118222
118281
  Start TUI agent shell (sessions are per-project)
@@ -118380,6 +118439,42 @@ Commands:
118380
118439
  workspace Shared Agent Context: workspaces, FWK reads, propose/review (module sac)
118381
118440
  retention Bound stores that grow without bound (gdctx raw/artifacts, owner write-conflict sidecars)
118382
118441
  forgetting Read the deletion trail \u2014 was this removed, or did it never exist?
118442
+ `;
118443
+ function printHelp25() {
118444
+ console.log(`keryx ${VERSION2}
118445
+
118446
+ ${USAGE_BODY}`);
118447
+ }
118448
+ function helpRequestedFor(rest) {
118449
+ const separator = rest.indexOf("--");
118450
+ const head = separator === -1 ? rest : rest.slice(0, separator);
118451
+ return head.some((token) => token === "--help" || token === "-h");
118452
+ }
118453
+ var DEEP_HELP_GROUPS = new Set(["agents", "shell"]);
118454
+ function shouldInterceptHelp(command, rest) {
118455
+ return !DEEP_HELP_GROUPS.has(command) && helpRequestedFor(rest);
118456
+ }
118457
+ function groupUsage(command, usage = USAGE_BODY) {
118458
+ const lines = usage.split(`
118459
+ `);
118460
+ const startsGroup = new RegExp(`^ {2,}keryx ${command}(?:\\s|$)`);
118461
+ const isContinuation = /^ {4,}\S/;
118462
+ const out = [];
118463
+ for (let i = 0;i < lines.length; i += 1) {
118464
+ const line = lines[i] ?? "";
118465
+ if (!startsGroup.test(line)) {
118466
+ continue;
118467
+ }
118468
+ out.push(line);
118469
+ for (let j = i + 1;j < lines.length; j += 1) {
118470
+ const next = lines[j] ?? "";
118471
+ if (!isContinuation.test(next) || startsGroup.test(next) || /keryx\s/.test(next)) {
118472
+ break;
118473
+ }
118474
+ out.push(next);
118475
+ }
118476
+ }
118477
+ return out.length === 0 ? undefined : out.join(`
118383
118478
  `);
118384
118479
  }
118385
118480
  function exitCodeForError(error) {
@@ -118393,6 +118488,10 @@ if (import.meta.main) {
118393
118488
  }
118394
118489
  export {
118395
118490
  CLI_ROUTES,
118491
+ USAGE_BODY,
118396
118492
  exitCodeForError,
118397
- main
118493
+ groupUsage,
118494
+ helpRequestedFor,
118495
+ main,
118496
+ shouldInterceptHelp
118398
118497
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrciphersmith/keryx",
3
- "version": "0.2.147",
3
+ "version": "0.2.150",
4
4
  "description": "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
5
5
  "private": false,
6
6
  "publishConfig": {