@kontextmind/kxm 0.7.195 → 0.7.196

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.
@@ -11,7 +11,7 @@
11
11
  "name": "kxm",
12
12
  "source": "./plugins/kxm",
13
13
  "description": "Durable workflows, peer agents, and kxm tui",
14
- "version": "0.7.195",
14
+ "version": "0.7.196",
15
15
  "category": "development",
16
16
  "tags": ["kxm", "multi-agent", "workflows", "mcp"]
17
17
  }
package/CHANGELOG.md CHANGED
@@ -714,6 +714,13 @@ All notable user-facing changes are documented here. The project follows [Semant
714
714
 
715
715
  ### Fixed
716
716
 
717
+ - **A first run says what to do next when Git or the hub is missing.**
718
+ `kxm init` outside a Git worktree still exits 1 with `git_root_required` and
719
+ now says to run `git init`, then `kxm init` again. `kxm hub view` adds
720
+ `hint` when both probes are unreachable or time out: on loopback, start a
721
+ hub with `kxm hub start`; on a remote URL, check the address and
722
+ `kxm hub bind`.
723
+
717
724
  - **`kxm vision assert --route` selects the Pi model, and an unadmitted route names the fix.**
718
725
  The flag used to change only the admission check. Pi still ran
719
726
  `zai-coding-cn/glm-5.3-flash`. Another admitted id is now `pi --model <id>`
@@ -721,7 +728,6 @@ All notable user-facing changes are documented here. The project follows [Semant
721
728
  `route_not_admitted` includes the route id and `kxm routes admit --model`.
722
729
  This checkout does not admit the default; pass
723
730
  `--route openrouter/z-ai/glm-5.3-flash`.
724
-
725
731
  - **The weekly model refresh opens its pull request with a GitHub App.**
726
732
  `.github/workflows/refresh-models.yml` uses `actions/create-github-app-token`
727
733
  with repository secrets `KXM_REFRESH_APP_ID` and
@@ -19,6 +19,7 @@ Work from the smallest boundary outward:
19
19
  | Symptom | Cause | Fix |
20
20
  |---|---|---|
21
21
  | `kxm: command not found` | Only the Pi package or the Claude Code plugin was installed; neither installs the CLI | `npm install --global --omit=peer @kontextmind/kxm`; see [Install KXM](../start/install.md) |
22
+ | `git_root_required` from `kxm init` | The current directory is not inside a Git worktree | Run `git init` in that directory, then `kxm init` again. If Git is present, run `kxm init` from the worktree root |
22
23
  | `kxm` works in one shell but not in another | npm's global bin directory is not on that shell's `PATH` | Run `kxm completion install` (bash and zsh also get a `PATH` entry), then open a new shell |
23
24
  | Tab completion does nothing | Completion is not installed for this shell | `kxm completion install --shell bash`, `zsh` or `fish`; it is idempotent, and `--dry-run` previews it |
24
25
  | Plugin tools fail on start | Node.js is older than 22.19 on the 22.x line, or older than 24 | Install a supported Node.js on the `PATH` the harness uses |
@@ -42,6 +43,10 @@ If it still reports `not_detected`, confirm that `%AppData%\Roaming\npm` is on t
42
43
 
43
44
  ## Hub and authentication
44
45
 
46
+ ### Nothing is listening
47
+
48
+ `kxm hub view` prints `hub health=false ready=false` and, for a loopback URL, `Nothing is listening on this loopback URL. Start a local hub with kxm hub start.` A remote URL names `kxm hub bind` instead. An HTML login page or a redirect is a different failure: the status line says `auth proxy`, and the fix is the proxy or the hub URL, not `kxm hub start`.
49
+
45
50
  ### The hub refuses to start
46
51
 
47
52
  | Message | Fix |
@@ -511,7 +511,7 @@ Calls `GET /health` and `GET /ready` on the target hub and reports whether the U
511
511
  No command-specific options.
512
512
 
513
513
  - Needs a hub to succeed. Reads only.
514
- - JSON keys: `target` (`url`, `scope`, and `source: "env"` when `KXM_SERVER_URL` overrides a binding), `identity` (`mode`, `modeSource`, `url`, `urlSource`, `project`, `projectSource`, `keySource`), `health`, `ready`. An unreachable hub reports `{"error":"hub_unreachable"}` for both probes. An auth proxy or redirect reports `{"error":"auth_proxy"}`.
514
+ - JSON keys: `target` (`url`, `scope`, and `source: "env"` when `KXM_SERVER_URL` overrides a binding), `identity` (`mode`, `modeSource`, `url`, `urlSource`, `project`, `projectSource`, `keySource`), `health`, `ready`, and `hint` when both probes are unreachable or time out. An unreachable hub reports `{"error":"hub_unreachable"}` for both probes. On a loopback URL the hint is `Nothing is listening on this loopback URL. Start a local hub with kxm hub start.` A remote URL names `kxm hub bind`. An auth proxy or redirect reports `{"error":"auth_proxy"}` and has no hint.
515
515
  - Exit 0 when both probes succeed, 1 otherwise. A cloud mode with no resolvable key exits 2 with `cloud_token_missing`.
516
516
 
517
517
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kontextmind/kxm",
3
- "version": "0.7.195",
3
+ "version": "0.7.196",
4
4
  "description": "KXM local-first multi-agent orchestration and operator dashboard",
5
5
  "type": "module",
6
6
  "author": "KontextMind",
@@ -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.195",
5
+ "version": "0.7.196",
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",
@@ -30893,7 +30893,7 @@ function initializeKxmProjectAtGitRoot(start, gitRoot, options, mutationLock) {
30893
30893
  };
30894
30894
  }
30895
30895
  if (plan.projectRoot !== gitRoot) {
30896
- throw new KxmConfigError([initIssue("git_root_required", ".", "kxm init must run inside the authoritative Git worktree")]);
30896
+ throw new KxmConfigError([initIssue("git_root_required", ".", "kxm init must run from the Git worktree root")]);
30897
30897
  }
30898
30898
  const projectId = generatedProjectId(options.projectId);
30899
30899
  const projectName = normalizedProjectName(gitRoot, options.projectName);
@@ -30918,7 +30918,7 @@ function initializeKxmProject(start = process.cwd(), options = {}) {
30918
30918
  assertNoRegisteredGates(options);
30919
30919
  const gitRoot = discoverGitRoot(start);
30920
30920
  if (!gitRoot) {
30921
- throw new KxmConfigError([initIssue("git_root_required", ".", "kxm init must run inside the authoritative Git worktree")]);
30921
+ throw new KxmConfigError([initIssue("git_root_required", ".", "kxm init must run inside a Git worktree. Run git init in this directory, then run kxm init again.")]);
30922
30922
  }
30923
30923
  if (options.projectId !== void 0) generatedProjectId(options.projectId);
30924
30924
  if (options.projectName !== void 0) normalizedProjectName(gitRoot, options.projectName);
@@ -53997,6 +53997,8 @@ async function cmdStatus(runtime) {
53997
53997
  const notHub = !proxyKind && (health.kind === "not_hub" || ready.kind === "not_hub");
53998
53998
  const probeNote = proxyKind === "redirect" ? " \xB7 auth proxy or redirect" : proxyKind === "auth_proxy" ? " \xB7 auth proxy (HTML login page)" : notHub ? " \xB7 not a kxm hub" : "";
53999
53999
  const effectiveScope = connection.scope;
54000
+ const hubDown = (health.kind === "unreachable" || health.kind === "timeout") && (ready.kind === "unreachable" || ready.kind === "timeout");
54001
+ const hint = !hubDown ? void 0 : effectiveScope === "loopback" ? "Nothing is listening on this loopback URL. Start a local hub with kxm hub start." : "Nothing answered this hub URL. Check the address, the tunnel, and kxm hub bind.";
54000
54002
  const overridden = connection.urlSource === "env";
54001
54003
  const identity = {
54002
54004
  mode: connection.mode,
@@ -54013,13 +54015,15 @@ async function cmdStatus(runtime) {
54013
54015
  target: { url: runtime.serverUrl, scope: effectiveScope, ...overridden ? { source: "env" } : {} },
54014
54016
  identity,
54015
54017
  health: health.body,
54016
- ready: ready.body
54018
+ ready: ready.body,
54019
+ ...hint ? { hint } : {}
54017
54020
  };
54018
54021
  print(
54019
54022
  runtime.io,
54020
54023
  runtime.json,
54021
54024
  payload,
54022
- `hub health=${health.ok} ready=${ready.ok} \xB7 ${effectiveScope} hub${overridden ? " (KXM_SERVER_URL)" : ""} \xB7 mode=${identity.mode} project=${identity.project} (${connection.sourceLabel}) key=${identity.keySource}${probeNote}`
54025
+ `hub health=${health.ok} ready=${ready.ok} \xB7 ${effectiveScope} hub${overridden ? " (KXM_SERVER_URL)" : ""} \xB7 mode=${identity.mode} project=${identity.project} (${connection.sourceLabel}) key=${identity.keySource}${probeNote}${hint ? `
54026
+ ${hint}` : ""}`
54023
54027
  );
54024
54028
  return payload.ok ? 0 : 1;
54025
54029
  }
@@ -25462,7 +25462,7 @@ function sessionTokenFixHint(policy) {
25462
25462
  }
25463
25463
 
25464
25464
  // plugins/kxm/src/mcp-server.ts
25465
- var VERSION = "0.7.195";
25465
+ var VERSION = "0.7.196";
25466
25466
  var CONFIGURE_PLUGIN = "/plugin configure kxm@kxm";
25467
25467
  var inbox = /* @__PURE__ */ new Map();
25468
25468
  var notifiedInbox = /* @__PURE__ */ new Set();
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-plugin",
3
- "version": "0.7.195",
3
+ "version": "0.7.196",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "engines": {
@@ -202,6 +202,11 @@ export async function cmdStatus(runtime: Runtime): Promise<number> {
202
202
  // A cloud mode is remote when the contacted URL is that endpoint, including a
203
203
  // loopback SSH forward.
204
204
  const effectiveScope = connection.scope;
205
+ const hubDown = (health.kind === "unreachable" || health.kind === "timeout")
206
+ && (ready.kind === "unreachable" || ready.kind === "timeout");
207
+ const hint = !hubDown ? undefined : effectiveScope === "loopback"
208
+ ? "Nothing is listening on this loopback URL. Start a local hub with kxm hub start."
209
+ : "Nothing answered this hub URL. Check the address, the tunnel, and kxm hub bind.";
205
210
  const overridden = connection.urlSource === "env";
206
211
  const identity = {
207
212
  mode: connection.mode,
@@ -219,9 +224,10 @@ export async function cmdStatus(runtime: Runtime): Promise<number> {
219
224
  identity,
220
225
  health: health.body,
221
226
  ready: ready.body,
227
+ ...(hint ? { hint } : {}),
222
228
  };
223
229
  print(runtime.io, runtime.json, payload,
224
- `hub health=${health.ok} ready=${ready.ok} · ${effectiveScope} hub${overridden ? " (KXM_SERVER_URL)" : ""} · mode=${identity.mode} project=${identity.project} (${connection.sourceLabel}) key=${identity.keySource}${probeNote}`);
230
+ `hub health=${health.ok} ready=${ready.ok} · ${effectiveScope} hub${overridden ? " (KXM_SERVER_URL)" : ""} · mode=${identity.mode} project=${identity.project} (${connection.sourceLabel}) key=${identity.keySource}${probeNote}${hint ? `\n${hint}` : ""}`);
225
231
  return payload.ok ? 0 : 1;
226
232
  }
227
233
 
@@ -390,7 +390,7 @@ function initializeKxmProjectAtGitRoot(
390
390
  }
391
391
 
392
392
  if (plan.projectRoot !== gitRoot) {
393
- throw new KxmConfigError([initIssue("git_root_required", ".", "kxm init must run inside the authoritative Git worktree")]);
393
+ throw new KxmConfigError([initIssue("git_root_required", ".", "kxm init must run from the Git worktree root")]);
394
394
  }
395
395
  const projectId = generatedProjectId(options.projectId);
396
396
  const projectName = normalizedProjectName(gitRoot, options.projectName);
@@ -416,7 +416,7 @@ export function initializeKxmProject(start = process.cwd(), options: KxmInitOpti
416
416
  assertNoRegisteredGates(options);
417
417
  const gitRoot = discoverGitRoot(start);
418
418
  if (!gitRoot) {
419
- throw new KxmConfigError([initIssue("git_root_required", ".", "kxm init must run inside the authoritative Git worktree")]);
419
+ throw new KxmConfigError([initIssue("git_root_required", ".", "kxm init must run inside a Git worktree. Run git init in this directory, then run kxm init again.")]);
420
420
  }
421
421
  if (options.projectId !== undefined) generatedProjectId(options.projectId);
422
422
  if (options.projectName !== undefined) normalizedProjectName(gitRoot, options.projectName);
@@ -11,7 +11,7 @@ import { deliverInboxNotification } from "./inbox.ts";
11
11
  import type { HubEvent, MessageRecord } from "./protocol.ts";
12
12
  import { sessionTokenFixHint } from "./session-token-hint.ts";
13
13
 
14
- const VERSION = "0.7.195";
14
+ const VERSION = "0.7.196";
15
15
  const CONFIGURE_PLUGIN = "/plugin configure kxm@kxm";
16
16
  const inbox = new Map<string, MessageRecord>();
17
17
  const notifiedInbox = new Set<string>();