@mrciphersmith/keryx 0.2.97 → 0.2.98
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 +569 -235
- package/dist/core.js +1 -1
- package/package.json +1 -1
- package/src/gdskills/bundled/rules/core/api-contracts.mdc +1 -0
- package/src/gdskills/bundled/rules/core/code-style-patterns.mdc +1 -0
- package/src/gdskills/bundled/rules/core/database-patterns.mdc +1 -0
- package/src/gdskills/bundled/rules/core/documentation-management.mdc +33 -38
- package/src/gdskills/bundled/rules/core/error-handling.mdc +1 -11
- package/src/gdskills/bundled/rules/core/execution-metrics.md +1 -2
- package/src/gdskills/bundled/rules/core/frontend-assistant.mdc +1 -0
- package/src/gdskills/bundled/rules/core/git-concurrency.mdc +101 -0
- package/src/gdskills/bundled/rules/core/implementation-plans.mdc +23 -11
- package/src/gdskills/bundled/rules/core/mobx-store-template.mdc +1 -0
- package/src/gdskills/bundled/rules/core/nestjs-dto.mdc +1 -0
- package/src/gdskills/bundled/rules/core/playwright-testing.mdc +1 -0
- package/src/gdskills/bundled/rules/core/requirements-management.mdc +15 -11
- package/src/gdskills/bundled/rules/core/rule-management-workflow.mdc +29 -14
- package/src/gdskills/bundled/rules/core/shared-definitions.mdc +1 -1
- package/src/gdskills/bundled/rules/core/skill-lifecycle.mdc +9 -5
- package/src/gdskills/bundled/rules/core/skills-storage-workflow.mdc +59 -16
- package/src/gdskills/bundled/rules/core/storybook-guidelines.mdc +1 -0
- package/src/gdskills/bundled/skills/orchestration/code-verifier/SKILL.codex.md +48 -71
- package/src/gdskills/bundled/skills/orchestration/code-verifier/SKILL.cursor.md +48 -71
- package/src/gdskills/bundled/skills/orchestration/code-verifier/SKILL.md +48 -71
- package/src/gdskills/bundled/skills/orchestration/code-verifier/SKILL.opencode.md +48 -71
- package/src/gdskills/bundled/skills/orchestration/code-verifier/SKILL.zed.md +48 -71
- package/src/gdskills/bundled/skills/orchestration/context-collector/SKILL.codex.md +4 -4
- package/src/gdskills/bundled/skills/orchestration/context-collector/SKILL.cursor.md +4 -4
- package/src/gdskills/bundled/skills/orchestration/context-collector/SKILL.md +4 -4
- package/src/gdskills/bundled/skills/orchestration/context-collector/SKILL.opencode.md +4 -4
- package/src/gdskills/bundled/skills/orchestration/context-collector/SKILL.zed.md +4 -4
- package/src/gdskills/bundled/skills/orchestration/context-collector/orchestrator-prompt.md +2 -2
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.codex.md +12 -22
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.cursor.md +12 -22
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.detail.md +12 -22
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.md +12 -22
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.opencode.md +12 -22
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/SKILL.zed.md +12 -22
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/analysis-request.md +2 -2
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/analysis-request.template.md +1 -1
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/input-contract.schema.json +4 -4
- package/src/gdskills/bundled/skills/orchestration/feature-analyzer/orchestrator-prompt.md +2 -2
- package/src/gdskills/bundled/skills/orchestration/feature-dev/SKILL.codex.md +2 -2
- package/src/gdskills/bundled/skills/orchestration/feature-dev/SKILL.cursor.md +2 -2
- package/src/gdskills/bundled/skills/orchestration/feature-dev/SKILL.md +2 -2
- package/src/gdskills/bundled/skills/orchestration/flow-orchestrator/SKILL.md +46 -4
- package/src/gdskills/bundled/skills/orchestration/issue-analyzer/SKILL.codex.md +2 -2
- package/src/gdskills/bundled/skills/orchestration/issue-analyzer/SKILL.cursor.md +2 -2
- package/src/gdskills/bundled/skills/orchestration/issue-analyzer/SKILL.md +2 -2
- package/src/gdskills/bundled/skills/orchestration/issue-analyzer/SKILL.opencode.md +2 -2
- package/src/gdskills/bundled/skills/orchestration/issue-analyzer/SKILL.zed.md +2 -2
- package/src/gdskills/bundled/skills/orchestration/job-documenter/SKILL.codex.md +3 -3
- package/src/gdskills/bundled/skills/orchestration/job-documenter/SKILL.cursor.md +3 -3
- package/src/gdskills/bundled/skills/orchestration/job-documenter/SKILL.md +3 -3
- package/src/gdskills/bundled/skills/orchestration/job-documenter/SKILL.opencode.md +3 -3
- package/src/gdskills/bundled/skills/orchestration/job-documenter/SKILL.zed.md +3 -3
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.codex.md +65 -23
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.cursor.md +65 -23
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.md +65 -23
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.opencode.md +65 -23
- package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.zed.md +65 -23
- package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.codex.md +19 -10
- package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.cursor.md +19 -10
- package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.md +19 -10
- package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.opencode.md +19 -10
- package/src/gdskills/bundled/skills/orchestration/task-implementer/SKILL.zed.md +19 -10
- package/src/gdskills/bundled/skills/planning/brainstorm/SKILL.codex.md +1 -1
- package/src/gdskills/bundled/skills/planning/brainstorm/SKILL.cursor.md +1 -1
- package/src/gdskills/bundled/skills/planning/brainstorm/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/planning/interview/SKILL.codex.md +1 -1
- package/src/gdskills/bundled/skills/planning/interview/SKILL.cursor.md +1 -1
- package/src/gdskills/bundled/skills/planning/interview/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/planning/interviewer/SKILL.codex.md +1 -1
- package/src/gdskills/bundled/skills/planning/interviewer/SKILL.cursor.md +1 -1
- package/src/gdskills/bundled/skills/planning/interviewer/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/planning/prd-creator/SKILL.codex.md +7 -7
- package/src/gdskills/bundled/skills/planning/prd-creator/SKILL.cursor.md +7 -7
- package/src/gdskills/bundled/skills/planning/prd-creator/SKILL.md +7 -7
- package/src/gdskills/bundled/skills/planning/prd-creator/SKILL.opencode.md +7 -7
- package/src/gdskills/bundled/skills/planning/prd-creator/SKILL.zed.md +7 -7
- package/src/gdskills/bundled/skills/platform/claude-md-management/SKILL.codex.md +1 -1
- package/src/gdskills/bundled/skills/platform/claude-md-management/SKILL.cursor.md +1 -1
- package/src/gdskills/bundled/skills/platform/claude-md-management/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/platform/hookify/SKILL.codex.md +1 -1
- package/src/gdskills/bundled/skills/platform/hookify/SKILL.cursor.md +1 -1
- package/src/gdskills/bundled/skills/platform/hookify/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/quality/changelog/SKILL.codex.md +1 -1
- package/src/gdskills/bundled/skills/quality/changelog/SKILL.cursor.md +1 -1
- package/src/gdskills/bundled/skills/quality/changelog/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/quality/commit/SKILL.codex.md +2 -2
- package/src/gdskills/bundled/skills/quality/commit/SKILL.cursor.md +2 -2
- package/src/gdskills/bundled/skills/quality/commit/SKILL.md +2 -2
- package/src/gdskills/bundled/skills/quality/db-migrate/SKILL.codex.md +1 -1
- package/src/gdskills/bundled/skills/quality/db-migrate/SKILL.cursor.md +1 -1
- package/src/gdskills/bundled/skills/quality/db-migrate/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/quality/dependency-update/SKILL.codex.md +1 -1
- package/src/gdskills/bundled/skills/quality/dependency-update/SKILL.cursor.md +1 -1
- package/src/gdskills/bundled/skills/quality/dependency-update/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/quality/deploy/SKILL.codex.md +1 -1
- package/src/gdskills/bundled/skills/quality/deploy/SKILL.cursor.md +1 -1
- package/src/gdskills/bundled/skills/quality/deploy/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/quality/perf-check/SKILL.codex.md +1 -1
- package/src/gdskills/bundled/skills/quality/perf-check/SKILL.cursor.md +1 -1
- package/src/gdskills/bundled/skills/quality/perf-check/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/quality/pr/SKILL.codex.md +1 -1
- package/src/gdskills/bundled/skills/quality/pr/SKILL.cursor.md +1 -1
- package/src/gdskills/bundled/skills/quality/pr/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/quality/pr-issue-documenter/SKILL.codex.md +2 -2
- package/src/gdskills/bundled/skills/quality/pr-issue-documenter/SKILL.cursor.md +2 -2
- package/src/gdskills/bundled/skills/quality/pr-issue-documenter/SKILL.md +2 -2
- package/src/gdskills/bundled/skills/quality/pr-issue-documenter/SKILL.opencode.md +2 -2
- package/src/gdskills/bundled/skills/quality/pr-issue-documenter/SKILL.zed.md +2 -2
- package/src/gdskills/bundled/skills/quality/push/SKILL.codex.md +1 -1
- package/src/gdskills/bundled/skills/quality/push/SKILL.cursor.md +1 -1
- package/src/gdskills/bundled/skills/quality/push/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/quality/test-gen/SKILL.codex.md +7 -2
- package/src/gdskills/bundled/skills/quality/test-gen/SKILL.cursor.md +7 -2
- package/src/gdskills/bundled/skills/quality/test-gen/SKILL.md +7 -2
- package/src/gdskills/bundled/skills/quality/tests-creator/SKILL.codex.md +15 -9
- package/src/gdskills/bundled/skills/quality/tests-creator/SKILL.cursor.md +15 -9
- package/src/gdskills/bundled/skills/quality/tests-creator/SKILL.md +15 -9
- package/src/gdskills/bundled/skills/quality/tests-creator/SKILL.opencode.md +15 -9
- package/src/gdskills/bundled/skills/quality/tests-creator/SKILL.zed.md +15 -9
- package/src/gdskills/bundled/skills/review/code-ai-review/SKILL.codex.md +2 -2
- package/src/gdskills/bundled/skills/review/code-ai-review/SKILL.cursor.md +2 -2
- package/src/gdskills/bundled/skills/review/code-ai-review/SKILL.md +2 -2
- package/src/gdskills/bundled/skills/review/code-ai-review/SKILL.opencode.md +2 -2
- package/src/gdskills/bundled/skills/review/code-ai-review/SKILL.zed.md +2 -2
- package/src/gdskills/bundled/skills/review/code-learned-review/SKILL.codex.md +2 -2
- package/src/gdskills/bundled/skills/review/code-learned-review/SKILL.cursor.md +2 -2
- package/src/gdskills/bundled/skills/review/code-learned-review/SKILL.md +2 -2
- package/src/gdskills/bundled/skills/review/code-learned-review/SKILL.opencode.md +2 -2
- package/src/gdskills/bundled/skills/review/code-learned-review/SKILL.zed.md +2 -2
- package/src/gdskills/bundled/skills/review/code-mobx-store-review/SKILL.codex.md +2 -2
- package/src/gdskills/bundled/skills/review/code-mobx-store-review/SKILL.cursor.md +2 -2
- package/src/gdskills/bundled/skills/review/code-mobx-store-review/SKILL.md +2 -2
- package/src/gdskills/bundled/skills/review/code-mobx-store-review/SKILL.opencode.md +2 -2
- package/src/gdskills/bundled/skills/review/code-mobx-store-review/SKILL.zed.md +2 -2
- package/src/gdskills/bundled/skills/review/code-style-review/SKILL.codex.md +2 -2
- package/src/gdskills/bundled/skills/review/code-style-review/SKILL.cursor.md +2 -2
- package/src/gdskills/bundled/skills/review/code-style-review/SKILL.md +2 -2
- package/src/gdskills/bundled/skills/review/code-style-review/SKILL.opencode.md +2 -2
- package/src/gdskills/bundled/skills/review/code-style-review/SKILL.zed.md +2 -2
- package/src/gdskills/bundled/skills/review/review-architecture/SKILL.md +2 -2
- package/src/gdskills/bundled/skills/review/review-backend/SKILL.md +3 -3
- package/src/gdskills/bundled/skills/review/review-clean-code/SKILL.md +2 -2
- package/src/gdskills/bundled/skills/review/review-core-boundaries/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-flow-graph/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-frontend/SKILL.md +2 -2
- package/src/gdskills/bundled/skills/review/review-frontend-conventions/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-highload/SKILL.md +2 -2
- package/src/gdskills/bundled/skills/review/review-layout/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-logic/SKILL.md +2 -2
- package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.md +40 -35
- package/src/gdskills/bundled/skills/review/review-orchestrator/input-contract.schema.json +1 -2
- package/src/gdskills/bundled/skills/review/review-orchestrator/review-context.schema.json +1 -5
- package/src/gdskills/bundled/skills/review/review-orchestrator/reviewer-input.schema.json +53 -9
- package/src/gdskills/bundled/skills/review/review-performance/SKILL.md +2 -2
- package/src/gdskills/bundled/skills/review/review-pr-feedback/SKILL.md +6 -6
- package/src/gdskills/bundled/skills/review/review-security-code/SKILL.md +2 -2
- package/src/gdskills/bundled/skills/review/review-style/SKILL.md +3 -3
- package/src/gdskills/bundled/skills/review/review-testing-practices/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-verifier/SKILL.md +1 -1
- package/src/gdskills/bundled/rules/core/review-agent-profile.mdc +0 -49
- package/src/gdskills/bundled/rules/core/review-strict-profile.mdc +0 -48
package/dist/cli.js
CHANGED
|
@@ -301,6 +301,13 @@ var init_provider_config = __esm(() => {
|
|
|
301
301
|
// src/lib/shell-config.ts
|
|
302
302
|
import { existsSync as existsSync2 } from "fs";
|
|
303
303
|
import path3 from "path";
|
|
304
|
+
function noteSavedCredentialEnv(keys) {
|
|
305
|
+
for (const key of keys)
|
|
306
|
+
savedCredentialKeys.add(key);
|
|
307
|
+
}
|
|
308
|
+
function savedCredentialEnvKeys() {
|
|
309
|
+
return savedCredentialKeys;
|
|
310
|
+
}
|
|
304
311
|
function shellConfigPath(dir) {
|
|
305
312
|
return path3.join(keryxConfigDir(dir), "auth.json");
|
|
306
313
|
}
|
|
@@ -383,10 +390,13 @@ function applySavedApiKeys(dir) {
|
|
|
383
390
|
}
|
|
384
391
|
}
|
|
385
392
|
} catch {}
|
|
393
|
+
noteSavedCredentialEnv(applied);
|
|
386
394
|
return applied;
|
|
387
395
|
}
|
|
396
|
+
var savedCredentialKeys;
|
|
388
397
|
var init_shell_config = __esm(() => {
|
|
389
398
|
init_config_dir();
|
|
399
|
+
savedCredentialKeys = new Set;
|
|
390
400
|
});
|
|
391
401
|
|
|
392
402
|
// src/lib/oauth/grants.ts
|
|
@@ -472,6 +482,7 @@ function applyOAuthAccessToEnv(dir) {
|
|
|
472
482
|
applied.push(envKey);
|
|
473
483
|
}
|
|
474
484
|
}
|
|
485
|
+
noteSavedCredentialEnv(applied);
|
|
475
486
|
return applied;
|
|
476
487
|
}
|
|
477
488
|
function grantFromTokens(method, tokens, now = Date.now) {
|
|
@@ -571,10 +582,61 @@ function customCompatProviders(dir) {
|
|
|
571
582
|
function allOpenAiCompatProviders(dir) {
|
|
572
583
|
return [...OPENAI_COMPAT_PROVIDERS, ...customCompatProviders(dir)];
|
|
573
584
|
}
|
|
585
|
+
function modelsErrorDetail(body) {
|
|
586
|
+
const text = body.slice(0, MODELS_ERROR_BODY_LIMIT).trim();
|
|
587
|
+
if (text.length === 0) {
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
let parsed;
|
|
591
|
+
try {
|
|
592
|
+
parsed = JSON.parse(text);
|
|
593
|
+
} catch {
|
|
594
|
+
parsed = undefined;
|
|
595
|
+
}
|
|
596
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
597
|
+
const record = parsed;
|
|
598
|
+
const error = record.error;
|
|
599
|
+
if (typeof error === "string" && error.length > 0) {
|
|
600
|
+
return error;
|
|
601
|
+
}
|
|
602
|
+
if (typeof error === "object" && error !== null) {
|
|
603
|
+
const message = error.message;
|
|
604
|
+
if (typeof message === "string" && message.length > 0) {
|
|
605
|
+
return message;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
for (const field of ["detail", "message"]) {
|
|
609
|
+
const value = record[field];
|
|
610
|
+
if (typeof value === "string" && value.length > 0) {
|
|
611
|
+
return value;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
616
|
+
if (text.startsWith("<") || text.includes("<html")) {
|
|
617
|
+
return;
|
|
618
|
+
}
|
|
619
|
+
const firstLine = text.split(`
|
|
620
|
+
`, 1)[0]?.trim();
|
|
621
|
+
return firstLine !== undefined && firstLine.length > 0 ? firstLine : undefined;
|
|
622
|
+
}
|
|
623
|
+
function modelsFailureLine(providerLabel, failure) {
|
|
624
|
+
const detail = "detail" in failure && failure.detail !== undefined ? ` \u2014 ${failure.detail}` : "";
|
|
625
|
+
switch (failure.kind) {
|
|
626
|
+
case "rejected":
|
|
627
|
+
return `${providerLabel} rejected the credential (HTTP ${failure.status})${detail}`;
|
|
628
|
+
case "http":
|
|
629
|
+
return `${providerLabel} could not list models (HTTP ${failure.status})${detail}`;
|
|
630
|
+
case "unreachable":
|
|
631
|
+
return `${providerLabel} could not be reached${detail}`;
|
|
632
|
+
case "empty":
|
|
633
|
+
return `${providerLabel} reports no models`;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
574
636
|
async function fetchOpenAiCompatModelsDetailed(fetchFn, provider, apiKey, opts) {
|
|
575
637
|
const url = `${provider.baseUrl.replace(/\/+$/, "")}${provider.modelsPath ?? DEFAULT_MODELS_PATH}`;
|
|
576
638
|
const timeoutMs = opts?.timeoutMs ?? MODELS_FETCH_TIMEOUT_MS;
|
|
577
|
-
const fallback = { models: [], source: "fallback" };
|
|
639
|
+
const fallback = (failure) => ({ models: [], source: "fallback", failure });
|
|
578
640
|
const controller = new AbortController;
|
|
579
641
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
580
642
|
try {
|
|
@@ -584,7 +646,9 @@ async function fetchOpenAiCompatModelsDetailed(fetchFn, provider, apiKey, opts)
|
|
|
584
646
|
}
|
|
585
647
|
const res = await fetchFn(url, init);
|
|
586
648
|
if (!res.ok) {
|
|
587
|
-
|
|
649
|
+
const detail = modelsErrorDetail(await res.text().catch(() => ""));
|
|
650
|
+
const kind = res.status === 401 || res.status === 403 ? "rejected" : "http";
|
|
651
|
+
return fallback({ kind, status: res.status, ...detail === undefined ? {} : { detail } });
|
|
588
652
|
}
|
|
589
653
|
const body = await res.json();
|
|
590
654
|
const ids = Array.isArray(body?.data) ? body.data.map((m) => {
|
|
@@ -597,11 +661,13 @@ async function fetchOpenAiCompatModelsDetailed(fetchFn, provider, apiKey, opts)
|
|
|
597
661
|
return "";
|
|
598
662
|
}).filter((id) => id.length > 0) : [];
|
|
599
663
|
if (ids.length === 0) {
|
|
600
|
-
return fallback;
|
|
664
|
+
return fallback({ kind: "empty" });
|
|
601
665
|
}
|
|
602
666
|
return { models: Array.from(new Set(ids)).sort(), source: "live" };
|
|
603
|
-
} catch {
|
|
604
|
-
|
|
667
|
+
} catch (err) {
|
|
668
|
+
const aborted = controller.signal.aborted;
|
|
669
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
670
|
+
return fallback({ kind: "unreachable", detail: aborted ? `timed out after ${timeoutMs}ms` : message });
|
|
605
671
|
} finally {
|
|
606
672
|
clearTimeout(timer);
|
|
607
673
|
}
|
|
@@ -821,7 +887,7 @@ optimisation. With no second family configured it reports single-family review
|
|
|
821
887
|
with a stated reason and exits 0 \u2014 that is a normal configuration, not an error.
|
|
822
888
|
`);
|
|
823
889
|
}
|
|
824
|
-
var DEFAULT_MODELS_PATH = "/v1/models", OPENAI_COMPAT_PROVIDERS, MODELS_FETCH_TIMEOUT_MS = 1e4, BALANCE_FETCH_TIMEOUT_MS = 8000;
|
|
890
|
+
var DEFAULT_MODELS_PATH = "/v1/models", OPENAI_COMPAT_PROVIDERS, MODELS_FETCH_TIMEOUT_MS = 1e4, MODELS_ERROR_BODY_LIMIT = 4096, BALANCE_FETCH_TIMEOUT_MS = 8000;
|
|
825
891
|
var init_providers = __esm(() => {
|
|
826
892
|
init_provider_config();
|
|
827
893
|
init_grants();
|
|
@@ -13250,7 +13316,7 @@ var init_staleness = __esm(() => {
|
|
|
13250
13316
|
});
|
|
13251
13317
|
|
|
13252
13318
|
// src/wiki/staleness.ts
|
|
13253
|
-
import { createHash as
|
|
13319
|
+
import { createHash as createHash7 } from "crypto";
|
|
13254
13320
|
import { readFile as readFile29 } from "fs/promises";
|
|
13255
13321
|
import path68 from "path";
|
|
13256
13322
|
async function computePageNodeHash(cwd, keyFiles, graph) {
|
|
@@ -13261,7 +13327,7 @@ async function computePageNodeHash(cwd, keyFiles, graph) {
|
|
|
13261
13327
|
if (knownPaths.has(file)) {
|
|
13262
13328
|
try {
|
|
13263
13329
|
const content = await readFile29(path68.join(cwd, file), "utf8");
|
|
13264
|
-
digest =
|
|
13330
|
+
digest = createHash7("sha256").update(content).digest("hex");
|
|
13265
13331
|
} catch {
|
|
13266
13332
|
digest = "<missing>";
|
|
13267
13333
|
}
|
|
@@ -13271,7 +13337,7 @@ async function computePageNodeHash(cwd, keyFiles, graph) {
|
|
|
13271
13337
|
entries.sort((a, b) => a.path.localeCompare(b.path));
|
|
13272
13338
|
const combined = entries.map((entry) => `${entry.path}:${entry.digest}`).join(`
|
|
13273
13339
|
`);
|
|
13274
|
-
return
|
|
13340
|
+
return createHash7("sha256").update(combined).digest("hex");
|
|
13275
13341
|
}
|
|
13276
13342
|
function isPageUnchangedSinceLastEnrich(pagePath, currentHash, completedNodeHashes) {
|
|
13277
13343
|
const previous = completedNodeHashes?.[pagePath];
|
|
@@ -13325,7 +13391,7 @@ var init_staleness2 = __esm(() => {
|
|
|
13325
13391
|
});
|
|
13326
13392
|
|
|
13327
13393
|
// src/wiki/provenance.ts
|
|
13328
|
-
import { createHash as
|
|
13394
|
+
import { createHash as createHash8 } from "crypto";
|
|
13329
13395
|
function parseProvenance(content) {
|
|
13330
13396
|
const verifiedAt = singleLineField(content, "VerifiedAt");
|
|
13331
13397
|
const verifiedScope = singleLineField(content, "VerifiedScope");
|
|
@@ -13337,7 +13403,7 @@ function parseProvenance(content) {
|
|
|
13337
13403
|
}
|
|
13338
13404
|
async function computeVerifiedScope(cwd, describePaths, graph) {
|
|
13339
13405
|
if (describePaths.length === 0) {
|
|
13340
|
-
return `sha256:${
|
|
13406
|
+
return `sha256:${createHash8("sha256").update("<empty-describe-set>").digest("hex")}`;
|
|
13341
13407
|
}
|
|
13342
13408
|
return `sha256:${await computePageNodeHash(cwd, describePaths, graph)}`;
|
|
13343
13409
|
}
|
|
@@ -13542,7 +13608,7 @@ var init_collect = __esm(() => {
|
|
|
13542
13608
|
});
|
|
13543
13609
|
|
|
13544
13610
|
// src/wiki/section-marker.ts
|
|
13545
|
-
import { createHash as
|
|
13611
|
+
import { createHash as createHash9 } from "crypto";
|
|
13546
13612
|
import { readFile as readFile31 } from "fs/promises";
|
|
13547
13613
|
function parseMarkers(content) {
|
|
13548
13614
|
const lines = content.split(`
|
|
@@ -13673,7 +13739,7 @@ function proposeSectionId(headingText, fallbackOrdinal) {
|
|
|
13673
13739
|
return slug.length > 0 && ID_RE.test(slug) ? slug : `section-${fallbackOrdinal}`;
|
|
13674
13740
|
}
|
|
13675
13741
|
function digest(value) {
|
|
13676
|
-
return
|
|
13742
|
+
return createHash9("sha256").update(value).digest("hex");
|
|
13677
13743
|
}
|
|
13678
13744
|
function planPageMigration(relativePath, content) {
|
|
13679
13745
|
const lines = content.split(`
|
|
@@ -13813,7 +13879,7 @@ var init_section_marker = __esm(() => {
|
|
|
13813
13879
|
});
|
|
13814
13880
|
|
|
13815
13881
|
// src/wiki/section-index.ts
|
|
13816
|
-
import { createHash as
|
|
13882
|
+
import { createHash as createHash10 } from "crypto";
|
|
13817
13883
|
function resolveWikiPageIdentity(relativePath, content) {
|
|
13818
13884
|
const markers = parseMarkers(content);
|
|
13819
13885
|
if (markers.page) {
|
|
@@ -13905,7 +13971,7 @@ function detectLanguage(text) {
|
|
|
13905
13971
|
return ru ? "ru" : "en";
|
|
13906
13972
|
}
|
|
13907
13973
|
function digestOf2(value) {
|
|
13908
|
-
return
|
|
13974
|
+
return createHash10("sha256").update(value).digest("hex");
|
|
13909
13975
|
}
|
|
13910
13976
|
function fieldFromLines(lines, name) {
|
|
13911
13977
|
const pattern = new RegExp(`^${name}:\\s*(.+)$`, "i");
|
|
@@ -14436,7 +14502,7 @@ async function runRuntimeEmbedder(dep, asset, texts, dims) {
|
|
|
14436
14502
|
var MEMORY_EMBEDDING_ID = "memory.embedding", DEFAULT_EMBED_DIMS = 96;
|
|
14437
14503
|
|
|
14438
14504
|
// src/memory/embedding/index.ts
|
|
14439
|
-
import { createHash as
|
|
14505
|
+
import { createHash as createHash11 } from "crypto";
|
|
14440
14506
|
import { mkdir as mkdir21, readFile as readFile32, writeFile as writeFile24 } from "fs/promises";
|
|
14441
14507
|
import path70 from "path";
|
|
14442
14508
|
function embeddingsDir(cwd) {
|
|
@@ -14449,7 +14515,7 @@ ${entry.tags.join(" ")}
|
|
|
14449
14515
|
${entry.details}`.trim();
|
|
14450
14516
|
}
|
|
14451
14517
|
function contentHash(text) {
|
|
14452
|
-
return
|
|
14518
|
+
return createHash11("sha256").update(text).digest("hex").slice(0, 16);
|
|
14453
14519
|
}
|
|
14454
14520
|
async function buildEmbeddingIndex(cwd, entries, embedder, model, now) {
|
|
14455
14521
|
const sorted = [...entries].sort((a, b) => a.relativePath.localeCompare(b.relativePath));
|
|
@@ -15181,7 +15247,7 @@ var init_backlinks = __esm(() => {
|
|
|
15181
15247
|
});
|
|
15182
15248
|
|
|
15183
15249
|
// src/ctx/assembly.ts
|
|
15184
|
-
import { createHash as
|
|
15250
|
+
import { createHash as createHash12 } from "crypto";
|
|
15185
15251
|
import { mkdir as mkdir22, rename as rename2, writeFile as writeFile25 } from "fs/promises";
|
|
15186
15252
|
import path73 from "path";
|
|
15187
15253
|
function assembleContext(input) {
|
|
@@ -15236,7 +15302,7 @@ async function recordContextAssembly(input) {
|
|
|
15236
15302
|
await rename2(temporary, target);
|
|
15237
15303
|
}
|
|
15238
15304
|
function traceIdFor(correlationId, outcome) {
|
|
15239
|
-
return
|
|
15305
|
+
return createHash12("sha256").update(`${outcome}\x00${correlationId}`).digest("hex").slice(0, 24);
|
|
15240
15306
|
}
|
|
15241
15307
|
function traceRefFor(traceId) {
|
|
15242
15308
|
return `./.metaproject/context-operations/traces/${traceId}.json`;
|
|
@@ -16095,9 +16161,9 @@ var init_evidence = __esm(() => {
|
|
|
16095
16161
|
});
|
|
16096
16162
|
|
|
16097
16163
|
// src/wiki/managed-block.ts
|
|
16098
|
-
import { createHash as
|
|
16164
|
+
import { createHash as createHash13 } from "crypto";
|
|
16099
16165
|
function hashBlockContent(content) {
|
|
16100
|
-
return
|
|
16166
|
+
return createHash13("sha256").update(content.trim()).digest("hex");
|
|
16101
16167
|
}
|
|
16102
16168
|
function findManagedBlock(content) {
|
|
16103
16169
|
const lines = content.split(`
|
|
@@ -16348,7 +16414,7 @@ var init_template_structure = __esm(() => {
|
|
|
16348
16414
|
|
|
16349
16415
|
// src/wiki/service.ts
|
|
16350
16416
|
import { spawn as spawn2 } from "child_process";
|
|
16351
|
-
import { createHash as
|
|
16417
|
+
import { createHash as createHash14 } from "crypto";
|
|
16352
16418
|
import { mkdir as mkdir23, readFile as readFile35, readdir as readdir7, rm as rm6, writeFile as writeFile26 } from "fs/promises";
|
|
16353
16419
|
import path75 from "path";
|
|
16354
16420
|
function wikiRootPath2(cwd) {
|
|
@@ -16650,7 +16716,7 @@ function resolveEvidenceScope(cwd, override) {
|
|
|
16650
16716
|
const absolute = path75.resolve(cwd);
|
|
16651
16717
|
return {
|
|
16652
16718
|
projectId: override?.projectId ?? (path75.basename(absolute) || "project"),
|
|
16653
|
-
checkoutId: override?.checkoutId ?? `checkout:${
|
|
16719
|
+
checkoutId: override?.checkoutId ?? `checkout:${createHash14("sha256").update(absolute).digest("hex").slice(0, 16)}`,
|
|
16654
16720
|
...override?.workspaceId ? { workspaceId: override.workspaceId } : {},
|
|
16655
16721
|
...override?.taskId ? { taskId: override.taskId } : {}
|
|
16656
16722
|
};
|
|
@@ -17456,7 +17522,7 @@ var init_service3 = __esm(() => {
|
|
|
17456
17522
|
});
|
|
17457
17523
|
|
|
17458
17524
|
// src/gdgraph/wiki-layer.ts
|
|
17459
|
-
import { createHash as
|
|
17525
|
+
import { createHash as createHash15 } from "crypto";
|
|
17460
17526
|
import { mkdir as mkdir24, stat as stat8, writeFile as writeFile27 } from "fs/promises";
|
|
17461
17527
|
import path76 from "path";
|
|
17462
17528
|
function storageDir(projectRoot) {
|
|
@@ -17513,7 +17579,7 @@ function buildWikiLayer(input) {
|
|
|
17513
17579
|
function computeFingerprints(fileRecords, mtimes) {
|
|
17514
17580
|
return fileRecords.map((record) => ({
|
|
17515
17581
|
path: record.path,
|
|
17516
|
-
contentHash:
|
|
17582
|
+
contentHash: createHash15("sha256").update(record.content).digest("hex"),
|
|
17517
17583
|
mtimeMs: mtimes.get(record.path) ?? 0
|
|
17518
17584
|
})).sort((a, b) => a.path.localeCompare(b.path));
|
|
17519
17585
|
}
|
|
@@ -22153,7 +22219,7 @@ var init_slate = __esm(() => {
|
|
|
22153
22219
|
});
|
|
22154
22220
|
|
|
22155
22221
|
// src/flow/store.ts
|
|
22156
|
-
import { createHash as
|
|
22222
|
+
import { createHash as createHash16 } from "crypto";
|
|
22157
22223
|
import { appendFile as appendFile3, mkdir as mkdir30, readFile as readFile48, readdir as readdir9 } from "fs/promises";
|
|
22158
22224
|
import path90 from "path";
|
|
22159
22225
|
function flowsRoot(cwd) {
|
|
@@ -22325,7 +22391,7 @@ async function acChecksum(cwd, dir) {
|
|
|
22325
22391
|
`).split(`
|
|
22326
22392
|
`).map((line) => line.trimEnd()).join(`
|
|
22327
22393
|
`).trim();
|
|
22328
|
-
return `sha256:${
|
|
22394
|
+
return `sha256:${createHash16("sha256").update(normalized).digest("hex")}`;
|
|
22329
22395
|
}
|
|
22330
22396
|
async function assertAcIntact(cwd, dir, flow) {
|
|
22331
22397
|
if (!flow.acChecksum) {
|
|
@@ -22365,7 +22431,7 @@ var init_slate_course = __esm(() => {
|
|
|
22365
22431
|
});
|
|
22366
22432
|
|
|
22367
22433
|
// src/sac/trusted-wrap-up.ts
|
|
22368
|
-
import { createHash as
|
|
22434
|
+
import { createHash as createHash17, randomUUID as randomUUID7 } from "crypto";
|
|
22369
22435
|
function createTrustedWrapUpAuthority(input) {
|
|
22370
22436
|
const now = input.now ?? (() => new Date);
|
|
22371
22437
|
return Object.freeze({
|
|
@@ -22397,7 +22463,7 @@ function createTrustedWrapUpAuthority(input) {
|
|
|
22397
22463
|
});
|
|
22398
22464
|
}
|
|
22399
22465
|
function digest2(value) {
|
|
22400
|
-
return
|
|
22466
|
+
return createHash17("sha256").update(value).digest("hex");
|
|
22401
22467
|
}
|
|
22402
22468
|
var issued, consumed;
|
|
22403
22469
|
var init_trusted_wrap_up = __esm(() => {
|
|
@@ -22407,7 +22473,7 @@ var init_trusted_wrap_up = __esm(() => {
|
|
|
22407
22473
|
|
|
22408
22474
|
// src/sac/index.ts
|
|
22409
22475
|
import { access as access2, readFile as readFile49, realpath as realpath5 } from "fs/promises";
|
|
22410
|
-
import { createHash as
|
|
22476
|
+
import { createHash as createHash18 } from "crypto";
|
|
22411
22477
|
import path91 from "path";
|
|
22412
22478
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
22413
22479
|
async function resolveSacNormativeSchemaPath(fileName, searchFrom = [fileURLToPath5(new URL(".", import.meta.url)), process.cwd()]) {
|
|
@@ -23085,7 +23151,7 @@ async function validateSacContract(input) {
|
|
|
23085
23151
|
return { valid: errors.length === 0, errors };
|
|
23086
23152
|
}
|
|
23087
23153
|
function hashSacRecord(value) {
|
|
23088
|
-
return
|
|
23154
|
+
return createHash18("sha256").update(typeof value === "string" ? value : JSON.stringify(value)).digest("hex");
|
|
23089
23155
|
}
|
|
23090
23156
|
async function resolveWorkspaceReference(input) {
|
|
23091
23157
|
if (!workspacePathPattern.test(input.uri) || path91.isAbsolute(input.uri) || /^[a-z][a-z0-9+.-]*:/i.test(input.uri) || input.uri.includes("\\"))
|
|
@@ -23196,7 +23262,7 @@ var init_secure_resource_read = __esm(() => {
|
|
|
23196
23262
|
|
|
23197
23263
|
// src/sac/workspace-service.ts
|
|
23198
23264
|
import { mkdir as mkdir31, readdir as readdir10, readFile as readFile50 } from "fs/promises";
|
|
23199
|
-
import { createHash as
|
|
23265
|
+
import { createHash as createHash19, randomUUID as randomUUID8 } from "crypto";
|
|
23200
23266
|
import path93 from "path";
|
|
23201
23267
|
|
|
23202
23268
|
class WorkspaceService {
|
|
@@ -23486,7 +23552,7 @@ class WorkspaceService {
|
|
|
23486
23552
|
}
|
|
23487
23553
|
contentDigest(absolutePath) {
|
|
23488
23554
|
try {
|
|
23489
|
-
return
|
|
23555
|
+
return createHash19("sha256").update(readWorkspaceFileNoFollow(this.root, absolutePath)).digest("hex");
|
|
23490
23556
|
} catch {
|
|
23491
23557
|
return;
|
|
23492
23558
|
}
|
|
@@ -23618,7 +23684,7 @@ var init_workspace_service = __esm(() => {
|
|
|
23618
23684
|
});
|
|
23619
23685
|
|
|
23620
23686
|
// src/sac/guarded-owner-writer.ts
|
|
23621
|
-
import { createHash as
|
|
23687
|
+
import { createHash as createHash20 } from "crypto";
|
|
23622
23688
|
function createGuardedOwnerWriter(input) {
|
|
23623
23689
|
const recoverReceipt = input.recoverReceipt;
|
|
23624
23690
|
return Object.freeze({
|
|
@@ -23643,7 +23709,7 @@ function receiptMatchesIntent(input) {
|
|
|
23643
23709
|
return binding.owner === input.owner && binding.bindingHash === bindingHash(input.owner, input.intent) && binding.intentRef === input.intent.intentRef && binding.proposalId === input.intent.proposalId && binding.proposalRevision === input.intent.proposalRevision && binding.workspaceId === input.intent.workspaceId && binding.correlationId === input.intent.correlationId && binding.idempotencyKey === input.intent.idempotencyKey && binding.reviewerSubject === input.intent.reviewerSubject && binding.reviewerAuthority === input.intent.reviewerAuthority && binding.policyRevision === input.intent.policyRevision;
|
|
23644
23710
|
}
|
|
23645
23711
|
function bindingHash(owner, intent) {
|
|
23646
|
-
return
|
|
23712
|
+
return createHash20("sha256").update(JSON.stringify({ owner, ...intent })).digest("hex");
|
|
23647
23713
|
}
|
|
23648
23714
|
var init_guarded_owner_writer = () => {};
|
|
23649
23715
|
|
|
@@ -24296,7 +24362,7 @@ var init_wrap_up_evidence = __esm(() => {
|
|
|
24296
24362
|
});
|
|
24297
24363
|
|
|
24298
24364
|
// src/sac/session-wrap-up.ts
|
|
24299
|
-
import { createHash as
|
|
24365
|
+
import { createHash as createHash21 } from "crypto";
|
|
24300
24366
|
import { mkdir as mkdir32, writeFile as writeFile33 } from "fs/promises";
|
|
24301
24367
|
import path95 from "path";
|
|
24302
24368
|
function sessionEvidenceRef(workspaceId, sessionId) {
|
|
@@ -24362,12 +24428,12 @@ async function resolveSessionWrapUp(input) {
|
|
|
24362
24428
|
await writeFile33(path95.join(input.cwd, noticeRelPath), floor.notice, "utf8");
|
|
24363
24429
|
const observedAt = now().toISOString();
|
|
24364
24430
|
const evidence = [
|
|
24365
|
-
{ kind: "wrap-up", uri: `./${wrapUpRelPath}`, revision:
|
|
24366
|
-
{ kind: diffKind, uri: `./${diffRelPath}`, revision:
|
|
24367
|
-
{ kind: "session", uri: `./${relPath}`, revision:
|
|
24431
|
+
{ kind: "wrap-up", uri: `./${wrapUpRelPath}`, revision: createHash21("sha256").update(safeWrapUp.content).digest("hex"), observedAt },
|
|
24432
|
+
{ kind: diffKind, uri: `./${diffRelPath}`, revision: createHash21("sha256").update(safeDiff.content).digest("hex"), observedAt },
|
|
24433
|
+
{ kind: "session", uri: `./${relPath}`, revision: createHash21("sha256").update(safeSession.content).digest("hex"), observedAt }
|
|
24368
24434
|
];
|
|
24369
24435
|
if (floor.notice !== undefined) {
|
|
24370
|
-
evidence.push({ kind: REDACTION_NOTICE_KIND, uri: `./${noticeRelPath}`, revision:
|
|
24436
|
+
evidence.push({ kind: REDACTION_NOTICE_KIND, uri: `./${noticeRelPath}`, revision: createHash21("sha256").update(floor.notice).digest("hex"), observedAt });
|
|
24371
24437
|
}
|
|
24372
24438
|
return {
|
|
24373
24439
|
workspaceId: input.workspaceId,
|
|
@@ -24393,7 +24459,7 @@ var init_session_wrap_up = __esm(() => {
|
|
|
24393
24459
|
});
|
|
24394
24460
|
|
|
24395
24461
|
// src/sac/review-confirm-token.ts
|
|
24396
|
-
import { createHash as
|
|
24462
|
+
import { createHash as createHash22, randomBytes as randomBytes3 } from "crypto";
|
|
24397
24463
|
import { readFile as readFile51 } from "fs/promises";
|
|
24398
24464
|
import path96 from "path";
|
|
24399
24465
|
function confirmTokenPath(cwd, workspaceId, proposalId) {
|
|
@@ -24403,7 +24469,7 @@ function confirmReceiptPath(cwd, workspaceId, proposalId, idempotencyKey) {
|
|
|
24403
24469
|
return path96.join(cwd, ".metaproject", "workspaces", workspaceId, "proposals", `${proposalId}.${sha256(idempotencyKey)}.confirm-receipt.json`);
|
|
24404
24470
|
}
|
|
24405
24471
|
function sha256(text) {
|
|
24406
|
-
return
|
|
24472
|
+
return createHash22("sha256").update(text).digest("hex");
|
|
24407
24473
|
}
|
|
24408
24474
|
async function mintConfirmToken(cwd, workspaceId, proposalId, deps = {}) {
|
|
24409
24475
|
const now = deps.now ?? (() => new Date);
|
|
@@ -24564,7 +24630,7 @@ function round(value) {
|
|
|
24564
24630
|
var init_dedup = () => {};
|
|
24565
24631
|
|
|
24566
24632
|
// src/sac/proposal-evidence.ts
|
|
24567
|
-
import { createHash as
|
|
24633
|
+
import { createHash as createHash23 } from "crypto";
|
|
24568
24634
|
import { readFile as readFile52, rm as rm8 } from "fs/promises";
|
|
24569
24635
|
import path97 from "path";
|
|
24570
24636
|
function proposalPath(cwd, workspaceId, proposalId) {
|
|
@@ -24592,7 +24658,7 @@ async function readVerifiedProposalEvidence(cwd, workspaceId, proposalId) {
|
|
|
24592
24658
|
} catch {
|
|
24593
24659
|
return { ok: false, code: "evidence_file_unreadable" };
|
|
24594
24660
|
}
|
|
24595
|
-
if (
|
|
24661
|
+
if (createHash23("sha256").update(content).digest("hex") !== evidence.revision) {
|
|
24596
24662
|
return { ok: false, code: "evidence_revision_mismatch" };
|
|
24597
24663
|
}
|
|
24598
24664
|
return { proposal, evidence, content };
|
|
@@ -24603,7 +24669,7 @@ async function readSidecarNote(cwd, workspaceId, proposalId) {
|
|
|
24603
24669
|
});
|
|
24604
24670
|
}
|
|
24605
24671
|
function digestOf3(content) {
|
|
24606
|
-
return
|
|
24672
|
+
return createHash23("sha256").update(content).digest("hex");
|
|
24607
24673
|
}
|
|
24608
24674
|
async function readTargetVersion(absolutePath) {
|
|
24609
24675
|
try {
|
|
@@ -25295,7 +25361,7 @@ var init_wiki_owner_writer = __esm(() => {
|
|
|
25295
25361
|
});
|
|
25296
25362
|
|
|
25297
25363
|
// src/gdskills/project-skills.ts
|
|
25298
|
-
import { createHash as
|
|
25364
|
+
import { createHash as createHash24 } from "crypto";
|
|
25299
25365
|
import { homedir as homedir3 } from "os";
|
|
25300
25366
|
import { mkdir as mkdir34, readFile as readFile57, stat as stat11 } from "fs/promises";
|
|
25301
25367
|
import path101 from "path";
|
|
@@ -25363,7 +25429,7 @@ function resolveOriginPath(ref, projectRoot) {
|
|
|
25363
25429
|
return path101.resolve(projectRoot, trimmed);
|
|
25364
25430
|
}
|
|
25365
25431
|
function hashOriginContent(content) {
|
|
25366
|
-
return `sha256:${
|
|
25432
|
+
return `sha256:${createHash24("sha256").update(content).digest("hex")}`;
|
|
25367
25433
|
}
|
|
25368
25434
|
async function readSkillOrigin(projectRoot, ref, now = () => new Date) {
|
|
25369
25435
|
const resolved = resolveOriginPath(ref, projectRoot);
|
|
@@ -25623,7 +25689,7 @@ ${filesToRead}
|
|
|
25623
25689
|
|
|
25624
25690
|
## Verification
|
|
25625
25691
|
|
|
25626
|
-
-
|
|
25692
|
+
- Verification status: see \`verification.md\` (written by \`keryx skills verify\`).
|
|
25627
25693
|
- Run: \`keryx skills verify ${moduleName}/${skillName}\`
|
|
25628
25694
|
`;
|
|
25629
25695
|
}
|
|
@@ -25874,7 +25940,7 @@ var init_skill_owner_writer = __esm(() => {
|
|
|
25874
25940
|
});
|
|
25875
25941
|
|
|
25876
25942
|
// src/sac/proposal-lifecycle.ts
|
|
25877
|
-
import { createHash as
|
|
25943
|
+
import { createHash as createHash25, randomUUID as randomUUID11 } from "crypto";
|
|
25878
25944
|
import { appendFile as appendFile4, mkdir as mkdir35, readdir as readdir12, readFile as readFile59 } from "fs/promises";
|
|
25879
25945
|
import path102 from "path";
|
|
25880
25946
|
function supportsOwnerWriteRecovery(writer) {
|
|
@@ -26311,7 +26377,7 @@ class ProposalLifecycleService {
|
|
|
26311
26377
|
}
|
|
26312
26378
|
}
|
|
26313
26379
|
function hash(value) {
|
|
26314
|
-
return
|
|
26380
|
+
return createHash25("sha256").update(value).digest("hex");
|
|
26315
26381
|
}
|
|
26316
26382
|
function recordHash(value) {
|
|
26317
26383
|
return hash(JSON.stringify(value));
|
|
@@ -26535,7 +26601,7 @@ var init_workspace_resolve = __esm(() => {
|
|
|
26535
26601
|
});
|
|
26536
26602
|
|
|
26537
26603
|
// src/sac/machine-wrap-up.ts
|
|
26538
|
-
import { createHash as
|
|
26604
|
+
import { createHash as createHash26, randomUUID as randomUUID13 } from "crypto";
|
|
26539
26605
|
import { mkdir as mkdir36 } from "fs/promises";
|
|
26540
26606
|
import path103 from "path";
|
|
26541
26607
|
function groupSeedsByKind(slate) {
|
|
@@ -26550,7 +26616,7 @@ function groupSeedsByKind(slate) {
|
|
|
26550
26616
|
return map;
|
|
26551
26617
|
}
|
|
26552
26618
|
function sha2562(value) {
|
|
26553
|
-
return
|
|
26619
|
+
return createHash26("sha256").update(value).digest("hex");
|
|
26554
26620
|
}
|
|
26555
26621
|
function mechanicalSummary(diff, course) {
|
|
26556
26622
|
return `Mechanical wrap-up summary (model turn unavailable or timed out):
|
|
@@ -28496,9 +28562,9 @@ var init_orchestrate = __esm(() => {
|
|
|
28496
28562
|
});
|
|
28497
28563
|
|
|
28498
28564
|
// src/harness/policy/profiles.ts
|
|
28499
|
-
import { createHash as
|
|
28565
|
+
import { createHash as createHash27 } from "crypto";
|
|
28500
28566
|
function sha256Hex2(input) {
|
|
28501
|
-
return
|
|
28567
|
+
return createHash27("sha256").update(input, "utf8").digest("hex");
|
|
28502
28568
|
}
|
|
28503
28569
|
function readOnlyReview() {
|
|
28504
28570
|
return {
|
|
@@ -29718,7 +29784,7 @@ var init_supersede = __esm(() => {
|
|
|
29718
29784
|
});
|
|
29719
29785
|
|
|
29720
29786
|
// src/memory/service.ts
|
|
29721
|
-
import { createHash as
|
|
29787
|
+
import { createHash as createHash28 } from "crypto";
|
|
29722
29788
|
import { mkdir as mkdir38, readFile as readFile63, writeFile as writeFile36 } from "fs/promises";
|
|
29723
29789
|
import path110 from "path";
|
|
29724
29790
|
function dataRoot(cwd) {
|
|
@@ -29775,7 +29841,7 @@ function createMemoryService() {
|
|
|
29775
29841
|
const indexPath = path110.join(indexDir, "index.json");
|
|
29776
29842
|
await writeFile36(indexPath, `${JSON.stringify({
|
|
29777
29843
|
catalogVersion: 1,
|
|
29778
|
-
sourceFingerprint:
|
|
29844
|
+
sourceFingerprint: createHash28("sha256").update(JSON.stringify(entries.map((e) => ({
|
|
29779
29845
|
path: e.relativePath,
|
|
29780
29846
|
content: [e.title, e.type, e.status, e.confidence, e.summary, e.details, e.tags, e.scopes, e.validFrom, e.validTo].join("\x00")
|
|
29781
29847
|
})))).digest("hex"),
|
|
@@ -35918,7 +35984,7 @@ var init_github = __esm(() => {
|
|
|
35918
35984
|
});
|
|
35919
35985
|
|
|
35920
35986
|
// src/harness/tool/metaproject-adapter.ts
|
|
35921
|
-
import { lstat as
|
|
35987
|
+
import { lstat as lstat4, readdir as readdir17, readFile as readFile74, realpath as realpath6, stat as stat14 } from "fs/promises";
|
|
35922
35988
|
import { isAbsolute, join, relative, resolve } from "path";
|
|
35923
35989
|
function isMissingExecutable(cause) {
|
|
35924
35990
|
const message = cause instanceof Error ? cause.message : String(cause);
|
|
@@ -35974,12 +36040,16 @@ function flattenAttribution(attribution) {
|
|
|
35974
36040
|
}
|
|
35975
36041
|
async function projectRemovalTrail(cwd, query) {
|
|
35976
36042
|
const lookup = searchRemovals(await loadDeletionTrail(cwd), query);
|
|
36043
|
+
if (lookup.verdict === "trail-absent") {
|
|
36044
|
+
return { verdict: "trail-absent", summary: TRAIL_ABSENT_SUMMARY };
|
|
36045
|
+
}
|
|
36046
|
+
const summary = clipAutomaticRecallText(lookup.reason.split(`${cwd}/`).join(""), MAX_REMOVAL_SUMMARY_BYTES);
|
|
35977
36047
|
if (lookup.verdict !== "recorded-removed") {
|
|
35978
|
-
return { verdict: lookup.verdict, summary
|
|
36048
|
+
return { verdict: lookup.verdict, summary };
|
|
35979
36049
|
}
|
|
35980
36050
|
return {
|
|
35981
36051
|
verdict: "recorded-removed",
|
|
35982
|
-
summary
|
|
36052
|
+
summary,
|
|
35983
36053
|
totalRemovals: lookup.occurrences.length,
|
|
35984
36054
|
removals: lookup.occurrences.slice(0, MAX_REMOVAL_RECORDS).map((item) => ({
|
|
35985
36055
|
layer: item.layer,
|
|
@@ -36049,7 +36119,7 @@ async function parseCatalogSummaries(cwd) {
|
|
|
36049
36119
|
async function walkSkillCatalog(cwd) {
|
|
36050
36120
|
const root = join(cwd, ".metaproject", "skills", "gdskills");
|
|
36051
36121
|
const entries = [];
|
|
36052
|
-
const rootInfo = await
|
|
36122
|
+
const rootInfo = await lstat4(root).catch(() => null);
|
|
36053
36123
|
if (!rootInfo || !rootInfo.isDirectory() || rootInfo.isSymbolicLink())
|
|
36054
36124
|
return entries;
|
|
36055
36125
|
const rootReal = await realpath6(root).catch(() => null);
|
|
@@ -36735,7 +36805,7 @@ function createMetaprojectAdapter(cwd, overrides = {}) {
|
|
|
36735
36805
|
}
|
|
36736
36806
|
};
|
|
36737
36807
|
}
|
|
36738
|
-
var DEFAULT_DEPS, MAX_EXCERPT_BYTES = 400, MAX_QUERY_BYTES2 = 4096, UNKNOWN_PROVENANCE = "unknown", MAX_SEARCH_OUTPUT_BYTES = 20000, SEARCH_CODE_RG_MISSING, MAX_REMOVAL_RECORDS = 5, MAX_REMOVAL_SUMMARY_BYTES = 1600;
|
|
36808
|
+
var DEFAULT_DEPS, MAX_EXCERPT_BYTES = 400, MAX_QUERY_BYTES2 = 4096, UNKNOWN_PROVENANCE = "unknown", MAX_SEARCH_OUTPUT_BYTES = 20000, SEARCH_CODE_RG_MISSING, MAX_REMOVAL_RECORDS = 5, MAX_REMOVAL_SUMMARY_BYTES = 1600, TRAIL_ABSENT_SUMMARY = 'no removal has ever been recorded in this project (it has no deletion trail) \u2014 not the claim "this never existed".';
|
|
36739
36809
|
var init_metaproject_adapter = __esm(() => {
|
|
36740
36810
|
init_wiki_freshness();
|
|
36741
36811
|
init_fs();
|
|
@@ -38150,7 +38220,7 @@ var init_metaproject_operations = __esm(() => {
|
|
|
38150
38220
|
});
|
|
38151
38221
|
|
|
38152
38222
|
// src/wiki/deep-enrich.ts
|
|
38153
|
-
import { randomUUID as randomUUID15, createHash as
|
|
38223
|
+
import { randomUUID as randomUUID15, createHash as createHash29 } from "crypto";
|
|
38154
38224
|
function composeAbortSignals(external, timeout) {
|
|
38155
38225
|
if (external === undefined) {
|
|
38156
38226
|
return { signal: timeout, dispose: () => {} };
|
|
@@ -38181,7 +38251,7 @@ function errorMessage2(cause) {
|
|
|
38181
38251
|
return cause instanceof Error ? cause.message : String(cause);
|
|
38182
38252
|
}
|
|
38183
38253
|
function sha256Hex3(text) {
|
|
38184
|
-
return
|
|
38254
|
+
return createHash29("sha256").update(text).digest("hex");
|
|
38185
38255
|
}
|
|
38186
38256
|
function buildDeepEnrichTools(port) {
|
|
38187
38257
|
const deepOps = METAPROJECT_OPERATIONS.filter((op) => DEEP_ENRICH_OPS.includes(op.name));
|
|
@@ -41172,15 +41242,43 @@ async function refreshProviderGrant(provider, http, dir) {
|
|
|
41172
41242
|
saveOAuthGrant(provider, next, dir);
|
|
41173
41243
|
return next;
|
|
41174
41244
|
}
|
|
41245
|
+
async function refreshSavedGrants(http, dir, providers = SESSION_REFRESHED_GRANTS) {
|
|
41246
|
+
const warnings = [];
|
|
41247
|
+
const now = http.now ?? Date.now;
|
|
41248
|
+
for (const provider of providers) {
|
|
41249
|
+
if (!SESSION_REFRESHED_GRANTS.includes(provider))
|
|
41250
|
+
continue;
|
|
41251
|
+
const grant = loadOAuthGrant(provider, dir);
|
|
41252
|
+
if (grant === undefined)
|
|
41253
|
+
continue;
|
|
41254
|
+
if (grant.refresh === undefined || grant.refresh.length === 0) {
|
|
41255
|
+
if (grant.expires !== undefined && grant.expires <= now()) {
|
|
41256
|
+
warnings.push(`${provider}: the saved login has expired and holds no refresh token. Run \`keryx auth login ${provider}\`.`);
|
|
41257
|
+
}
|
|
41258
|
+
continue;
|
|
41259
|
+
}
|
|
41260
|
+
if (!grantNeedsRefresh(grant, http.now))
|
|
41261
|
+
continue;
|
|
41262
|
+
try {
|
|
41263
|
+
await refreshProviderGrant(provider, http, dir);
|
|
41264
|
+
} catch (cause) {
|
|
41265
|
+
const reason = cause instanceof Error ? cause.message : String(cause);
|
|
41266
|
+
warnings.push(`${provider}: the saved login is expiring or expired and could not be refreshed (${reason}). ` + `Run \`keryx auth login ${provider}\`.`);
|
|
41267
|
+
}
|
|
41268
|
+
}
|
|
41269
|
+
return warnings;
|
|
41270
|
+
}
|
|
41175
41271
|
function logoutProvider(provider, dir) {
|
|
41176
41272
|
deleteOAuthGrant(provider, dir);
|
|
41177
41273
|
}
|
|
41274
|
+
var SESSION_REFRESHED_GRANTS;
|
|
41178
41275
|
var init_login = __esm(() => {
|
|
41179
41276
|
init_catalog();
|
|
41180
41277
|
init_copilot();
|
|
41181
41278
|
init_device_code();
|
|
41182
41279
|
init_grants();
|
|
41183
41280
|
init_openai_codex();
|
|
41281
|
+
SESSION_REFRESHED_GRANTS = ["grok", "github-copilot"];
|
|
41184
41282
|
});
|
|
41185
41283
|
|
|
41186
41284
|
// src/cli.ts
|
|
@@ -41193,7 +41291,7 @@ import {
|
|
|
41193
41291
|
chmod as chmod2,
|
|
41194
41292
|
mkdir as mkdir14,
|
|
41195
41293
|
readFile as readFile23,
|
|
41196
|
-
unlink,
|
|
41294
|
+
unlink as unlink2,
|
|
41197
41295
|
writeFile as writeFile16
|
|
41198
41296
|
} from "fs/promises";
|
|
41199
41297
|
import { existsSync as existsSync11 } from "fs";
|
|
@@ -42784,7 +42882,7 @@ var BUNDLED_GDSKILLS = [
|
|
|
42784
42882
|
"If the request asks to create, run, resume, track, or finish a managed flow and Task Manager is enabled, route implementation work to `gdskills/orchestration/flow-orchestrator/SKILL.md` before `job-orchestrator`.",
|
|
42785
42883
|
"Prefer project-local skills and module manifests before broad raw file search.",
|
|
42786
42884
|
"Route to the narrowest applicable skill and record unavailable modules explicitly."
|
|
42787
|
-
], ["any repository task", "route context", "which skill should be used", "ordinary product-development request", "agent should decide tools"]),
|
|
42885
|
+
], ["any repository task", "route context", "which skill should be used", "ordinary product-development request", "agent should decide tools"], "Use when a request's routing to a Metaproject module, skill, or project-skill is unclear and needs deciding before any work starts. NOT for: picking between gdgraph, gdctx, gdwiki, memory, and health once the module is already known (see context-router)."),
|
|
42788
42886
|
skill("context-router", "core", ["minimal", "recommended", "full"], "Choose between gdgraph, gdctx, gdwiki, memory, health, and project-skills before raw file reads.", [
|
|
42789
42887
|
"Start from the user's goal, not from command names.",
|
|
42790
42888
|
"Use gdgraph for file relationships and affected context.",
|
|
@@ -42794,13 +42892,13 @@ var BUNDLED_GDSKILLS = [
|
|
|
42794
42892
|
"Use health for normalized quality and gate status; use testing for test selection and test context.",
|
|
42795
42893
|
"Prefer MCP tools/resources for these capabilities when connected; otherwise use the matching skill and CLI command.",
|
|
42796
42894
|
"Use project-skills for known modules, components, stores, services, and domain entities."
|
|
42797
|
-
], ["find files", "understand code", "collect context", "what should I inspect", "agent routing"]),
|
|
42895
|
+
], ["find files", "understand code", "collect context", "what should I inspect", "agent routing"], "Use when the Metaproject module or skill is already known and the next step is picking gdgraph, gdctx, gdwiki, memory, health, or project-skills before reading raw files. NOT for: deciding which top-level skill or module should handle a request (see metaproject-router)."),
|
|
42798
42896
|
skill("entity-skill-router", "core", ["minimal", "recommended", "full"], "Select relevant project-skills for known modules, components, stores, services, and domain entities.", [
|
|
42799
42897
|
"Check `.metaproject/project-skills` for matching module/entity skills.",
|
|
42800
42898
|
"Use gdgraph affected context to find nearby entities when the target is a file.",
|
|
42801
42899
|
"Load only the matching project-skill and directly referenced files.",
|
|
42802
42900
|
"If no project-skill exists, suggest creating one with `keryx skills generate`."
|
|
42803
|
-
], ["project skill", "component pattern", "module-specific work"]),
|
|
42901
|
+
], ["project skill", "component pattern", "module-specific work"], "Use when a known module, component, store, service, or domain entity already has a project-skill that should be loaded instead of searched for from scratch. NOT for: scaffolding a project-skill that does not exist yet (see entity-skill-creator), checking one against current code (see entity-skill-verifier), or applying a finding to one (see entity-skill-learner)."),
|
|
42804
42902
|
skill("entity-skill-creator", "core", ["minimal", "recommended", "full"], "Create canonical project-skills from a path, symbol, wiki page, module, component, store, service, or domain entity.", [
|
|
42805
42903
|
"Normalize the target into module, entity, files, symbols, and wiki references.",
|
|
42806
42904
|
"Collect evidence from gdgraph, gdctx, gdwiki, health, and memory when available.",
|
|
@@ -42809,7 +42907,7 @@ var BUNDLED_GDSKILLS = [
|
|
|
42809
42907
|
"To refresh a project-skill from its Origin (or a new file), run `keryx skills update <module>/<name> [--from <origin>]`.",
|
|
42810
42908
|
"Run `keryx skills route <target>` and `keryx skills inspect <module>/<skill-name>` to confirm registration and routing.",
|
|
42811
42909
|
"Run `keryx skills verify <module>/<skill-name>` and finish with `keryx skills status`."
|
|
42812
|
-
], ["create skill", "generate project skill", "new entity skill", "\u0441\u043E\u0437\u0434\u0430\u0439 \u0441\u043A\u0438\u043B", "\u0441\u043E\u0437\u0434\u0430\u0439 \u0441\u043A\u0438\u043B\u043B \u0434\u043B\u044F <path>", "import skill", "import skills from", "update skill from", "\u043F\u043E\u0434\u0442\u044F\u043D\u0438 \u0441\u043A\u0438\u043B\u044B", "\u043E\u0431\u043D\u043E\u0432\u0438 \u0441\u043A\u0438\u043B"]),
|
|
42910
|
+
], ["create skill", "generate project skill", "new entity skill", "\u0441\u043E\u0437\u0434\u0430\u0439 \u0441\u043A\u0438\u043B", "\u0441\u043E\u0437\u0434\u0430\u0439 \u0441\u043A\u0438\u043B\u043B \u0434\u043B\u044F <path>", "import skill", "import skills from", "update skill from", "\u043F\u043E\u0434\u0442\u044F\u043D\u0438 \u0441\u043A\u0438\u043B\u044B", "\u043E\u0431\u043D\u043E\u0432\u0438 \u0441\u043A\u0438\u043B"], "Use when no project-skill exists yet for a target module, component, store, service, or domain entity, or one needs scaffolding, importing, or refreshing from its origin. NOT for: loading a project-skill that already exists (see entity-skill-router)."),
|
|
42813
42911
|
skill("reviewer-skill-creator", "core", ["recommended", "full"], "Create a project-local reviewer for review-orchestrator from a rules file, review profile, or written team standard.", [
|
|
42814
42912
|
"Read the source in full and sort it into method, convention, and persona before writing anything.",
|
|
42815
42913
|
"Scaffold with `keryx skills create <target> --module review --name <reviewer> --note <gist> --origin <source file>`; the target is a routing key, the note is the prose.",
|
|
@@ -42819,18 +42917,18 @@ var BUNDLED_GDSKILLS = [
|
|
|
42819
42917
|
"Confirm with `keryx review reviewers` \u2014 creating files is not registration, and registration is not discovery.",
|
|
42820
42918
|
"For existing SKILL.md packages, run `keryx skills import --from <dir|file|https-url> --module <module>`; `keryx review import` is the review-shaped alias with the review-vantage-* prefix."
|
|
42821
42919
|
], ["create a reviewer", "new reviewer for review-orchestrator", "make a reviewer from this profile", "\u0441\u043E\u0437\u0434\u0430\u0439 \u0440\u0435\u0432\u044C\u044E\u0435\u0440\u0430", "\u0441\u043E\u0437\u0434\u0430\u0439 \u043D\u043E\u0432\u043E\u0433\u043E \u0440\u0435\u0432\u044C\u044E\u0435\u0440\u0430 \u043D\u0430 \u043E\u0441\u043D\u043E\u0432\u0430\u043D\u0438\u0438", "import vantage reviewers", "import overlay reviewers"]),
|
|
42822
|
-
skill("entity-skill-verifier", "core", ["minimal", "recommended", "full"], "
|
|
42823
|
-
"Resolve
|
|
42824
|
-
"
|
|
42825
|
-
"
|
|
42826
|
-
"
|
|
42827
|
-
], ["verify skill", "skill-verify-skill", "stale skill"]),
|
|
42920
|
+
skill("entity-skill-verifier", "core", ["minimal", "recommended", "full"], "Run `keryx skills verify` to check a project-skill's required files, SKILL.md metadata, manifest registration, target-path existence, and evidence artifacts (gdgraph, gdctx, validated gdwiki, Code Health, canonical accepted memory), then classify it as fresh, needs-review, stale, or blocked. The command does not read the skill's prose or compare it against current code \u2014 that comparison is a manual agent step.", [
|
|
42921
|
+
"Resolve the target project-skill through gdgraph affected context or `keryx skills route <target>`.",
|
|
42922
|
+
"Run `keryx skills verify <module>/<skill-name>` (`--dry-run` previews without writing).",
|
|
42923
|
+
"The command checks required files, SKILL.md metadata (version, target, last-verified), manifest registration, target path existence, and evidence artifacts for gdgraph, gdctx, gdwiki, Code Health, and memory consultation, then classifies the skill fresh, needs-review, stale, or blocked and writes the JSON report plus `verification.md`.",
|
|
42924
|
+
"Manually read the skill and the code, wiki, and health evidence it points at to check its claims \u2014 the command does not do this comparison \u2014 then route stale or blocked findings to entity-skill-learner."
|
|
42925
|
+
], ["verify skill", "skill-verify-skill", "stale skill"], "Use when an existing project-skill needs classifying \u2014 fresh, needs-review, stale, or blocked \u2014 from its required files, metadata, manifest registration, target-path existence, and evidence artifacts (gdgraph, gdctx, gdwiki, Code Health, memory), followed by a manual read of its claims against current code as this skill's next step. NOT for: applying a review, test, or health finding to update a skill (see entity-skill-learner)."),
|
|
42828
42926
|
skill("entity-skill-learner", "core", ["minimal", "recommended", "full"], "Update project-skills from review findings, test failures, health reports, memory entries, and verifier reports.", [
|
|
42829
42927
|
"Parse the source report and map findings to project-skills.",
|
|
42830
42928
|
"Classify lessons as anti-patterns, checklist changes, template changes, workflow changes, or architecture rules.",
|
|
42831
42929
|
"Respect manual sections and autonomy policy.",
|
|
42832
42930
|
"Increment version and append `skill-changelog.md` entries with provenance."
|
|
42833
|
-
], ["learn from review", "update skill", "skill lesson"]),
|
|
42931
|
+
], ["learn from review", "update skill", "skill lesson"], "Use when a review finding, test failure, health report, memory entry, or verifier report points at a project-skill that needs updating. NOT for: checking a skill's current accuracy with no source report driving it (see entity-skill-verifier)."),
|
|
42834
42932
|
skill("job-orchestrator", "orchestration", ["recommended", "full"], "Run full task pipelines: clarify, collect context, plan, implement, verify, review, and summarize.", [
|
|
42835
42933
|
"Clarify ambiguity with interviewer-style questions only when required.",
|
|
42836
42934
|
"Collect compact context through Metaproject modules before implementation.",
|
|
@@ -43177,7 +43275,7 @@ var BUNDLED_GDSKILLS = [
|
|
|
43177
43275
|
"Find existing root agent entrypoints.",
|
|
43178
43276
|
"Keep managed Metaproject blocks idempotent.",
|
|
43179
43277
|
"Ensure local `.metaproject/index.md` and skill catalog are first-class references."
|
|
43180
|
-
], ["agents.md", "claude.md", "entrypoint"]),
|
|
43278
|
+
], ["agents.md", "claude.md", "entrypoint"], "Use when AGENTS.md or CLAUDE.md needs its managed Metaproject block added, refreshed, or kept idempotent. NOT for: splitting an oversized entrypoint into rules and project-skills (see agent-entrypoint-distiller)."),
|
|
43181
43279
|
skill("agent-entrypoint-distiller", "platform", ["minimal", "recommended", "full"], "Split large AGENTS.md/CLAUDE.md files into high-priority Metaproject rules and project-specific skills.", [
|
|
43182
43280
|
"Run `keryx rules distill` when the user asks to decompose a large CLAUDE.md/AGENTS.md.",
|
|
43183
43281
|
"Keep root entrypoints compact: non-project/highest-priority instructions plus `.metaproject/index.md` routing.",
|
|
@@ -43187,7 +43285,7 @@ var BUNDLED_GDSKILLS = [
|
|
|
43187
43285
|
"Install hooks only when explicitly enabled.",
|
|
43188
43286
|
"Keep hooks lightweight and idempotent.",
|
|
43189
43287
|
"Avoid network and destructive behavior inside hooks."
|
|
43190
|
-
], ["install hook", "git hook", "post-commit"]),
|
|
43288
|
+
], ["install hook", "git hook", "post-commit"], "Use when a lightweight, explicitly-enabled git hook for graph, health, or skill verification needs installing or checking. NOT for: general hook design guidance not tied to these three (see hookify)."),
|
|
43191
43289
|
skill("hookify", "platform", ["full"], "Use hook guidance for safe hook design and installation.", [
|
|
43192
43290
|
"Detect existing hooks and preserve user content.",
|
|
43193
43291
|
"Install idempotent managed blocks.",
|
|
@@ -43202,23 +43300,23 @@ var BUNDLED_GDSKILLS = [
|
|
|
43202
43300
|
"Read bundled and project-local skill metadata.",
|
|
43203
43301
|
"Generate concise catalog entries grouped by category.",
|
|
43204
43302
|
"Keep catalog deterministic and local-first."
|
|
43205
|
-
], ["skill catalog", "list skills", "skills registry"]),
|
|
43303
|
+
], ["skill catalog", "list skills", "skills registry"], "Use when `.metaproject/skills/catalog.md` or the machine-readable skill registry is missing or out of date with bundled and project-local skill metadata. NOT for: turning skills into runtime artifacts (see skill-runtime-exporter) or pushing them to local runtimes (see skill-sync)."),
|
|
43206
43304
|
skill("skill-runtime-exporter", "platform", ["full"], "Export canonical skills to runtime-compatible Codex or Claude artifacts.", [
|
|
43207
43305
|
"Read canonical skill packages.",
|
|
43208
43306
|
"Remove management-only files from runtime exports.",
|
|
43209
43307
|
"Keep runtime `SKILL.md` concise with references, scripts, and assets as needed."
|
|
43210
|
-
], ["export skill", "runtime skill", "codex skill"]),
|
|
43308
|
+
], ["export skill", "runtime skill", "codex skill"], "Use when canonical skill packages need turning into runtime-compatible Codex or Claude artifacts, stripped of management-only files. NOT for: regenerating the skill catalog (see skill-catalog-manager) or pushing the export to local runtimes (see skill-sync)."),
|
|
43211
43309
|
skill("skill-sync", "platform", ["full"], "Sync exported runtime skills to configured local runtimes only when explicitly enabled.", [
|
|
43212
43310
|
"Read configured runtime targets.",
|
|
43213
43311
|
"Validate runtime skill packages before sync.",
|
|
43214
43312
|
"Sync only selected skills and report changed files."
|
|
43215
|
-
], ["sync skills", "install runtime skills", "global skill sync"])
|
|
43313
|
+
], ["sync skills", "install runtime skills", "global skill sync"], "Use when already-exported runtime skills need pushing to configured local runtimes, and only when sync is explicitly enabled. NOT for: producing the runtime export itself (see skill-runtime-exporter).")
|
|
43216
43314
|
];
|
|
43217
|
-
function skill(name, category, profiles, purpose, workflow, triggers) {
|
|
43315
|
+
function skill(name, category, profiles, purpose, workflow, triggers, descriptionOverride) {
|
|
43218
43316
|
return {
|
|
43219
43317
|
name,
|
|
43220
43318
|
category,
|
|
43221
|
-
description: `Use when ${purpose.charAt(0).toLowerCase()}${purpose.slice(1)}`,
|
|
43319
|
+
description: descriptionOverride ?? `Use when ${purpose.charAt(0).toLowerCase()}${purpose.slice(1)}`,
|
|
43222
43320
|
purpose,
|
|
43223
43321
|
workflow,
|
|
43224
43322
|
triggers,
|
|
@@ -43243,9 +43341,10 @@ function renderBundledSkill(skillEntry) {
|
|
|
43243
43341
|
const workflow = skillEntry.workflow.map((step, index) => `${index + 1}. ${step}`).join(`
|
|
43244
43342
|
`);
|
|
43245
43343
|
const commandContract = renderAgentCommandContract(skillEntry);
|
|
43344
|
+
const descriptionField = skillEntry.description.includes(":") ? `description: ${JSON.stringify(skillEntry.description)}` : `description: ${skillEntry.description}`;
|
|
43246
43345
|
return `---
|
|
43247
43346
|
name: ${skillEntry.name}
|
|
43248
|
-
|
|
43347
|
+
${descriptionField}
|
|
43249
43348
|
---
|
|
43250
43349
|
|
|
43251
43350
|
# ${skillEntry.name}
|
|
@@ -43380,8 +43479,9 @@ ${sections}
|
|
|
43380
43479
|
|
|
43381
43480
|
// src/gdskills/install.ts
|
|
43382
43481
|
init_fs();
|
|
43383
|
-
import { cp, copyFile, mkdir as mkdir7, readFile as readFile10, writeFile as writeFile7 } from "fs/promises";
|
|
43482
|
+
import { cp, copyFile, lstat as lstat3, mkdir as mkdir7, readFile as readFile10, unlink, writeFile as writeFile7 } from "fs/promises";
|
|
43384
43483
|
import { existsSync as existsSync9 } from "fs";
|
|
43484
|
+
import { createHash as createHash5 } from "crypto";
|
|
43385
43485
|
import path31 from "path";
|
|
43386
43486
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
43387
43487
|
|
|
@@ -43742,6 +43842,27 @@ function relativeContractPath(contract) {
|
|
|
43742
43842
|
return contract.sourcePath ?? path30.join("src", "gdskills", "contracts", contract.fileName);
|
|
43743
43843
|
}
|
|
43744
43844
|
|
|
43845
|
+
// src/gdskills/retired-rules.ts
|
|
43846
|
+
var RETIRED_RULES = [
|
|
43847
|
+
{
|
|
43848
|
+
fileName: "review-agent-profile.mdc",
|
|
43849
|
+
shippedSha256: [
|
|
43850
|
+
"e29a832821e501fa8a0acb5130007db1e21f1cee29f8ab6b2a1a7b35f9945281"
|
|
43851
|
+
],
|
|
43852
|
+
reason: "Byte-identical duplicate of code-review-ai-assistant.mdc \u2014 nothing distinguished the two, and only the latter was ever routed to."
|
|
43853
|
+
},
|
|
43854
|
+
{
|
|
43855
|
+
fileName: "review-strict-profile.mdc",
|
|
43856
|
+
shippedSha256: [
|
|
43857
|
+
"2e8847426bfba76ece8a208952402edadc6a062920aed07a721902b635a3f0e6",
|
|
43858
|
+
"bc7e6df820682f75cbc1349e70d98b5692aa1c4bae903e28f41a67edb7a5a484"
|
|
43859
|
+
],
|
|
43860
|
+
reason: "Outlived the review-strict skill it backed; review-orchestrator's Step 6 now resolves the model tier directly via `keryx review tier` instead."
|
|
43861
|
+
}
|
|
43862
|
+
];
|
|
43863
|
+
var LARGEST_SHIPPED_RETIRED_RULE_BYTES = 2248;
|
|
43864
|
+
var RETIRED_RULE_SIZE_CAP_BYTES = LARGEST_SHIPPED_RETIRED_RULE_BYTES * 4;
|
|
43865
|
+
|
|
43745
43866
|
// src/gdskills/install.ts
|
|
43746
43867
|
async function installGdskills(metaprojectRoot, profile, options = {}) {
|
|
43747
43868
|
const skills = getBundledSkillsForProfile(profile);
|
|
@@ -43773,18 +43894,20 @@ async function installGdskills(metaprojectRoot, profile, options = {}) {
|
|
|
43773
43894
|
}
|
|
43774
43895
|
}
|
|
43775
43896
|
await installBundledSharedSkills(skillsRoot);
|
|
43776
|
-
await installBundledRules(metaprojectRoot);
|
|
43897
|
+
const retiredRuleOutcomes = await installBundledRules(metaprojectRoot);
|
|
43777
43898
|
const catalogPath = path31.join(metaprojectRoot, "skills", "catalog.md");
|
|
43778
43899
|
await writeFile7(catalogPath, await preserveProjectSkillsSection(catalogPath, renderGdskillsCatalog(profile)), "utf8");
|
|
43779
43900
|
const manifestPath = path31.join(metaprojectRoot, "modules", "gdskills.md");
|
|
43780
43901
|
await writeFile7(manifestPath, renderGdskillsManifest(profile), "utf8");
|
|
43781
43902
|
await installContracts(contractsRoot);
|
|
43903
|
+
const warnings = retiredRuleOutcomes.map(retiredRuleWarning).filter((warning) => warning !== null);
|
|
43782
43904
|
return {
|
|
43783
43905
|
profile,
|
|
43784
43906
|
installedSkills: skills.length,
|
|
43785
43907
|
skillsRoot,
|
|
43786
43908
|
catalogPath,
|
|
43787
|
-
manifestPath
|
|
43909
|
+
manifestPath,
|
|
43910
|
+
warnings
|
|
43788
43911
|
};
|
|
43789
43912
|
}
|
|
43790
43913
|
async function installBundledSharedSkills(skillsRoot) {
|
|
@@ -43796,10 +43919,83 @@ async function installBundledSharedSkills(skillsRoot) {
|
|
|
43796
43919
|
}
|
|
43797
43920
|
async function installBundledRules(metaprojectRoot) {
|
|
43798
43921
|
const rulesSource = bundledRulesSourcePath();
|
|
43922
|
+
const rulesTarget = path31.join(metaprojectRoot, "rules", "core");
|
|
43799
43923
|
if (!existsSync9(rulesSource)) {
|
|
43800
|
-
return;
|
|
43924
|
+
return [];
|
|
43925
|
+
}
|
|
43926
|
+
await cp(rulesSource, rulesTarget, { recursive: true, force: true });
|
|
43927
|
+
return removeUnmodifiedRetiredRules(rulesTarget);
|
|
43928
|
+
}
|
|
43929
|
+
async function removeUnmodifiedRetiredRules(rulesTarget, fsOps = { unlink }) {
|
|
43930
|
+
const outcomes = [];
|
|
43931
|
+
for (const retired of RETIRED_RULES) {
|
|
43932
|
+
const installedPath = path31.join(rulesTarget, retired.fileName);
|
|
43933
|
+
let stage = "lstat";
|
|
43934
|
+
try {
|
|
43935
|
+
const stats = await lstat3(installedPath);
|
|
43936
|
+
if (!stats.isFile()) {
|
|
43937
|
+
outcomes.push({ fileName: retired.fileName, action: "kept-not-regular-file" });
|
|
43938
|
+
continue;
|
|
43939
|
+
}
|
|
43940
|
+
if (stats.size > RETIRED_RULE_SIZE_CAP_BYTES) {
|
|
43941
|
+
outcomes.push({ fileName: retired.fileName, action: "kept-oversized", sizeBytes: stats.size });
|
|
43942
|
+
continue;
|
|
43943
|
+
}
|
|
43944
|
+
stage = "read";
|
|
43945
|
+
const content = await readFile10(installedPath);
|
|
43946
|
+
const hash = createHash5("sha256").update(normalizeRetiredRuleContent(content)).digest("hex");
|
|
43947
|
+
if (retired.shippedSha256.includes(hash)) {
|
|
43948
|
+
stage = "unlink";
|
|
43949
|
+
await fsOps.unlink(installedPath);
|
|
43950
|
+
outcomes.push({ fileName: retired.fileName, action: "removed" });
|
|
43951
|
+
} else {
|
|
43952
|
+
outcomes.push({ fileName: retired.fileName, action: "kept-modified" });
|
|
43953
|
+
}
|
|
43954
|
+
} catch (error) {
|
|
43955
|
+
if (isErrnoException(error) && error.code === "ENOENT") {
|
|
43956
|
+
continue;
|
|
43957
|
+
}
|
|
43958
|
+
outcomes.push({
|
|
43959
|
+
fileName: retired.fileName,
|
|
43960
|
+
action: "kept-error",
|
|
43961
|
+
stage,
|
|
43962
|
+
errorCode: isErrnoException(error) && error.code ? error.code : "UNKNOWN"
|
|
43963
|
+
});
|
|
43964
|
+
}
|
|
43965
|
+
}
|
|
43966
|
+
return outcomes;
|
|
43967
|
+
}
|
|
43968
|
+
function normalizeRetiredRuleContent(content) {
|
|
43969
|
+
let text = content.toString("utf8");
|
|
43970
|
+
if (text.charCodeAt(0) === 65279) {
|
|
43971
|
+
text = text.slice(1);
|
|
43972
|
+
}
|
|
43973
|
+
return text.replace(/\r\n/g, `
|
|
43974
|
+
`);
|
|
43975
|
+
}
|
|
43976
|
+
function isErrnoException(error) {
|
|
43977
|
+
return error instanceof Error && "code" in error;
|
|
43978
|
+
}
|
|
43979
|
+
function retiredRuleWarning(outcome) {
|
|
43980
|
+
if (outcome.action === "removed") {
|
|
43981
|
+
return null;
|
|
43982
|
+
}
|
|
43983
|
+
const reason = RETIRED_RULES.find((retired) => retired.fileName === outcome.fileName)?.reason ?? "no longer shipped by keryx";
|
|
43984
|
+
const prefix = `${outcome.fileName} is no longer shipped by keryx (${reason})`;
|
|
43985
|
+
switch (outcome.action) {
|
|
43986
|
+
case "kept-modified":
|
|
43987
|
+
return `${prefix}; kept because it differs from every shipped version \u2014 delete it, or rename it if you still rely on it`;
|
|
43988
|
+
case "kept-not-regular-file":
|
|
43989
|
+
return `${prefix}; kept because it is not a regular file (a symlink, directory, or similar) \u2014 keryx will not read or remove it; delete or rename it yourself if appropriate`;
|
|
43990
|
+
case "kept-oversized":
|
|
43991
|
+
return `${prefix}; kept because it is ${outcome.sizeBytes} bytes, far larger than any version keryx ever shipped under this name \u2014 inspect it, then delete or rename it if appropriate`;
|
|
43992
|
+
case "kept-error":
|
|
43993
|
+
return outcome.stage === "unlink" ? `${prefix}; matches a shipped version but could not be removed (${outcome.errorCode}) \u2014 delete it by hand` : `${prefix}; kept because it could not be read (${outcome.errorCode}) \u2014 inspect it, then delete or rename it if appropriate`;
|
|
43994
|
+
default: {
|
|
43995
|
+
const exhaustive = outcome;
|
|
43996
|
+
throw new Error(`unhandled retired rule outcome: ${JSON.stringify(exhaustive)}`);
|
|
43997
|
+
}
|
|
43801
43998
|
}
|
|
43802
|
-
await cp(rulesSource, path31.join(metaprojectRoot, "rules", "core"), { recursive: true, force: true });
|
|
43803
43999
|
}
|
|
43804
44000
|
async function preserveProjectSkillsSection(catalogPath, nextCatalog) {
|
|
43805
44001
|
if (!await pathExists(catalogPath)) {
|
|
@@ -46105,13 +46301,33 @@ function escapeHtml(value) {
|
|
|
46105
46301
|
function renderProjectRulesReadme() {
|
|
46106
46302
|
return `# Project Rules
|
|
46107
46303
|
|
|
46108
|
-
This directory
|
|
46304
|
+
This directory holds two different kinds of rule files. Do not treat them the same way.
|
|
46109
46305
|
|
|
46110
|
-
|
|
46306
|
+
## Imported entrypoint rules (this directory)
|
|
46307
|
+
|
|
46308
|
+
The \`.md\` files here (e.g. \`agents-md.md\`, \`claude-md.md\`) are repository-level instructions
|
|
46309
|
+
imported from root agent entrypoints such as \`AGENTS.md\` or \`CLAUDE.md\`.
|
|
46111
46310
|
|
|
46112
46311
|
- treat files here as high-priority agent-readable mirrors of root instructions;
|
|
46113
46312
|
- update the root entrypoint first when changing project-wide instructions;
|
|
46114
46313
|
- rerun \`keryx rules sync\`, \`keryx init\`, or \`keryx update\` to resync imported rule files.
|
|
46314
|
+
|
|
46315
|
+
## Core rule library (\`core/*.mdc\`)
|
|
46316
|
+
|
|
46317
|
+
\`core/*.mdc\` is an on-demand rule library, not something loaded automatically. A rule file is
|
|
46318
|
+
read only when a skill or \`routing.md\` cites it by path.
|
|
46319
|
+
|
|
46320
|
+
- \`alwaysApply\` and \`globs\` in each rule's frontmatter are Cursor-format metadata for Cursor's
|
|
46321
|
+
own auto-attach behavior; keryx itself does not read or act on either field;
|
|
46322
|
+
- a stack-specific rule (e.g. \`nestjs-dto.mdc\`, \`mobx-store-template.mdc\`) declares the stack(s)
|
|
46323
|
+
it applies to via a \`stack_requires\` frontmatter key, using the same tag vocabulary as a
|
|
46324
|
+
skill's \`metadata.stack_requires\`; it is only relevant to projects on that stack;
|
|
46325
|
+
- the bundled tree (\`src/gdskills/bundled/rules/core/\`) is the source of truth \u2014 \`core/\` here is
|
|
46326
|
+
an installed mirror, and \`keryx init\`/\`keryx update\` overwrite it wholesale on install;
|
|
46327
|
+
a rule retired from the bundled tree is removed from here too when it is an unmodified shipped
|
|
46328
|
+
copy; otherwise it is kept (with a warning that says why \u2014 edited, not a regular file, oversized,
|
|
46329
|
+
or unreadable/unremovable), since discarding it silently could lose your changes or hide a
|
|
46330
|
+
filesystem problem.
|
|
46115
46331
|
`;
|
|
46116
46332
|
}
|
|
46117
46333
|
function renderImportedAgentRules({
|
|
@@ -46119,7 +46335,7 @@ function renderImportedAgentRules({
|
|
|
46119
46335
|
content
|
|
46120
46336
|
}) {
|
|
46121
46337
|
const body = extractAgentRuleBody(content);
|
|
46122
|
-
const normalizedBody = body.length > 0 ? body : `This root entrypoint delegates agent routing to \`.metaproject/index.md\`.
|
|
46338
|
+
const normalizedBody = body.length > 0 && !isHeadingOnlyBody(body) ? body : `This root entrypoint delegates agent routing to \`.metaproject/index.md\`.
|
|
46123
46339
|
|
|
46124
46340
|
Read \`.metaproject/index.md\` first, then follow the high-priority rules, skills, and module references listed there.`;
|
|
46125
46341
|
return `---
|
|
@@ -46143,6 +46359,9 @@ This file is generated from the repository root agent entrypoint. Edit \`${sourc
|
|
|
46143
46359
|
${normalizedBody}
|
|
46144
46360
|
`;
|
|
46145
46361
|
}
|
|
46362
|
+
function isHeadingOnlyBody(body) {
|
|
46363
|
+
return body.replace(/^#[^\n]*\n?/, "").trim().length === 0;
|
|
46364
|
+
}
|
|
46146
46365
|
function extractAgentRuleBody(content) {
|
|
46147
46366
|
const marker = "<!-- keryx:index -->";
|
|
46148
46367
|
const endMarker = "<!-- /keryx:index -->";
|
|
@@ -47243,13 +47462,13 @@ import { readFile as readFile17, rm as rm3 } from "fs/promises";
|
|
|
47243
47462
|
import path44 from "path";
|
|
47244
47463
|
|
|
47245
47464
|
// src/lib/install-plan.ts
|
|
47246
|
-
import { createHash as
|
|
47465
|
+
import { createHash as createHash6 } from "crypto";
|
|
47247
47466
|
import { readFile as readFile16 } from "fs/promises";
|
|
47248
47467
|
import path43 from "path";
|
|
47249
47468
|
// package.json
|
|
47250
47469
|
var package_default = {
|
|
47251
47470
|
name: "@mrciphersmith/keryx",
|
|
47252
|
-
version: "0.2.
|
|
47471
|
+
version: "0.2.98",
|
|
47253
47472
|
description: "Version-controlled project context for AI coding agents: code graph, architecture wiki, project memory, relevant tests, quality signals, and task flows.",
|
|
47254
47473
|
private: false,
|
|
47255
47474
|
publishConfig: {
|
|
@@ -47390,7 +47609,7 @@ function parseDivergenceResolution(args) {
|
|
|
47390
47609
|
return;
|
|
47391
47610
|
}
|
|
47392
47611
|
function digestOf(content) {
|
|
47393
|
-
return `sha256:${
|
|
47612
|
+
return `sha256:${createHash6("sha256").update(content, "utf8").digest("hex")}`;
|
|
47394
47613
|
}
|
|
47395
47614
|
function installJournalPath(metaprojectRoot) {
|
|
47396
47615
|
return path43.join(metaprojectRoot, INSTALL_JOURNAL_RELATIVE_PATH);
|
|
@@ -49612,8 +49831,10 @@ async function initCommand(args) {
|
|
|
49612
49831
|
await installGdwikiPostCommitHook(projectRoot);
|
|
49613
49832
|
}
|
|
49614
49833
|
}
|
|
49834
|
+
let gdskillsWarnings = [];
|
|
49615
49835
|
if (enableGdskills) {
|
|
49616
|
-
await installGdskills(metaprojectRoot, gdskillsProfile);
|
|
49836
|
+
const gdskillsInstallResult = await installGdskills(metaprojectRoot, gdskillsProfile);
|
|
49837
|
+
gdskillsWarnings = gdskillsInstallResult.warnings;
|
|
49617
49838
|
if (enableGdskillsHook) {
|
|
49618
49839
|
await installGdskillsPostCommitHook(projectRoot);
|
|
49619
49840
|
}
|
|
@@ -49867,6 +50088,12 @@ async function initCommand(args) {
|
|
|
49867
50088
|
if (enableSac) {
|
|
49868
50089
|
statusLine("sac", true, "shared agent context: cross-session workspace propose/review (opt-in)");
|
|
49869
50090
|
}
|
|
50091
|
+
if (gdskillsWarnings.length > 0) {
|
|
50092
|
+
heading("Warnings");
|
|
50093
|
+
for (const warning of gdskillsWarnings) {
|
|
50094
|
+
note(warning);
|
|
50095
|
+
}
|
|
50096
|
+
}
|
|
49870
50097
|
const gitHooksRoot = await resolveGitHooksRoot(projectRoot);
|
|
49871
50098
|
const hookLines = [];
|
|
49872
50099
|
if (enableGdgraph) {
|
|
@@ -50240,7 +50467,7 @@ Use this skill when a task requires code graph context, dependency impact analys
|
|
|
50240
50467
|
4. Use \`keryx gdgraph affected <target>\` before implementation or review.
|
|
50241
50468
|
`;
|
|
50242
50469
|
if (await readFile23(legacyReadmePath, "utf8") === legacyContent) {
|
|
50243
|
-
await
|
|
50470
|
+
await unlink2(legacyReadmePath);
|
|
50244
50471
|
}
|
|
50245
50472
|
}
|
|
50246
50473
|
function runtimeSourcePath(relativePath) {
|
|
@@ -53184,7 +53411,7 @@ function readLiteral(source, start, quote) {
|
|
|
53184
53411
|
|
|
53185
53412
|
// src/wiki/freshness/queue.ts
|
|
53186
53413
|
init_fs();
|
|
53187
|
-
import { readFile as readFile43, rename as rename3, stat as stat10, unlink as
|
|
53414
|
+
import { readFile as readFile43, rename as rename3, stat as stat10, unlink as unlink3, writeFile as writeFile30 } from "fs/promises";
|
|
53188
53415
|
import path86 from "path";
|
|
53189
53416
|
var QUEUE_FILE = "freshness-queue.jsonl";
|
|
53190
53417
|
var ROTATED_FILE = "freshness-queue.1.jsonl";
|
|
@@ -53225,7 +53452,7 @@ async function drainQueue(cwd) {
|
|
|
53225
53452
|
async function clearQueue(cwd) {
|
|
53226
53453
|
for (const file of [rotatedQueuePath(cwd), queuePath(cwd)]) {
|
|
53227
53454
|
if (await pathExists(file)) {
|
|
53228
|
-
await
|
|
53455
|
+
await unlink3(file).catch(() => {
|
|
53229
53456
|
return;
|
|
53230
53457
|
});
|
|
53231
53458
|
}
|
|
@@ -57464,6 +57691,8 @@ var BUNDLED_SKILL_CHECKS = [
|
|
|
57464
57691
|
"frontmatter:name-unique",
|
|
57465
57692
|
"frontmatter:description",
|
|
57466
57693
|
"frontmatter:metadata",
|
|
57694
|
+
"frontmatter:harness-claude",
|
|
57695
|
+
"frontmatter:category",
|
|
57467
57696
|
"catalog:registered",
|
|
57468
57697
|
"model:concrete-declaration",
|
|
57469
57698
|
"persona:name",
|
|
@@ -57608,17 +57837,60 @@ var INSTALLED_PREFIXES = [
|
|
|
57608
57837
|
var GENERATED_PATH_ROOTS = [
|
|
57609
57838
|
{ prefix: "rules/entrypoints/", producedBy: "keryx rules distill" }
|
|
57610
57839
|
];
|
|
57611
|
-
var PATH_REFERENCE = /(?:^|[\s"'`([])((?:\.metaproject\/|skills\/|rules\/|scripts\/)[\w
|
|
57612
|
-
function
|
|
57840
|
+
var PATH_REFERENCE = /(?:^|[\s"'`([])((?:\.metaproject\/|skills\/|rules\/|scripts\/)[\w./@*-]*[\w.@*-])/g;
|
|
57841
|
+
function resolveInstalledReference(reference, known) {
|
|
57613
57842
|
for (const [from, to] of INSTALLED_PREFIXES) {
|
|
57614
57843
|
if (reference.startsWith(from))
|
|
57615
57844
|
return to + reference.slice(from.length);
|
|
57616
57845
|
}
|
|
57617
57846
|
if (reference.startsWith(".metaproject/"))
|
|
57618
57847
|
return;
|
|
57619
|
-
const
|
|
57848
|
+
const segments = reference.split("/");
|
|
57849
|
+
const root = segments[0] ?? "";
|
|
57850
|
+
if (root === "skills") {
|
|
57851
|
+
if (segments.length === 3 && known.has(segments[2] ?? ""))
|
|
57852
|
+
return reference;
|
|
57853
|
+
return null;
|
|
57854
|
+
}
|
|
57620
57855
|
return CHECKED_PATH_ROOTS.includes(root) ? reference : undefined;
|
|
57621
57856
|
}
|
|
57857
|
+
function scanCrossReferences(text, root, known, checkSkillNames, add) {
|
|
57858
|
+
text.split(`
|
|
57859
|
+
`).forEach((line, index) => {
|
|
57860
|
+
if (checkSkillNames) {
|
|
57861
|
+
for (const pattern of SKILL_REFERENCE_PATTERNS) {
|
|
57862
|
+
for (const match of line.matchAll(pattern)) {
|
|
57863
|
+
const referenced = match[1];
|
|
57864
|
+
if (!referenced.includes("-"))
|
|
57865
|
+
continue;
|
|
57866
|
+
if (known.has(referenced))
|
|
57867
|
+
continue;
|
|
57868
|
+
if (KNOWN_EXTERNAL_SKILL_REFERENCES.has(referenced))
|
|
57869
|
+
continue;
|
|
57870
|
+
add("xref:skill", index + 1, `names a skill \`${referenced}\` that this tree does not ship; either bundle it or stop naming it.`);
|
|
57871
|
+
}
|
|
57872
|
+
}
|
|
57873
|
+
}
|
|
57874
|
+
for (const match of line.matchAll(PATH_REFERENCE)) {
|
|
57875
|
+
const raw = match[1];
|
|
57876
|
+
if (raw.includes("<") || raw.includes("*") || raw.includes("$"))
|
|
57877
|
+
continue;
|
|
57878
|
+
const resolved = resolveInstalledReference(raw, known);
|
|
57879
|
+
if (resolved === undefined)
|
|
57880
|
+
continue;
|
|
57881
|
+
if (resolved === null) {
|
|
57882
|
+
add("xref:path", index + 1, `path \`${raw}\` names the SOURCE tree's own layout, not an installed one \u2014 an installed project has no top-level \`skills/\`, only \`.metaproject/skills/gdskills/\u2026\`. Write \`.metaproject/skills/gdskills/${raw.slice("skills/".length)}\` (or the \`skills/gdskills/\u2026\` form), or, to name the whole skill rather than a file in it, drop everything past its directory.`);
|
|
57883
|
+
continue;
|
|
57884
|
+
}
|
|
57885
|
+
if (GENERATED_PATH_ROOTS.some((entry) => resolved === entry.prefix.replace(/\/$/, "") || resolved.startsWith(entry.prefix))) {
|
|
57886
|
+
continue;
|
|
57887
|
+
}
|
|
57888
|
+
if (existsSync24(path143.join(root, resolved)))
|
|
57889
|
+
continue;
|
|
57890
|
+
add("xref:path", index + 1, `path \`${raw}\` resolves to nothing under the shipped tree (looked for \`${resolved}\`).`);
|
|
57891
|
+
}
|
|
57892
|
+
});
|
|
57893
|
+
}
|
|
57622
57894
|
var SKILL_DOCUMENT_NAMES = new Set(HARNESS_SKILL_RUNTIMES.map((runtime) => skillBuildFileName(runtime)));
|
|
57623
57895
|
var KNOWN_SKILL_COMPANION_DOCUMENTS = new Map([
|
|
57624
57896
|
[
|
|
@@ -57650,6 +57922,12 @@ function bundledSkillFiles(root) {
|
|
|
57650
57922
|
function bundledSkillDocuments(root) {
|
|
57651
57923
|
return walkSkillDocuments(root, (name) => SKILL_DOCUMENT_NAMES.has(name));
|
|
57652
57924
|
}
|
|
57925
|
+
function bundledRuleFiles(root) {
|
|
57926
|
+
const rulesRoot = path143.join(root, "rules", "core");
|
|
57927
|
+
if (!existsSync24(rulesRoot))
|
|
57928
|
+
return [];
|
|
57929
|
+
return readdirSync2(rulesRoot, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => path143.join(rulesRoot, entry.name)).sort();
|
|
57930
|
+
}
|
|
57653
57931
|
function defaultBundledRoot() {
|
|
57654
57932
|
const directPath = path143.join(import.meta.dir, "bundled");
|
|
57655
57933
|
if (existsSync24(directPath))
|
|
@@ -57672,6 +57950,7 @@ function evaluateBundledTree(root = defaultBundledRoot()) {
|
|
|
57672
57950
|
const skillDir = path143.dirname(file);
|
|
57673
57951
|
const skill = path143.basename(skillDir);
|
|
57674
57952
|
const rel = path143.relative(skillsRoot, file).split(path143.sep).join("/");
|
|
57953
|
+
const category = path143.dirname(rel).split("/")[0] ?? "";
|
|
57675
57954
|
const text = readFileSync6(file, "utf8");
|
|
57676
57955
|
const add = (check, line, message) => {
|
|
57677
57956
|
findings.push({ check, skill, file: rel, line, message });
|
|
@@ -57710,9 +57989,25 @@ function evaluateBundledTree(root = defaultBundledRoot()) {
|
|
|
57710
57989
|
if (metadataVersion === null) {
|
|
57711
57990
|
add("frontmatter:metadata", 1, "frontmatter `metadata` declares no `version`; without one a skill cannot be said to have changed.");
|
|
57712
57991
|
}
|
|
57992
|
+
const metadataCategory = /^\s{2,}category\s*:\s*(.+)$/m.exec(block);
|
|
57993
|
+
if (metadataCategory !== null) {
|
|
57994
|
+
const declaredCategory = (metadataCategory[1] ?? "").trim().replace(/^["']|["']$/g, "");
|
|
57995
|
+
if (declaredCategory.length > 0 && declaredCategory !== category) {
|
|
57996
|
+
add("frontmatter:category", 1, `frontmatter \`metadata.category\` is "${declaredCategory}" but this skill ships under \`${category}/${skill}\`; set it to "${category}" or drop the field.`);
|
|
57997
|
+
}
|
|
57998
|
+
}
|
|
57999
|
+
}
|
|
58000
|
+
if (path143.basename(file) === "SKILL.md") {
|
|
58001
|
+
const compatibleHarnesses = /^\s{2,}compatible_harnesses\s*:\s*(.+)$/m.exec(block);
|
|
58002
|
+
if (compatibleHarnesses !== null) {
|
|
58003
|
+
const declared = (compatibleHarnesses[1] ?? "").trim().replace(/^["']|["']$/g, "");
|
|
58004
|
+
const harnesses = declared.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
58005
|
+
if (!harnesses.includes("claude")) {
|
|
58006
|
+
add("frontmatter:harness-claude", 1, `frontmatter \`compatible_harnesses\` ("${declared}") omits \`claude\`, but this file IS the Claude build \u2014 add \`claude\` to the list.`);
|
|
58007
|
+
}
|
|
58008
|
+
}
|
|
57713
58009
|
}
|
|
57714
58010
|
}
|
|
57715
|
-
const category = path143.dirname(rel).split("/")[0] ?? "";
|
|
57716
58011
|
if (!catalogued.has(`${category}/${skill}`)) {
|
|
57717
58012
|
add("catalog:registered", null, `BUNDLED_GDSKILLS (src/gdskills/catalog.ts) does not name \`${category}/${skill}\`, so \`keryx skills install\` never copies this directory and no user ever sees it.`);
|
|
57718
58013
|
}
|
|
@@ -57726,35 +58021,15 @@ function evaluateBundledTree(root = defaultBundledRoot()) {
|
|
|
57726
58021
|
for (const offender of homePathOffenders(text)) {
|
|
57727
58022
|
add("path:personal-home", offender.line, offender.why);
|
|
57728
58023
|
}
|
|
57729
|
-
text
|
|
57730
|
-
|
|
57731
|
-
|
|
57732
|
-
|
|
57733
|
-
|
|
57734
|
-
|
|
57735
|
-
|
|
57736
|
-
|
|
57737
|
-
|
|
57738
|
-
if (KNOWN_EXTERNAL_SKILL_REFERENCES.has(referenced))
|
|
57739
|
-
continue;
|
|
57740
|
-
add("xref:skill", index + 1, `names a skill \`${referenced}\` that this tree does not ship; either bundle it or stop naming it.`);
|
|
57741
|
-
}
|
|
57742
|
-
}
|
|
57743
|
-
for (const match of line.matchAll(PATH_REFERENCE)) {
|
|
57744
|
-
const raw = match[1];
|
|
57745
|
-
if (raw.includes("<") || raw.includes("*") || raw.includes("$"))
|
|
57746
|
-
continue;
|
|
57747
|
-
const normalised = normaliseReferencePath(raw);
|
|
57748
|
-
if (normalised === undefined)
|
|
57749
|
-
continue;
|
|
57750
|
-
if (GENERATED_PATH_ROOTS.some((entry) => normalised === entry.prefix.replace(/\/$/, "") || normalised.startsWith(entry.prefix))) {
|
|
57751
|
-
continue;
|
|
57752
|
-
}
|
|
57753
|
-
if (existsSync24(path143.join(root, normalised)))
|
|
57754
|
-
continue;
|
|
57755
|
-
add("xref:path", index + 1, `path \`${raw}\` resolves to nothing under the shipped tree (looked for \`${normalised}\`).`);
|
|
57756
|
-
}
|
|
57757
|
-
});
|
|
58024
|
+
scanCrossReferences(text, root, known, true, add);
|
|
58025
|
+
}
|
|
58026
|
+
for (const file of bundledRuleFiles(root)) {
|
|
58027
|
+
const rel = path143.relative(root, file).split(path143.sep).join("/");
|
|
58028
|
+
const text = readFileSync6(file, "utf8");
|
|
58029
|
+
const add = (check, line, message) => {
|
|
58030
|
+
findings.push({ check, skill: path143.basename(file, path143.extname(file)), file: rel, line, message });
|
|
58031
|
+
};
|
|
58032
|
+
scanCrossReferences(text, root, known, false, add);
|
|
57758
58033
|
}
|
|
57759
58034
|
for (const dir of [...new Set(files.map((file) => path143.dirname(file)))].sort()) {
|
|
57760
58035
|
for (const entry of readdirSync2(dir, { withFileTypes: true })) {
|
|
@@ -57878,6 +58153,12 @@ async function skillsCommand(args) {
|
|
|
57878
58153
|
note(`skills ${relativeToCwd(result.skillsRoot)}`);
|
|
57879
58154
|
note(`catalog ${relativeToCwd(result.catalogPath)}`);
|
|
57880
58155
|
note(`manifest ${relativeToCwd(result.manifestPath)}`);
|
|
58156
|
+
if (result.warnings.length > 0) {
|
|
58157
|
+
console.log("Warnings:");
|
|
58158
|
+
for (const warning of result.warnings) {
|
|
58159
|
+
console.log(`- ${warning}`);
|
|
58160
|
+
}
|
|
58161
|
+
}
|
|
57881
58162
|
nextSteps([
|
|
57882
58163
|
`Browse the catalog: ${style.cyan("keryx skills catalog")}.`,
|
|
57883
58164
|
`Route a request: ${style.cyan("keryx skills route <target>")}.`
|
|
@@ -64758,14 +65039,17 @@ init_pr_comments();
|
|
|
64758
65039
|
init_loop();
|
|
64759
65040
|
|
|
64760
65041
|
// src/review/stack.ts
|
|
64761
|
-
var STACK_TAGS = ["nestjs", "react", "mobx", "prisma"];
|
|
65042
|
+
var STACK_TAGS = ["nestjs", "react", "mobx", "prisma", "playwright", "sql", "http-server"];
|
|
64762
65043
|
function isStackTag(value) {
|
|
64763
65044
|
return STACK_TAGS.includes(value);
|
|
64764
65045
|
}
|
|
64765
65046
|
var TAG_MARKERS = {
|
|
64766
65047
|
react: ["react", "react-dom"],
|
|
64767
65048
|
mobx: ["mobx", "mobx-react", "mobx-react-lite"],
|
|
64768
|
-
prisma: ["prisma", "@prisma/client"]
|
|
65049
|
+
prisma: ["prisma", "@prisma/client"],
|
|
65050
|
+
playwright: ["@playwright/test", "playwright"],
|
|
65051
|
+
sql: ["prisma", "@prisma/client", "typeorm", "sequelize", "knex", "drizzle-orm", "pg", "mysql2", "better-sqlite3", "kysely"],
|
|
65052
|
+
"http-server": ["express", "fastify", "koa", "hono", "@nestjs/core", "@hapi/hapi"]
|
|
64769
65053
|
};
|
|
64770
65054
|
var DEPENDENCY_FIELDS = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
|
|
64771
65055
|
async function detectProjectStack(cwd, options = {}) {
|
|
@@ -68127,14 +68411,14 @@ init_fs();
|
|
|
68127
68411
|
init_json();
|
|
68128
68412
|
|
|
68129
68413
|
// src/security/detect/mcp.ts
|
|
68130
|
-
import { createHash as
|
|
68414
|
+
import { createHash as createHash30 } from "crypto";
|
|
68131
68415
|
function hashToolDefinition(tool) {
|
|
68132
68416
|
const canonical = JSON.stringify({
|
|
68133
68417
|
name: tool.name,
|
|
68134
68418
|
description: tool.description ?? "",
|
|
68135
68419
|
inputSchema: tool.inputSchema ?? null
|
|
68136
68420
|
});
|
|
68137
|
-
return
|
|
68421
|
+
return createHash30("sha256").update(canonical).digest("hex");
|
|
68138
68422
|
}
|
|
68139
68423
|
var POISONING_PATTERNS = [
|
|
68140
68424
|
{
|
|
@@ -69236,7 +69520,7 @@ function wrapBwrap(command, profile, launcherPath = BWRAP_PROGRAM) {
|
|
|
69236
69520
|
}
|
|
69237
69521
|
|
|
69238
69522
|
// src/harness/process/sandbox/adapter.ts
|
|
69239
|
-
import { createHash as
|
|
69523
|
+
import { createHash as createHash31 } from "crypto";
|
|
69240
69524
|
|
|
69241
69525
|
// src/harness/process/sandbox/wrap.ts
|
|
69242
69526
|
function wrapWithSandbox(command, profile, opts) {
|
|
@@ -69266,7 +69550,7 @@ function wrapWithSandbox(command, profile, opts) {
|
|
|
69266
69550
|
function spawnError(command, message) {
|
|
69267
69551
|
return {
|
|
69268
69552
|
kind: "spawn-error",
|
|
69269
|
-
observedHash:
|
|
69553
|
+
observedHash: createHash31("sha256").update(`${command.path}
|
|
69270
69554
|
${command.argv.join(" ")}`, "utf8").digest("hex"),
|
|
69271
69555
|
errorMessage: message
|
|
69272
69556
|
};
|
|
@@ -71455,7 +71739,7 @@ async function closeServers(states) {
|
|
|
71455
71739
|
|
|
71456
71740
|
// src/mcp-servers/trust.ts
|
|
71457
71741
|
init_config_dir();
|
|
71458
|
-
import { createHash as
|
|
71742
|
+
import { createHash as createHash32 } from "crypto";
|
|
71459
71743
|
import path166 from "path";
|
|
71460
71744
|
function trustFile(configDir) {
|
|
71461
71745
|
return path166.join(configDir ?? ensureKeryxConfigDir(), "mcp-servers-trust.json");
|
|
@@ -71470,7 +71754,7 @@ function serverFingerprint(server) {
|
|
|
71470
71754
|
headers: sortedKeys(server.headers),
|
|
71471
71755
|
bearer_token_env_var: server.bearer_token_env_var ?? null
|
|
71472
71756
|
});
|
|
71473
|
-
return
|
|
71757
|
+
return createHash32("sha256").update(material).digest("hex").slice(0, 32);
|
|
71474
71758
|
}
|
|
71475
71759
|
function sortedKeys(values) {
|
|
71476
71760
|
return Object.entries(values ?? {}).sort(([a], [b]) => a.localeCompare(b));
|
|
@@ -72369,7 +72653,7 @@ function resolveInteractive(explicit, stdin, stdout) {
|
|
|
72369
72653
|
function bothStreamsAreATerminal(stdin, stdout) {
|
|
72370
72654
|
return stdin.isTTY === true && stdout.isTTY === true;
|
|
72371
72655
|
}
|
|
72372
|
-
function openAuthorisationUrl(url, log, platform = process.platform, env = process.env) {
|
|
72656
|
+
function openAuthorisationUrl(url, log, platform = process.platform, env = process.env, open = openVerificationUrl) {
|
|
72373
72657
|
const plan = browserOpenPlan(url.toString(), platform, env);
|
|
72374
72658
|
if (plan === undefined) {
|
|
72375
72659
|
log("No graphical session detected, so nothing was opened.");
|
|
@@ -72379,7 +72663,7 @@ function openAuthorisationUrl(url, log, platform = process.platform, env = proce
|
|
|
72379
72663
|
`);
|
|
72380
72664
|
return;
|
|
72381
72665
|
}
|
|
72382
|
-
|
|
72666
|
+
open(url.toString(), { platform, env });
|
|
72383
72667
|
}
|
|
72384
72668
|
function removeCommand(args, deps) {
|
|
72385
72669
|
const own = splitAtSeparator(args).own;
|
|
@@ -72779,17 +73063,17 @@ init_sac();
|
|
|
72779
73063
|
init_workspace_service();
|
|
72780
73064
|
init_store2();
|
|
72781
73065
|
init_fs();
|
|
72782
|
-
import { createHash as
|
|
73066
|
+
import { createHash as createHash35, randomUUID as randomUUID17 } from "crypto";
|
|
72783
73067
|
import { appendFile as appendFile7, mkdir as mkdir58, open as open2, readFile as readFile93, rename as rename7, rm as rm12, stat as stat16, writeFile as writeFile50 } from "fs/promises";
|
|
72784
73068
|
import path170 from "path";
|
|
72785
73069
|
|
|
72786
73070
|
// src/sac/policy-experiment.ts
|
|
72787
|
-
import { createHash as
|
|
73071
|
+
import { createHash as createHash34, createHmac as createHmac2 } from "crypto";
|
|
72788
73072
|
|
|
72789
73073
|
// src/sac/receipt-integrity.ts
|
|
72790
73074
|
init_sac();
|
|
72791
|
-
import { createHash as
|
|
72792
|
-
var sha2563 = (value) =>
|
|
73075
|
+
import { createHash as createHash33 } from "crypto";
|
|
73076
|
+
var sha2563 = (value) => createHash33("sha256").update(value, "utf8").digest("hex");
|
|
72793
73077
|
function bodyOf(receipt) {
|
|
72794
73078
|
const { integrity: _integrity, ...body } = receipt;
|
|
72795
73079
|
return body;
|
|
@@ -72846,7 +73130,7 @@ function stableValue(value) {
|
|
|
72846
73130
|
return value;
|
|
72847
73131
|
}
|
|
72848
73132
|
var stableJson2 = (value) => JSON.stringify(stableValue(value));
|
|
72849
|
-
var sha2564 = (value) =>
|
|
73133
|
+
var sha2564 = (value) => createHash34("sha256").update(stableJson2(value), "utf8").digest("hex");
|
|
72850
73134
|
var workspacePathPattern2 = /^\.\/(?!.*(?:^|\/)\.\.(?:\/|$))(?:[A-Za-z0-9._-]+\/)*[A-Za-z0-9._-]+$/;
|
|
72851
73135
|
var trustedOutcomes = new WeakMap;
|
|
72852
73136
|
var trustedSandboxEvidence = new WeakMap;
|
|
@@ -72866,7 +73150,7 @@ function policyCorpusDigest(manifest, rows, quarantine) {
|
|
|
72866
73150
|
function splitFor(receiptHash, outcome, split) {
|
|
72867
73151
|
if (outcome.caseClass === "adversarial")
|
|
72868
73152
|
return "adversarial";
|
|
72869
|
-
const byte = Number.parseInt(
|
|
73153
|
+
const byte = Number.parseInt(createHash34("sha256").update(`${split.seed}\x00${receiptHash}`).digest("hex").slice(0, 2), 16);
|
|
72870
73154
|
return byte / 256 * 100 < split.holdoutPercent ? "holdout" : "train";
|
|
72871
73155
|
}
|
|
72872
73156
|
function quarantineCounts(entries) {
|
|
@@ -72950,12 +73234,12 @@ var stableValue2 = (value) => {
|
|
|
72950
73234
|
return value;
|
|
72951
73235
|
};
|
|
72952
73236
|
var stableJson3 = (value) => JSON.stringify(stableValue2(value));
|
|
72953
|
-
var sha2565 = (value) =>
|
|
73237
|
+
var sha2565 = (value) => createHash35("sha256").update(stableJson3(value), "utf8").digest("hex");
|
|
72954
73238
|
var isImmutableVersion2 = (value) => typeof value === "string" && value.length >= 3 && value.length <= 256 && /^[A-Za-z0-9][A-Za-z0-9._:+-]*$/.test(value) && /\d/.test(value) && !immutableVersionPattern.test(value);
|
|
72955
73239
|
var receiptHashPattern2 = /^[a-f0-9]{64}$/;
|
|
72956
73240
|
var ledgerDigestChunkBytes = 64 * 1024;
|
|
72957
73241
|
var isMissing = (error) => error instanceof Error && error.code === "ENOENT";
|
|
72958
|
-
var checkpointHash = (body) =>
|
|
73242
|
+
var checkpointHash = (body) => createHash35("sha256").update(JSON.stringify(body), "utf8").digest("hex");
|
|
72959
73243
|
async function ledgerByteLength(ledger) {
|
|
72960
73244
|
const value = await stat16(ledger, { bigint: true });
|
|
72961
73245
|
if (value.size > BigInt(Number.MAX_SAFE_INTEGER))
|
|
@@ -72963,7 +73247,7 @@ async function ledgerByteLength(ledger) {
|
|
|
72963
73247
|
return Number(value.size);
|
|
72964
73248
|
}
|
|
72965
73249
|
async function digestLedgerPrefix(handle, byteLength) {
|
|
72966
|
-
const digest =
|
|
73250
|
+
const digest = createHash35("sha256");
|
|
72967
73251
|
if (byteLength === 0)
|
|
72968
73252
|
return digest;
|
|
72969
73253
|
const buffer = Buffer.alloc(Math.min(ledgerDigestChunkBytes, byteLength));
|
|
@@ -73087,7 +73371,7 @@ async function auditLedger(ledger, checkpointPath, verifier) {
|
|
|
73087
73371
|
const verification = await verifier(receipts);
|
|
73088
73372
|
if (!verification.ok)
|
|
73089
73373
|
throw new Error(`invalid access receipt ledger: ${verification.reason} at record ${verification.firstInvalidIndex}`);
|
|
73090
|
-
const digest =
|
|
73374
|
+
const digest = createHash35("sha256").update(bytes);
|
|
73091
73375
|
const tailOffset = receipts.length === 0 ? 0 : bytes.lastIndexOf(10, bytes.length - 2) + 1;
|
|
73092
73376
|
const state = { ledgerBytes: bytes.length, recordCount: receipts.length, headHash: verification.headHash, tailOffset, digest };
|
|
73093
73377
|
await writeCheckpoint(checkpointPath, { schemaVersion: "1.1", ledgerBytes: state.ledgerBytes, recordCount: state.recordCount, headHash: state.headHash, tailOffset, contentDigest: digest.copy().digest("hex") });
|
|
@@ -73103,7 +73387,7 @@ async function resolveLedgerState(ledger, checkpointPath, verifier) {
|
|
|
73103
73387
|
throw error;
|
|
73104
73388
|
if (document.present)
|
|
73105
73389
|
throw new Error("invalid access receipt ledger: orphaned-checkpoint");
|
|
73106
|
-
return { ledgerBytes: 0, recordCount: 0, headHash: "GENESIS", tailOffset: 0, digest:
|
|
73390
|
+
return { ledgerBytes: 0, recordCount: 0, headHash: "GENESIS", tailOffset: 0, digest: createHash35("sha256") };
|
|
73107
73391
|
}
|
|
73108
73392
|
if (document.checkpoint) {
|
|
73109
73393
|
const fast = await fastCheckpointState(ledger, document.checkpoint, ledgerBytes);
|
|
@@ -73122,7 +73406,7 @@ var isConfigRecord = (value) => typeof value.enabled === "boolean" && typeof val
|
|
|
73122
73406
|
async function readPinnedJson(input) {
|
|
73123
73407
|
const ref = await resolveWorkspaceReference({ workspaceRoot: input.workspaceRoot, kind: "artifact", uri: input.uri });
|
|
73124
73408
|
const raw = await readFile93(ref, "utf8");
|
|
73125
|
-
const digest =
|
|
73409
|
+
const digest = createHash35("sha256").update(raw).digest("hex");
|
|
73126
73410
|
if (digest !== input.digest)
|
|
73127
73411
|
throw new Error("policy experiment pinned artifact digest mismatch");
|
|
73128
73412
|
return { artifact: JSON.parse(raw), digest };
|
|
@@ -73552,7 +73836,7 @@ function createLocalFwkReadService(cwd, opts) {
|
|
|
73552
73836
|
const facts = await Promise.all(manifest.resources.filter((resource) => resource.kind === "evidence").map(async (resource, index) => {
|
|
73553
73837
|
try {
|
|
73554
73838
|
const raw = await workspaces.readResourceForActor({ actorContext, workspaceId, resource });
|
|
73555
|
-
const revision =
|
|
73839
|
+
const revision = createHash35("sha256").update(raw).digest("hex");
|
|
73556
73840
|
return { id: `fact-${index}`, uri: resource.uri, revision: resource.revision ?? revision, observedAt: manifest.updatedAt, expiresAt: "9999-12-31T23:59:59Z", trust: "primary", visible: true, statement: `Evidence reference ${resource.uri}`, status: resource.revision === revision || resource.revision === undefined ? "fresh" : "stale" };
|
|
73557
73841
|
} catch (error) {
|
|
73558
73842
|
withhold(error);
|
|
@@ -73562,7 +73846,7 @@ function createLocalFwkReadService(cwd, opts) {
|
|
|
73562
73846
|
const knowHow = await Promise.all(manifest.resources.filter((resource) => resource.kind === "wiki" || resource.kind === "memory" || resource.kind === "skill").map(async (resource, index) => {
|
|
73563
73847
|
try {
|
|
73564
73848
|
const raw = await workspaces.readResourceForActor({ actorContext, workspaceId, resource, encoding: "utf8" });
|
|
73565
|
-
const revision =
|
|
73849
|
+
const revision = createHash35("sha256").update(raw).digest("hex");
|
|
73566
73850
|
const accepted = /^Status:\s*(accepted|reviewed)\s*$/mi.test(raw);
|
|
73567
73851
|
return { id: `knowhow-${index}`, kind: resource.kind, uri: resource.uri, revision: resource.revision ?? revision, trust: "accepted", status: resource.revision === revision || resource.revision === undefined ? "fresh" : "stale", accepted, visible: true };
|
|
73568
73852
|
} catch (error) {
|
|
@@ -74381,7 +74665,7 @@ function buildToolRegistry() {
|
|
|
74381
74665
|
init_fs();
|
|
74382
74666
|
init_contained_read();
|
|
74383
74667
|
import path173 from "path";
|
|
74384
|
-
import { lstat as
|
|
74668
|
+
import { lstat as lstat5, readdir as readdir32, realpath as realpath7, stat as stat17 } from "fs/promises";
|
|
74385
74669
|
var URI_PREFIX = "metaproject://";
|
|
74386
74670
|
function mimeForPath(filePath) {
|
|
74387
74671
|
if (filePath.endsWith(".json") || filePath.endsWith(".jsonl")) {
|
|
@@ -74406,7 +74690,7 @@ async function walkFiles(root, ownerRoot = root, ancestors = new Set) {
|
|
|
74406
74690
|
if (!await pathExists(root)) {
|
|
74407
74691
|
return [];
|
|
74408
74692
|
}
|
|
74409
|
-
const ownerInfo = await
|
|
74693
|
+
const ownerInfo = await lstat5(ownerRoot).catch(() => null);
|
|
74410
74694
|
if (!ownerInfo || !ownerInfo.isDirectory() || ownerInfo.isSymbolicLink())
|
|
74411
74695
|
return [];
|
|
74412
74696
|
const ownerReal = await realpath7(ownerRoot).catch(() => null);
|
|
@@ -74942,7 +75226,7 @@ init_make_provider();
|
|
|
74942
75226
|
init_profiles();
|
|
74943
75227
|
|
|
74944
75228
|
// src/harness/run/run.ts
|
|
74945
|
-
import { createHash as
|
|
75229
|
+
import { createHash as createHash39 } from "crypto";
|
|
74946
75230
|
|
|
74947
75231
|
// src/harness/completion/gate.ts
|
|
74948
75232
|
var SCHEMA_VERSION3 = 1;
|
|
@@ -74993,10 +75277,10 @@ function evaluateCompletion(input, deps) {
|
|
|
74993
75277
|
}
|
|
74994
75278
|
|
|
74995
75279
|
// src/harness/evidence/redaction.ts
|
|
74996
|
-
import { createHash as
|
|
75280
|
+
import { createHash as createHash36 } from "crypto";
|
|
74997
75281
|
var CLEAN_CATEGORY = "none";
|
|
74998
75282
|
function hashContent(content) {
|
|
74999
|
-
return
|
|
75283
|
+
return createHash36("sha256").update(content, "utf8").digest("hex");
|
|
75000
75284
|
}
|
|
75001
75285
|
function redactForPersistence(content, deps) {
|
|
75002
75286
|
const scan = deps.scan(content);
|
|
@@ -75047,7 +75331,7 @@ async function metaprojectBlastRadius(port, target) {
|
|
|
75047
75331
|
}
|
|
75048
75332
|
|
|
75049
75333
|
// src/harness/session/session.ts
|
|
75050
|
-
import { createHash as
|
|
75334
|
+
import { createHash as createHash37 } from "crypto";
|
|
75051
75335
|
var SCHEMA_VERSION4 = 1;
|
|
75052
75336
|
function canonicalStringify(value) {
|
|
75053
75337
|
if (Array.isArray(value)) {
|
|
@@ -75061,7 +75345,7 @@ function canonicalStringify(value) {
|
|
|
75061
75345
|
return JSON.stringify(value) ?? "null";
|
|
75062
75346
|
}
|
|
75063
75347
|
function sha2566(input) {
|
|
75064
|
-
return
|
|
75348
|
+
return createHash37("sha256").update(input, "utf8").digest("hex");
|
|
75065
75349
|
}
|
|
75066
75350
|
function deepFreeze(value) {
|
|
75067
75351
|
if (value !== null && typeof value === "object") {
|
|
@@ -75153,11 +75437,11 @@ class AppendOnlySession {
|
|
|
75153
75437
|
}
|
|
75154
75438
|
|
|
75155
75439
|
// src/harness/context/manifest.ts
|
|
75156
|
-
import { createHash as
|
|
75440
|
+
import { createHash as createHash38 } from "crypto";
|
|
75157
75441
|
var MAX_CONTEXT_BYTES = 2 * 1024 * 1024;
|
|
75158
75442
|
var MAX_CONTEXT_TOKENS = 200000;
|
|
75159
75443
|
function sha2567(input) {
|
|
75160
|
-
return
|
|
75444
|
+
return createHash38("sha256").update(input, "utf8").digest("hex");
|
|
75161
75445
|
}
|
|
75162
75446
|
function normalizeSource2(value) {
|
|
75163
75447
|
const record = typeof value === "object" && value !== null ? value : {};
|
|
@@ -75283,7 +75567,7 @@ function canonicalize2(value) {
|
|
|
75283
75567
|
return `{${keys.map((key) => `${JSON.stringify(key)}:${canonicalize2(record[key])}`).join(",")}}`;
|
|
75284
75568
|
}
|
|
75285
75569
|
function sha2568(input) {
|
|
75286
|
-
return
|
|
75570
|
+
return createHash39("sha256").update(input, "utf8").digest("hex");
|
|
75287
75571
|
}
|
|
75288
75572
|
function uniqueInOrder2(values) {
|
|
75289
75573
|
const seen = new Set;
|
|
@@ -75721,7 +76005,7 @@ function replayOffline(fixture, run, deps) {
|
|
|
75721
76005
|
}
|
|
75722
76006
|
|
|
75723
76007
|
// src/harness/tool/registry.ts
|
|
75724
|
-
import { createHash as
|
|
76008
|
+
import { createHash as createHash40 } from "crypto";
|
|
75725
76009
|
function canonicalize3(value) {
|
|
75726
76010
|
if (value === null || typeof value !== "object") {
|
|
75727
76011
|
return JSON.stringify(value) ?? "null";
|
|
@@ -75735,7 +76019,7 @@ function canonicalize3(value) {
|
|
|
75735
76019
|
return `{${entries.join(",")}}`;
|
|
75736
76020
|
}
|
|
75737
76021
|
function sha2569(input) {
|
|
75738
|
-
return
|
|
76022
|
+
return createHash40("sha256").update(input, "utf8").digest("hex");
|
|
75739
76023
|
}
|
|
75740
76024
|
function definitionHash(definition) {
|
|
75741
76025
|
return sha2569(canonicalize3(definition));
|
|
@@ -75886,11 +76170,11 @@ function runContainedProcess(input, deps) {
|
|
|
75886
76170
|
|
|
75887
76171
|
// src/harness/process/real-process-adapter.ts
|
|
75888
76172
|
import { spawnSync } from "child_process";
|
|
75889
|
-
import { createHash as
|
|
76173
|
+
import { createHash as createHash41 } from "crypto";
|
|
75890
76174
|
var DEFAULT_TIMEOUT_MS = 5000;
|
|
75891
76175
|
var DEFAULT_MAX_OUTPUT_BYTES = 10 * 1024 * 1024;
|
|
75892
76176
|
function sha256Hex4(input) {
|
|
75893
|
-
return
|
|
76177
|
+
return createHash41("sha256").update(input, "utf8").digest("hex");
|
|
75894
76178
|
}
|
|
75895
76179
|
function byteLength(chunk) {
|
|
75896
76180
|
if (chunk === null || chunk === undefined)
|
|
@@ -77807,12 +78091,14 @@ function resolveShellRestrictedMasks(env, sandboxConfigDir, projectRoot) {
|
|
|
77807
78091
|
tlsTerminate: result.resolution.tlsTerminate
|
|
77808
78092
|
};
|
|
77809
78093
|
}
|
|
77810
|
-
async function resolveShellEnv() {
|
|
78094
|
+
async function resolveShellEnv(configDir) {
|
|
77811
78095
|
await Promise.resolve().then(() => init_shell_config());
|
|
77812
|
-
|
|
78096
|
+
const passSaved = process.env.KERYX_SHELL_PASS_SAVED_KEYS === "1";
|
|
78097
|
+
const source = passSaved ? envWithSavedApiKeys(process.env, configDir) : process.env;
|
|
78098
|
+
const withheld = passSaved ? new Set : savedCredentialEnvKeys();
|
|
77813
78099
|
const env = {};
|
|
77814
|
-
for (const [key, value] of Object.entries(
|
|
77815
|
-
if (typeof value === "string")
|
|
78100
|
+
for (const [key, value] of Object.entries(source)) {
|
|
78101
|
+
if (typeof value === "string" && !withheld.has(key))
|
|
77816
78102
|
env[key] = value;
|
|
77817
78103
|
}
|
|
77818
78104
|
return env;
|
|
@@ -77833,7 +78119,8 @@ async function resolveShellSpawn(root, command, baseEnv, detectOpts) {
|
|
|
77833
78119
|
}
|
|
77834
78120
|
let netClose = async () => {};
|
|
77835
78121
|
if (profile.network === "restricted") {
|
|
77836
|
-
|
|
78122
|
+
await Promise.resolve().then(() => init_shell_config());
|
|
78123
|
+
const masks = resolveShellRestrictedMasks(envWithSavedApiKeys(env), undefined, root);
|
|
77837
78124
|
if (!masks.ok)
|
|
77838
78125
|
return { ok: false, error: `shell_exec: ${masks.reason}` };
|
|
77839
78126
|
const net = await setupNetworkRun(profile, {
|
|
@@ -79391,7 +79678,7 @@ init_command_risk();
|
|
|
79391
79678
|
init_shell_syntax();
|
|
79392
79679
|
import { existsSync as existsSync30 } from "fs";
|
|
79393
79680
|
import path181 from "path";
|
|
79394
|
-
import { createHash as
|
|
79681
|
+
import { createHash as createHash42 } from "crypto";
|
|
79395
79682
|
var PREFIX_BANNED = new Set([
|
|
79396
79683
|
"sh",
|
|
79397
79684
|
"bash",
|
|
@@ -79711,7 +79998,7 @@ function shellPermissionsFingerprint(dir) {
|
|
|
79711
79998
|
if (!read.ok) {
|
|
79712
79999
|
return "";
|
|
79713
80000
|
}
|
|
79714
|
-
return
|
|
80001
|
+
return createHash42("sha256").update(read.text, "utf8").digest("hex");
|
|
79715
80002
|
} catch {
|
|
79716
80003
|
return "";
|
|
79717
80004
|
}
|
|
@@ -80203,7 +80490,7 @@ function createDefaultSearchProviderController(configDir) {
|
|
|
80203
80490
|
return new SearchProviderController(registry, configDir);
|
|
80204
80491
|
}
|
|
80205
80492
|
// src/harness/tool/builtin/spawn-subagent-tool.ts
|
|
80206
|
-
import { createHash as
|
|
80493
|
+
import { createHash as createHash43, randomUUID as randomUUID24 } from "crypto";
|
|
80207
80494
|
import { mkdtemp, rm as rm13 } from "fs/promises";
|
|
80208
80495
|
import { tmpdir as tmpdir4 } from "os";
|
|
80209
80496
|
import path183 from "path";
|
|
@@ -80253,7 +80540,7 @@ function readExternalRuntimeRequest(input) {
|
|
|
80253
80540
|
return raw.kind === "external" ? raw : undefined;
|
|
80254
80541
|
}
|
|
80255
80542
|
function sha25610(text) {
|
|
80256
|
-
return
|
|
80543
|
+
return createHash43("sha256").update(text).digest("hex");
|
|
80257
80544
|
}
|
|
80258
80545
|
var parentShellPolicy = shellParentProfile;
|
|
80259
80546
|
var childReadOnlyPolicy = shellChildReadOnlyProfile;
|
|
@@ -92740,6 +93027,9 @@ function promptApiKeyStep(otui, r, opts) {
|
|
|
92740
93027
|
const box = overlayBox(otui, r, "key-picker");
|
|
92741
93028
|
r.root.add(box);
|
|
92742
93029
|
box.add(new otui.TextRenderable(r, { id: "kp-title", content: otui.t`${otui.bold(`Paste your ${opts.label} API key`)} ${otui.dim("(Enter \xB7 Esc to go back)")}` }));
|
|
93030
|
+
if (opts.notice !== undefined) {
|
|
93031
|
+
box.add(new otui.TextRenderable(r, { id: "kp-notice", content: otui.t`${otui.red("\u2717")} ${opts.notice}`, marginTop: 1 }));
|
|
93032
|
+
}
|
|
92743
93033
|
box.add(new otui.TextRenderable(r, {
|
|
92744
93034
|
id: "kp-note",
|
|
92745
93035
|
content: otui.t`${otui.dim(`Set as ${opts.envKey} \xB7 saved to your keryx config dir (owner-only, 0600)`)}`,
|
|
@@ -92859,9 +93149,14 @@ function runDeviceLoginInTui(otui, r, provider) {
|
|
|
92859
93149
|
});
|
|
92860
93150
|
});
|
|
92861
93151
|
}
|
|
92862
|
-
async function modelsForPicker(prov) {
|
|
92863
|
-
|
|
92864
|
-
|
|
93152
|
+
async function modelsForPicker(prov, deps = {}) {
|
|
93153
|
+
return await resolveModelsForPicker(deps.fetch ?? globalThis.fetch, prov, deps.env ?? process.env);
|
|
93154
|
+
}
|
|
93155
|
+
function modelPickerNotice(label, result) {
|
|
93156
|
+
if (result.models.length > 0 || result.failure === undefined) {
|
|
93157
|
+
return;
|
|
93158
|
+
}
|
|
93159
|
+
return modelsFailureLine(label, result.failure);
|
|
92865
93160
|
}
|
|
92866
93161
|
function pickProviderStep(otui, r, detected) {
|
|
92867
93162
|
return new Promise((resolve) => {
|
|
@@ -92948,44 +93243,66 @@ function selectProviderModelInTui(otui, r, detected, options = {}) {
|
|
|
92948
93243
|
continue;
|
|
92949
93244
|
}
|
|
92950
93245
|
if (!options.onlyConnected && selectedBaseUrl !== undefined)
|
|
92951
|
-
saveProviderBaseUrl(prov.name, selectedBaseUrl);
|
|
93246
|
+
saveProviderBaseUrl(prov.name, selectedBaseUrl, options.configDir);
|
|
92952
93247
|
const selectedProvider = selectedBaseUrl === undefined ? prov : { ...prov, baseUrl: selectedBaseUrl };
|
|
92953
93248
|
const envKey = prov.envKey;
|
|
92954
|
-
|
|
92955
|
-
|
|
92956
|
-
|
|
92957
|
-
|
|
92958
|
-
|
|
92959
|
-
|
|
92960
|
-
|
|
92961
|
-
|
|
92962
|
-
|
|
92963
|
-
|
|
92964
|
-
if (offered.length > 1) {
|
|
92965
|
-
method = await pickAuthMethodStep(otui, r, prov.label ?? prov.name, offered);
|
|
92966
|
-
if (method === undefined) {
|
|
92967
|
-
continue;
|
|
92968
|
-
}
|
|
93249
|
+
const label = prov.label ?? prov.name;
|
|
93250
|
+
const collectCredential = async (notice) => {
|
|
93251
|
+
if (options.onlyConnected || envKey === undefined) {
|
|
93252
|
+
return "ok";
|
|
93253
|
+
}
|
|
93254
|
+
if (notice === undefined) {
|
|
93255
|
+
const existingKey = (options.env ?? process.env)[envKey];
|
|
93256
|
+
const hasOauth = oauthAccessToken(prov.name, options.configDir) !== undefined;
|
|
93257
|
+
if (existingKey !== undefined && existingKey.length > 0 || hasOauth) {
|
|
93258
|
+
return "ok";
|
|
92969
93259
|
}
|
|
92970
|
-
|
|
92971
|
-
|
|
92972
|
-
|
|
92973
|
-
|
|
92974
|
-
|
|
92975
|
-
|
|
92976
|
-
|
|
92977
|
-
|
|
92978
|
-
|
|
92979
|
-
|
|
92980
|
-
|
|
92981
|
-
process.env[envKey] = kr.value;
|
|
92982
|
-
saveApiKey(envKey, kr.value);
|
|
92983
|
-
}
|
|
93260
|
+
}
|
|
93261
|
+
const offered = [];
|
|
93262
|
+
if (catalogAllows(prov.name, "device-code"))
|
|
93263
|
+
offered.push("device-code");
|
|
93264
|
+
if (catalogMethods(prov.name).includes("api-key"))
|
|
93265
|
+
offered.push("api-key");
|
|
93266
|
+
let method = offered.length === 1 ? offered[0] : undefined;
|
|
93267
|
+
if (offered.length > 1) {
|
|
93268
|
+
method = await pickAuthMethodStep(otui, r, label, offered);
|
|
93269
|
+
if (method === undefined) {
|
|
93270
|
+
return "back";
|
|
92984
93271
|
}
|
|
92985
93272
|
}
|
|
93273
|
+
if (method === "device-code") {
|
|
93274
|
+
return await runDeviceLoginInTui(otui, r, prov.name) ? "ok" : "back";
|
|
93275
|
+
}
|
|
93276
|
+
const kr = await promptApiKeyStep(otui, r, {
|
|
93277
|
+
label,
|
|
93278
|
+
envKey,
|
|
93279
|
+
...notice === undefined ? {} : { notice }
|
|
93280
|
+
});
|
|
93281
|
+
if (kr.kind === "back") {
|
|
93282
|
+
return "back";
|
|
93283
|
+
}
|
|
93284
|
+
if (kr.kind === "key") {
|
|
93285
|
+
process.env[envKey] = kr.value;
|
|
93286
|
+
noteSavedCredentialEnv([envKey]);
|
|
93287
|
+
saveApiKey(envKey, kr.value, options.configDir);
|
|
93288
|
+
}
|
|
93289
|
+
return "ok";
|
|
93290
|
+
};
|
|
93291
|
+
if (await collectCredential() === "back") {
|
|
93292
|
+
continue;
|
|
93293
|
+
}
|
|
93294
|
+
const modelDeps = {
|
|
93295
|
+
...options.fetch === undefined ? {} : { fetch: options.fetch },
|
|
93296
|
+
...options.env === undefined ? {} : { env: options.env }
|
|
93297
|
+
};
|
|
93298
|
+
let models = await modelsForPicker(selectedProvider, modelDeps);
|
|
93299
|
+
if (models.failure?.kind === "rejected") {
|
|
93300
|
+
if (await collectCredential(modelsFailureLine(label, models.failure)) === "back") {
|
|
93301
|
+
continue;
|
|
93302
|
+
}
|
|
93303
|
+
models = await modelsForPicker(selectedProvider, modelDeps);
|
|
92986
93304
|
}
|
|
92987
|
-
const
|
|
92988
|
-
const model = await pickModelInTui(otui, r, models);
|
|
93305
|
+
const model = await pickModelInTui(otui, r, models.models, modelPickerNotice(label, models));
|
|
92989
93306
|
if (model === undefined) {
|
|
92990
93307
|
continue;
|
|
92991
93308
|
}
|
|
@@ -92999,13 +93316,16 @@ function adaptiveSelectHeight(count, available, per = 1) {
|
|
|
92999
93316
|
const min = Math.max(1, Math.floor(available / 4));
|
|
93000
93317
|
return Math.min(available, Math.max(min, count * per));
|
|
93001
93318
|
}
|
|
93002
|
-
function pickModelInTui(otui, r, models) {
|
|
93319
|
+
function pickModelInTui(otui, r, models, notice) {
|
|
93003
93320
|
return new Promise((resolve) => {
|
|
93004
93321
|
const all = models;
|
|
93005
|
-
const NO_MODELS = "(no models found)";
|
|
93322
|
+
const NO_MODELS = notice ?? "(no models found)";
|
|
93006
93323
|
const box = overlayBox(otui, r, "model-picker");
|
|
93007
93324
|
r.root.add(box);
|
|
93008
93325
|
box.add(new otui.TextRenderable(r, { id: "mp-title", content: otui.t`${otui.bold("Select a model")}` }));
|
|
93326
|
+
if (all.length === 0 && notice !== undefined) {
|
|
93327
|
+
box.add(new otui.TextRenderable(r, { id: "mp-notice", content: otui.t`${otui.red("\u2717")} ${notice}` }));
|
|
93328
|
+
}
|
|
93009
93329
|
const filterLine = new otui.TextRenderable(r, { id: "mp-filter", content: otui.t`${otui.dim("type to filter \xB7 \u2191/\u2193 Enter \xB7 Esc to go back")}` });
|
|
93010
93330
|
box.add(filterLine);
|
|
93011
93331
|
const NO_MATCH = "(no match)";
|
|
@@ -95101,8 +95421,9 @@ ${formatThemeList(getThemeId())}`);
|
|
|
95101
95421
|
(async () => {
|
|
95102
95422
|
const detected = opts.redetect !== undefined ? await opts.redetect() : opts.detected;
|
|
95103
95423
|
const prov = detected.find((d) => d.name === currentSel.provider);
|
|
95104
|
-
const models = prov !== undefined ? await modelsForPicker(prov) :
|
|
95105
|
-
const
|
|
95424
|
+
const models = prov !== undefined ? await modelsForPicker(prov) : undefined;
|
|
95425
|
+
const notice = prov === undefined || models === undefined ? undefined : modelPickerNotice(prov.label ?? prov.name, models);
|
|
95426
|
+
const chosen = await chrome.withOverlay(() => pickModelInTui(otui, r, models?.models ?? [], notice));
|
|
95106
95427
|
if (chosen !== undefined) {
|
|
95107
95428
|
await switchTo(currentSel.baseUrl === undefined ? { provider: currentSel.provider, model: chosen } : { provider: currentSel.provider, model: chosen, baseUrl: currentSel.baseUrl });
|
|
95108
95429
|
try {
|
|
@@ -95777,7 +96098,8 @@ async function launchTuiChatShell(opts) {
|
|
|
95777
96098
|
return await selectProviderModelInTui(otui, r, detected);
|
|
95778
96099
|
}
|
|
95779
96100
|
const prov = detected.find((d) => d.name === only);
|
|
95780
|
-
const
|
|
96101
|
+
const models = prov === undefined ? undefined : await modelsForPicker(prov);
|
|
96102
|
+
const chosen = await pickModelInTui(otui, r, models?.models ?? [], prov === undefined || models === undefined ? undefined : modelPickerNotice(prov.label ?? prov.name, models));
|
|
95781
96103
|
if (chosen === undefined) {
|
|
95782
96104
|
return;
|
|
95783
96105
|
}
|
|
@@ -96167,17 +96489,19 @@ function oauthCredentialsFor(name) {
|
|
|
96167
96489
|
}
|
|
96168
96490
|
function realSelectProviderModel(baseUrl) {
|
|
96169
96491
|
return async (io, opts) => {
|
|
96492
|
+
const env = envWithSavedApiKeys(process.env);
|
|
96170
96493
|
const detected = await detectProviders({
|
|
96171
96494
|
fetch: globalThis.fetch,
|
|
96172
|
-
env
|
|
96495
|
+
env,
|
|
96173
96496
|
platform: process.platform,
|
|
96174
96497
|
...baseUrl !== undefined ? { baseUrl } : {}
|
|
96175
96498
|
});
|
|
96176
96499
|
const filtered = opts?.onlyProvider !== undefined ? detected.filter((d) => d.name === opts.onlyProvider) : detected;
|
|
96177
96500
|
const list = filtered.length > 0 ? filtered : detected;
|
|
96178
|
-
return pickProviderModel(io, list, { fetch: globalThis.fetch, env
|
|
96501
|
+
return pickProviderModel(io, list, { fetch: globalThis.fetch, env });
|
|
96179
96502
|
};
|
|
96180
96503
|
}
|
|
96504
|
+
var GRANT_REFRESH_TIMEOUT_MS = 5000;
|
|
96181
96505
|
var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
96182
96506
|
var PROMPT_MARK = "\u276F ";
|
|
96183
96507
|
var GUTTER = " ";
|
|
@@ -97051,14 +97375,6 @@ ${GUTTER}${turnSeparator()}
|
|
|
97051
97375
|
}
|
|
97052
97376
|
async function resolveTuiStartup(opts) {
|
|
97053
97377
|
const savedCfg = loadShellConfig(opts.configDir);
|
|
97054
|
-
await Promise.resolve().then(() => init_login());
|
|
97055
|
-
const oauthFetch = (input, init) => globalThis.fetch(input, init);
|
|
97056
|
-
await refreshProviderGrant("grok", { fetch: oauthFetch }, opts.configDir).catch(() => {
|
|
97057
|
-
return;
|
|
97058
|
-
});
|
|
97059
|
-
await refreshProviderGrant("github-copilot", { fetch: oauthFetch }, opts.configDir).catch(() => {
|
|
97060
|
-
return;
|
|
97061
|
-
});
|
|
97062
97378
|
const appliedKeys = applySavedApiKeys(opts.configDir);
|
|
97063
97379
|
const { providerArg, modelArg, baseUrl } = opts;
|
|
97064
97380
|
if (providerArg !== undefined && modelArg !== undefined) {
|
|
@@ -97237,6 +97553,15 @@ Example: keryx shell --provider ollama --model llama3.1:latest`);
|
|
|
97237
97553
|
const modelArg = flags.modelArg;
|
|
97238
97554
|
let baseUrl = flags.baseUrl;
|
|
97239
97555
|
let modeFlag = flags.modeFlag;
|
|
97556
|
+
{
|
|
97557
|
+
await Promise.resolve().then(() => init_login());
|
|
97558
|
+
const oauthFetch = (input, init) => globalThis.fetch(input, init);
|
|
97559
|
+
const http = { fetch: oauthFetch, signal: AbortSignal.timeout(GRANT_REFRESH_TIMEOUT_MS) };
|
|
97560
|
+
const warnings = await refreshSavedGrants(http, runtime.cacheDir, providerArg === undefined ? undefined : [providerArg]);
|
|
97561
|
+
for (const warning of warnings)
|
|
97562
|
+
process.stderr.write(`keryx: ${warning}
|
|
97563
|
+
`);
|
|
97564
|
+
}
|
|
97240
97565
|
const surface = chooseShellSurface(flags, runtime.isTty ?? process.stdout.isTTY === true);
|
|
97241
97566
|
if (surface !== "readline") {
|
|
97242
97567
|
const cwd = process.cwd();
|
|
@@ -97862,7 +98187,7 @@ init_serve_config();
|
|
|
97862
98187
|
|
|
97863
98188
|
// src/lib/serve-credential.ts
|
|
97864
98189
|
init_config_dir();
|
|
97865
|
-
import { createHash as
|
|
98190
|
+
import { createHash as createHash44, randomBytes as randomBytes5, randomUUID as randomUUID30 } from "crypto";
|
|
97866
98191
|
import {
|
|
97867
98192
|
chmodSync as chmodSync4,
|
|
97868
98193
|
closeSync as closeSync3,
|
|
@@ -97889,10 +98214,10 @@ function constantTimeEqual(a, b) {
|
|
|
97889
98214
|
return difference === 0;
|
|
97890
98215
|
}
|
|
97891
98216
|
function hashToken(salt, token) {
|
|
97892
|
-
return
|
|
98217
|
+
return createHash44("sha256").update(Buffer.from(salt, "hex")).update(Buffer.from(token, "utf8")).digest("hex");
|
|
97893
98218
|
}
|
|
97894
98219
|
function credentialFingerprint(record) {
|
|
97895
|
-
return
|
|
98220
|
+
return createHash44("sha256").update(`keryx-serve-fingerprint:${record.hash}`).digest("hex").slice(0, 8);
|
|
97896
98221
|
}
|
|
97897
98222
|
function isValidRecord(value) {
|
|
97898
98223
|
if (typeof value !== "object" || value === null) {
|
|
@@ -98108,7 +98433,7 @@ class AuthFailureThrottle {
|
|
|
98108
98433
|
|
|
98109
98434
|
// src/lib/serve-turn-store.ts
|
|
98110
98435
|
init_config_dir();
|
|
98111
|
-
import { createHash as
|
|
98436
|
+
import { createHash as createHash45 } from "crypto";
|
|
98112
98437
|
import { existsSync as existsSync34, readdirSync as readdirSync3, rmSync as rmSync2 } from "fs";
|
|
98113
98438
|
import path193 from "path";
|
|
98114
98439
|
var MAX_TURN_EVENTS = 1e4;
|
|
@@ -98120,11 +98445,11 @@ function turnDir(turnId, dir) {
|
|
|
98120
98445
|
}
|
|
98121
98446
|
function keyPath(project, idempotencyKey, dir) {
|
|
98122
98447
|
const projectBytes = Buffer.byteLength(project, "utf8");
|
|
98123
|
-
const digest =
|
|
98448
|
+
const digest = createHash45("sha256").update(`${projectBytes}:${project}\x00${idempotencyKey}`, "utf8").digest("hex");
|
|
98124
98449
|
return path193.join(turnsRoot(dir), "keys", `${digest}.json`);
|
|
98125
98450
|
}
|
|
98126
98451
|
function legacyKeyPath(idempotencyKey, dir) {
|
|
98127
|
-
const digest =
|
|
98452
|
+
const digest = createHash45("sha256").update(idempotencyKey, "utf8").digest("hex");
|
|
98128
98453
|
return path193.join(turnsRoot(dir), "keys", `${digest}.json`);
|
|
98129
98454
|
}
|
|
98130
98455
|
function adoptLegacyClaim(project, idempotencyKey, dir) {
|
|
@@ -99480,6 +99805,12 @@ async function updateCommand(args = []) {
|
|
|
99480
99805
|
if (summary.modules.sac) {
|
|
99481
99806
|
statusLine("sac", true, "shared agent context: cross-session workspace propose/review (opt-in)");
|
|
99482
99807
|
}
|
|
99808
|
+
if (summary.gdskillsWarnings.length > 0) {
|
|
99809
|
+
heading("Warnings");
|
|
99810
|
+
for (const warning of summary.gdskillsWarnings) {
|
|
99811
|
+
note(warning);
|
|
99812
|
+
}
|
|
99813
|
+
}
|
|
99483
99814
|
const steps = [];
|
|
99484
99815
|
if (options.hooks) {
|
|
99485
99816
|
await runPostUpdateHooks(projectRoot);
|
|
@@ -99637,8 +99968,10 @@ async function refreshServiceFiles(projectRoot, options) {
|
|
|
99637
99968
|
await writeTextIfMissing4(path195.join(metaprojectRoot, "modules", "sac.md"), renderSacManifest());
|
|
99638
99969
|
await writeTextIfChanged4(path195.join(metaprojectRoot, "skills", "sac", "SKILL.md"), renderSacSkillReadme());
|
|
99639
99970
|
}
|
|
99971
|
+
let gdskillsWarnings = [];
|
|
99640
99972
|
if (enableGdskills) {
|
|
99641
|
-
await installGdskills(metaprojectRoot, gdskillsProfile, { createDataDirs: false });
|
|
99973
|
+
const gdskillsInstallResult = await installGdskills(metaprojectRoot, gdskillsProfile, { createDataDirs: false });
|
|
99974
|
+
gdskillsWarnings = gdskillsInstallResult.warnings;
|
|
99642
99975
|
if (manifest.modules?.gdskills?.hooks?.gitPostCommit) {
|
|
99643
99976
|
await installManagedHook2(projectRoot, "post-commit", "gdskills-post-commit", renderGdskillsPostCommitHook());
|
|
99644
99977
|
}
|
|
@@ -99738,6 +100071,7 @@ async function refreshServiceFiles(projectRoot, options) {
|
|
|
99738
100071
|
sac: enableSac
|
|
99739
100072
|
},
|
|
99740
100073
|
gdskillsProfile,
|
|
100074
|
+
gdskillsWarnings,
|
|
99741
100075
|
backfilledTasks: backfillTasks,
|
|
99742
100076
|
recoveredManifest
|
|
99743
100077
|
};
|