@kontextmind/kxm 0.7.38 → 0.7.40
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/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.40",
|
|
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.40";
|
|
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.40";
|
|
12
12
|
const inbox = new Map<string, MessageRecord>();
|
|
13
13
|
const notifiedInbox = new Set<string>();
|
|
14
14
|
let meshClient: HubClient | undefined;
|
|
@@ -97,9 +97,11 @@ export function validateRosterDocument(policy, readBlob) {
|
|
|
97
97
|
text(model, 'origin model'); keys(origin, ['vendor', 'evidence'], 'origin');
|
|
98
98
|
text(origin.vendor, 'origin vendor');
|
|
99
99
|
if (PI_ALLOWED_PROVIDERS.includes(canonical(origin.vendor.toLowerCase()))) refuse('origin/vendor must name the model vendor, not billing provider');
|
|
100
|
-
|
|
100
|
+
const evidenceKeys = origin.evidence.commit === undefined ? ['source', 'sha256'] : ['source', 'commit', 'sha256'];
|
|
101
|
+
keys(origin.evidence, evidenceKeys, 'origin evidence'); digest(origin.evidence.sha256);
|
|
101
102
|
sourcePath(origin.evidence.source);
|
|
102
|
-
|
|
103
|
+
if (origin.evidence.commit !== undefined) objectId(origin.evidence.commit, 'origin evidence commit');
|
|
104
|
+
const bytes = readBlob(origin.evidence.source, origin.evidence.commit);
|
|
103
105
|
if (bytes == null || sha256(bytes) !== origin.evidence.sha256) refuse('origin evidence hash mismatch');
|
|
104
106
|
}
|
|
105
107
|
for (const [id, route] of Object.entries(policy.routes)) {
|
|
@@ -160,17 +162,24 @@ export function validateRosterDocument(policy, readBlob) {
|
|
|
160
162
|
}
|
|
161
163
|
return policy;
|
|
162
164
|
}
|
|
163
|
-
function validate(bytes, commit) {
|
|
165
|
+
function validate(bytes, commit, trusted) {
|
|
164
166
|
let policy;
|
|
165
167
|
try { policy = YAML.parse(bytes.toString('utf8')); } catch { refuse('invalid policy YAML'); }
|
|
166
168
|
if (policy === undefined || policy === null || typeof policy !== 'object' || Array.isArray(policy)) refuse('invalid policy YAML');
|
|
167
|
-
|
|
169
|
+
const readBlob = (source, pinnedCommit) => {
|
|
170
|
+
if (pinnedCommit === undefined) return blobAt(commit, source).bytes;
|
|
171
|
+
// A pinned evidence commit decouples the digest from later edits to the
|
|
172
|
+
// evidence file; the pinned commit itself must be part of trusted history.
|
|
173
|
+
git('merge-base', '--is-ancestor', pinnedCommit, trusted);
|
|
174
|
+
return blobAt(pinnedCommit, source).bytes;
|
|
175
|
+
};
|
|
176
|
+
return validateRosterDocument(policy, readBlob);
|
|
168
177
|
}
|
|
169
178
|
export function loadTrustedRosterPolicy() {
|
|
170
179
|
const snapshot = control();
|
|
171
180
|
const { blob, bytes } = blobAt(snapshot.head, POLICY);
|
|
172
181
|
if (!workingBytes(POLICY).equals(bytes)) refuse('working policy differs from committed bytes');
|
|
173
|
-
const policy = validate(bytes, snapshot.head);
|
|
182
|
+
const policy = validate(bytes, snapshot.head, snapshot.trusted);
|
|
174
183
|
unchanged(snapshot);
|
|
175
184
|
return frozen({ identity: { commit: snapshot.head, blob, sha256: sha256(bytes) }, policy });
|
|
176
185
|
}
|
|
@@ -181,7 +190,7 @@ export function resolveBoundPolicy(identity) {
|
|
|
181
190
|
git('merge-base', '--is-ancestor', identity.commit, snapshot.trusted);
|
|
182
191
|
const { blob, bytes } = blobAt(identity.commit, POLICY);
|
|
183
192
|
if (blob !== identity.blob || sha256(bytes) !== identity.sha256) refuse('bound identity mismatch');
|
|
184
|
-
const policy = validate(bytes, identity.commit);
|
|
193
|
+
const policy = validate(bytes, identity.commit, snapshot.trusted);
|
|
185
194
|
unchanged(snapshot);
|
|
186
195
|
return frozen({ identity: { ...identity }, policy });
|
|
187
196
|
}
|