@mrciphersmith/keryx 0.3.78 → 0.3.79
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 +237 -28
- package/dist/core.js +4 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1758,7 +1758,8 @@ function isValidIp(value) {
|
|
|
1758
1758
|
return false;
|
|
1759
1759
|
}
|
|
1760
1760
|
function isWordBoundary(flavour, content, index) {
|
|
1761
|
-
|
|
1761
|
+
flavour.boundary.lastIndex = index;
|
|
1762
|
+
return flavour.boundary.test(content);
|
|
1762
1763
|
}
|
|
1763
1764
|
function wordCharBefore(content, index) {
|
|
1764
1765
|
if (index <= 0) {
|
|
@@ -2498,12 +2499,12 @@ var init_pii = __esm(() => {
|
|
|
2498
2499
|
UNICODE_EMAIL = {
|
|
2499
2500
|
from: /(?:(?<=[\p{L}\p{N}\p{M}_])(?![\p{L}\p{N}\p{M}_])|(?<![\p{L}\p{N}\p{M}_])(?=[\p{L}\p{N}\p{M}_]))[\p{L}\p{N}\p{M}._%+-]+@[\p{L}\p{N}\p{M}.-]+\.[\p{L}\p{M}]{2,}(?![\p{L}\p{N}\p{M}_])/uy,
|
|
2500
2501
|
localChar: /[\p{L}\p{N}\p{M}._%+-]/u,
|
|
2501
|
-
|
|
2502
|
+
boundary: /(?:(?<=[\p{L}\p{N}\p{M}_])(?![\p{L}\p{N}\p{M}_])|(?<![\p{L}\p{N}\p{M}_])(?=[\p{L}\p{N}\p{M}_]))/uy
|
|
2502
2503
|
};
|
|
2503
2504
|
ASCII_EMAIL = {
|
|
2504
2505
|
from: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/y,
|
|
2505
2506
|
localChar: /[A-Za-z0-9._%+-]/,
|
|
2506
|
-
|
|
2507
|
+
boundary: /\b/y
|
|
2507
2508
|
};
|
|
2508
2509
|
emailScanner = emailScannerFor(UNICODE_EMAIL);
|
|
2509
2510
|
asciiEmailScanner = emailScannerFor(ASCII_EMAIL);
|
|
@@ -21097,7 +21098,7 @@ var package_default;
|
|
|
21097
21098
|
var init_package = __esm(() => {
|
|
21098
21099
|
package_default = {
|
|
21099
21100
|
name: "@mrciphersmith/keryx",
|
|
21100
|
-
version: "0.3.
|
|
21101
|
+
version: "0.3.79",
|
|
21101
21102
|
description: "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
|
|
21102
21103
|
private: false,
|
|
21103
21104
|
publishConfig: {
|
|
@@ -110125,6 +110126,22 @@ var init_theme_text = __esm(() => {
|
|
|
110125
110126
|
init_theme();
|
|
110126
110127
|
});
|
|
110127
110128
|
|
|
110129
|
+
// src/tui/transcript-history.ts
|
|
110130
|
+
function trackTranscriptNode(node, policy) {
|
|
110131
|
+
policies.set(node, policy);
|
|
110132
|
+
}
|
|
110133
|
+
function transcriptNodeProtected(node) {
|
|
110134
|
+
return policies.get(node)?.protected() === true;
|
|
110135
|
+
}
|
|
110136
|
+
function forgetTranscriptNode(node) {
|
|
110137
|
+
policies.get(node)?.evict?.();
|
|
110138
|
+
policies.delete(node);
|
|
110139
|
+
}
|
|
110140
|
+
var TRANSCRIPT_HISTORY_LIMIT = 256, policies;
|
|
110141
|
+
var init_transcript_history = __esm(() => {
|
|
110142
|
+
policies = new WeakMap;
|
|
110143
|
+
});
|
|
110144
|
+
|
|
110128
110145
|
// src/tui/transcript-blocks.ts
|
|
110129
110146
|
function createBlockRegistry(options = {}) {
|
|
110130
110147
|
const maxBlocks = options.maxBlocks ?? DEFAULT_MAX_BLOCKS;
|
|
@@ -110185,6 +110202,15 @@ function createBlockRegistry(options = {}) {
|
|
|
110185
110202
|
}
|
|
110186
110203
|
return id;
|
|
110187
110204
|
},
|
|
110205
|
+
remove: (id) => {
|
|
110206
|
+
const index = blocks.findIndex((block) => block.id === id);
|
|
110207
|
+
if (index < 0)
|
|
110208
|
+
return;
|
|
110209
|
+
blocks.splice(index, 1);
|
|
110210
|
+
if (focusIndex > index)
|
|
110211
|
+
focusIndex -= 1;
|
|
110212
|
+
focusIndex = Math.min(focusIndex, blocks.length - 1);
|
|
110213
|
+
},
|
|
110188
110214
|
get: (id) => {
|
|
110189
110215
|
const block = find(id);
|
|
110190
110216
|
return block === undefined ? undefined : snapshot(block);
|
|
@@ -110582,8 +110608,13 @@ function createAssistantMessageStream(otui, renderer, parent) {
|
|
|
110582
110608
|
flexDirection: "column",
|
|
110583
110609
|
flexShrink: 0
|
|
110584
110610
|
});
|
|
110611
|
+
let live = true;
|
|
110612
|
+
trackTranscriptNode(container, { protected: () => live });
|
|
110613
|
+
const complete = () => {
|
|
110614
|
+
live = false;
|
|
110615
|
+
};
|
|
110585
110616
|
parent.add(container);
|
|
110586
|
-
return { container, segmenter: createStreamSegmenter(), views: [], frozen: 0 };
|
|
110617
|
+
return { complete, container, segmenter: createStreamSegmenter(), views: [], frozen: 0 };
|
|
110587
110618
|
};
|
|
110588
110619
|
const paint = (m, segments, frozen) => {
|
|
110589
110620
|
for (let i = m.frozen;i < segments.length; i++) {
|
|
@@ -110626,9 +110657,10 @@ function createAssistantMessageStream(otui, renderer, parent) {
|
|
|
110626
110657
|
m.frozen = 0;
|
|
110627
110658
|
const segments = segmentMarkdown(text);
|
|
110628
110659
|
paint(m, segments, segments.length);
|
|
110660
|
+
m.complete();
|
|
110629
110661
|
if (segments.length === 0) {
|
|
110630
110662
|
try {
|
|
110631
|
-
|
|
110663
|
+
m.container.destroyRecursively();
|
|
110632
110664
|
} catch {}
|
|
110633
110665
|
}
|
|
110634
110666
|
message = undefined;
|
|
@@ -110638,11 +110670,12 @@ function createAssistantMessageStream(otui, renderer, parent) {
|
|
|
110638
110670
|
if (message === undefined) {
|
|
110639
110671
|
return;
|
|
110640
110672
|
}
|
|
110673
|
+
message.complete();
|
|
110641
110674
|
for (const view of message.views.splice(0)) {
|
|
110642
110675
|
view.destroy();
|
|
110643
110676
|
}
|
|
110644
110677
|
try {
|
|
110645
|
-
|
|
110678
|
+
message.container.destroyRecursively();
|
|
110646
110679
|
} catch {}
|
|
110647
110680
|
message = undefined;
|
|
110648
110681
|
},
|
|
@@ -110660,6 +110693,8 @@ function createBlockView(otui, renderer, parent, block, options = {}) {
|
|
|
110660
110693
|
});
|
|
110661
110694
|
const header = new otui.TextRenderable(renderer, { id: `${id}-h`, content: "" });
|
|
110662
110695
|
box.add(header);
|
|
110696
|
+
let protectedView = false;
|
|
110697
|
+
trackTranscriptNode(box, { protected: () => protectedView, evict: () => options.onHistoryEvict?.() });
|
|
110663
110698
|
parent.add(box);
|
|
110664
110699
|
let body;
|
|
110665
110700
|
let bodyText;
|
|
@@ -110732,6 +110767,9 @@ function createBlockView(otui, renderer, parent, block, options = {}) {
|
|
|
110732
110767
|
return {
|
|
110733
110768
|
id: block.id,
|
|
110734
110769
|
render: (state, opts = {}) => {
|
|
110770
|
+
if (box.isDestroyed)
|
|
110771
|
+
return;
|
|
110772
|
+
protectedView = opts.focused === true;
|
|
110735
110773
|
paintHeader(state, opts.focused === true);
|
|
110736
110774
|
if (state.collapsed) {
|
|
110737
110775
|
if (options.collapsedPreview !== undefined) {
|
|
@@ -110788,7 +110826,14 @@ function createBlockMount(otui, renderer, parent, registry) {
|
|
|
110788
110826
|
}
|
|
110789
110827
|
const state = registry.get(id);
|
|
110790
110828
|
if (state !== undefined) {
|
|
110791
|
-
views.set(id, createBlockView(otui, renderer, parent, state,
|
|
110829
|
+
views.set(id, createBlockView(otui, renderer, parent, state, {
|
|
110830
|
+
...options,
|
|
110831
|
+
onHistoryEvict: () => {
|
|
110832
|
+
views.delete(id);
|
|
110833
|
+
registry.remove(id);
|
|
110834
|
+
options.onHistoryEvict?.();
|
|
110835
|
+
}
|
|
110836
|
+
}));
|
|
110792
110837
|
}
|
|
110793
110838
|
return id;
|
|
110794
110839
|
},
|
|
@@ -111014,6 +111059,7 @@ var init_transcript_blocks = __esm(() => {
|
|
|
111014
111059
|
init_md_blocks();
|
|
111015
111060
|
init_theme();
|
|
111016
111061
|
init_theme_text();
|
|
111062
|
+
init_transcript_history();
|
|
111017
111063
|
});
|
|
111018
111064
|
|
|
111019
111065
|
// src/tui/modal-host.ts
|
|
@@ -111062,6 +111108,20 @@ function resolveModalInnerWidth(availableWidth) {
|
|
|
111062
111108
|
function formatModalFooter(actions) {
|
|
111063
111109
|
return actions.map((action) => `${action.key} ${action.label}`).join(" \xB7 ");
|
|
111064
111110
|
}
|
|
111111
|
+
function modalFocusFallback(node) {
|
|
111112
|
+
return modalHandBack.get(node) ?? null;
|
|
111113
|
+
}
|
|
111114
|
+
function focusIsLive(node, root) {
|
|
111115
|
+
let current = node;
|
|
111116
|
+
while (current !== null) {
|
|
111117
|
+
if (current.isDestroyed || !current.visible)
|
|
111118
|
+
return false;
|
|
111119
|
+
if (current === root)
|
|
111120
|
+
return true;
|
|
111121
|
+
current = current.parent;
|
|
111122
|
+
}
|
|
111123
|
+
return false;
|
|
111124
|
+
}
|
|
111065
111125
|
function destroyModalHost(renderer) {
|
|
111066
111126
|
hosts.get(renderer)?.unsubTheme();
|
|
111067
111127
|
}
|
|
@@ -111076,6 +111136,10 @@ function containsNode(root, node) {
|
|
|
111076
111136
|
}
|
|
111077
111137
|
return false;
|
|
111078
111138
|
}
|
|
111139
|
+
function modalHides(renderer, node) {
|
|
111140
|
+
const state = hosts.get(renderer);
|
|
111141
|
+
return state !== undefined && state.open && !containsNode(state.backdrop, node);
|
|
111142
|
+
}
|
|
111079
111143
|
function resolveInitialTab(tabs, initialTab) {
|
|
111080
111144
|
const first = tabs[0];
|
|
111081
111145
|
if (first === undefined) {
|
|
@@ -111160,7 +111224,15 @@ function closeHost(state, opts) {
|
|
|
111160
111224
|
if (state.savedScrollTop !== undefined && scroll !== undefined) {
|
|
111161
111225
|
scroll.scrollTop = state.savedScrollTop;
|
|
111162
111226
|
}
|
|
111163
|
-
state.chrome.
|
|
111227
|
+
const r = state.chrome.renderer;
|
|
111228
|
+
const current = r.currentFocusedRenderable;
|
|
111229
|
+
if (current === null || containsNode(state.backdrop, current)) {
|
|
111230
|
+
const previous = state.savedFocus;
|
|
111231
|
+
if (previous !== null && focusIsLive(previous, r.root))
|
|
111232
|
+
previous.focus();
|
|
111233
|
+
else
|
|
111234
|
+
state.chrome.focusComposer();
|
|
111235
|
+
}
|
|
111164
111236
|
}
|
|
111165
111237
|
if (opts.runOnClose && onClose !== undefined) {
|
|
111166
111238
|
onClose();
|
|
@@ -111290,6 +111362,7 @@ function ensureHost(otui, chrome) {
|
|
|
111290
111362
|
releaseOverlay: undefined,
|
|
111291
111363
|
unsubKeys: undefined,
|
|
111292
111364
|
savedScrollTop: undefined,
|
|
111365
|
+
savedFocus: null,
|
|
111293
111366
|
unsubTheme: () => {}
|
|
111294
111367
|
};
|
|
111295
111368
|
state.releaseOverlay = chrome.addOverlaySource(() => state.open, { kind: "modal" });
|
|
@@ -111414,6 +111487,8 @@ function openModal(otui, chrome, input) {
|
|
|
111414
111487
|
state.onClose = undefined;
|
|
111415
111488
|
previousClose?.();
|
|
111416
111489
|
} else {
|
|
111490
|
+
state.savedFocus = chrome.renderer.currentFocusedRenderable;
|
|
111491
|
+
modalHandBack.set(state.tabStrip, state.savedFocus);
|
|
111417
111492
|
state.savedScrollTop = chrome.scroll.scrollTop;
|
|
111418
111493
|
chrome.hideMenu();
|
|
111419
111494
|
chrome.blurComposer();
|
|
@@ -111440,7 +111515,7 @@ function openModal(otui, chrome, input) {
|
|
|
111440
111515
|
}, 0);
|
|
111441
111516
|
return makeHandle(state, generation);
|
|
111442
111517
|
}
|
|
111443
|
-
var BACKDROP_ID = "modal-backdrop", PANEL_ID = "modal-panel", BACKDROP_ALPHA = 1, MODAL_PANEL_MARGIN = 1, MODAL_PANEL_CHROME_X = 4, MODAL_PANEL_MIN_WIDTH = 72, MODAL_PANEL_MIN_HEIGHT = 18, MODAL_PANEL_SIZE_RATIO = 0.95, MODAL_PANEL_MAX_HEIGHT_RATIO = 0.85, MODAL_CHROME_ROWS = 5, MODAL_PANEL_WIDTH, MODAL_PANEL_HEIGHT, MODAL_PANEL_INNER_WIDTH, CLOSE_HINT = "[x] esc", DEFAULT_FOOTER, hosts, MODAL_BODY_SCROLLBAR_COLS = 1;
|
|
111518
|
+
var BACKDROP_ID = "modal-backdrop", PANEL_ID = "modal-panel", BACKDROP_ALPHA = 1, MODAL_PANEL_MARGIN = 1, MODAL_PANEL_CHROME_X = 4, MODAL_PANEL_MIN_WIDTH = 72, MODAL_PANEL_MIN_HEIGHT = 18, MODAL_PANEL_SIZE_RATIO = 0.95, MODAL_PANEL_MAX_HEIGHT_RATIO = 0.85, MODAL_CHROME_ROWS = 5, MODAL_PANEL_WIDTH, MODAL_PANEL_HEIGHT, MODAL_PANEL_INNER_WIDTH, CLOSE_HINT = "[x] esc", DEFAULT_FOOTER, modalHandBack, hosts, MODAL_BODY_SCROLLBAR_COLS = 1;
|
|
111444
111519
|
var init_modal_host = __esm(() => {
|
|
111445
111520
|
init_theme();
|
|
111446
111521
|
init_theme_text();
|
|
@@ -111452,6 +111527,7 @@ var init_modal_host = __esm(() => {
|
|
|
111452
111527
|
{ key: "\u2190/\u2192", label: "tabs" },
|
|
111453
111528
|
{ key: "esc", label: "close" }
|
|
111454
111529
|
];
|
|
111530
|
+
modalHandBack = new WeakMap;
|
|
111455
111531
|
hosts = new WeakMap;
|
|
111456
111532
|
});
|
|
111457
111533
|
|
|
@@ -134844,14 +134920,60 @@ async function createShellChrome(otui, renderer, opts) {
|
|
|
134844
134920
|
let liveStatus;
|
|
134845
134921
|
const originalTranscriptAdd = transcript.add.bind(transcript);
|
|
134846
134922
|
const originalTranscriptRemove = transcript.remove.bind(transcript);
|
|
134923
|
+
let historyNotice;
|
|
134924
|
+
let historyAnchor;
|
|
134925
|
+
const restoreHistoryAnchor = () => {
|
|
134926
|
+
const anchor = historyAnchor;
|
|
134927
|
+
historyAnchor = undefined;
|
|
134928
|
+
if (anchor === undefined || anchor.node.isDestroyed || scroll.stickyScroll || scroll.scrollTop !== anchor.scrollTop)
|
|
134929
|
+
return;
|
|
134930
|
+
scroll.scrollTop += anchor.node.y - anchor.y;
|
|
134931
|
+
};
|
|
134932
|
+
r.on(otui.CliRenderEvents.FRAME, restoreHistoryAnchor);
|
|
134933
|
+
const trimHistory = () => {
|
|
134934
|
+
const completed = transcript.getChildren().filter((node) => node !== liveStatus && node !== historyNotice && !transcriptNodeProtected(node));
|
|
134935
|
+
const excess = completed.length - TRANSCRIPT_HISTORY_LIMIT;
|
|
134936
|
+
if (excess <= 0)
|
|
134937
|
+
return;
|
|
134938
|
+
if (!scroll.stickyScroll && historyAnchor === undefined) {
|
|
134939
|
+
const evicted = new Set(completed.slice(0, excess));
|
|
134940
|
+
const node = transcript.getChildren().find((child) => child !== liveStatus && child !== historyNotice && !evicted.has(child) && child.y + child.height > scroll.y && child.y < scroll.y + scroll.height);
|
|
134941
|
+
if (node !== undefined)
|
|
134942
|
+
historyAnchor = { node, y: node.y, scrollTop: scroll.scrollTop };
|
|
134943
|
+
}
|
|
134944
|
+
for (const node of completed.slice(0, excess)) {
|
|
134945
|
+
forgetTranscriptNode(node);
|
|
134946
|
+
node.destroyRecursively();
|
|
134947
|
+
}
|
|
134948
|
+
for (let i = userPrompts.length - 1;i >= 0; i--) {
|
|
134949
|
+
if (userPrompts[i]?.box.isDestroyed)
|
|
134950
|
+
userPrompts.splice(i, 1);
|
|
134951
|
+
}
|
|
134952
|
+
if (pinnedPrompt?.box.isDestroyed) {
|
|
134953
|
+
pinnedPrompt = undefined;
|
|
134954
|
+
promptPin.visible = false;
|
|
134955
|
+
}
|
|
134956
|
+
if (historyNotice === undefined || historyNotice.isDestroyed) {
|
|
134957
|
+
historyNotice = new otui.TextRenderable(r, {
|
|
134958
|
+
id: "transcript-history-notice",
|
|
134959
|
+
content: "Older output is no longer mounted in this view.",
|
|
134960
|
+
fg: getTheme().muted,
|
|
134961
|
+
flexShrink: 0
|
|
134962
|
+
});
|
|
134963
|
+
originalTranscriptAdd(historyNotice, 0);
|
|
134964
|
+
}
|
|
134965
|
+
};
|
|
134847
134966
|
transcript.add = (child, index) => {
|
|
134848
134967
|
if (liveStatus !== undefined && child !== liveStatus) {
|
|
134849
134968
|
originalTranscriptRemove(liveStatus);
|
|
134850
134969
|
const added = originalTranscriptAdd(child, index);
|
|
134851
134970
|
originalTranscriptAdd(liveStatus);
|
|
134971
|
+
trimHistory();
|
|
134852
134972
|
return added;
|
|
134853
134973
|
}
|
|
134854
|
-
|
|
134974
|
+
const added = originalTranscriptAdd(child, index);
|
|
134975
|
+
trimHistory();
|
|
134976
|
+
return added;
|
|
134855
134977
|
};
|
|
134856
134978
|
const queueDock = new otui.BoxRenderable(r, {
|
|
134857
134979
|
id: "queue-dock",
|
|
@@ -135392,6 +135514,7 @@ async function createShellChrome(otui, renderer, opts) {
|
|
|
135392
135514
|
} catch {}
|
|
135393
135515
|
try {
|
|
135394
135516
|
r.off(otui.CliRenderEvents.FRAME, syncPromptPin);
|
|
135517
|
+
r.off(otui.CliRenderEvents.FRAME, restoreHistoryAnchor);
|
|
135395
135518
|
} catch {}
|
|
135396
135519
|
}
|
|
135397
135520
|
};
|
|
@@ -135404,6 +135527,7 @@ var init_shell_chrome = __esm(() => {
|
|
|
135404
135527
|
init_modal_host();
|
|
135405
135528
|
init_debug_log();
|
|
135406
135529
|
init_renderer_debug();
|
|
135530
|
+
init_transcript_history();
|
|
135407
135531
|
SIDEBAR_TEXT_WIDTH = SIDEBAR_WIDTH - SIDEBAR_BORDER_LEFT - SIDEBAR_PADDING_LEFT - SIDEBAR_PADDING_RIGHT;
|
|
135408
135532
|
SPINNER = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
135409
135533
|
});
|
|
@@ -136741,7 +136865,7 @@ function openRouting(otui, chrome, options) {
|
|
|
136741
136865
|
cwd: options.cwd,
|
|
136742
136866
|
...options.userConfigDir !== undefined ? { userConfigDir: options.userConfigDir } : {}
|
|
136743
136867
|
};
|
|
136744
|
-
const loadProviders = options.providers ??
|
|
136868
|
+
const loadProviders = options.providers ?? loadRoutingProviders;
|
|
136745
136869
|
const loadProfiles = options.loadProfiles ?? ((dir) => loadModelProfiles(dir));
|
|
136746
136870
|
const rendererHint = options.renderer ?? chrome?.renderer;
|
|
136747
136871
|
const panelRows = typeof rendererHint?.width === "number" && typeof rendererHint.height === "number" ? modalBodyRows(resolveModalPanelSize(rendererHint.width, rendererHint.height).height) : 13;
|
|
@@ -136956,7 +137080,7 @@ function describePickerRowProfile(opt, profiles) {
|
|
|
136956
137080
|
parts.push("non-chat/free \u2014 never auto-derived");
|
|
136957
137081
|
return parts.join(" \xB7 ");
|
|
136958
137082
|
}
|
|
136959
|
-
async function
|
|
137083
|
+
async function loadRoutingProviders() {
|
|
136960
137084
|
await Promise.resolve().then(() => init_provider_catalog());
|
|
136961
137085
|
await Promise.resolve().then(() => init_shell_config());
|
|
136962
137086
|
const catalog = await loadOrRefreshProviderCatalog({ fetch, env: envWithSavedApiKeys() });
|
|
@@ -145390,33 +145514,55 @@ var init_classifier_model = __esm(() => {
|
|
|
145390
145514
|
});
|
|
145391
145515
|
|
|
145392
145516
|
// src/tui/routing-classifier-source.ts
|
|
145517
|
+
async function loadTurnProviders(load, signal, timeoutMs) {
|
|
145518
|
+
if (signal?.aborted || timeoutMs <= 0)
|
|
145519
|
+
return;
|
|
145520
|
+
let stop;
|
|
145521
|
+
const stopped = new Promise((resolve) => {
|
|
145522
|
+
stop = () => resolve(undefined);
|
|
145523
|
+
});
|
|
145524
|
+
signal?.addEventListener("abort", stop, { once: true });
|
|
145525
|
+
const timer = setTimeout(stop, timeoutMs);
|
|
145526
|
+
try {
|
|
145527
|
+
return await Promise.race([Promise.resolve().then(load), stopped]);
|
|
145528
|
+
} finally {
|
|
145529
|
+
clearTimeout(timer);
|
|
145530
|
+
signal?.removeEventListener("abort", stop);
|
|
145531
|
+
}
|
|
145532
|
+
}
|
|
145393
145533
|
async function runRoutingClassifierForTurn(line, opts) {
|
|
145394
145534
|
if (opts.signal?.aborted)
|
|
145395
145535
|
return;
|
|
145396
145536
|
if (!opts.enabled)
|
|
145397
145537
|
return;
|
|
145538
|
+
const deadline = performance.now() + Math.max(0, opts.timeoutMs ?? CLASSIFY_TURN_TIMEOUT_MS);
|
|
145398
145539
|
const profiles = loadModelProfiles(opts.userConfigDir);
|
|
145540
|
+
const providers = opts.providers === undefined ? opts.detected : await loadTurnProviders(opts.providers, opts.signal, Math.max(0, deadline - performance.now()));
|
|
145541
|
+
if (providers === undefined)
|
|
145542
|
+
return;
|
|
145543
|
+
if (opts.signal?.aborted)
|
|
145544
|
+
return;
|
|
145399
145545
|
const env = envWithSavedApiKeys(opts.env ?? process.env);
|
|
145400
145546
|
const external = await resolveExternalSetting({ cwd: opts.cwd, ...opts.userConfigDir !== undefined ? { dir: opts.userConfigDir } : {} });
|
|
145401
145547
|
if (opts.signal?.aborted)
|
|
145402
145548
|
return;
|
|
145403
|
-
const externalAllowed = externalAllowedConnectedPredicate(connectedPredicateFrom(
|
|
145404
|
-
const fallbackModel = selectClassifierModel(
|
|
145549
|
+
const externalAllowed = externalAllowedConnectedPredicate(connectedPredicateFrom(providers), external.value === "on", loadExternalProvidersConfig(opts.userConfigDir).config);
|
|
145550
|
+
const fallbackModel = selectClassifierModel(providers, profiles, (providerId, modelId) => externalAllowed(providerId, modelId) && (opts.classifierAllowed?.(providerId, modelId) ?? true) && (opts.providerFactory !== undefined || hasCredential(providerId, env)));
|
|
145405
145551
|
const classification = await classifyTurn(line, TURN_CLASSIFIER_CATEGORIES, {
|
|
145406
|
-
jevEnabled: opts.jevEnabled && opts.jevAllowed !== false,
|
|
145552
|
+
jevEnabled: opts.jevEnabled && opts.jevAllowed !== false && external.value === "on",
|
|
145407
145553
|
...opts.signal !== undefined ? { signal: opts.signal } : {},
|
|
145408
145554
|
fallbackModel: fallbackModel ?? null,
|
|
145409
145555
|
...opts.providerFactory !== undefined ? { providerFactory: opts.providerFactory } : {},
|
|
145410
145556
|
...opts.env !== undefined ? { env: opts.env } : {},
|
|
145411
145557
|
...opts.fetch !== undefined ? { fetch: opts.fetch } : {},
|
|
145412
|
-
timeoutMs:
|
|
145558
|
+
timeoutMs: Math.max(0, deadline - performance.now())
|
|
145413
145559
|
});
|
|
145414
145560
|
if (opts.signal?.aborted)
|
|
145415
145561
|
return;
|
|
145416
145562
|
if (classification === undefined)
|
|
145417
145563
|
return;
|
|
145418
145564
|
const baseline = { providerId: opts.sessionProvider, modelId: opts.sessionModel };
|
|
145419
|
-
const skippedJev = opts.jevEnabled && opts.jevAllowed === false ? "jev: caller policy denied" : opts.jevEnabled && resolveJevClassifierCredential(opts.env).key === undefined ? "jev: credentials unavailable" : undefined;
|
|
145565
|
+
const skippedJev = opts.jevEnabled && opts.jevAllowed === false ? "jev: caller policy denied" : opts.jevEnabled && external.value !== "on" ? "jev: external policy denied" : opts.jevEnabled && resolveJevClassifierCredential(opts.env).key === undefined ? "jev: credentials unavailable" : undefined;
|
|
145420
145566
|
if (!classification.result.ok) {
|
|
145421
145567
|
const failures = classification.trace.flatMap((stage) => stage.result.ok ? [] : [`${stage.source}: ${stage.result.reason}`]);
|
|
145422
145568
|
return {
|
|
@@ -145436,12 +145582,12 @@ async function runRoutingClassifierForTurn(line, opts) {
|
|
|
145436
145582
|
const [project, user] = await Promise.all([loadRoutingConfig("project", location), loadRoutingConfig("user", location)]);
|
|
145437
145583
|
if (opts.signal?.aborted)
|
|
145438
145584
|
return;
|
|
145439
|
-
const connected = connectedPredicateFrom(
|
|
145585
|
+
const connected = connectedPredicateFrom(providers);
|
|
145440
145586
|
const available = availablePredicateFromProfiles(profiles);
|
|
145441
145587
|
let fallbackReason;
|
|
145442
145588
|
const connectedForTurn = (providerId, modelId) => {
|
|
145443
145589
|
if (modelId !== undefined) {
|
|
145444
|
-
const reason = !connected(providerId, modelId) ? "model not connected" : !available(providerId, modelId) ? "model unavailable" : !(opts.executorAllowed?.(providerId, modelId) ?? true) ? "executor policy denied" : undefined;
|
|
145590
|
+
const reason = !connected(providerId, modelId) ? "model not connected" : !externalAllowed(providerId, modelId) ? "external policy denied" : !available(providerId, modelId) ? "model unavailable" : !(opts.executorAllowed?.(providerId, modelId) ?? true) ? "executor policy denied" : opts.providerFactory === undefined && !hasCredential(providerId, env) ? "credentials unavailable" : undefined;
|
|
145445
145591
|
if (reason !== undefined) {
|
|
145446
145592
|
fallbackReason ??= `${providerId}/${modelId}: ${reason}`;
|
|
145447
145593
|
return false;
|
|
@@ -145449,14 +145595,14 @@ async function runRoutingClassifierForTurn(line, opts) {
|
|
|
145449
145595
|
return true;
|
|
145450
145596
|
}
|
|
145451
145597
|
const defaultId = resolveProviderDefaultModelId(providerId);
|
|
145452
|
-
const reason = !connected(providerId) ? "provider not connected" : defaultId === undefined ? "no documented provider default" : !connected(providerId, defaultId) ? "default model not connected" : !available(providerId, defaultId) ? "default model unavailable" : !(opts.executorAllowed?.(providerId, defaultId) ?? true) ? "executor policy denied" : opts.providerFactory === undefined && !hasCredential(providerId, env) ? "credentials unavailable" : undefined;
|
|
145598
|
+
const reason = !connected(providerId) ? "provider not connected" : defaultId === undefined ? "no documented provider default" : !connected(providerId, defaultId) ? "default model not connected" : !externalAllowed(providerId, defaultId) ? "external policy denied" : !available(providerId, defaultId) ? "default model unavailable" : !(opts.executorAllowed?.(providerId, defaultId) ?? true) ? "executor policy denied" : opts.providerFactory === undefined && !hasCredential(providerId, env) ? "credentials unavailable" : undefined;
|
|
145453
145599
|
if (reason !== undefined) {
|
|
145454
145600
|
fallbackReason ??= `${providerId} (provider default): ${reason}`;
|
|
145455
145601
|
return false;
|
|
145456
145602
|
}
|
|
145457
145603
|
return true;
|
|
145458
145604
|
};
|
|
145459
|
-
const sessionProvider =
|
|
145605
|
+
const sessionProvider = providers.find((p) => p.name === opts.sessionProvider);
|
|
145460
145606
|
const models = sessionProvider?.models ?? [opts.sessionModel];
|
|
145461
145607
|
const derived = deriveDefaultTable(opts.sessionProvider, models, profiles, opts.sessionModel);
|
|
145462
145608
|
const resolved = resolveCategoryDetailed(category, { project: project.table, user: user.table, derived }, connectedForTurn, available);
|
|
@@ -145479,11 +145625,17 @@ async function runRoutingClassifierForTurn(line, opts) {
|
|
|
145479
145625
|
const modelId = resolveProviderDefaultModelId(resolved.assignment.providerId);
|
|
145480
145626
|
return modelId === undefined ? result : { ...result, routed: { providerId: resolved.assignment.providerId, modelId } };
|
|
145481
145627
|
}
|
|
145628
|
+
function classificationSource(result) {
|
|
145629
|
+
if (!result.classification.result.ok)
|
|
145630
|
+
return "none";
|
|
145631
|
+
const source = result.classification.result.source;
|
|
145632
|
+
return source === "jev" ? "JEV" : source === "main-model" ? "fallback" : source;
|
|
145633
|
+
}
|
|
145482
145634
|
function renderRoutingFallbackLine(result) {
|
|
145483
145635
|
if (result === undefined)
|
|
145484
145636
|
return "[route fallback: no classifier category; using session model]";
|
|
145485
145637
|
const target = result.baseline === undefined ? "session model" : `${result.baseline.providerId}/${result.baseline.modelId}`;
|
|
145486
|
-
return redactSensitiveText(`[route fallback: ${result.category ?? "no classifier category"} -> ${describeAssignment(result.assignment)}${result.fallbackReason !== undefined ? `; ${result.fallbackReason}` : ""}; using ${target}]`);
|
|
145638
|
+
return redactSensitiveText(`[route fallback: ${result.category ?? "no classifier category"} -> ${describeAssignment(result.assignment)}; classifier: ${classificationSource(result)}${result.fallbackReason !== undefined ? `; ${result.fallbackReason}` : ""}; using ${target}]`);
|
|
145487
145639
|
}
|
|
145488
145640
|
function pct6(n) {
|
|
145489
145641
|
return `${Math.round(n * 100)}%`;
|
|
@@ -145491,7 +145643,7 @@ function pct6(n) {
|
|
|
145491
145643
|
function renderRoutingTagLine(result) {
|
|
145492
145644
|
if (result.routed === undefined)
|
|
145493
145645
|
return;
|
|
145494
|
-
const source = result
|
|
145646
|
+
const source = classificationSource(result);
|
|
145495
145647
|
const confidence = result.classification.result.ok ? ` ${pct6(result.classification.result.confidence)}` : "";
|
|
145496
145648
|
return `[${result.category} -> ${result.routed.providerId}/${result.routed.modelId}] (${source}${confidence}${result.fallbackReason !== undefined ? `; fallback: ${result.fallbackReason}` : ""})`;
|
|
145497
145649
|
}
|
|
@@ -151547,6 +151699,53 @@ function onKeypress3(r, handler) {
|
|
|
151547
151699
|
r._internalKeyInput.onInternal("keypress", handler);
|
|
151548
151700
|
return () => r._internalKeyInput.offInternal("keypress", handler);
|
|
151549
151701
|
}
|
|
151702
|
+
function focusedNode(r) {
|
|
151703
|
+
return r.currentFocusedRenderable;
|
|
151704
|
+
}
|
|
151705
|
+
function canTakeKeyboard(node, root) {
|
|
151706
|
+
let current = node;
|
|
151707
|
+
while (current !== null && current !== undefined) {
|
|
151708
|
+
if (current.isDestroyed === true || current.visible === false) {
|
|
151709
|
+
return false;
|
|
151710
|
+
}
|
|
151711
|
+
if (current === root) {
|
|
151712
|
+
return true;
|
|
151713
|
+
}
|
|
151714
|
+
current = current.parent;
|
|
151715
|
+
}
|
|
151716
|
+
return false;
|
|
151717
|
+
}
|
|
151718
|
+
function resolveHandBack(start, root) {
|
|
151719
|
+
const seen = new Set;
|
|
151720
|
+
let candidate = start;
|
|
151721
|
+
while (candidate !== null && !seen.has(candidate)) {
|
|
151722
|
+
if (canTakeKeyboard(candidate, root)) {
|
|
151723
|
+
return candidate;
|
|
151724
|
+
}
|
|
151725
|
+
seen.add(candidate);
|
|
151726
|
+
candidate = handBackFrom.get(candidate) ?? modalFocusFallback(candidate);
|
|
151727
|
+
}
|
|
151728
|
+
return;
|
|
151729
|
+
}
|
|
151730
|
+
function handBackFocus(r, previous, mounted, title) {
|
|
151731
|
+
if (r.isDestroyed === true) {
|
|
151732
|
+
return;
|
|
151733
|
+
}
|
|
151734
|
+
const current = focusedNode(r);
|
|
151735
|
+
if (current !== null && !mounted.some((node) => containsNode(node, current))) {
|
|
151736
|
+
debugEvent("choice.focus-kept", { title, focused: current.id ?? null });
|
|
151737
|
+
return;
|
|
151738
|
+
}
|
|
151739
|
+
const target = resolveHandBack(previous, r.root);
|
|
151740
|
+
if (target === undefined || modalHides(r, target)) {
|
|
151741
|
+
debugEvent("choice.focus-not-restored", { title, previous: previous?.id ?? null, modal: target !== undefined });
|
|
151742
|
+
return;
|
|
151743
|
+
}
|
|
151744
|
+
try {
|
|
151745
|
+
target.focus();
|
|
151746
|
+
debugEvent("choice.focus-restored", { title, focused: target.id ?? null });
|
|
151747
|
+
} catch {}
|
|
151748
|
+
}
|
|
151550
151749
|
function dockBusy(dock) {
|
|
151551
151750
|
return (dockDepth.get(dock) ?? 0) > 0;
|
|
151552
151751
|
}
|
|
@@ -151603,6 +151802,7 @@ function presentComposerChoice(otui, r, dock, request) {
|
|
|
151603
151802
|
return Promise.resolve({ kind: "id", id: request.cancelId });
|
|
151604
151803
|
}
|
|
151605
151804
|
return new Promise((resolve) => {
|
|
151805
|
+
const previousFocus = focusedNode(r);
|
|
151606
151806
|
const ownEnabled = request.ownAnswer !== undefined;
|
|
151607
151807
|
const options = request.options.map((o) => ({
|
|
151608
151808
|
...o,
|
|
@@ -151653,6 +151853,7 @@ function presentComposerChoice(otui, r, dock, request) {
|
|
|
151653
151853
|
scrollY: true,
|
|
151654
151854
|
contentOptions: { flexDirection: "column" }
|
|
151655
151855
|
});
|
|
151856
|
+
handBackFrom.set(subtitleScroll, previousFocus);
|
|
151656
151857
|
for (const [i, line] of subtitleLines.entries()) {
|
|
151657
151858
|
subtitleScroll.content.add(new otui.TextRenderable(r, {
|
|
151658
151859
|
id: `ch-sub-line-${i}-${Date.now()}`,
|
|
@@ -151676,6 +151877,7 @@ function presentComposerChoice(otui, r, dock, request) {
|
|
|
151676
151877
|
contentOptions: { flexDirection: "column" }
|
|
151677
151878
|
});
|
|
151678
151879
|
dock.add(optionsScroll);
|
|
151880
|
+
handBackFrom.set(optionsScroll, previousFocus);
|
|
151679
151881
|
const optionsBox = optionsScroll.content;
|
|
151680
151882
|
const rows = [];
|
|
151681
151883
|
const paintOptions = () => {
|
|
@@ -151736,6 +151938,7 @@ function presentComposerChoice(otui, r, dock, request) {
|
|
|
151736
151938
|
content: otui.t`${dimChunk(otui, picked === undefined ? "Your own answer \u2014 Enter sends, Esc goes back to the options" : `Reason for "${picked.label}" \u2014 Enter sends, Esc goes back to the options`)}`
|
|
151737
151939
|
});
|
|
151738
151940
|
ownInput = new otui.InputRenderable(r, { id: `ch-own-input-${Date.now()}`, value: "", marginTop: 0 });
|
|
151941
|
+
handBackFrom.set(ownInput, previousFocus);
|
|
151739
151942
|
dock.add(ownNote);
|
|
151740
151943
|
dock.add(ownInput);
|
|
151741
151944
|
paintTitle();
|
|
@@ -151792,7 +151995,8 @@ function presentComposerChoice(otui, r, dock, request) {
|
|
|
151792
151995
|
id: rowId,
|
|
151793
151996
|
width: "100%",
|
|
151794
151997
|
flexDirection: "column",
|
|
151795
|
-
onMouseDown: () => {
|
|
151998
|
+
onMouseDown: (event) => {
|
|
151999
|
+
event.preventDefault();
|
|
151796
152000
|
finish(o.id, "click");
|
|
151797
152001
|
}
|
|
151798
152002
|
});
|
|
@@ -151850,6 +152054,9 @@ function presentComposerChoice(otui, r, dock, request) {
|
|
|
151850
152054
|
}
|
|
151851
152055
|
} catch {}
|
|
151852
152056
|
dock.visible = false;
|
|
152057
|
+
queueMicrotask(() => {
|
|
152058
|
+
handBackFocus(r, previousFocus, mounted, request.title);
|
|
152059
|
+
});
|
|
151853
152060
|
setTimeout(() => {
|
|
151854
152061
|
for (const node of mounted) {
|
|
151855
152062
|
try {
|
|
@@ -151959,12 +152166,13 @@ function presentComposerChoice(otui, r, dock, request) {
|
|
|
151959
152166
|
});
|
|
151960
152167
|
});
|
|
151961
152168
|
}
|
|
151962
|
-
var OWN_ROW_ID = "\x00own-answer", DEFAULT_ACCEPT_DELAY_MS = 400, MAX_SUBTITLE_CHARS = 8000, MAX_SUBTITLE_ROWS = 10, SUBTITLE_INLINE_MAX_CHARS = 76, OPTION_ROWS = 2, MAX_OPTIONS_ROWS = 16, dockChain, dockDepth;
|
|
152169
|
+
var OWN_ROW_ID = "\x00own-answer", DEFAULT_ACCEPT_DELAY_MS = 400, MAX_SUBTITLE_CHARS = 8000, MAX_SUBTITLE_ROWS = 10, SUBTITLE_INLINE_MAX_CHARS = 76, OPTION_ROWS = 2, MAX_OPTIONS_ROWS = 16, handBackFrom, dockChain, dockDepth;
|
|
151963
152170
|
var init_composer_choice = __esm(() => {
|
|
151964
152171
|
init_theme();
|
|
151965
152172
|
init_theme_text();
|
|
151966
152173
|
init_modal_host();
|
|
151967
152174
|
init_debug_log();
|
|
152175
|
+
handBackFrom = new WeakMap;
|
|
151968
152176
|
dockChain = new WeakMap;
|
|
151969
152177
|
dockDepth = new WeakMap;
|
|
151970
152178
|
});
|
|
@@ -164541,6 +164749,7 @@ ${formatThemeList(getThemeId())}`);
|
|
|
164541
164749
|
jevEnabled: routingEnabled,
|
|
164542
164750
|
cwd: opts.session?.cwd ?? process.cwd(),
|
|
164543
164751
|
detected: opts.detected ?? [],
|
|
164752
|
+
providers: loadRoutingProviders,
|
|
164544
164753
|
sessionProvider: currentSel.provider,
|
|
164545
164754
|
sessionModel: currentSel.model
|
|
164546
164755
|
});
|
|
@@ -214877,7 +215086,7 @@ function parseCategory(raw) {
|
|
|
214877
215086
|
return;
|
|
214878
215087
|
return raw;
|
|
214879
215088
|
}
|
|
214880
|
-
async function
|
|
215089
|
+
async function defaultProviders() {
|
|
214881
215090
|
await Promise.resolve().then(() => init_provider_catalog());
|
|
214882
215091
|
const catalog = await loadOrRefreshProviderCatalog({ fetch, env: envWithSavedApiKeys() });
|
|
214883
215092
|
return catalogToFlatPickerProviders(catalog);
|
|
@@ -214890,7 +215099,7 @@ function defaultSession(userConfigDir) {
|
|
|
214890
215099
|
return { providerId: cfg.provider, modelId: cfg.model };
|
|
214891
215100
|
}
|
|
214892
215101
|
async function runList5(args, location, deps) {
|
|
214893
|
-
const loadProviders = deps.providers ??
|
|
215102
|
+
const loadProviders = deps.providers ?? defaultProviders;
|
|
214894
215103
|
const loadSession = deps.session ?? (() => defaultSession(location.userConfigDir));
|
|
214895
215104
|
const [project, user, providers] = await Promise.all([
|
|
214896
215105
|
loadRoutingConfig("project", location),
|
package/dist/core.js
CHANGED
|
@@ -1970,7 +1970,8 @@ function isValidIp(value) {
|
|
|
1970
1970
|
return false;
|
|
1971
1971
|
}
|
|
1972
1972
|
function isWordBoundary(flavour, content, index) {
|
|
1973
|
-
|
|
1973
|
+
flavour.boundary.lastIndex = index;
|
|
1974
|
+
return flavour.boundary.test(content);
|
|
1974
1975
|
}
|
|
1975
1976
|
function wordCharBefore(content, index) {
|
|
1976
1977
|
if (index <= 0) {
|
|
@@ -2710,12 +2711,12 @@ var init_pii = __esm(() => {
|
|
|
2710
2711
|
UNICODE_EMAIL = {
|
|
2711
2712
|
from: /(?:(?<=[\p{L}\p{N}\p{M}_])(?![\p{L}\p{N}\p{M}_])|(?<![\p{L}\p{N}\p{M}_])(?=[\p{L}\p{N}\p{M}_]))[\p{L}\p{N}\p{M}._%+-]+@[\p{L}\p{N}\p{M}.-]+\.[\p{L}\p{M}]{2,}(?![\p{L}\p{N}\p{M}_])/uy,
|
|
2712
2713
|
localChar: /[\p{L}\p{N}\p{M}._%+-]/u,
|
|
2713
|
-
|
|
2714
|
+
boundary: /(?:(?<=[\p{L}\p{N}\p{M}_])(?![\p{L}\p{N}\p{M}_])|(?<![\p{L}\p{N}\p{M}_])(?=[\p{L}\p{N}\p{M}_]))/uy
|
|
2714
2715
|
};
|
|
2715
2716
|
ASCII_EMAIL = {
|
|
2716
2717
|
from: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/y,
|
|
2717
2718
|
localChar: /[A-Za-z0-9._%+-]/,
|
|
2718
|
-
|
|
2719
|
+
boundary: /\b/y
|
|
2719
2720
|
};
|
|
2720
2721
|
emailScanner = emailScannerFor(UNICODE_EMAIL);
|
|
2721
2722
|
asciiEmailScanner = emailScannerFor(ASCII_EMAIL);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrciphersmith/keryx",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.79",
|
|
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": {
|