@mrciphersmith/keryx 0.2.27 → 0.2.31
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 +58 -161
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -38944,7 +38944,8 @@ import { homedir as homedir5 } from "os";
|
|
|
38944
38944
|
var WORKER_TIMEOUT_MS = 1e4;
|
|
38945
38945
|
var MAX_WORKER_OUTPUT_BYTES = 192000;
|
|
38946
38946
|
var WORKER_SOURCE = String.raw`
|
|
38947
|
-
const { request } = await import("node:https");
|
|
38947
|
+
const { request: httpsRequest } = await import("node:https");
|
|
38948
|
+
const { request: httpRequest } = await import("node:http");
|
|
38948
38949
|
const { isIP } = await import("node:net");
|
|
38949
38950
|
const input = JSON.parse(await Bun.stdin.text());
|
|
38950
38951
|
const fail = () => process.stdout.write(JSON.stringify({ ok: false, reason: "request failed or timed out" }));
|
|
@@ -38959,6 +38960,7 @@ try {
|
|
|
38959
38960
|
}
|
|
38960
38961
|
const encoded = payload ? JSON.stringify(payload) : undefined;
|
|
38961
38962
|
if (encoded) { headers["content-type"] = "application/json"; headers["content-length"] = String(Buffer.byteLength(encoded)); }
|
|
38963
|
+
const request = input.url.startsWith("http:") ? httpRequest : httpsRequest;
|
|
38962
38964
|
const req = request(input.url, {
|
|
38963
38965
|
method: input.method,
|
|
38964
38966
|
lookup: (_host, options, callback) => {
|
|
@@ -38969,7 +38971,7 @@ try {
|
|
|
38969
38971
|
if (options && options.all) callback(null, [record]);
|
|
38970
38972
|
else callback(null, record.address, record.family);
|
|
38971
38973
|
},
|
|
38972
|
-
servername: input.hostname,
|
|
38974
|
+
...(input.url.startsWith("https:") ? { servername: input.hostname } : {}),
|
|
38973
38975
|
headers,
|
|
38974
38976
|
}, (res) => {
|
|
38975
38977
|
const chunks = []; let size = 0;
|
|
@@ -41116,7 +41118,7 @@ var AGENT_SLASH_COMMANDS = [
|
|
|
41116
41118
|
description: "Switch provider / API key",
|
|
41117
41119
|
modes: BOTH,
|
|
41118
41120
|
modeDescriptions: {
|
|
41119
|
-
agent: "
|
|
41121
|
+
agent: "Connect to an already configured provider (interactive picker)",
|
|
41120
41122
|
chat: "Show how to set a provider API key in the environment"
|
|
41121
41123
|
}
|
|
41122
41124
|
},
|
|
@@ -41128,16 +41130,6 @@ var AGENT_SLASH_COMMANDS = [
|
|
|
41128
41130
|
agent: "Add or configure a provider (interactive picker)"
|
|
41129
41131
|
}
|
|
41130
41132
|
},
|
|
41131
|
-
{
|
|
41132
|
-
name: "/search-provider",
|
|
41133
|
-
description: "Configure or edit a web search provider",
|
|
41134
|
-
modes: AGENT_ONLY
|
|
41135
|
-
},
|
|
41136
|
-
{
|
|
41137
|
-
name: "/search-connect",
|
|
41138
|
-
description: "Select an active tested web search provider",
|
|
41139
|
-
modes: AGENT_ONLY
|
|
41140
|
-
},
|
|
41141
41133
|
{ name: "/think", description: "Expand the last reasoning block", modes: AGENT_ONLY },
|
|
41142
41134
|
{ name: "/expand", description: "Expand the last tool output block", modes: AGENT_ONLY },
|
|
41143
41135
|
{
|
|
@@ -44061,6 +44053,42 @@ function resolveSidebarMetadata(cwd) {
|
|
|
44061
44053
|
} catch {}
|
|
44062
44054
|
return { branch };
|
|
44063
44055
|
}
|
|
44056
|
+
async function filterConnectedDetectedProviders(detected, options = {}) {
|
|
44057
|
+
const fetchFn = options.fetch ?? globalThis.fetch;
|
|
44058
|
+
const env = options.env ?? process.env;
|
|
44059
|
+
const connected = [];
|
|
44060
|
+
for (const prov of detected) {
|
|
44061
|
+
const registry = providerByName(prov.name);
|
|
44062
|
+
if (registry === undefined) {
|
|
44063
|
+
connected.push(prov);
|
|
44064
|
+
continue;
|
|
44065
|
+
}
|
|
44066
|
+
const requiresApiKey = registry.requiresApiKey ?? true;
|
|
44067
|
+
const envKey = prov.envKey ?? registry.envKey;
|
|
44068
|
+
if (!requiresApiKey || envKey === undefined) {
|
|
44069
|
+
connected.push(prov);
|
|
44070
|
+
continue;
|
|
44071
|
+
}
|
|
44072
|
+
const raw = env[envKey];
|
|
44073
|
+
if (raw === undefined || raw.length === 0) {
|
|
44074
|
+
continue;
|
|
44075
|
+
}
|
|
44076
|
+
const compat = {
|
|
44077
|
+
...registry,
|
|
44078
|
+
...prov.baseUrl !== undefined ? { baseUrl: prov.baseUrl } : {},
|
|
44079
|
+
...prov.chatPath !== undefined ? { chatPath: prov.chatPath } : {},
|
|
44080
|
+
...prov.modelsPath !== undefined ? { modelsPath: prov.modelsPath } : {}
|
|
44081
|
+
};
|
|
44082
|
+
const result = await fetchOpenAiCompatModelsDetailed(fetchFn, compat, raw, {
|
|
44083
|
+
timeoutMs: MODELS_FETCH_TIMEOUT_MS
|
|
44084
|
+
});
|
|
44085
|
+
if (result.source !== "live" || result.models.length === 0) {
|
|
44086
|
+
continue;
|
|
44087
|
+
}
|
|
44088
|
+
connected.push(prov);
|
|
44089
|
+
}
|
|
44090
|
+
return connected;
|
|
44091
|
+
}
|
|
44064
44092
|
function createTuiAgentIo(otui, renderer, transcript) {
|
|
44065
44093
|
let seq = 0;
|
|
44066
44094
|
const append = (content) => {
|
|
@@ -44313,34 +44341,6 @@ function onKeypress3(r, handler) {
|
|
|
44313
44341
|
r._internalKeyInput.onInternal("keypress", handler);
|
|
44314
44342
|
return () => r._internalKeyInput.offInternal("keypress", handler);
|
|
44315
44343
|
}
|
|
44316
|
-
function promptTextStep(otui, r, opts) {
|
|
44317
|
-
return new Promise((resolve3) => {
|
|
44318
|
-
const box = overlayBox(otui, r, "search-field-picker");
|
|
44319
|
-
r.root.add(box);
|
|
44320
|
-
box.add(new otui.TextRenderable(r, { id: "sf-title", content: otui.t`${otui.bold(opts.title)} ${otui.dim("(Enter \xB7 Esc to cancel)")}` }));
|
|
44321
|
-
box.add(new otui.TextRenderable(r, { id: "sf-note", content: otui.t`${otui.dim(opts.note)}`, marginTop: 1 }));
|
|
44322
|
-
const field3 = new otui.InputRenderable(r, { id: "sf-input", value: opts.value, marginTop: 1 });
|
|
44323
|
-
box.add(field3);
|
|
44324
|
-
field3.focus();
|
|
44325
|
-
const cleanup = () => {
|
|
44326
|
-
unsub();
|
|
44327
|
-
r.root.remove(box);
|
|
44328
|
-
};
|
|
44329
|
-
const unsub = onKeypress3(r, (key) => {
|
|
44330
|
-
if (key.name === "escape") {
|
|
44331
|
-
cleanup();
|
|
44332
|
-
resolve3(undefined);
|
|
44333
|
-
key.preventDefault();
|
|
44334
|
-
key.stopPropagation();
|
|
44335
|
-
}
|
|
44336
|
-
});
|
|
44337
|
-
field3.on(otui.InputRenderableEvents.ENTER, () => {
|
|
44338
|
-
const value = field3.value.trim();
|
|
44339
|
-
cleanup();
|
|
44340
|
-
resolve3(value.length > 0 ? value : undefined);
|
|
44341
|
-
});
|
|
44342
|
-
});
|
|
44343
|
-
}
|
|
44344
44344
|
function promptBaseUrlStep(otui, r, label, baseUrl2) {
|
|
44345
44345
|
return new Promise((resolve3) => {
|
|
44346
44346
|
const box = overlayBox(otui, r, "base-url-picker");
|
|
@@ -44442,15 +44442,24 @@ function pickProviderStep(otui, r, detected) {
|
|
|
44442
44442
|
});
|
|
44443
44443
|
});
|
|
44444
44444
|
}
|
|
44445
|
-
function selectProviderModelInTui(otui, r, detected) {
|
|
44445
|
+
function selectProviderModelInTui(otui, r, detected, options = {}) {
|
|
44446
44446
|
return new Promise((resolve3) => {
|
|
44447
44447
|
if (detected.length === 0) {
|
|
44448
44448
|
resolve3(undefined);
|
|
44449
44449
|
return;
|
|
44450
44450
|
}
|
|
44451
|
+
const candidatesPromise = options.onlyConnected ? filterConnectedDetectedProviders(detected, {
|
|
44452
|
+
...options.fetch !== undefined ? { fetch: options.fetch } : {},
|
|
44453
|
+
...options.env !== undefined ? { env: options.env } : {}
|
|
44454
|
+
}) : Promise.resolve(detected);
|
|
44451
44455
|
(async () => {
|
|
44456
|
+
const candidates = await candidatesPromise;
|
|
44457
|
+
if (candidates.length === 0) {
|
|
44458
|
+
resolve3(undefined);
|
|
44459
|
+
return;
|
|
44460
|
+
}
|
|
44452
44461
|
while (true) {
|
|
44453
|
-
const prov = await pickProviderStep(otui, r,
|
|
44462
|
+
const prov = await pickProviderStep(otui, r, candidates);
|
|
44454
44463
|
if (prov === undefined) {
|
|
44455
44464
|
resolve3(undefined);
|
|
44456
44465
|
return;
|
|
@@ -44463,7 +44472,7 @@ function selectProviderModelInTui(otui, r, detected) {
|
|
|
44463
44472
|
saveProviderBaseUrl(prov.name, selectedBaseUrl);
|
|
44464
44473
|
const selectedProvider = selectedBaseUrl === undefined ? prov : { ...prov, baseUrl: selectedBaseUrl };
|
|
44465
44474
|
const envKey = prov.envKey;
|
|
44466
|
-
if (envKey !== undefined) {
|
|
44475
|
+
if (!options.onlyConnected && envKey !== undefined) {
|
|
44467
44476
|
const existingKey = process.env[envKey];
|
|
44468
44477
|
if (existingKey === undefined || existingKey.length === 0) {
|
|
44469
44478
|
const kr = await promptApiKeyStep(otui, r, { label: prov.label ?? prov.name, envKey });
|
|
@@ -45499,103 +45508,6 @@ Staying in the current session.
|
|
|
45499
45508
|
}
|
|
45500
45509
|
return;
|
|
45501
45510
|
}
|
|
45502
|
-
if (command.name === "/search-provider") {
|
|
45503
|
-
if (opts.searchController === undefined) {
|
|
45504
|
-
io.onSystem?.(`Web search configuration is unavailable in this shell.
|
|
45505
|
-
`);
|
|
45506
|
-
return;
|
|
45507
|
-
}
|
|
45508
|
-
(async () => {
|
|
45509
|
-
const descriptors = opts.searchController.configurable();
|
|
45510
|
-
const selected = await showComposerChoice(otui, r, chrome.dock, {
|
|
45511
|
-
title: "Configure web search provider",
|
|
45512
|
-
subtitle: "All supported providers are shown; only a successful test makes one selectable.",
|
|
45513
|
-
options: descriptors.map((descriptor2) => ({
|
|
45514
|
-
id: descriptor2.id,
|
|
45515
|
-
label: descriptor2.displayName,
|
|
45516
|
-
description: descriptor2.kind === "local" ? "Local loopback only" : "Remote HTTPS API",
|
|
45517
|
-
recommended: descriptor2.id === "searxng"
|
|
45518
|
-
})),
|
|
45519
|
-
cancelId: "cancel"
|
|
45520
|
-
});
|
|
45521
|
-
if (selected === "cancel") {
|
|
45522
|
-
input2.focus();
|
|
45523
|
-
return;
|
|
45524
|
-
}
|
|
45525
|
-
const descriptor = descriptors.find((item) => item.id === selected);
|
|
45526
|
-
if (descriptor === undefined) {
|
|
45527
|
-
input2.focus();
|
|
45528
|
-
return;
|
|
45529
|
-
}
|
|
45530
|
-
const fields = { ...descriptor.defaults };
|
|
45531
|
-
if (descriptor.id === "searxng") {
|
|
45532
|
-
const baseUrl2 = await promptTextStep(otui, r, {
|
|
45533
|
-
title: "SearXNG URL",
|
|
45534
|
-
note: "Default is local; only localhost, 127.0.0.1, or ::1 is permitted.",
|
|
45535
|
-
value: fields.baseUrl ?? "http://localhost"
|
|
45536
|
-
});
|
|
45537
|
-
if (baseUrl2 === undefined) {
|
|
45538
|
-
input2.focus();
|
|
45539
|
-
return;
|
|
45540
|
-
}
|
|
45541
|
-
const port = await promptTextStep(otui, r, {
|
|
45542
|
-
title: "SearXNG port",
|
|
45543
|
-
note: "Default: 8080. Edit it when your local server uses another port.",
|
|
45544
|
-
value: fields.port ?? "8080"
|
|
45545
|
-
});
|
|
45546
|
-
if (port === undefined) {
|
|
45547
|
-
input2.focus();
|
|
45548
|
-
return;
|
|
45549
|
-
}
|
|
45550
|
-
fields.baseUrl = baseUrl2;
|
|
45551
|
-
fields.port = port;
|
|
45552
|
-
opts.searchController.configure(descriptor.id, fields);
|
|
45553
|
-
} else {
|
|
45554
|
-
const key = await promptApiKeyStep(otui, r, { label: descriptor.displayName, envKey: "stored privately" });
|
|
45555
|
-
if (key.kind !== "key") {
|
|
45556
|
-
input2.focus();
|
|
45557
|
-
return;
|
|
45558
|
-
}
|
|
45559
|
-
opts.searchController.configure(descriptor.id, fields, key.value);
|
|
45560
|
-
}
|
|
45561
|
-
const result = await opts.searchController.test(descriptor.id);
|
|
45562
|
-
io.onSystem?.(result.ok ? `${descriptor.displayName} connected. Use /search-connect to make it active.
|
|
45563
|
-
` : `${descriptor.displayName} could not be connected (${result.reason ?? "unknown error"}).
|
|
45564
|
-
`);
|
|
45565
|
-
input2.focus();
|
|
45566
|
-
})();
|
|
45567
|
-
return;
|
|
45568
|
-
}
|
|
45569
|
-
if (command.name === "/search-connect") {
|
|
45570
|
-
if (opts.searchController === undefined) {
|
|
45571
|
-
io.onSystem?.(`Web search configuration is unavailable in this shell.
|
|
45572
|
-
`);
|
|
45573
|
-
return;
|
|
45574
|
-
}
|
|
45575
|
-
(async () => {
|
|
45576
|
-
const connected = opts.searchController.selectable();
|
|
45577
|
-
if (connected.length === 0) {
|
|
45578
|
-
io.onSystem?.(`No tested search providers. Configure one with /search-provider first.
|
|
45579
|
-
`);
|
|
45580
|
-
input2.focus();
|
|
45581
|
-
return;
|
|
45582
|
-
}
|
|
45583
|
-
const selected = await showComposerChoice(otui, r, chrome.dock, {
|
|
45584
|
-
title: "Select web search provider",
|
|
45585
|
-
subtitle: "Only successfully tested providers are available.",
|
|
45586
|
-
options: connected.map((descriptor) => ({ id: descriptor.id, label: descriptor.displayName, description: descriptor.kind })),
|
|
45587
|
-
cancelId: "cancel"
|
|
45588
|
-
});
|
|
45589
|
-
if (selected !== "cancel") {
|
|
45590
|
-
const result = await opts.searchController.select(selected);
|
|
45591
|
-
io.onSystem?.(result.ok ? `Web search provider selected.
|
|
45592
|
-
` : `Provider is no longer connected; test it again.
|
|
45593
|
-
`);
|
|
45594
|
-
}
|
|
45595
|
-
input2.focus();
|
|
45596
|
-
})();
|
|
45597
|
-
return;
|
|
45598
|
-
}
|
|
45599
45511
|
if (command.name === "/model") {
|
|
45600
45512
|
(async () => {
|
|
45601
45513
|
const detected = opts.redetect !== undefined ? await opts.redetect() : opts.detected;
|
|
@@ -45618,27 +45530,13 @@ Staying in the current session.
|
|
|
45618
45530
|
if (command.name === "/connect" || command.name === "/provider") {
|
|
45619
45531
|
(async () => {
|
|
45620
45532
|
const detected = opts.redetect !== undefined ? await opts.redetect() : opts.detected;
|
|
45621
|
-
const
|
|
45622
|
-
if (provider.name === "fake")
|
|
45623
|
-
return;
|
|
45624
|
-
if (provider.name === "rapid-mlx") {
|
|
45625
|
-
return (await modelsForPicker(provider)).length > 0 ? provider : undefined;
|
|
45626
|
-
}
|
|
45627
|
-
if (provider.envKey !== undefined) {
|
|
45628
|
-
return process.env[provider.envKey]?.length ? provider : undefined;
|
|
45629
|
-
}
|
|
45630
|
-
return provider;
|
|
45631
|
-
}))).filter((provider) => provider !== undefined);
|
|
45632
|
-
if (candidates.length === 0) {
|
|
45633
|
-
io.onSystem?.(`No connected providers found. Use /provider to add or configure one.
|
|
45634
|
-
`);
|
|
45635
|
-
input2.focus();
|
|
45636
|
-
return;
|
|
45637
|
-
}
|
|
45638
|
-
const ns = await chrome.withOverlay(() => selectProviderModelInTui(otui, r, candidates));
|
|
45533
|
+
const ns = await chrome.withOverlay(() => command.name === "/connect" ? selectProviderModelInTui(otui, r, detected, { onlyConnected: true, env: process.env }) : selectProviderModelInTui(otui, r, detected));
|
|
45639
45534
|
if (ns !== undefined) {
|
|
45640
45535
|
await switchTo(ns);
|
|
45641
45536
|
} else {
|
|
45537
|
+
if (command.name === "/connect") {
|
|
45538
|
+
chrome.showToast("No connected providers found. Run /provider to configure one first.");
|
|
45539
|
+
}
|
|
45642
45540
|
input2.focus();
|
|
45643
45541
|
}
|
|
45644
45542
|
})();
|
|
@@ -46153,7 +46051,7 @@ init_shell_config();
|
|
|
46153
46051
|
// package.json
|
|
46154
46052
|
var package_default = {
|
|
46155
46053
|
name: "@mrciphersmith/keryx",
|
|
46156
|
-
version: "0.2.
|
|
46054
|
+
version: "0.2.31",
|
|
46157
46055
|
description: "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
|
|
46158
46056
|
private: false,
|
|
46159
46057
|
publishConfig: {
|
|
@@ -47431,7 +47329,6 @@ async function shellCommand(args2, runtime = {}) {
|
|
|
47431
47329
|
} else if (await (runtime.launchAgent ?? launchTuiAgentShell)({
|
|
47432
47330
|
detected: tuiDetected,
|
|
47433
47331
|
makeAgentDeps,
|
|
47434
|
-
searchController: searchProviderController,
|
|
47435
47332
|
redetect,
|
|
47436
47333
|
...tuiInitial !== undefined ? { initial: tuiInitial } : {},
|
|
47437
47334
|
session: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrciphersmith/keryx",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.31",
|
|
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": {
|