knodin 0.7.5 → 0.8.2
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/README.md +18 -3
- package/benchmarks/competitors/SYNTHESIS.md +66 -0
- package/dist/bin/cli.js +371 -66
- package/dist/bin/launcher.js +16 -1
- package/dist/src/agent-integration.js +82 -16
- package/dist/src/artifact-refresh.js +2 -1
- package/dist/src/cli-args.js +19 -1
- package/dist/src/cli-model.js +28 -2
- package/dist/src/codeflow-replay.js +2 -1
- package/dist/src/compare.js +39 -0
- package/dist/src/competitive-constraints.js +2 -1
- package/dist/src/competitive-runner.js +4 -4
- package/dist/src/context-export.js +3 -2
- package/dist/src/context.js +1 -1
- package/dist/src/deterministic-random.js +34 -0
- package/dist/src/diagnostics-write-helper.js +473 -0
- package/dist/src/diagnostics.js +1160 -133
- package/dist/src/doctor.js +3 -1
- package/dist/src/engine/ann-hnsw.js +2 -12
- package/dist/src/engine/file-walker.js +8 -2
- package/dist/src/engine/git-history.js +12 -12
- package/dist/src/engine/index.js +1174 -313
- package/dist/src/engine/sarif-import.js +341 -0
- package/dist/src/engine/scip-import.js +28 -13
- package/dist/src/engine/source-policy.js +16 -0
- package/dist/src/engine/state-paths.js +175 -0
- package/dist/src/execution-profile.js +15 -10
- package/dist/src/failure-diagnosis.js +7 -1
- package/dist/src/graph-layout.js +173 -0
- package/dist/src/index-activity.js +2 -1
- package/dist/src/init.js +86 -45
- package/dist/src/lifecycle-health.js +41 -9
- package/dist/src/mcp-graph-worker.js +69 -0
- package/dist/src/mcp-reliability.js +154 -0
- package/dist/src/mcp-worker-supervisor.js +350 -0
- package/dist/src/mirror.js +290 -0
- package/dist/src/node-runtime.js +157 -0
- package/dist/src/output-compression.js +2 -1
- package/dist/src/output-telemetry.js +16 -11
- package/dist/src/progressive-evidence.js +30 -26
- package/dist/src/pure-compression-cli.js +4 -3
- package/dist/src/relationship-adapters.js +15 -8
- package/dist/src/release-preflight.js +13 -10
- package/dist/src/repair-lease.js +85 -0
- package/dist/src/repository-init-process.js +13 -9
- package/dist/src/repository-management.js +34 -4
- package/dist/src/response-budget.js +8 -6
- package/dist/src/server.js +80 -35
- package/dist/src/structural-fast-path.js +16 -10
- package/dist/src/structural-snapshot.js +6 -2
- package/dist/src/system-config.js +25 -2
- package/dist/src/tools/knodin-tools.js +142 -31
- package/dist/src/update-ceremony.js +9 -5
- package/dist/src/update-trust.js +5 -4
- package/dist/src/visualization.js +372 -19
- package/dist/src/worktree-lifecycle.js +5 -2
- package/docs/BEHAVIORAL-CONTRACT.md +72 -0
- package/docs/CLI.md +20 -1
- package/docs/COMPARISON.md +403 -0
- package/docs/COMPETITIVE-LANDSCAPE-2026-08.md +267 -0
- package/docs/DIAGNOSTICS.md +46 -11
- package/docs/HANDOFF.md +180 -0
- package/docs/INSTALLATION.md +21 -2
- package/docs/MCP.md +59 -8
- package/docs/PT-ACCESS-RECOMMENDATION.md +5 -7
- package/docs/REPOSITORIES-AND-WORKTREES.md +18 -6
- package/docs/SCIP-IMPORT.md +5 -0
- package/docs/TOKEN-OPTIMIZER-SCORECARD.md +79 -0
- package/docs/releases/0.5.1.md +4 -4
- package/docs/releases/0.8.0.md +74 -0
- package/docs/releases/0.8.2.md +34 -0
- package/package.json +17 -4
- package/roadmap/competitive-roadmap.md +3801 -0
- package/schemas/release-attestation-v1.schema.json +1 -1
- package/schemas/support-bundle-v2.schema.json +212 -0
package/dist/src/doctor.js
CHANGED
|
@@ -168,7 +168,7 @@ function readAgentConfig(agent, file) {
|
|
|
168
168
|
};
|
|
169
169
|
}
|
|
170
170
|
const document = JSON.parse(content);
|
|
171
|
-
const registration = document.mcpServers?.knodin;
|
|
171
|
+
const registration = document.mcpServers?.knodin ?? document.servers?.knodin;
|
|
172
172
|
return {
|
|
173
173
|
agent,
|
|
174
174
|
file,
|
|
@@ -188,6 +188,7 @@ function configuredAgentCommands(repo) {
|
|
|
188
188
|
{ agent: "claude", file: ".mcp.json" },
|
|
189
189
|
{ agent: "codex", file: ".codex/config.toml" },
|
|
190
190
|
{ agent: "gemini", file: ".gemini/settings.json" },
|
|
191
|
+
{ agent: "copilot", file: ".vscode/mcp.json" },
|
|
191
192
|
{ agent: "antigravity", file: ".agents/mcp_config.json" },
|
|
192
193
|
];
|
|
193
194
|
return candidates.map(({ agent, file }) => readAgentConfig(agent, path.join(repo, file)));
|
|
@@ -197,6 +198,7 @@ function personalAgentCommands(homeDir) {
|
|
|
197
198
|
readAgentConfig("claude", path.join(homeDir, ".claude.json")),
|
|
198
199
|
readAgentConfig("codex", path.join(homeDir, ".codex", "config.toml")),
|
|
199
200
|
readAgentConfig("gemini", path.join(homeDir, ".gemini", "settings.json")),
|
|
201
|
+
readAgentConfig("copilot", path.join(homeDir, "Library", "Application Support", "Code", "User", "mcp.json")),
|
|
200
202
|
readAgentConfig("antigravity", path.join(homeDir, ".agents", "mcp_config.json")),
|
|
201
203
|
];
|
|
202
204
|
}
|
|
@@ -44,22 +44,12 @@
|
|
|
44
44
|
* degenerate "scan everything" implementation is observable at the integration
|
|
45
45
|
* layer (the gate test counts these calls and asserts real pruning).
|
|
46
46
|
*/
|
|
47
|
+
import { DEFAULT_PRNG_SEED, mulberry32 } from "../deterministic-random.js";
|
|
47
48
|
import * as embeddings from "./embeddings.js";
|
|
48
49
|
const DEFAULT_M = 16;
|
|
49
50
|
const DEFAULT_EF_CONSTRUCTION = 200;
|
|
50
51
|
const DEFAULT_EF_SEARCH = 200;
|
|
51
|
-
const DEFAULT_SEED =
|
|
52
|
-
/** Deterministic PRNG so index topology (and thus recall) is reproducible. */
|
|
53
|
-
function mulberry32(seed) {
|
|
54
|
-
let a = seed >>> 0;
|
|
55
|
-
return () => {
|
|
56
|
-
a |= 0;
|
|
57
|
-
a = (a + 0x6d2b79f5) | 0;
|
|
58
|
-
let t = Math.imul(a ^ (a >>> 15), 1 | a);
|
|
59
|
-
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
|
60
|
-
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
61
|
-
};
|
|
62
|
-
}
|
|
52
|
+
const DEFAULT_SEED = DEFAULT_PRNG_SEED;
|
|
63
53
|
class Hnsw {
|
|
64
54
|
nodes = [];
|
|
65
55
|
entryPoint = -1;
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { isIndexablePath } from "./prune.js";
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Byte-order path comparison. Deliberately NOT `localeCompare`: index order must
|
|
6
|
+
* be identical on every machine, and locale collation is not.
|
|
7
|
+
*/
|
|
8
|
+
export function comparePaths(left, right) {
|
|
9
|
+
if (left < right)
|
|
10
|
+
return -1;
|
|
11
|
+
return left > right ? 1 : 0;
|
|
6
12
|
}
|
|
7
13
|
/**
|
|
8
14
|
* Deterministically enumerate regular files beneath a repository without
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import childProcess from "node:child_process";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { compareBytes } from "../compare.js";
|
|
3
4
|
export const DEFAULT_GIT_HISTORY_BOUNDS = Object.freeze({
|
|
4
5
|
maxCommits: 250,
|
|
5
6
|
maxFiles: 25,
|
|
@@ -101,7 +102,7 @@ function parseLog(output) {
|
|
|
101
102
|
*/
|
|
102
103
|
export function collectGitHistorySignals(repoPath, filePaths, limits = {}) {
|
|
103
104
|
const bounds = resolveBounds(limits);
|
|
104
|
-
const requestedAll = [...new Set(filePaths.map(safeHistoryFile))].sort();
|
|
105
|
+
const requestedAll = [...new Set(filePaths.map(safeHistoryFile))].sort(compareBytes);
|
|
105
106
|
const requested = requestedAll.slice(0, bounds.maxFiles);
|
|
106
107
|
const omissions = [];
|
|
107
108
|
if (requestedAll.length > requested.length) {
|
|
@@ -133,13 +134,10 @@ export function collectGitHistorySignals(repoPath, filePaths, limits = {}) {
|
|
|
133
134
|
detail: "HEAD does not exist; no historical facts are available",
|
|
134
135
|
}, requested);
|
|
135
136
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
: reason === "timeout"
|
|
141
|
-
? "timeout"
|
|
142
|
-
: "unavailable";
|
|
137
|
+
// A recognised probe failure is reported verbatim; anything else degrades
|
|
138
|
+
// to the generic bucket rather than leaking an unmodelled reason string.
|
|
139
|
+
const recognised = ["git-unavailable", "not-a-repository", "timeout"];
|
|
140
|
+
const availability = recognised.find((known) => known === reason) ?? "unavailable";
|
|
143
141
|
return emptyResult(availability, bounds, commands, {
|
|
144
142
|
reason,
|
|
145
143
|
detail: "Git HEAD probe failed; history signals were omitted",
|
|
@@ -232,12 +230,14 @@ export function collectGitHistorySignals(repoPath, filePaths, limits = {}) {
|
|
|
232
230
|
file,
|
|
233
231
|
relatedFile,
|
|
234
232
|
sharedCommitCount: hashes.size,
|
|
235
|
-
commits: [...hashes].sort(),
|
|
233
|
+
commits: [...hashes].sort(compareBytes),
|
|
236
234
|
};
|
|
237
235
|
})
|
|
236
|
+
// Byte order: these tie-breaks decide which co-change facts survive the
|
|
237
|
+
// maxRelatedFiles slice below, not merely how the surviving ones read.
|
|
238
238
|
.sort((a, b) => b.sharedCommitCount - a.sharedCommitCount ||
|
|
239
|
-
a.file
|
|
240
|
-
a.relatedFile
|
|
239
|
+
compareBytes(a.file, b.file) ||
|
|
240
|
+
compareBytes(a.relatedFile, b.relatedFile));
|
|
241
241
|
const coChange = allCoChange.slice(0, bounds.maxRelatedFiles);
|
|
242
242
|
if (coChange.length < allCoChange.length) {
|
|
243
243
|
omissions.push({
|
|
@@ -246,7 +246,7 @@ export function collectGitHistorySignals(repoPath, filePaths, limits = {}) {
|
|
|
246
246
|
});
|
|
247
247
|
}
|
|
248
248
|
const churn = requested.map((file) => {
|
|
249
|
-
const hashes = [...(commitsByFile.get(file) ?? [])].sort();
|
|
249
|
+
const hashes = [...(commitsByFile.get(file) ?? [])].sort(compareBytes);
|
|
250
250
|
return { file, commitCount: hashes.length, commits: hashes };
|
|
251
251
|
});
|
|
252
252
|
const coupling = coChange.map((fact) => {
|