@kontextmind/kxm 0.7.91 → 0.7.93
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/.kxm/workflows/default.yaml +1 -1
- package/CHANGELOG.md +212 -0
- package/README.md +3 -0
- package/docs/README.md +3 -0
- package/docs/agent-skills.md +123 -60
- package/docs/architecture.md +5 -2
- package/docs/cli-reference.md +3527 -0
- package/docs/config-reference.md +1943 -0
- package/docs/configuration.md +30 -4
- package/docs/continuous-improvement.md +122 -10
- package/docs/contracts/routing.md +95 -11
- package/docs/harness-routing.md +616 -0
- package/docs/kxm-handbook.md +106 -19
- package/docs/templates/README.md +1 -1
- package/docs/test-matrix.md +12 -6
- package/docs/troubleshooting.md +2 -2
- package/examples/project/.kxm/workflows/fix.yaml +1 -1
- package/examples/project/.kxm/workflows/improve.yaml +1 -1
- package/package.json +1 -1
- package/plugins/kxm/.claude-plugin/plugin.json +9 -10
- package/plugins/kxm/README.md +238 -56
- package/plugins/kxm/dist/claude-hook.js +10083 -0
- package/plugins/kxm/dist/cli.js +2487 -1848
- package/plugins/kxm/dist/client.js +64 -0
- package/plugins/kxm/dist/core.js +102 -9
- package/plugins/kxm/dist/extension.js +210 -68
- package/plugins/kxm/dist/mcp-server.js +217 -40
- package/plugins/kxm/dist/runtime-supervisor.js +1628 -157
- package/plugins/kxm/dist/runtime.js +1874 -298
- package/plugins/kxm/dist/server.js +416 -82
- package/plugins/kxm/package.json +1 -1
- package/plugins/kxm/skills/hints.json +1 -1
- package/plugins/kxm/skills/kxm/SKILL.md +48 -24
- package/plugins/kxm/skills/kxm/references/protocol.md +3 -3
- package/plugins/kxm/skills/kxm-context-memory/SKILL.md +67 -21
- package/plugins/kxm/skills/kxm-definitions/SKILL.md +9 -0
- package/plugins/kxm/skills/kxm-harness-auth/SKILL.md +82 -16
- package/plugins/kxm/skills/kxm-harvest/SKILL.md +1 -1
- package/plugins/kxm/skills/kxm-hub-ops/SKILL.md +55 -27
- package/plugins/kxm/skills/kxm-insights/SKILL.md +1 -1
- package/plugins/kxm/skills/kxm-mind/SKILL.md +2 -2
- package/plugins/kxm/skills/{kxm-setup → kxm-mind-setup}/SKILL.md +4 -4
- package/plugins/kxm/skills/kxm-peer/SKILL.md +68 -93
- package/plugins/kxm/skills/kxm-project-setup/SKILL.md +156 -23
- package/plugins/kxm/skills/kxm-projects/SKILL.md +1 -1
- package/plugins/kxm/skills/kxm-protocol/SKILL.md +1 -1
- package/plugins/kxm/skills/kxm-query/SKILL.md +1 -1
- package/plugins/kxm/skills/kxm-routing-improve/SKILL.md +74 -15
- package/plugins/kxm/skills/kxm-runs/SKILL.md +46 -17
- package/plugins/kxm/skills/kxm-session/SKILL.md +64 -36
- package/plugins/kxm/skills/kxm-skill-lifecycle/SKILL.md +44 -15
- package/plugins/kxm/skills/kxm-tasks/SKILL.md +16 -4
- package/plugins/kxm/skills/kxm-triage/SKILL.md +1 -1
- package/plugins/kxm/skills/kxm-work/SKILL.md +1 -1
- package/plugins/kxm/skills/kxm-workflow/SKILL.md +60 -19
- package/plugins/kxm/src/arbiter.ts +67 -22
- package/plugins/kxm/src/autocomplete.ts +1 -1
- package/plugins/kxm/src/claude-hook.ts +192 -0
- package/plugins/kxm/src/cli/project.ts +11 -5
- package/plugins/kxm/src/cli/system.ts +85 -13
- package/plugins/kxm/src/cli/types.ts +4 -1
- package/plugins/kxm/src/cli/workflows.ts +18 -16
- package/plugins/kxm/src/cli.ts +23 -13
- package/plugins/kxm/src/client.ts +15 -4
- package/plugins/kxm/src/commands.ts +19 -9
- package/plugins/kxm/src/config.ts +42 -7
- package/plugins/kxm/src/context-packet.ts +14 -2
- package/plugins/kxm/src/context.ts +16 -5
- package/plugins/kxm/src/dispatch-context.ts +286 -0
- package/plugins/kxm/src/engine-plan.ts +40 -0
- package/plugins/kxm/src/engine.ts +138 -6
- package/plugins/kxm/src/hub-env.ts +17 -1
- package/plugins/kxm/src/hub.ts +92 -29
- package/plugins/kxm/src/improve-sources.ts +228 -0
- package/plugins/kxm/src/improve.ts +325 -140
- package/plugins/kxm/src/local-snapshot.ts +101 -42
- package/plugins/kxm/src/mcp-server.ts +129 -30
- package/plugins/kxm/src/memory.ts +43 -20
- package/plugins/kxm/src/project-config.ts +25 -0
- package/plugins/kxm/src/protocol.ts +11 -0
- package/plugins/kxm/src/relevance.ts +138 -0
- package/plugins/kxm/src/retrospective.ts +16 -10
- package/plugins/kxm/src/runtime-service.ts +8 -1
- package/plugins/kxm/src/runtime-supervisor.ts +16 -2
- package/plugins/kxm/src/session-token-hint.ts +17 -0
- package/plugins/kxm/src/suggest.ts +7 -7
- package/plugins/kxm/src/workflow-manager.ts +80 -78
- package/plugins/kxm/src/workflow.ts +202 -12
- package/scripts/build-runtime.mjs +7 -1
- package/scripts/check-generated.mjs +1 -0
- package/scripts/emit-codex-artifacts.mjs +1 -1
|
@@ -7187,6 +7187,10 @@ var require_dist = __commonJS({
|
|
|
7187
7187
|
}
|
|
7188
7188
|
});
|
|
7189
7189
|
|
|
7190
|
+
// plugins/kxm/src/mcp-server.ts
|
|
7191
|
+
import { statSync } from "node:fs";
|
|
7192
|
+
import { join as join4 } from "node:path";
|
|
7193
|
+
|
|
7190
7194
|
// node_modules/zod/v4/core/core.js
|
|
7191
7195
|
var _a;
|
|
7192
7196
|
// @__NO_SIDE_EFFECTS__
|
|
@@ -15765,8 +15769,93 @@ var MAX_BODY_BYTES = 256 * 1024;
|
|
|
15765
15769
|
var MAX_AGENT_HOST_CHARS = 64;
|
|
15766
15770
|
var MAX_LEASE_TTL_MS = 10 * 6e4;
|
|
15767
15771
|
var DEFAULT_LEASE_TTL_MS = 5 * 6e4;
|
|
15772
|
+
var IMPROVEMENT_AREAS = [
|
|
15773
|
+
"harness",
|
|
15774
|
+
"gates",
|
|
15775
|
+
"implementation",
|
|
15776
|
+
"workflow",
|
|
15777
|
+
"documentation",
|
|
15778
|
+
"security",
|
|
15779
|
+
"other"
|
|
15780
|
+
];
|
|
15781
|
+
|
|
15782
|
+
// plugins/kxm/src/relevance.ts
|
|
15783
|
+
var RELEVANCE_STOPWORDS = Object.freeze(/* @__PURE__ */ new Set([
|
|
15784
|
+
"a",
|
|
15785
|
+
"an",
|
|
15786
|
+
"and",
|
|
15787
|
+
"are",
|
|
15788
|
+
"as",
|
|
15789
|
+
"at",
|
|
15790
|
+
"be",
|
|
15791
|
+
"been",
|
|
15792
|
+
"but",
|
|
15793
|
+
"by",
|
|
15794
|
+
"can",
|
|
15795
|
+
"could",
|
|
15796
|
+
"did",
|
|
15797
|
+
"do",
|
|
15798
|
+
"does",
|
|
15799
|
+
"for",
|
|
15800
|
+
"from",
|
|
15801
|
+
"had",
|
|
15802
|
+
"has",
|
|
15803
|
+
"have",
|
|
15804
|
+
"how",
|
|
15805
|
+
"if",
|
|
15806
|
+
"in",
|
|
15807
|
+
"into",
|
|
15808
|
+
"is",
|
|
15809
|
+
"it",
|
|
15810
|
+
"its",
|
|
15811
|
+
"of",
|
|
15812
|
+
"on",
|
|
15813
|
+
"or",
|
|
15814
|
+
"our",
|
|
15815
|
+
"should",
|
|
15816
|
+
"so",
|
|
15817
|
+
"than",
|
|
15818
|
+
"that",
|
|
15819
|
+
"the",
|
|
15820
|
+
"their",
|
|
15821
|
+
"them",
|
|
15822
|
+
"then",
|
|
15823
|
+
"there",
|
|
15824
|
+
"these",
|
|
15825
|
+
"they",
|
|
15826
|
+
"this",
|
|
15827
|
+
"those",
|
|
15828
|
+
"to",
|
|
15829
|
+
"was",
|
|
15830
|
+
"we",
|
|
15831
|
+
"were",
|
|
15832
|
+
"what",
|
|
15833
|
+
"when",
|
|
15834
|
+
"where",
|
|
15835
|
+
"which",
|
|
15836
|
+
"while",
|
|
15837
|
+
"who",
|
|
15838
|
+
"why",
|
|
15839
|
+
"will",
|
|
15840
|
+
"with",
|
|
15841
|
+
"would",
|
|
15842
|
+
"you",
|
|
15843
|
+
"your"
|
|
15844
|
+
]));
|
|
15768
15845
|
|
|
15769
15846
|
// plugins/kxm/src/workflow.ts
|
|
15847
|
+
var JOURNAL_CATEGORIES = [
|
|
15848
|
+
"plan",
|
|
15849
|
+
"decision",
|
|
15850
|
+
"contradiction",
|
|
15851
|
+
"error",
|
|
15852
|
+
"lesson",
|
|
15853
|
+
"observation",
|
|
15854
|
+
"hypothesis",
|
|
15855
|
+
"experiment",
|
|
15856
|
+
"state-change",
|
|
15857
|
+
"skill-candidate"
|
|
15858
|
+
];
|
|
15770
15859
|
function canonicalWorkflowEvidenceKey(value) {
|
|
15771
15860
|
return value.trim().replace(/\s+/gu, " ").toLowerCase();
|
|
15772
15861
|
}
|
|
@@ -16283,11 +16372,12 @@ function readHubEnvRecord(env = process.env) {
|
|
|
16283
16372
|
...record2.projectTokens !== void 0 ? { projectTokens: record2.projectTokens } : {}
|
|
16284
16373
|
};
|
|
16285
16374
|
}
|
|
16286
|
-
function
|
|
16375
|
+
function resolveAgentHubAuthToken(env, project) {
|
|
16287
16376
|
const envToken = env.KXM_AUTH_TOKEN?.trim();
|
|
16288
16377
|
if (envToken) return envToken;
|
|
16289
|
-
const
|
|
16290
|
-
|
|
16378
|
+
const tokens = readHubEnvRecord(env)?.projectTokens;
|
|
16379
|
+
if (!tokens || !Object.hasOwn(tokens, project)) return void 0;
|
|
16380
|
+
return tokens[project]?.trim() || void 0;
|
|
16291
16381
|
}
|
|
16292
16382
|
|
|
16293
16383
|
// plugins/kxm/src/project-name.ts
|
|
@@ -16655,7 +16745,7 @@ var AGENT_COMMANDS = [
|
|
|
16655
16745
|
group: "workflow",
|
|
16656
16746
|
verb: "run",
|
|
16657
16747
|
label: "Get workflow run",
|
|
16658
|
-
description: "Get a workflow's stages and journal
|
|
16748
|
+
description: "Get a workflow's stages and its learning journal (plans, decisions, contradictions, errors, lessons, and the other journal categories).",
|
|
16659
16749
|
parameters: {
|
|
16660
16750
|
type: "object",
|
|
16661
16751
|
properties: {
|
|
@@ -16729,20 +16819,24 @@ var AGENT_COMMANDS = [
|
|
|
16729
16819
|
group: "workflow",
|
|
16730
16820
|
verb: "record",
|
|
16731
16821
|
label: "Record workflow journal entry",
|
|
16732
|
-
description: "Record a plan, decision, contradiction, error, or
|
|
16822
|
+
description: "Record a plan, decision, contradiction, error, lesson, observation, hypothesis, experiment, state-change, or skill-candidate for continuous improvement. Pass stageId to bind the entry to that stage: the hub derives the attempt, and area defaults to the stage's declared area. Lessons and skill-candidates require evidence.",
|
|
16733
16823
|
parameters: {
|
|
16734
16824
|
type: "object",
|
|
16735
16825
|
properties: {
|
|
16736
16826
|
runId: { type: "string", description: "Active durable workflow run ID" },
|
|
16737
16827
|
category: {
|
|
16738
16828
|
type: "string",
|
|
16739
|
-
enum: [
|
|
16829
|
+
enum: [...JOURNAL_CATEGORIES],
|
|
16740
16830
|
description: "Category of journal entry"
|
|
16741
16831
|
},
|
|
16742
16832
|
area: {
|
|
16743
16833
|
type: "string",
|
|
16744
|
-
enum: [
|
|
16745
|
-
description: "System area"
|
|
16834
|
+
enum: [...IMPROVEMENT_AREAS],
|
|
16835
|
+
description: "System area; required unless stageId names a stage that declares an area"
|
|
16836
|
+
},
|
|
16837
|
+
stageId: {
|
|
16838
|
+
type: "string",
|
|
16839
|
+
description: "Stage the entry belongs to; the hub binds the attempt from the stage's state"
|
|
16746
16840
|
},
|
|
16747
16841
|
severity: {
|
|
16748
16842
|
type: "string",
|
|
@@ -16765,13 +16859,14 @@ var AGENT_COMMANDS = [
|
|
|
16765
16859
|
description: "Related previous journal entry IDs"
|
|
16766
16860
|
}
|
|
16767
16861
|
},
|
|
16768
|
-
required: ["runId", "category", "
|
|
16862
|
+
required: ["runId", "category", "summary"],
|
|
16769
16863
|
additionalProperties: false
|
|
16770
16864
|
},
|
|
16771
16865
|
async execute(client, args) {
|
|
16772
16866
|
return await client.recordWorkflowEntry(requiredString(args.runId, "runId"), {
|
|
16773
16867
|
category: requiredString(args.category, "category"),
|
|
16774
|
-
area:
|
|
16868
|
+
...optionalString(args.area) ? { area: optionalString(args.area) } : {},
|
|
16869
|
+
...optionalString(args.stageId) ? { stageId: optionalString(args.stageId) } : {},
|
|
16775
16870
|
...optionalString(args.severity) ? { severity: optionalString(args.severity) } : {},
|
|
16776
16871
|
summary: requiredString(args.summary, "summary"),
|
|
16777
16872
|
...optionalString(args.details) ? { details: optionalString(args.details) } : {},
|
|
@@ -16848,7 +16943,7 @@ var AGENT_COMMANDS = [
|
|
|
16848
16943
|
group: "workflow",
|
|
16849
16944
|
verb: "improve-report",
|
|
16850
16945
|
label: "Summarize improvement report",
|
|
16851
|
-
description: "Summarize workflow errors, contradictions, and
|
|
16946
|
+
description: "Summarize workflow errors, contradictions, lessons, and skill candidates by improvement area, plus ranked cross-run signals: duplicates merged across runs and scored by frequency x severity x run-attempt cost x evidence confidence, security first, with redacted text.",
|
|
16852
16947
|
parameters: {
|
|
16853
16948
|
type: "object",
|
|
16854
16949
|
properties: {},
|
|
@@ -16902,7 +16997,7 @@ var AGENT_COMMANDS = [
|
|
|
16902
16997
|
group: "context",
|
|
16903
16998
|
verb: "recall",
|
|
16904
16999
|
label: "Recall context metadata",
|
|
16905
|
-
description: "Search durable context records for a project by query; returns bounded metadata
|
|
17000
|
+
description: "Search durable context records for a project by query. Ranks exact-phrase matches first, then token relevance, then id; returns bounded metadata with a numeric relevance per item, never summaries.",
|
|
16906
17001
|
parameters: {
|
|
16907
17002
|
type: "object",
|
|
16908
17003
|
properties: {
|
|
@@ -17181,8 +17276,17 @@ async function deliverInboxNotification(messageId, delivered, notify) {
|
|
|
17181
17276
|
return true;
|
|
17182
17277
|
}
|
|
17183
17278
|
|
|
17279
|
+
// plugins/kxm/src/session-token-hint.ts
|
|
17280
|
+
var ENV_TEXT = "KXM_SESSION_TOKEN in the environment Claude Code was launched from is malformed or expired, so every kxm_* tool fails with tool_policy_denied. Ask the user to unset or replace KXM_SESSION_TOKEN in the environment Claude Code was launched from, then restart Claude Code.";
|
|
17281
|
+
var DISK_TEXT = "The KXM session token file on this machine is expired, malformed or unreadable, so every kxm_* tool fails with tool_policy_denied. Ask the user to run `kxm session token --clear` in their own terminal. `kxm session token --status` reports No active session token found for an expired file even though the file still blocks tools. The kxm plugin no longer refreshes that 24-hour token.";
|
|
17282
|
+
function sessionTokenFixHint(policy) {
|
|
17283
|
+
if (policy.error !== "session_token_invalid") return void 0;
|
|
17284
|
+
return policy.detail?.startsWith("KXM_SESSION_TOKEN") ? ENV_TEXT : DISK_TEXT;
|
|
17285
|
+
}
|
|
17286
|
+
|
|
17184
17287
|
// plugins/kxm/src/mcp-server.ts
|
|
17185
|
-
var VERSION = "0.7.
|
|
17288
|
+
var VERSION = "0.7.93";
|
|
17289
|
+
var CONFIGURE_PLUGIN = "/plugin configure kxm@kxm";
|
|
17186
17290
|
var inbox = /* @__PURE__ */ new Map();
|
|
17187
17291
|
var notifiedInbox = /* @__PURE__ */ new Set();
|
|
17188
17292
|
var meshClient;
|
|
@@ -17195,11 +17299,11 @@ var mcp = new Server(
|
|
|
17195
17299
|
tools: {}
|
|
17196
17300
|
},
|
|
17197
17301
|
instructions: [
|
|
17198
|
-
'
|
|
17199
|
-
"
|
|
17200
|
-
"
|
|
17201
|
-
"
|
|
17202
|
-
"If
|
|
17302
|
+
'Peer requests arrive as <channel source="kxm" message_id="..."> events, or in kxm_inbox; handle each under normal safety rules, then call kxm_reply with message_id and the final response.',
|
|
17303
|
+
"For workflow requests, call kxm_workflow_get, record material knowledge with kxm_workflow_record in its ten categories (plan, decision, contradiction, error, lesson, observation, hypothesis, experiment, state-change, skill-candidate), pass the stageId each entry belongs to, and pass every checkpoint before replying.",
|
|
17304
|
+
"For external work, call kxm_workflow_wait, then kxm_reply; a signed callback resumes the run.",
|
|
17305
|
+
"In a KXM project, call kxm_context with your role and task before planning.",
|
|
17306
|
+
"If a KXM tool reports a problem with the hub or token, continue without KXM and tell the user the next step it names."
|
|
17203
17307
|
].join(" ")
|
|
17204
17308
|
}
|
|
17205
17309
|
);
|
|
@@ -17209,6 +17313,14 @@ function textResult(value) {
|
|
|
17209
17313
|
function asRecord2(value) {
|
|
17210
17314
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
17211
17315
|
}
|
|
17316
|
+
function sessionIdentity() {
|
|
17317
|
+
const projectDir = process.env.KXM_PROJECT_DIR || process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
17318
|
+
return {
|
|
17319
|
+
projectDir,
|
|
17320
|
+
project: defaultProjectName(projectDir, process.env),
|
|
17321
|
+
serverUrl: process.env.KXM_SERVER_URL?.trim() || "http://127.0.0.1:7331"
|
|
17322
|
+
};
|
|
17323
|
+
}
|
|
17212
17324
|
async function onHubEvent(event) {
|
|
17213
17325
|
if (event.type === "cancelled" || event.type === "expired") {
|
|
17214
17326
|
inbox.delete(event.message.id);
|
|
@@ -17242,28 +17354,44 @@ async function onHubEvent(event) {
|
|
|
17242
17354
|
});
|
|
17243
17355
|
});
|
|
17244
17356
|
}
|
|
17357
|
+
async function startClient(project, serverUrl, name, authToken) {
|
|
17358
|
+
const candidate = new HubClient({
|
|
17359
|
+
serverUrl,
|
|
17360
|
+
name,
|
|
17361
|
+
purpose: process.env.KXM_AGENT_PURPOSE?.trim() || "Claude Code implementation and review agent",
|
|
17362
|
+
project,
|
|
17363
|
+
model: "claude-code",
|
|
17364
|
+
authToken
|
|
17365
|
+
});
|
|
17366
|
+
try {
|
|
17367
|
+
await candidate.start(onHubEvent);
|
|
17368
|
+
meshClient = candidate;
|
|
17369
|
+
return candidate;
|
|
17370
|
+
} catch (error2) {
|
|
17371
|
+
await candidate.stop();
|
|
17372
|
+
throw error2;
|
|
17373
|
+
}
|
|
17374
|
+
}
|
|
17245
17375
|
async function ensureClient() {
|
|
17246
17376
|
if (meshClient?.agent) return meshClient;
|
|
17247
17377
|
if (starting) return starting;
|
|
17248
17378
|
starting = (async () => {
|
|
17249
|
-
const
|
|
17250
|
-
const
|
|
17251
|
-
|
|
17252
|
-
|
|
17253
|
-
|
|
17254
|
-
|
|
17255
|
-
|
|
17256
|
-
|
|
17257
|
-
model: "claude-code",
|
|
17258
|
-
...authToken ? { authToken } : {}
|
|
17259
|
-
});
|
|
17379
|
+
const { project, serverUrl } = sessionIdentity();
|
|
17380
|
+
const authToken = resolveAgentHubAuthToken(process.env, project);
|
|
17381
|
+
if (!authToken) {
|
|
17382
|
+
throw new Error(
|
|
17383
|
+
`KXM has no project token for project ${project} on this machine. Ask the user to set the kxm plugin auth_token (${CONFIGURE_PLUGIN}) or to add ${project} to the hub KXM_PROJECT_TOKENS, listing every existing project too because that variable replaces the saved map.`
|
|
17384
|
+
);
|
|
17385
|
+
}
|
|
17386
|
+
const name = process.env.KXM_AGENT_NAME?.trim() || `claude-${process.pid}`;
|
|
17260
17387
|
try {
|
|
17261
|
-
await
|
|
17262
|
-
meshClient = candidate;
|
|
17263
|
-
return candidate;
|
|
17388
|
+
return await startClient(project, serverUrl, name, authToken);
|
|
17264
17389
|
} catch (error2) {
|
|
17265
|
-
|
|
17266
|
-
|
|
17390
|
+
if (!(error2 instanceof HubHttpError && error2.code === "duplicate_agent_name")) throw error2;
|
|
17391
|
+
const substitute = `${name}-${process.pid}`;
|
|
17392
|
+
process.stderr.write(`kxm: agent name ${name} is already active in project ${project}; this session registers as ${substitute}
|
|
17393
|
+
`);
|
|
17394
|
+
return await startClient(project, serverUrl, substitute, authToken);
|
|
17267
17395
|
}
|
|
17268
17396
|
})();
|
|
17269
17397
|
try {
|
|
@@ -17272,15 +17400,45 @@ async function ensureClient() {
|
|
|
17272
17400
|
starting = void 0;
|
|
17273
17401
|
}
|
|
17274
17402
|
}
|
|
17403
|
+
function unreachableCause(error2) {
|
|
17404
|
+
if (!(error2 instanceof Error)) return void 0;
|
|
17405
|
+
if (error2.message.startsWith("request timed out after")) return error2.message;
|
|
17406
|
+
const cause = error2.cause;
|
|
17407
|
+
const causeCode = cause && typeof cause === "object" ? cause.code : void 0;
|
|
17408
|
+
if (error2.message === "fetch failed") {
|
|
17409
|
+
if (typeof causeCode === "string") return causeCode;
|
|
17410
|
+
return cause instanceof Error && cause.message ? cause.message : error2.message;
|
|
17411
|
+
}
|
|
17412
|
+
if (error2.code === "ECONNREFUSED" || error2.message.includes("ECONNREFUSED")) return "ECONNREFUSED";
|
|
17413
|
+
return void 0;
|
|
17414
|
+
}
|
|
17415
|
+
async function connectedClient() {
|
|
17416
|
+
try {
|
|
17417
|
+
return await ensureClient();
|
|
17418
|
+
} catch (error2) {
|
|
17419
|
+
const cause = unreachableCause(error2);
|
|
17420
|
+
if (!cause) throw error2;
|
|
17421
|
+
throw new Error(
|
|
17422
|
+
`KXM hub unreachable at ${sessionIdentity().serverUrl} (${cause}). Ask the user to start the hub (\`kxm hub start\`) or to correct the kxm plugin server_url with ${CONFIGURE_PLUGIN}.`
|
|
17423
|
+
);
|
|
17424
|
+
}
|
|
17425
|
+
}
|
|
17426
|
+
function toolErrorText(error2) {
|
|
17427
|
+
if (error2 instanceof HubHttpError && error2.code === "invalid_auth") {
|
|
17428
|
+
return `KXM hub rejected the project token for project ${sessionIdentity().project}. Ask the user to set the kxm plugin auth_token (${CONFIGURE_PLUGIN}) to that project's token from the hub KXM_PROJECT_TOKENS.`;
|
|
17429
|
+
}
|
|
17430
|
+
return error2 instanceof Error ? error2.message : String(error2);
|
|
17431
|
+
}
|
|
17275
17432
|
var tools = getMcpTools();
|
|
17276
17433
|
mcp.setRequestHandler(ListToolsRequestSchema, async () => ({ tools }));
|
|
17277
17434
|
mcp.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
|
|
17278
17435
|
try {
|
|
17279
17436
|
const policy = enforceToolPolicy(request.params.name);
|
|
17280
17437
|
if (!policy.allowed) {
|
|
17281
|
-
|
|
17438
|
+
const hint = sessionTokenFixHint(policy);
|
|
17439
|
+
throw new Error(hint ? `tool_policy_denied: ${policy.detail}. ${hint}` : `tool_policy_denied: ${policy.detail ?? policy.error}`);
|
|
17282
17440
|
}
|
|
17283
|
-
const client = await
|
|
17441
|
+
const client = await connectedClient();
|
|
17284
17442
|
const cmd = AGENT_COMMANDS_MAP.get(request.params.name);
|
|
17285
17443
|
if (!cmd) throw new Error(`unknown tool: ${request.params.name}`);
|
|
17286
17444
|
const args = asRecord2(request.params.arguments);
|
|
@@ -17288,15 +17446,34 @@ mcp.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
|
|
|
17288
17446
|
return textResult(result);
|
|
17289
17447
|
} catch (error2) {
|
|
17290
17448
|
return {
|
|
17291
|
-
content: [{ type: "text", text:
|
|
17449
|
+
content: [{ type: "text", text: toolErrorText(error2) }],
|
|
17292
17450
|
isError: true
|
|
17293
17451
|
};
|
|
17294
17452
|
}
|
|
17295
17453
|
});
|
|
17454
|
+
function registersAtStartup() {
|
|
17455
|
+
const { projectDir, project } = sessionIdentity();
|
|
17456
|
+
try {
|
|
17457
|
+
if (!statSync(join4(projectDir, ".kxm")).isDirectory()) return false;
|
|
17458
|
+
if (!resolveAgentHubAuthToken(process.env, project)) return false;
|
|
17459
|
+
} catch {
|
|
17460
|
+
return false;
|
|
17461
|
+
}
|
|
17462
|
+
return enforceToolPolicy("kxm_inbox").allowed && enforceToolPolicy("kxm_reply").allowed;
|
|
17463
|
+
}
|
|
17464
|
+
mcp.oninitialized = () => {
|
|
17465
|
+
if (registersAtStartup()) void ensureClient().catch(() => void 0);
|
|
17466
|
+
};
|
|
17296
17467
|
await mcp.connect(new StdioServerTransport());
|
|
17297
|
-
|
|
17298
|
-
|
|
17299
|
-
|
|
17468
|
+
var shuttingDown;
|
|
17469
|
+
function shutdown() {
|
|
17470
|
+
shuttingDown ??= (async () => {
|
|
17471
|
+
const client = meshClient ?? await starting?.catch(() => void 0);
|
|
17472
|
+
await client?.stop();
|
|
17473
|
+
await mcp.close();
|
|
17474
|
+
})();
|
|
17475
|
+
return shuttingDown;
|
|
17300
17476
|
}
|
|
17301
17477
|
process.once("SIGINT", () => void shutdown());
|
|
17302
17478
|
process.once("SIGTERM", () => void shutdown());
|
|
17479
|
+
process.stdin.once("end", () => void shutdown());
|