@kontextmind/kxm 0.7.43 → 0.7.44
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/CHANGELOG.md +4 -0
- 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/package.json +1 -1
- package/plugins/kxm/src/mcp-server.ts +1 -1
- package/scripts/kxm-hub.mjs +36 -0
package/CHANGELOG.md
CHANGED
|
@@ -38,6 +38,10 @@ All notable user-facing changes are documented here. The project follows [Semant
|
|
|
38
38
|
happens to share the product's version is left alone, and a workspace package
|
|
39
39
|
with no lock entry fails loudly instead of releasing half-bumped.
|
|
40
40
|
|
|
41
|
+
- **`kxm hub start` no longer generates and persists an admin token when it is
|
|
42
|
+
about to refuse** because another hub already owns the claim. A refused start
|
|
43
|
+
used to leave behind credentials the running hub never issued.
|
|
44
|
+
|
|
41
45
|
## 0.7.0 - 2026-09-11
|
|
42
46
|
|
|
43
47
|
### Added
|
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.44",
|
|
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",
|
|
@@ -17121,7 +17121,7 @@ async function deliverInboxNotification(messageId, delivered, notify) {
|
|
|
17121
17121
|
}
|
|
17122
17122
|
|
|
17123
17123
|
// plugins/kxm/src/mcp-server.ts
|
|
17124
|
-
var VERSION = "0.7.
|
|
17124
|
+
var VERSION = "0.7.44";
|
|
17125
17125
|
var inbox = /* @__PURE__ */ new Map();
|
|
17126
17126
|
var notifiedInbox = /* @__PURE__ */ new Set();
|
|
17127
17127
|
var meshClient;
|
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.44";
|
|
12
12
|
const inbox = new Map<string, MessageRecord>();
|
|
13
13
|
const notifiedInbox = new Set<string>();
|
|
14
14
|
let meshClient: HubClient | undefined;
|
package/scripts/kxm-hub.mjs
CHANGED
|
@@ -39,6 +39,29 @@ function processExists(pid) {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Live hub claim, if any. Read-only: returns the pid of a well-formed
|
|
44
|
+
* `hub.pid` claim whose wrapper is still alive, otherwise null.
|
|
45
|
+
*
|
|
46
|
+
* Claims that are missing, malformed, dead, or stale return null so the
|
|
47
|
+
* atomic `claimPidFile()` below keeps sole authority over those cases — it is
|
|
48
|
+
* the real single-instance guard and fails closed on them. This exists only so
|
|
49
|
+
* a start that is certainly going to be refused can refuse *before* it
|
|
50
|
+
* persists credentials.
|
|
51
|
+
*/
|
|
52
|
+
function liveHubClaimPid() {
|
|
53
|
+
let existing;
|
|
54
|
+
try {
|
|
55
|
+
existing = JSON.parse(readFileSync(pidPath, "utf8"));
|
|
56
|
+
} catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
if (existing?.version === 1 && existing.role === "hub" && Number.isInteger(existing.pid) && processExists(existing.pid)) {
|
|
60
|
+
return existing.pid;
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
|
|
42
65
|
function parseHubEnvFile() {
|
|
43
66
|
const file = join(resolveUserStateRoot(), "hub-env.json");
|
|
44
67
|
let raw;
|
|
@@ -122,6 +145,19 @@ function resolveCredentials() {
|
|
|
122
145
|
return { authToken, authTokenSource, projectTokens, projectTokensSource, file };
|
|
123
146
|
}
|
|
124
147
|
|
|
148
|
+
// Pre-flight: refuse a start that a live hub already owns before
|
|
149
|
+
// resolveCredentials() can generate and persist an admin token that the
|
|
150
|
+
// running hub never issued. `kxm hub start` used to mint the credential at
|
|
151
|
+
// module load and only then report "already managed by PID <n>", leaving a
|
|
152
|
+
// hub-env.json whose token no process trusts.
|
|
153
|
+
try {
|
|
154
|
+
const livePid = liveHubClaimPid();
|
|
155
|
+
if (livePid) {
|
|
156
|
+
process.stderr.write(`kxm hub: KXM hub is already managed by PID ${livePid}. Run kxm hub stop before starting another hub.\n`);
|
|
157
|
+
process.exit(1);
|
|
158
|
+
}
|
|
159
|
+
} catch { /* the atomic claim below still guards startup */ }
|
|
160
|
+
|
|
125
161
|
let credentials;
|
|
126
162
|
try {
|
|
127
163
|
credentials = resolveCredentials();
|