@mrciphersmith/keryx 0.2.147 → 0.2.149
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +113 -15
- 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
|
|
30211
|
-
|
|
30212
|
-
|
|
30213
|
-
|
|
30214
|
-
|
|
30215
|
-
|
|
30216
|
-
|
|
30217
|
-
|
|
30218
|
-
|
|
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.
|
|
51500
|
+
version: "0.2.149",
|
|
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) {
|
|
@@ -104090,6 +104127,7 @@ function attachUsageIo(io, chrome) {
|
|
|
104090
104127
|
totalOut = 0;
|
|
104091
104128
|
chrome.setHeaderMeta("\u21910 \u21930");
|
|
104092
104129
|
chrome.setContextTotal(0);
|
|
104130
|
+
chrome.setUsage?.(0, 0);
|
|
104093
104131
|
}
|
|
104094
104132
|
});
|
|
104095
104133
|
}
|
|
@@ -105758,6 +105796,12 @@ async function launchTuiAgentShell(opts) {
|
|
|
105758
105796
|
};
|
|
105759
105797
|
const approvalContext = createApprovalContextLoader(opts.session?.cwd ?? process.cwd());
|
|
105760
105798
|
io.requestApproval = async (tool, inputJson, meta) => {
|
|
105799
|
+
if (meta?.untrustedOrigin === true) {
|
|
105800
|
+
transcript.add(new otui.TextRenderable(r, {
|
|
105801
|
+
id: `ap${uid++}`,
|
|
105802
|
+
content: otui.t`${otui.yellow("\u26A0 follows untrusted external content \u2014 it cannot authorize this call; your answer does")}`
|
|
105803
|
+
}));
|
|
105804
|
+
}
|
|
105761
105805
|
if (tool === "spawn_subagent") {
|
|
105762
105806
|
let mode = "read_only";
|
|
105763
105807
|
let taskPreview = inputJson;
|
|
@@ -109717,6 +109761,13 @@ ${GUTTER}${style.dim(formatReasoningOneLiner({
|
|
|
109717
109761
|
},
|
|
109718
109762
|
requestApproval: async (tool, input, meta) => {
|
|
109719
109763
|
stopSpinner();
|
|
109764
|
+
if (meta?.untrustedOrigin === true) {
|
|
109765
|
+
out(`
|
|
109766
|
+
${GUTTER}${style.red("\u26A0 this call follows untrusted external content in this turn")}
|
|
109767
|
+
`);
|
|
109768
|
+
out(`${GUTTER}${style.dim("that content cannot authorize it \u2014 only your answer can")}
|
|
109769
|
+
`);
|
|
109770
|
+
}
|
|
109720
109771
|
if (tool === "apply_patch") {
|
|
109721
109772
|
const patch = extractPatchText(input);
|
|
109722
109773
|
out(`
|
|
@@ -118206,6 +118257,16 @@ async function main() {
|
|
|
118206
118257
|
}
|
|
118207
118258
|
const route = CLI_ROUTES[command];
|
|
118208
118259
|
if (route) {
|
|
118260
|
+
if (shouldInterceptHelp(command, args.slice(1))) {
|
|
118261
|
+
const usage = groupUsage(command);
|
|
118262
|
+
console.log(usage === undefined ? `keryx ${VERSION2}
|
|
118263
|
+
|
|
118264
|
+
${USAGE_BODY}` : `keryx ${command} \u2014 usage:
|
|
118265
|
+
|
|
118266
|
+
${usage}
|
|
118267
|
+
`);
|
|
118268
|
+
return;
|
|
118269
|
+
}
|
|
118209
118270
|
await route(args.slice(1));
|
|
118210
118271
|
return;
|
|
118211
118272
|
}
|
|
@@ -118213,10 +118274,7 @@ async function main() {
|
|
|
118213
118274
|
printHelp25();
|
|
118214
118275
|
process.exitCode = 1;
|
|
118215
118276
|
}
|
|
118216
|
-
|
|
118217
|
-
console.log(`keryx ${VERSION2}
|
|
118218
|
-
|
|
118219
|
-
Usage:
|
|
118277
|
+
var USAGE_BODY = `Usage:
|
|
118220
118278
|
keryx Show CLI usage
|
|
118221
118279
|
keryx shell [-c|--continue] [-r|--resume [id]] [--provider <p>] [--model <m>] [--base-url <url>] [--agent|--chat] [--tui|--no-tui]
|
|
118222
118280
|
Start TUI agent shell (sessions are per-project)
|
|
@@ -118380,6 +118438,42 @@ Commands:
|
|
|
118380
118438
|
workspace Shared Agent Context: workspaces, FWK reads, propose/review (module sac)
|
|
118381
118439
|
retention Bound stores that grow without bound (gdctx raw/artifacts, owner write-conflict sidecars)
|
|
118382
118440
|
forgetting Read the deletion trail \u2014 was this removed, or did it never exist?
|
|
118441
|
+
`;
|
|
118442
|
+
function printHelp25() {
|
|
118443
|
+
console.log(`keryx ${VERSION2}
|
|
118444
|
+
|
|
118445
|
+
${USAGE_BODY}`);
|
|
118446
|
+
}
|
|
118447
|
+
function helpRequestedFor(rest) {
|
|
118448
|
+
const separator = rest.indexOf("--");
|
|
118449
|
+
const head = separator === -1 ? rest : rest.slice(0, separator);
|
|
118450
|
+
return head.some((token) => token === "--help" || token === "-h");
|
|
118451
|
+
}
|
|
118452
|
+
var DEEP_HELP_GROUPS = new Set(["agents", "shell"]);
|
|
118453
|
+
function shouldInterceptHelp(command, rest) {
|
|
118454
|
+
return !DEEP_HELP_GROUPS.has(command) && helpRequestedFor(rest);
|
|
118455
|
+
}
|
|
118456
|
+
function groupUsage(command, usage = USAGE_BODY) {
|
|
118457
|
+
const lines = usage.split(`
|
|
118458
|
+
`);
|
|
118459
|
+
const startsGroup = new RegExp(`^ {2,}keryx ${command}(?:\\s|$)`);
|
|
118460
|
+
const isContinuation = /^ {4,}\S/;
|
|
118461
|
+
const out = [];
|
|
118462
|
+
for (let i = 0;i < lines.length; i += 1) {
|
|
118463
|
+
const line = lines[i] ?? "";
|
|
118464
|
+
if (!startsGroup.test(line)) {
|
|
118465
|
+
continue;
|
|
118466
|
+
}
|
|
118467
|
+
out.push(line);
|
|
118468
|
+
for (let j = i + 1;j < lines.length; j += 1) {
|
|
118469
|
+
const next = lines[j] ?? "";
|
|
118470
|
+
if (!isContinuation.test(next) || startsGroup.test(next) || /keryx\s/.test(next)) {
|
|
118471
|
+
break;
|
|
118472
|
+
}
|
|
118473
|
+
out.push(next);
|
|
118474
|
+
}
|
|
118475
|
+
}
|
|
118476
|
+
return out.length === 0 ? undefined : out.join(`
|
|
118383
118477
|
`);
|
|
118384
118478
|
}
|
|
118385
118479
|
function exitCodeForError(error) {
|
|
@@ -118393,6 +118487,10 @@ if (import.meta.main) {
|
|
|
118393
118487
|
}
|
|
118394
118488
|
export {
|
|
118395
118489
|
CLI_ROUTES,
|
|
118490
|
+
USAGE_BODY,
|
|
118396
118491
|
exitCodeForError,
|
|
118397
|
-
|
|
118492
|
+
groupUsage,
|
|
118493
|
+
helpRequestedFor,
|
|
118494
|
+
main,
|
|
118495
|
+
shouldInterceptHelp
|
|
118398
118496
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrciphersmith/keryx",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.149",
|
|
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": {
|