@kontextmind/kxm 0.7.76 → 0.7.77
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/.claude-plugin/marketplace.json +1 -1
- package/package.json +1 -1
- package/plugins/kxm/.claude-plugin/plugin.json +1 -1
- package/plugins/kxm/dist/mcp-server.js +1 -1
- package/plugins/kxm/dist/runtime-supervisor.js +18 -32
- package/plugins/kxm/dist/runtime.js +39 -53
- package/plugins/kxm/package.json +1 -1
- package/plugins/kxm/src/mcp-server.ts +1 -1
- package/plugins/kxm/src/runtime-supervisor.ts +6 -2
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
|
3
3
|
"name": "kxm",
|
|
4
4
|
"displayName": "KXM",
|
|
5
|
-
"version": "0.7.
|
|
5
|
+
"version": "0.7.77",
|
|
6
6
|
"description": "Headless multi-agent orchestration, durable workflows, and a live operator dashboard for Pi and Claude Code",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "KontextMind",
|
|
@@ -17182,7 +17182,7 @@ async function deliverInboxNotification(messageId, delivered, notify) {
|
|
|
17182
17182
|
}
|
|
17183
17183
|
|
|
17184
17184
|
// plugins/kxm/src/mcp-server.ts
|
|
17185
|
-
var VERSION = "0.7.
|
|
17185
|
+
var VERSION = "0.7.77";
|
|
17186
17186
|
var inbox = /* @__PURE__ */ new Map();
|
|
17187
17187
|
var notifiedInbox = /* @__PURE__ */ new Set();
|
|
17188
17188
|
var meshClient;
|
|
@@ -14781,9 +14781,9 @@ var require_dist = __commonJS({
|
|
|
14781
14781
|
// plugins/kxm/src/runtime-supervisor.ts
|
|
14782
14782
|
import { spawn as spawn3 } from "node:child_process";
|
|
14783
14783
|
import { createHash as createHash12, createHmac, randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
|
|
14784
|
-
import { chmodSync as chmodSync2, existsSync as existsSync12, lstatSync as lstatSync5, mkdirSync as mkdirSync6, readFileSync as
|
|
14784
|
+
import { chmodSync as chmodSync2, existsSync as existsSync12, lstatSync as lstatSync5, mkdirSync as mkdirSync6, readFileSync as readFileSync10, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync6 } from "node:fs";
|
|
14785
14785
|
import { createServer } from "node:http";
|
|
14786
|
-
import { dirname as dirname8, isAbsolute as isAbsolute6, join as
|
|
14786
|
+
import { dirname as dirname8, isAbsolute as isAbsolute6, join as join15 } from "node:path";
|
|
14787
14787
|
|
|
14788
14788
|
// plugins/kxm/src/repo-root.ts
|
|
14789
14789
|
import { existsSync } from "node:fs";
|
|
@@ -16919,8 +16919,8 @@ function validateWorkflow(workflow, agents, models, repositories, gates, issues)
|
|
|
16919
16919
|
const writable = Object.values(objectValue(step.repositories) ?? {}).filter((access) => access === "write").length;
|
|
16920
16920
|
if (maxWriteRepositories > writable) issues.push(issue2("semantic", "write_repository_bound_invalid", file, `${stepId} maxWriteRepositories exceeds writable repository scope`));
|
|
16921
16921
|
}
|
|
16922
|
-
const
|
|
16923
|
-
const minimumPassed =
|
|
16922
|
+
const join16 = objectValue(step.join);
|
|
16923
|
+
const minimumPassed = join16 && typeof join16.minimumPassed === "number" ? join16.minimumPassed : void 0;
|
|
16924
16924
|
if (minimumPassed !== void 0 && minimumPassed > maximum) issues.push(issue2("semantic", "join_impossible", file, `${stepId} minimumPassed exceeds assignment maximum`));
|
|
16925
16925
|
const distinctBy = names(assignment?.distinctBy);
|
|
16926
16926
|
if (distinctBy.length > 0) {
|
|
@@ -20987,7 +20987,7 @@ function compileStep(step, index, stepIndex, requirePlanHash, sink) {
|
|
|
20987
20987
|
const maxAttempts = compileCountField(step.maxAttempts, 1, `${id}.maxAttempts`, id, sink);
|
|
20988
20988
|
const timeoutMs = compileOptionalDuration(step.timeoutMs, `${id}.timeoutMs`, id, sink);
|
|
20989
20989
|
const assignments = compileAssignments(step, id, agent, sink);
|
|
20990
|
-
const
|
|
20990
|
+
const join16 = compileJoin(step, id, sink);
|
|
20991
20991
|
const requiredEvidence = compileEvidence(step, id, sink);
|
|
20992
20992
|
const transitions = compileTransitions(step, id, index, stepIndex, sink);
|
|
20993
20993
|
const outcomes = Object.keys(transitions).sort(compareCodeUnits4);
|
|
@@ -21015,7 +21015,7 @@ function compileStep(step, index, stepIndex, requirePlanHash, sink) {
|
|
|
21015
21015
|
transitions: orderedTransitions,
|
|
21016
21016
|
requiresPlanHash: requirePlanHash.includes(id),
|
|
21017
21017
|
assignments,
|
|
21018
|
-
join:
|
|
21018
|
+
join: join16
|
|
21019
21019
|
};
|
|
21020
21020
|
if (kind === "agent" || kind === "moa") {
|
|
21021
21021
|
if (!agent) return void 0;
|
|
@@ -21065,15 +21065,15 @@ function compileAssignments(step, stepId, primaryAgentId, sink) {
|
|
|
21065
21065
|
};
|
|
21066
21066
|
}
|
|
21067
21067
|
function compileJoin(step, stepId, sink) {
|
|
21068
|
-
const
|
|
21069
|
-
if (!
|
|
21070
|
-
const declared = stringValue2(
|
|
21068
|
+
const join16 = objectValue2(step.join);
|
|
21069
|
+
if (!join16) return { strategy: "all" };
|
|
21070
|
+
const declared = stringValue2(join16.strategy);
|
|
21071
21071
|
const strategy = declared && JOIN_STRATEGIES.has(declared) ? declared : "all";
|
|
21072
|
-
const minimumPassed = compileOptionalCount(
|
|
21072
|
+
const minimumPassed = compileOptionalCount(join16.minimumPassed, `${stepId}.join.minimumPassed`, stepId, sink);
|
|
21073
21073
|
const compiled = {
|
|
21074
21074
|
strategy,
|
|
21075
21075
|
...minimumPassed !== void 0 ? { minimumPassed } : {},
|
|
21076
|
-
...typeof
|
|
21076
|
+
...typeof join16.cancelRemaining === "boolean" ? { cancelRemaining: join16.cancelRemaining } : {}
|
|
21077
21077
|
};
|
|
21078
21078
|
return compiled;
|
|
21079
21079
|
}
|
|
@@ -27473,23 +27473,9 @@ function resolveClientHubAuthToken(env, project) {
|
|
|
27473
27473
|
return record2?.projectTokens?.[project]?.trim() || record2?.authToken?.trim() || void 0;
|
|
27474
27474
|
}
|
|
27475
27475
|
|
|
27476
|
-
// plugins/kxm/src/project-name.ts
|
|
27477
|
-
import { readFileSync as readFileSync10 } from "node:fs";
|
|
27478
|
-
import { basename as basename3, join as join15 } from "node:path";
|
|
27479
|
-
function defaultProjectName(cwd, env = process.env) {
|
|
27480
|
-
const fromEnv = env.KXM_PROJECT?.trim();
|
|
27481
|
-
if (fromEnv) return fromEnv;
|
|
27482
|
-
try {
|
|
27483
|
-
const pkg = JSON.parse(readFileSync10(join15(cwd, "package.json"), "utf8"));
|
|
27484
|
-
if (typeof pkg.name === "string" && pkg.name.trim().length > 0) return pkg.name.trim();
|
|
27485
|
-
} catch {
|
|
27486
|
-
}
|
|
27487
|
-
return basename3(cwd);
|
|
27488
|
-
}
|
|
27489
|
-
|
|
27490
27476
|
// plugins/kxm/src/runtime-supervisor.ts
|
|
27491
27477
|
function kxmSupervisorTokenFile(paths) {
|
|
27492
|
-
return
|
|
27478
|
+
return join15(paths.runtimeDir, "supervisor.token");
|
|
27493
27479
|
}
|
|
27494
27480
|
function publishKxmSupervisorToken(paths, token) {
|
|
27495
27481
|
const file = kxmSupervisorTokenFile(paths);
|
|
@@ -27517,7 +27503,7 @@ function readKxmSupervisorToken(paths) {
|
|
|
27517
27503
|
if (stat.isSymbolicLink() || !stat.isFile()) {
|
|
27518
27504
|
throw runtimeError("runtime_path_invalid", file, "supervisor token file must be a regular file, not a link");
|
|
27519
27505
|
}
|
|
27520
|
-
const token =
|
|
27506
|
+
const token = readFileSync10(file, "utf8").trim();
|
|
27521
27507
|
return token.length >= 32 ? token : void 0;
|
|
27522
27508
|
}
|
|
27523
27509
|
function processAlive(pid) {
|
|
@@ -27531,7 +27517,7 @@ function processAlive(pid) {
|
|
|
27531
27517
|
var HEARTBEAT_STALE_MS = 15e3;
|
|
27532
27518
|
var SUPERVISOR_ERROR_MAX_AGE_MS = 3e4;
|
|
27533
27519
|
function supervisorErrorFile(paths) {
|
|
27534
|
-
return
|
|
27520
|
+
return join15(paths.runtimeDir, "supervisor.error");
|
|
27535
27521
|
}
|
|
27536
27522
|
function clearSupervisorError(paths) {
|
|
27537
27523
|
const file = supervisorErrorFile(paths);
|
|
@@ -27552,7 +27538,7 @@ function readRecentSupervisorError(paths) {
|
|
|
27552
27538
|
const ageMs = Date.now() - stat.mtimeMs;
|
|
27553
27539
|
if (ageMs > SUPERVISOR_ERROR_MAX_AGE_MS) return void 0;
|
|
27554
27540
|
try {
|
|
27555
|
-
return
|
|
27541
|
+
return readFileSync10(file, "utf8").trim();
|
|
27556
27542
|
} catch {
|
|
27557
27543
|
return void 0;
|
|
27558
27544
|
}
|
|
@@ -27628,7 +27614,7 @@ async function ensureKxmSupervisor(options = {}) {
|
|
|
27628
27614
|
throw runtimeError("runtime_supervisor_unreachable", paths.registryDb, `runtime supervisor pid ${status.pid} is registered as running but cannot be probed`);
|
|
27629
27615
|
}
|
|
27630
27616
|
clearSupervisorError(paths);
|
|
27631
|
-
const scriptPath =
|
|
27617
|
+
const scriptPath = join15(findKxmRepoRoot(import.meta.url), "scripts", "kxm-runtime-supervisor.mjs");
|
|
27632
27618
|
const spawnImpl = options.spawnImpl ?? ((script, env) => {
|
|
27633
27619
|
const child = spawn3(process.execPath, [script], {
|
|
27634
27620
|
detached: true,
|
|
@@ -27783,7 +27769,7 @@ async function syncKxmOutbox(eventStore, client, options = {}) {
|
|
|
27783
27769
|
function runtimeHubClientFor(context, env) {
|
|
27784
27770
|
const serverUrl = env.KXM_SERVER_URL?.trim() || readHubBinding(env)?.url;
|
|
27785
27771
|
if (!serverUrl) return void 0;
|
|
27786
|
-
const project =
|
|
27772
|
+
const project = context.projectId;
|
|
27787
27773
|
const authToken = resolveClientHubAuthToken(env, project);
|
|
27788
27774
|
return new RuntimeHubClient({
|
|
27789
27775
|
serverUrl,
|
|
@@ -27815,7 +27801,7 @@ async function startKxmRuntimeSupervisorInner(paths, requestedPortOption, now) {
|
|
|
27815
27801
|
let activeRuntimeId = runtimeId;
|
|
27816
27802
|
const contexts = /* @__PURE__ */ new Map();
|
|
27817
27803
|
const registerSyncCredentials = (context) => {
|
|
27818
|
-
const hubToken = resolveClientHubAuthToken(process.env,
|
|
27804
|
+
const hubToken = resolveClientHubAuthToken(process.env, context.projectId);
|
|
27819
27805
|
if (hubToken) context.eventStore.syncRedactor.register(hubToken);
|
|
27820
27806
|
for (const key of Object.keys(process.env)) {
|
|
27821
27807
|
if (key.startsWith("KXM_") && (key.endsWith("_TOKEN") || key.endsWith("_KEY")) || key.endsWith("_API_KEY") || key.endsWith("_SECRET")) {
|
|
@@ -17089,8 +17089,8 @@ function validateWorkflow(workflow, agents, models, repositories, gates, issues)
|
|
|
17089
17089
|
const writable = Object.values(objectValue(step.repositories) ?? {}).filter((access) => access === "write").length;
|
|
17090
17090
|
if (maxWriteRepositories > writable) issues.push(issue2("semantic", "write_repository_bound_invalid", file, `${stepId} maxWriteRepositories exceeds writable repository scope`));
|
|
17091
17091
|
}
|
|
17092
|
-
const
|
|
17093
|
-
const minimumPassed =
|
|
17092
|
+
const join20 = objectValue(step.join);
|
|
17093
|
+
const minimumPassed = join20 && typeof join20.minimumPassed === "number" ? join20.minimumPassed : void 0;
|
|
17094
17094
|
if (minimumPassed !== void 0 && minimumPassed > maximum) issues.push(issue2("semantic", "join_impossible", file, `${stepId} minimumPassed exceeds assignment maximum`));
|
|
17095
17095
|
const distinctBy = names(assignment?.distinctBy);
|
|
17096
17096
|
if (distinctBy.length > 0) {
|
|
@@ -21422,7 +21422,7 @@ function compileStep(step, index, stepIndex, requirePlanHash, sink) {
|
|
|
21422
21422
|
const maxAttempts = compileCountField(step.maxAttempts, 1, `${id}.maxAttempts`, id, sink);
|
|
21423
21423
|
const timeoutMs = compileOptionalDuration(step.timeoutMs, `${id}.timeoutMs`, id, sink);
|
|
21424
21424
|
const assignments = compileAssignments(step, id, agent, sink);
|
|
21425
|
-
const
|
|
21425
|
+
const join20 = compileJoin(step, id, sink);
|
|
21426
21426
|
const requiredEvidence = compileEvidence(step, id, sink);
|
|
21427
21427
|
const transitions = compileTransitions(step, id, index, stepIndex, sink);
|
|
21428
21428
|
const outcomes = Object.keys(transitions).sort(compareCodeUnits4);
|
|
@@ -21450,7 +21450,7 @@ function compileStep(step, index, stepIndex, requirePlanHash, sink) {
|
|
|
21450
21450
|
transitions: orderedTransitions,
|
|
21451
21451
|
requiresPlanHash: requirePlanHash.includes(id),
|
|
21452
21452
|
assignments,
|
|
21453
|
-
join:
|
|
21453
|
+
join: join20
|
|
21454
21454
|
};
|
|
21455
21455
|
if (kind === "agent" || kind === "moa") {
|
|
21456
21456
|
if (!agent) return void 0;
|
|
@@ -21500,15 +21500,15 @@ function compileAssignments(step, stepId, primaryAgentId, sink) {
|
|
|
21500
21500
|
};
|
|
21501
21501
|
}
|
|
21502
21502
|
function compileJoin(step, stepId, sink) {
|
|
21503
|
-
const
|
|
21504
|
-
if (!
|
|
21505
|
-
const declared = stringValue2(
|
|
21503
|
+
const join20 = objectValue2(step.join);
|
|
21504
|
+
if (!join20) return { strategy: "all" };
|
|
21505
|
+
const declared = stringValue2(join20.strategy);
|
|
21506
21506
|
const strategy = declared && JOIN_STRATEGIES.has(declared) ? declared : "all";
|
|
21507
|
-
const minimumPassed = compileOptionalCount(
|
|
21507
|
+
const minimumPassed = compileOptionalCount(join20.minimumPassed, `${stepId}.join.minimumPassed`, stepId, sink);
|
|
21508
21508
|
const compiled = {
|
|
21509
21509
|
strategy,
|
|
21510
21510
|
...minimumPassed !== void 0 ? { minimumPassed } : {},
|
|
21511
|
-
...typeof
|
|
21511
|
+
...typeof join20.cancelRemaining === "boolean" ? { cancelRemaining: join20.cancelRemaining } : {}
|
|
21512
21512
|
};
|
|
21513
21513
|
return compiled;
|
|
21514
21514
|
}
|
|
@@ -23356,9 +23356,9 @@ function assertKxmConfigError(error) {
|
|
|
23356
23356
|
// plugins/kxm/src/runtime-supervisor.ts
|
|
23357
23357
|
import { spawn as spawn3 } from "node:child_process";
|
|
23358
23358
|
import { createHash as createHash13, createHmac, randomBytes as randomBytes3, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
|
|
23359
|
-
import { chmodSync as chmodSync2, existsSync as existsSync12, lstatSync as lstatSync5, mkdirSync as mkdirSync6, readFileSync as
|
|
23359
|
+
import { chmodSync as chmodSync2, existsSync as existsSync12, lstatSync as lstatSync5, mkdirSync as mkdirSync6, readFileSync as readFileSync10, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync6 } from "node:fs";
|
|
23360
23360
|
import { createServer } from "node:http";
|
|
23361
|
-
import { dirname as dirname8, isAbsolute as isAbsolute6, join as
|
|
23361
|
+
import { dirname as dirname8, isAbsolute as isAbsolute6, join as join15 } from "node:path";
|
|
23362
23362
|
|
|
23363
23363
|
// plugins/kxm/src/oneshot-producer.ts
|
|
23364
23364
|
import { join as join12 } from "node:path";
|
|
@@ -27988,23 +27988,9 @@ function resolveClientHubAuthToken(env, project) {
|
|
|
27988
27988
|
return record2?.projectTokens?.[project]?.trim() || record2?.authToken?.trim() || void 0;
|
|
27989
27989
|
}
|
|
27990
27990
|
|
|
27991
|
-
// plugins/kxm/src/project-name.ts
|
|
27992
|
-
import { readFileSync as readFileSync10 } from "node:fs";
|
|
27993
|
-
import { basename as basename3, join as join15 } from "node:path";
|
|
27994
|
-
function defaultProjectName(cwd, env = process.env) {
|
|
27995
|
-
const fromEnv = env.KXM_PROJECT?.trim();
|
|
27996
|
-
if (fromEnv) return fromEnv;
|
|
27997
|
-
try {
|
|
27998
|
-
const pkg = JSON.parse(readFileSync10(join15(cwd, "package.json"), "utf8"));
|
|
27999
|
-
if (typeof pkg.name === "string" && pkg.name.trim().length > 0) return pkg.name.trim();
|
|
28000
|
-
} catch {
|
|
28001
|
-
}
|
|
28002
|
-
return basename3(cwd);
|
|
28003
|
-
}
|
|
28004
|
-
|
|
28005
27991
|
// plugins/kxm/src/runtime-supervisor.ts
|
|
28006
27992
|
function kxmSupervisorTokenFile(paths) {
|
|
28007
|
-
return
|
|
27993
|
+
return join15(paths.runtimeDir, "supervisor.token");
|
|
28008
27994
|
}
|
|
28009
27995
|
function publishKxmSupervisorToken(paths, token) {
|
|
28010
27996
|
const file = kxmSupervisorTokenFile(paths);
|
|
@@ -28032,7 +28018,7 @@ function readKxmSupervisorToken(paths) {
|
|
|
28032
28018
|
if (stat.isSymbolicLink() || !stat.isFile()) {
|
|
28033
28019
|
throw runtimeError("runtime_path_invalid", file, "supervisor token file must be a regular file, not a link");
|
|
28034
28020
|
}
|
|
28035
|
-
const token =
|
|
28021
|
+
const token = readFileSync10(file, "utf8").trim();
|
|
28036
28022
|
return token.length >= 32 ? token : void 0;
|
|
28037
28023
|
}
|
|
28038
28024
|
function processAlive(pid) {
|
|
@@ -28046,7 +28032,7 @@ function processAlive(pid) {
|
|
|
28046
28032
|
var HEARTBEAT_STALE_MS = 15e3;
|
|
28047
28033
|
var SUPERVISOR_ERROR_MAX_AGE_MS = 3e4;
|
|
28048
28034
|
function supervisorErrorFile(paths) {
|
|
28049
|
-
return
|
|
28035
|
+
return join15(paths.runtimeDir, "supervisor.error");
|
|
28050
28036
|
}
|
|
28051
28037
|
function clearSupervisorError(paths) {
|
|
28052
28038
|
const file = supervisorErrorFile(paths);
|
|
@@ -28067,7 +28053,7 @@ function readRecentSupervisorError(paths) {
|
|
|
28067
28053
|
const ageMs = Date.now() - stat.mtimeMs;
|
|
28068
28054
|
if (ageMs > SUPERVISOR_ERROR_MAX_AGE_MS) return void 0;
|
|
28069
28055
|
try {
|
|
28070
|
-
return
|
|
28056
|
+
return readFileSync10(file, "utf8").trim();
|
|
28071
28057
|
} catch {
|
|
28072
28058
|
return void 0;
|
|
28073
28059
|
}
|
|
@@ -28143,7 +28129,7 @@ async function ensureKxmSupervisor(options = {}) {
|
|
|
28143
28129
|
throw runtimeError("runtime_supervisor_unreachable", paths.registryDb, `runtime supervisor pid ${status.pid} is registered as running but cannot be probed`);
|
|
28144
28130
|
}
|
|
28145
28131
|
clearSupervisorError(paths);
|
|
28146
|
-
const scriptPath =
|
|
28132
|
+
const scriptPath = join15(findKxmRepoRoot(import.meta.url), "scripts", "kxm-runtime-supervisor.mjs");
|
|
28147
28133
|
const spawnImpl = options.spawnImpl ?? ((script, env) => {
|
|
28148
28134
|
const child = spawn3(process.execPath, [script], {
|
|
28149
28135
|
detached: true,
|
|
@@ -28298,7 +28284,7 @@ async function syncKxmOutbox(eventStore, client, options = {}) {
|
|
|
28298
28284
|
function runtimeHubClientFor(context, env) {
|
|
28299
28285
|
const serverUrl = env.KXM_SERVER_URL?.trim() || readHubBinding(env)?.url;
|
|
28300
28286
|
if (!serverUrl) return void 0;
|
|
28301
|
-
const project =
|
|
28287
|
+
const project = context.projectId;
|
|
28302
28288
|
const authToken = resolveClientHubAuthToken(env, project);
|
|
28303
28289
|
return new RuntimeHubClient({
|
|
28304
28290
|
serverUrl,
|
|
@@ -28330,7 +28316,7 @@ async function startKxmRuntimeSupervisorInner(paths, requestedPortOption, now) {
|
|
|
28330
28316
|
let activeRuntimeId = runtimeId;
|
|
28331
28317
|
const contexts = /* @__PURE__ */ new Map();
|
|
28332
28318
|
const registerSyncCredentials = (context) => {
|
|
28333
|
-
const hubToken = resolveClientHubAuthToken(process.env,
|
|
28319
|
+
const hubToken = resolveClientHubAuthToken(process.env, context.projectId);
|
|
28334
28320
|
if (hubToken) context.eventStore.syncRedactor.register(hubToken);
|
|
28335
28321
|
for (const key of Object.keys(process.env)) {
|
|
28336
28322
|
if (key.startsWith("KXM_") && (key.endsWith("_TOKEN") || key.endsWith("_KEY")) || key.endsWith("_API_KEY") || key.endsWith("_SECRET")) {
|
|
@@ -28774,7 +28760,7 @@ async function kxmRuntimeRequest(handle, method, path, body) {
|
|
|
28774
28760
|
|
|
28775
28761
|
// plugins/kxm/src/pi-producer.ts
|
|
28776
28762
|
import { spawn as spawn4 } from "node:child_process";
|
|
28777
|
-
import { join as
|
|
28763
|
+
import { join as join16 } from "node:path";
|
|
28778
28764
|
import { StringDecoder } from "node:string_decoder";
|
|
28779
28765
|
function formatPiSessionKey(params) {
|
|
28780
28766
|
if (params.agentId === "coordinator") {
|
|
@@ -29148,7 +29134,7 @@ function createKxmPiProducer(options = {}) {
|
|
|
29148
29134
|
const args = ["--mode", "rpc", "--name", displayName];
|
|
29149
29135
|
if (options.sessionDir) {
|
|
29150
29136
|
const safeDirName = key.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
29151
|
-
args.push("--session-dir",
|
|
29137
|
+
args.push("--session-dir", join16(options.sessionDir, request.runId, safeDirName));
|
|
29152
29138
|
}
|
|
29153
29139
|
if (model) {
|
|
29154
29140
|
args.push("--model", model);
|
|
@@ -29427,7 +29413,7 @@ function createLogger(options) {
|
|
|
29427
29413
|
// plugins/kxm/src/improve.ts
|
|
29428
29414
|
import { createHash as createHash14 } from "node:crypto";
|
|
29429
29415
|
import { existsSync as existsSync14, mkdirSync as mkdirSync8, writeFileSync as writeFileSync7 } from "node:fs";
|
|
29430
|
-
import { join as
|
|
29416
|
+
import { join as join17, relative as relative4, resolve as resolve8 } from "node:path";
|
|
29431
29417
|
var CANDIDATE_SCHEMA = "kxm.candidate.v1";
|
|
29432
29418
|
var IMPROVEMENT_REPORT_SCHEMA = "kxm.improvement-report.v2";
|
|
29433
29419
|
var IMPROVEMENT_REPORT_V1_SCHEMA = "kxm.improvement-report.v1";
|
|
@@ -29600,7 +29586,7 @@ function groupRoutingRecords(records, options = {}) {
|
|
|
29600
29586
|
}
|
|
29601
29587
|
function buildImprovementReport(records, options = {}) {
|
|
29602
29588
|
const projectRoot = options.projectRoot ? resolve8(options.projectRoot) : process.cwd();
|
|
29603
|
-
const candidatesDir = options.candidatesDir ? resolve8(options.candidatesDir) :
|
|
29589
|
+
const candidatesDir = options.candidatesDir ? resolve8(options.candidatesDir) : join17(projectRoot, ".kxm", "candidates");
|
|
29604
29590
|
const groups = groupRoutingRecords(records, options);
|
|
29605
29591
|
const candidates = [];
|
|
29606
29592
|
for (const group of groups) {
|
|
@@ -29612,7 +29598,7 @@ function buildImprovementReport(records, options = {}) {
|
|
|
29612
29598
|
group.workflowHash
|
|
29613
29599
|
);
|
|
29614
29600
|
const diffFileName = `${group.candidateId}.diff`;
|
|
29615
|
-
const diffFilePath =
|
|
29601
|
+
const diffFilePath = join17(candidatesDir, diffFileName);
|
|
29616
29602
|
const relDiffPath = relative4(projectRoot, diffFilePath).replace(/\\/g, "/");
|
|
29617
29603
|
const candidate = {
|
|
29618
29604
|
schema: CANDIDATE_SCHEMA,
|
|
@@ -29638,7 +29624,7 @@ function buildImprovementReport(records, options = {}) {
|
|
|
29638
29624
|
mkdirSync8(candidatesDir, { recursive: true });
|
|
29639
29625
|
}
|
|
29640
29626
|
writeFileSync7(diffFilePath, diff, "utf8");
|
|
29641
|
-
const jsonFilePath =
|
|
29627
|
+
const jsonFilePath = join17(candidatesDir, `${group.candidateId}.json`);
|
|
29642
29628
|
writeFileSync7(jsonFilePath, JSON.stringify(candidate, null, 2) + "\n", "utf8");
|
|
29643
29629
|
}
|
|
29644
29630
|
candidates.push(candidate);
|
|
@@ -29654,7 +29640,7 @@ function buildImprovementReport(records, options = {}) {
|
|
|
29654
29640
|
}
|
|
29655
29641
|
function writeImprovementReport(improvementsDir, report, dryRun = false) {
|
|
29656
29642
|
const stamp = report.createdAt.replace(/[:.]/g, "-");
|
|
29657
|
-
const path =
|
|
29643
|
+
const path = join17(improvementsDir, `${stamp}.json`);
|
|
29658
29644
|
if (!dryRun) {
|
|
29659
29645
|
mkdirSync8(improvementsDir, { recursive: true });
|
|
29660
29646
|
writeFileSync7(path, `${JSON.stringify(report, null, 2)}
|
|
@@ -30158,8 +30144,8 @@ Instructions for Operator:
|
|
|
30158
30144
|
|
|
30159
30145
|
// plugins/kxm/src/modes.ts
|
|
30160
30146
|
var import_yaml6 = __toESM(require_dist(), 1);
|
|
30161
|
-
import { existsSync as existsSync15, readFileSync as
|
|
30162
|
-
import { join as
|
|
30147
|
+
import { existsSync as existsSync15, readFileSync as readFileSync12 } from "node:fs";
|
|
30148
|
+
import { join as join18 } from "node:path";
|
|
30163
30149
|
var DEFAULT_MODES_CONFIG = Object.freeze({
|
|
30164
30150
|
schema: "kxm.modes.v1",
|
|
30165
30151
|
majorModes: {
|
|
@@ -30222,12 +30208,12 @@ function loadModesConfig(projectRoot) {
|
|
|
30222
30208
|
if (!projectRoot) {
|
|
30223
30209
|
return DEFAULT_MODES_CONFIG;
|
|
30224
30210
|
}
|
|
30225
|
-
const modesPath =
|
|
30211
|
+
const modesPath = join18(projectRoot, ".kxm", "modes.yaml");
|
|
30226
30212
|
if (!existsSync15(modesPath)) {
|
|
30227
30213
|
return DEFAULT_MODES_CONFIG;
|
|
30228
30214
|
}
|
|
30229
30215
|
try {
|
|
30230
|
-
const raw =
|
|
30216
|
+
const raw = readFileSync12(modesPath, "utf8");
|
|
30231
30217
|
const parsed = (0, import_yaml6.parse)(raw);
|
|
30232
30218
|
if (parsed && parsed.schema === "kxm.modes.v1" && parsed.majorModes) {
|
|
30233
30219
|
return {
|
|
@@ -30313,11 +30299,11 @@ function calculatePromptFootprint(resolved, projectRoot = process.cwd(), catalog
|
|
|
30313
30299
|
estimatedTokens: estimateTokens(baseSystemPromptChars)
|
|
30314
30300
|
});
|
|
30315
30301
|
for (const relPath of resolved.contextFiles) {
|
|
30316
|
-
const fullPath =
|
|
30302
|
+
const fullPath = join18(projectRoot, relPath);
|
|
30317
30303
|
let chars = 0;
|
|
30318
30304
|
if (existsSync15(fullPath)) {
|
|
30319
30305
|
try {
|
|
30320
|
-
chars =
|
|
30306
|
+
chars = readFileSync12(fullPath, "utf8").length;
|
|
30321
30307
|
} catch {
|
|
30322
30308
|
chars = 0;
|
|
30323
30309
|
}
|
|
@@ -30449,9 +30435,9 @@ ${divider}
|
|
|
30449
30435
|
|
|
30450
30436
|
// plugins/kxm/src/ssh-remote.ts
|
|
30451
30437
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
30452
|
-
import { existsSync as existsSync16, mkdirSync as mkdirSync9, readFileSync as
|
|
30438
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync9, readFileSync as readFileSync13, readdirSync as readdirSync5, rmSync as rmSync4, statSync as statSync4 } from "node:fs";
|
|
30453
30439
|
import { homedir as homedir4 } from "node:os";
|
|
30454
|
-
import { join as
|
|
30440
|
+
import { join as join19, resolve as resolve9 } from "node:path";
|
|
30455
30441
|
var MAX_SSH_OUTPUT_BYTES = 50 * 1024;
|
|
30456
30442
|
var MAX_SSH_OUTPUT_LINES = 2e3;
|
|
30457
30443
|
var DEFAULT_SOCKET_DIR = ".kxm/run/ssh-sockets";
|
|
@@ -30477,12 +30463,12 @@ function truncateSshOutput(raw) {
|
|
|
30477
30463
|
return { text, truncated };
|
|
30478
30464
|
}
|
|
30479
30465
|
function parseSshConfig(configPath) {
|
|
30480
|
-
const targetPath = configPath ??
|
|
30466
|
+
const targetPath = configPath ?? join19(homedir4(), ".ssh", "config");
|
|
30481
30467
|
if (!existsSync16(targetPath)) {
|
|
30482
30468
|
return [];
|
|
30483
30469
|
}
|
|
30484
30470
|
try {
|
|
30485
|
-
const content =
|
|
30471
|
+
const content = readFileSync13(targetPath, "utf-8");
|
|
30486
30472
|
const lines = content.split("\n");
|
|
30487
30473
|
const hosts = [];
|
|
30488
30474
|
let currentHosts = [];
|
|
@@ -30567,7 +30553,7 @@ function ensureSocketDir(socketDir = DEFAULT_SOCKET_DIR) {
|
|
|
30567
30553
|
}
|
|
30568
30554
|
function buildSshArgs(options) {
|
|
30569
30555
|
const socketDir = ensureSocketDir(options.socketDir ?? DEFAULT_SOCKET_DIR);
|
|
30570
|
-
const controlPath =
|
|
30556
|
+
const controlPath = join19(socketDir, "%C");
|
|
30571
30557
|
const persist2 = options.controlPersist ?? DEFAULT_CONTROL_PERSIST;
|
|
30572
30558
|
const args = [
|
|
30573
30559
|
"-o",
|
|
@@ -30592,7 +30578,7 @@ function buildSshArgs(options) {
|
|
|
30592
30578
|
}
|
|
30593
30579
|
function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync3) {
|
|
30594
30580
|
const resolvedDir = ensureSocketDir(socketDir);
|
|
30595
|
-
const controlPath =
|
|
30581
|
+
const controlPath = join19(resolvedDir, "%C");
|
|
30596
30582
|
try {
|
|
30597
30583
|
const result = execFn("ssh", ["-O", "check", "-o", `ControlPath=${controlPath}`, host], {
|
|
30598
30584
|
encoding: "utf-8"
|
|
@@ -30604,7 +30590,7 @@ function checkControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawn
|
|
|
30604
30590
|
}
|
|
30605
30591
|
function closeControlSocket(host, socketDir = DEFAULT_SOCKET_DIR, execFn = spawnSync3) {
|
|
30606
30592
|
const resolvedDir = ensureSocketDir(socketDir);
|
|
30607
|
-
const controlPath =
|
|
30593
|
+
const controlPath = join19(resolvedDir, "%C");
|
|
30608
30594
|
try {
|
|
30609
30595
|
const result = execFn("ssh", ["-O", "stop", "-o", `ControlPath=${controlPath}`, host], {
|
|
30610
30596
|
encoding: "utf-8"
|
|
@@ -30620,7 +30606,7 @@ function pruneSocketDir(socketDir = DEFAULT_SOCKET_DIR) {
|
|
|
30620
30606
|
try {
|
|
30621
30607
|
const entries = readdirSync5(resolvedDir);
|
|
30622
30608
|
for (const entry of entries) {
|
|
30623
|
-
const fullPath =
|
|
30609
|
+
const fullPath = join19(resolvedDir, entry);
|
|
30624
30610
|
try {
|
|
30625
30611
|
const stat = statSync4(fullPath);
|
|
30626
30612
|
if (stat.isSocket()) {
|
package/plugins/kxm/package.json
CHANGED
|
@@ -8,7 +8,7 @@ import { AGENT_COMMANDS_MAP, enforceToolPolicy, getMcpTools, reconcileInbox } fr
|
|
|
8
8
|
import { deliverInboxNotification } from "./inbox.ts";
|
|
9
9
|
import type { HubEvent, MessageRecord } from "./protocol.ts";
|
|
10
10
|
|
|
11
|
-
const VERSION = "0.7.
|
|
11
|
+
const VERSION = "0.7.77";
|
|
12
12
|
const inbox = new Map<string, MessageRecord>();
|
|
13
13
|
const notifiedInbox = new Set<string>();
|
|
14
14
|
let meshClient: HubClient | undefined;
|
|
@@ -436,7 +436,11 @@ export async function syncKxmOutbox(
|
|
|
436
436
|
function runtimeHubClientFor(context: KxmRuntimeContext, env: NodeJS.ProcessEnv): RuntimeHubClient | undefined {
|
|
437
437
|
const serverUrl = env.KXM_SERVER_URL?.trim() || readHubBinding(env)?.url;
|
|
438
438
|
if (!serverUrl) return undefined;
|
|
439
|
-
|
|
439
|
+
// Use the context's actual projectId — the same identity sync events carry — so the
|
|
440
|
+
// ops snapshot can join runs to their home Runtime. defaultProjectName() resolves to
|
|
441
|
+
// the npm package name (e.g. "@kontextmind/kxm"), which never matches project.yaml's
|
|
442
|
+
// prj_* id, leaving presence orphaned from the runs it owns.
|
|
443
|
+
const project = context.projectId;
|
|
440
444
|
const authToken = resolveClientHubAuthToken(env, project);
|
|
441
445
|
return new RuntimeHubClient({
|
|
442
446
|
serverUrl,
|
|
@@ -495,7 +499,7 @@ async function startKxmRuntimeSupervisorInner(
|
|
|
495
499
|
// BEFORE any event can be appended — so the very first outbox row is
|
|
496
500
|
// already scrubbed. Registering on the sync tick leaves a window where
|
|
497
501
|
// appended events retain credentials.
|
|
498
|
-
const hubToken = resolveClientHubAuthToken(process.env,
|
|
502
|
+
const hubToken = resolveClientHubAuthToken(process.env, context.projectId);
|
|
499
503
|
if (hubToken) context.eventStore.syncRedactor.register(hubToken);
|
|
500
504
|
for (const key of Object.keys(process.env)) {
|
|
501
505
|
if ((key.startsWith("KXM_") && (key.endsWith("_TOKEN") || key.endsWith("_KEY"))) || key.endsWith("_API_KEY") || key.endsWith("_SECRET")) {
|