@mrciphersmith/keryx 0.2.101 → 0.2.105
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 +89 -27
- package/dist/core.js +25 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1089,6 +1089,8 @@ var init_providers = __esm(() => {
|
|
|
1089
1089
|
label: "GitHub Copilot",
|
|
1090
1090
|
baseUrl: "https://api.githubcopilot.com",
|
|
1091
1091
|
envKey: "GITHUB_COPILOT_TOKEN",
|
|
1092
|
+
chatPath: "/chat/completions",
|
|
1093
|
+
modelsPath: "/models",
|
|
1092
1094
|
models: ["gpt-4o", "gpt-4.1", "gpt-4o-mini"],
|
|
1093
1095
|
note: "Copilot \xB7 device login"
|
|
1094
1096
|
}
|
|
@@ -10264,6 +10266,28 @@ var init_templates3 = __esm(() => {
|
|
|
10264
10266
|
init_default_tasks();
|
|
10265
10267
|
});
|
|
10266
10268
|
|
|
10269
|
+
// src/lib/git-env.ts
|
|
10270
|
+
function withoutGitDiscoveryOverrides(env) {
|
|
10271
|
+
const clean = {};
|
|
10272
|
+
for (const [key, value] of Object.entries(env)) {
|
|
10273
|
+
if (value !== undefined && !GIT_DISCOVERY_OVERRIDE_VARS.includes(key)) {
|
|
10274
|
+
clean[key] = value;
|
|
10275
|
+
}
|
|
10276
|
+
}
|
|
10277
|
+
return clean;
|
|
10278
|
+
}
|
|
10279
|
+
var GIT_DISCOVERY_OVERRIDE_VARS;
|
|
10280
|
+
var init_git_env = __esm(() => {
|
|
10281
|
+
GIT_DISCOVERY_OVERRIDE_VARS = [
|
|
10282
|
+
"GIT_DIR",
|
|
10283
|
+
"GIT_WORK_TREE",
|
|
10284
|
+
"GIT_INDEX_FILE",
|
|
10285
|
+
"GIT_OBJECT_DIRECTORY",
|
|
10286
|
+
"GIT_ALTERNATE_OBJECT_DIRECTORIES",
|
|
10287
|
+
"GIT_COMMON_DIR"
|
|
10288
|
+
];
|
|
10289
|
+
});
|
|
10290
|
+
|
|
10267
10291
|
// src/metrics/provenance.ts
|
|
10268
10292
|
async function collectGitProvenance(cwd) {
|
|
10269
10293
|
const [commit, branch, worktree] = await Promise.all([
|
|
@@ -11674,7 +11698,12 @@ function pathExistsSync(filePath) {
|
|
|
11674
11698
|
return existsSync11(filePath);
|
|
11675
11699
|
}
|
|
11676
11700
|
async function runCommand(command, cwd) {
|
|
11677
|
-
const proc = Bun.spawn(command, {
|
|
11701
|
+
const proc = Bun.spawn(command, {
|
|
11702
|
+
cwd,
|
|
11703
|
+
env: withoutGitDiscoveryOverrides(process.env),
|
|
11704
|
+
stdout: "pipe",
|
|
11705
|
+
stderr: "pipe"
|
|
11706
|
+
});
|
|
11678
11707
|
const [stdout, stderr, exitCode] = await Promise.all([
|
|
11679
11708
|
new Response(proc.stdout).text(),
|
|
11680
11709
|
new Response(proc.stderr).text(),
|
|
@@ -11837,6 +11866,7 @@ function normalizePath3(file) {
|
|
|
11837
11866
|
var IGNORED_DIRS, TEST_FILE_RE2, SOURCE_FILE_RE, CONFIG_FILE_RE, CI_FILE_RE, INSTRUCTION_FILE_RE, IMPORT_RE, DEFAULT_TESTING_CONFIG, BASE_STRATEGIES, BUN_LOCKFILES;
|
|
11838
11867
|
var init_service2 = __esm(() => {
|
|
11839
11868
|
init_fs();
|
|
11869
|
+
init_git_env();
|
|
11840
11870
|
init_lifecycle();
|
|
11841
11871
|
init_guard2();
|
|
11842
11872
|
init_capability();
|
|
@@ -27377,9 +27407,6 @@ var init_slate_terminal_state = __esm(() => {
|
|
|
27377
27407
|
});
|
|
27378
27408
|
|
|
27379
27409
|
// src/commands/agent.ts
|
|
27380
|
-
function isDurableToolCall(name, risk) {
|
|
27381
|
-
return risk !== "read" || DURABLE_READ_TOOL_NAMES.has(name);
|
|
27382
|
-
}
|
|
27383
27410
|
function resolveAgentMaxRounds(env = process.env) {
|
|
27384
27411
|
const raw = env[ENV_AGENT_MAX_ROUNDS];
|
|
27385
27412
|
if (raw === undefined || raw.trim().length === 0) {
|
|
@@ -27995,7 +28022,8 @@ async function runAgentTurnCore(io, deps, history, userLine, options = {}) {
|
|
|
27995
28022
|
return {};
|
|
27996
28023
|
}
|
|
27997
28024
|
const risk = toolByName.get(call.name)?.definition.risk;
|
|
27998
|
-
|
|
28025
|
+
const isPureReadTool = risk === "read" && !DURABLE_READ_TOOL_NAMES.has(call.name);
|
|
28026
|
+
if (!isPureReadTool && (untrustedContentSeen || batchContainsUntrustedWeb)) {
|
|
27999
28027
|
const result = {
|
|
28000
28028
|
output: "tool blocked: external web content cannot authorize further tool calls in this turn",
|
|
28001
28029
|
isError: true
|
|
@@ -41137,6 +41165,24 @@ var init_device_code = __esm(() => {
|
|
|
41137
41165
|
});
|
|
41138
41166
|
|
|
41139
41167
|
// src/lib/oauth/copilot.ts
|
|
41168
|
+
function copilotApiBaseFromExchange(raw) {
|
|
41169
|
+
if (typeof raw !== "string" || raw.length === 0) {
|
|
41170
|
+
return;
|
|
41171
|
+
}
|
|
41172
|
+
try {
|
|
41173
|
+
const url = new URL(raw);
|
|
41174
|
+
if (url.protocol !== "https:" || url.username.length > 0 || url.password.length > 0) {
|
|
41175
|
+
return;
|
|
41176
|
+
}
|
|
41177
|
+
const host = url.hostname;
|
|
41178
|
+
if (host !== "api.githubcopilot.com" && !host.endsWith(".githubcopilot.com")) {
|
|
41179
|
+
return;
|
|
41180
|
+
}
|
|
41181
|
+
return `https://${host}${url.port.length > 0 ? `:${url.port}` : ""}`;
|
|
41182
|
+
} catch {
|
|
41183
|
+
return;
|
|
41184
|
+
}
|
|
41185
|
+
}
|
|
41140
41186
|
function expiresInSecondsFrom(rec, now) {
|
|
41141
41187
|
if (typeof rec.expires_at === "string") {
|
|
41142
41188
|
const expires = Date.parse(rec.expires_at);
|
|
@@ -41197,7 +41243,12 @@ async function exchangeGithubTokenForCopilot(githubToken, http) {
|
|
|
41197
41243
|
throw new DeviceCodeError("failed", "GitHub Copilot token exchange returned no token");
|
|
41198
41244
|
}
|
|
41199
41245
|
const expiresInSeconds = expiresInSecondsFrom(rec, Date.now());
|
|
41200
|
-
|
|
41246
|
+
const apiBaseUrl = copilotApiBaseFromExchange(rec.endpoints?.api);
|
|
41247
|
+
return {
|
|
41248
|
+
accessToken: rec.token,
|
|
41249
|
+
...expiresInSeconds !== undefined ? { expiresInSeconds } : {},
|
|
41250
|
+
...apiBaseUrl !== undefined ? { apiBaseUrl } : {}
|
|
41251
|
+
};
|
|
41201
41252
|
}
|
|
41202
41253
|
var COPILOT_TOKEN_URL = "https://api.github.com/copilot_internal/v2/token";
|
|
41203
41254
|
var init_copilot = __esm(() => {
|
|
@@ -41321,6 +41372,9 @@ async function loginRfc8628(input) {
|
|
|
41321
41372
|
}, http);
|
|
41322
41373
|
if (endpoints.afterToken === "github-copilot") {
|
|
41323
41374
|
const copilot = await exchangeGithubTokenForCopilot(tokens.accessToken, http);
|
|
41375
|
+
if (copilot.apiBaseUrl !== undefined) {
|
|
41376
|
+
saveProviderBaseUrl("github-copilot", copilot.apiBaseUrl, input.dir);
|
|
41377
|
+
}
|
|
41324
41378
|
return {
|
|
41325
41379
|
accessToken: copilot.accessToken,
|
|
41326
41380
|
refreshToken: tokens.accessToken,
|
|
@@ -41370,6 +41424,9 @@ async function refreshProviderGrant(provider, http, dir) {
|
|
|
41370
41424
|
const endpoints = provider === "github-copilot" ? GITHUB_COPILOT_DEVICE : XAI_GROK_DEVICE;
|
|
41371
41425
|
if (provider === "github-copilot") {
|
|
41372
41426
|
const copilot = await exchangeGithubTokenForCopilot(grant.refresh, http);
|
|
41427
|
+
if (copilot.apiBaseUrl !== undefined) {
|
|
41428
|
+
saveProviderBaseUrl("github-copilot", copilot.apiBaseUrl, dir);
|
|
41429
|
+
}
|
|
41373
41430
|
const next = grantFromTokens("device-code", {
|
|
41374
41431
|
accessToken: copilot.accessToken,
|
|
41375
41432
|
refreshToken: grant.refresh,
|
|
@@ -41424,6 +41481,7 @@ function logoutProvider(provider, dir) {
|
|
|
41424
41481
|
}
|
|
41425
41482
|
var SESSION_REFRESHED_GRANTS;
|
|
41426
41483
|
var init_login = __esm(() => {
|
|
41484
|
+
init_shell_config();
|
|
41427
41485
|
init_catalog();
|
|
41428
41486
|
init_copilot();
|
|
41429
41487
|
init_device_code();
|
|
@@ -45289,6 +45347,7 @@ init_templates3();
|
|
|
45289
45347
|
init_service2();
|
|
45290
45348
|
|
|
45291
45349
|
// src/testing/templates.ts
|
|
45350
|
+
init_git_env();
|
|
45292
45351
|
function renderTestingConfig(input) {
|
|
45293
45352
|
return `${JSON.stringify({
|
|
45294
45353
|
schemaVersion: 1,
|
|
@@ -45481,6 +45540,11 @@ function renderTestingPrePushHook() {
|
|
|
45481
45540
|
return 0
|
|
45482
45541
|
fi
|
|
45483
45542
|
|
|
45543
|
+
# Git exports GIT_DIR to hooks. Inherited by the suite, it redirects every
|
|
45544
|
+
# fixture repo a test creates onto this checkout, so a fixture's
|
|
45545
|
+
# 'git config user.name' rewrites the identity of the repo being pushed.
|
|
45546
|
+
unset ${GIT_DISCOVERY_OVERRIDE_VARS.join(" ")}
|
|
45547
|
+
|
|
45484
45548
|
if command -v keryx >/dev/null 2>&1; then
|
|
45485
45549
|
keryx test run --changed --strict
|
|
45486
45550
|
return $?
|
|
@@ -48228,7 +48292,7 @@ import path47 from "path";
|
|
|
48228
48292
|
// package.json
|
|
48229
48293
|
var package_default = {
|
|
48230
48294
|
name: "@mrciphersmith/keryx",
|
|
48231
|
-
version: "0.2.
|
|
48295
|
+
version: "0.2.105",
|
|
48232
48296
|
description: "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
|
|
48233
48297
|
private: false,
|
|
48234
48298
|
publishConfig: {
|
|
@@ -79525,23 +79589,10 @@ function builtinReadOnlyTools(root) {
|
|
|
79525
79589
|
|
|
79526
79590
|
// src/harness/tool/builtin/apply-patch-tool.ts
|
|
79527
79591
|
init_patch_risk();
|
|
79592
|
+
init_git_env();
|
|
79528
79593
|
var MAX_OUTPUT_BYTES = 20000;
|
|
79529
|
-
var GIT_DISCOVERY_OVERRIDE_VARS = [
|
|
79530
|
-
"GIT_DIR",
|
|
79531
|
-
"GIT_WORK_TREE",
|
|
79532
|
-
"GIT_INDEX_FILE",
|
|
79533
|
-
"GIT_OBJECT_DIRECTORY",
|
|
79534
|
-
"GIT_ALTERNATE_OBJECT_DIRECTORIES",
|
|
79535
|
-
"GIT_COMMON_DIR"
|
|
79536
|
-
];
|
|
79537
79594
|
function gitDiscoveryCleanEnv() {
|
|
79538
|
-
|
|
79539
|
-
for (const [key, value] of Object.entries(process.env)) {
|
|
79540
|
-
if (value !== undefined && !GIT_DISCOVERY_OVERRIDE_VARS.includes(key)) {
|
|
79541
|
-
env[key] = value;
|
|
79542
|
-
}
|
|
79543
|
-
}
|
|
79544
|
-
return env;
|
|
79595
|
+
return withoutGitDiscoveryOverrides(process.env);
|
|
79545
79596
|
}
|
|
79546
79597
|
async function spawnGitApply(args, patch, cwd) {
|
|
79547
79598
|
try {
|
|
@@ -95021,7 +95072,7 @@ function pickAuthMethodStep(otui, r, providerLabel, methods) {
|
|
|
95021
95072
|
});
|
|
95022
95073
|
});
|
|
95023
95074
|
}
|
|
95024
|
-
function runDeviceLoginInTui(otui, r, provider) {
|
|
95075
|
+
function runDeviceLoginInTui(otui, r, provider, dir) {
|
|
95025
95076
|
return new Promise((resolve) => {
|
|
95026
95077
|
const box = overlayBox(otui, r, "device-login");
|
|
95027
95078
|
r.root.add(box);
|
|
@@ -95049,6 +95100,7 @@ function runDeviceLoginInTui(otui, r, provider) {
|
|
|
95049
95100
|
provider,
|
|
95050
95101
|
fetch: (input, init) => globalThis.fetch(input, init),
|
|
95051
95102
|
signal: controller.signal,
|
|
95103
|
+
...dir !== undefined ? { dir } : {},
|
|
95052
95104
|
onChallenge: (challenge) => {
|
|
95053
95105
|
status.content = otui.t`${otui.bold(challenge.userCode)}\n${otui.dim(challenge.verificationUri)}\n${otui.dim("Open that URL on any device and enter the code. Waiting for authorization\u2026")}`;
|
|
95054
95106
|
openVerificationUrl(challenge.verificationUriComplete ?? challenge.verificationUri);
|
|
@@ -95165,12 +95217,14 @@ function selectProviderModelInTui(otui, r, detected, options = {}) {
|
|
|
95165
95217
|
}
|
|
95166
95218
|
continue;
|
|
95167
95219
|
}
|
|
95168
|
-
|
|
95169
|
-
|
|
95220
|
+
const lockDiscoveredHost = prov.name === "github-copilot";
|
|
95221
|
+
let selectedBaseUrl = options.onlyConnected || prov.baseUrl === undefined || lockDiscoveredHost ? prov.baseUrl : await promptBaseUrlStep(otui, r, prov.label ?? prov.name, prov.baseUrl);
|
|
95222
|
+
if (!options.onlyConnected && !lockDiscoveredHost && prov.baseUrl !== undefined && selectedBaseUrl === undefined) {
|
|
95170
95223
|
continue;
|
|
95171
95224
|
}
|
|
95172
|
-
if (!options.onlyConnected && selectedBaseUrl !== undefined)
|
|
95225
|
+
if (!options.onlyConnected && !lockDiscoveredHost && selectedBaseUrl !== undefined) {
|
|
95173
95226
|
saveProviderBaseUrl(prov.name, selectedBaseUrl, options.configDir);
|
|
95227
|
+
}
|
|
95174
95228
|
let selectedProvider = selectedBaseUrl === undefined ? prov : { ...prov, baseUrl: selectedBaseUrl };
|
|
95175
95229
|
const envKey = prov.envKey;
|
|
95176
95230
|
const label = prov.label ?? prov.name;
|
|
@@ -95198,7 +95252,15 @@ function selectProviderModelInTui(otui, r, detected, options = {}) {
|
|
|
95198
95252
|
}
|
|
95199
95253
|
}
|
|
95200
95254
|
if (method === "device-code") {
|
|
95201
|
-
|
|
95255
|
+
if (!await runDeviceLoginInTui(otui, r, prov.name, options.configDir)) {
|
|
95256
|
+
return "back";
|
|
95257
|
+
}
|
|
95258
|
+
const saved = loadShellConfig(options.configDir).baseUrls?.[prov.name];
|
|
95259
|
+
if (typeof saved === "string" && saved.length > 0) {
|
|
95260
|
+
selectedBaseUrl = saved;
|
|
95261
|
+
selectedProvider = { ...prov, baseUrl: saved };
|
|
95262
|
+
}
|
|
95263
|
+
return "ok";
|
|
95202
95264
|
}
|
|
95203
95265
|
const kr = await promptApiKeyStep(otui, r, {
|
|
95204
95266
|
label,
|
package/dist/core.js
CHANGED
|
@@ -16331,6 +16331,25 @@ import { existsSync as existsSync7 } from "fs";
|
|
|
16331
16331
|
import { mkdir as mkdir21, readFile as readFile29, readdir as readdir10, writeFile as writeFile17 } from "fs/promises";
|
|
16332
16332
|
import path58 from "path";
|
|
16333
16333
|
|
|
16334
|
+
// src/lib/git-env.ts
|
|
16335
|
+
var GIT_DISCOVERY_OVERRIDE_VARS = [
|
|
16336
|
+
"GIT_DIR",
|
|
16337
|
+
"GIT_WORK_TREE",
|
|
16338
|
+
"GIT_INDEX_FILE",
|
|
16339
|
+
"GIT_OBJECT_DIRECTORY",
|
|
16340
|
+
"GIT_ALTERNATE_OBJECT_DIRECTORIES",
|
|
16341
|
+
"GIT_COMMON_DIR"
|
|
16342
|
+
];
|
|
16343
|
+
function withoutGitDiscoveryOverrides(env) {
|
|
16344
|
+
const clean = {};
|
|
16345
|
+
for (const [key, value] of Object.entries(env)) {
|
|
16346
|
+
if (value !== undefined && !GIT_DISCOVERY_OVERRIDE_VARS.includes(key)) {
|
|
16347
|
+
clean[key] = value;
|
|
16348
|
+
}
|
|
16349
|
+
}
|
|
16350
|
+
return clean;
|
|
16351
|
+
}
|
|
16352
|
+
|
|
16334
16353
|
// src/metrics/lifecycle.ts
|
|
16335
16354
|
init_fs();
|
|
16336
16355
|
init_guard();
|
|
@@ -17244,7 +17263,12 @@ function pathExistsSync(filePath) {
|
|
|
17244
17263
|
return existsSync7(filePath);
|
|
17245
17264
|
}
|
|
17246
17265
|
async function runCommand2(command, cwd) {
|
|
17247
|
-
const proc = Bun.spawn(command, {
|
|
17266
|
+
const proc = Bun.spawn(command, {
|
|
17267
|
+
cwd,
|
|
17268
|
+
env: withoutGitDiscoveryOverrides(process.env),
|
|
17269
|
+
stdout: "pipe",
|
|
17270
|
+
stderr: "pipe"
|
|
17271
|
+
});
|
|
17248
17272
|
const [stdout, stderr, exitCode] = await Promise.all([
|
|
17249
17273
|
new Response(proc.stdout).text(),
|
|
17250
17274
|
new Response(proc.stderr).text(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrciphersmith/keryx",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.105",
|
|
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": {
|