@kontextmind/kxm 0.7.120 → 0.7.121

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.
@@ -17313,7 +17313,7 @@ function sessionTokenFixHint(policy) {
17313
17313
  }
17314
17314
 
17315
17315
  // plugins/kxm/src/mcp-server.ts
17316
- var VERSION = "0.7.120";
17316
+ var VERSION = "0.7.121";
17317
17317
  var CONFIGURE_PLUGIN = "/plugin configure kxm@kxm";
17318
17318
  var inbox = /* @__PURE__ */ new Map();
17319
17319
  var notifiedInbox = /* @__PURE__ */ new Set();
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-plugin",
3
- "version": "0.7.120",
3
+ "version": "0.7.121",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "engines": {
@@ -20,7 +20,7 @@ writers, or replace `.kxm/roster.yaml` trusted policy.
20
20
  | Delegate to or answer another agent | `kxm-peer` | `peer` (`peer await` is capped at 60 seconds) |
21
21
  | Work inside a durable workflow run, gates, signed callbacks | `kxm-workflow` | `workflow`, `gate` |
22
22
  | Role definitions, role hosts, model rosters | `kxm-definitions` | `role` |
23
- | Create, drive, inspect, or cancel a run, or use a worktree lane | `kxm-runs` | `run`, `runs`, `lane` |
23
+ | Create, drive, inspect, or cancel a run, use a worktree lane, or land a branch | `kxm-runs` | `run`, `runs`, `lane`, `land` |
24
24
  | What we know or decided, recall, context footprint, Git memory | `kxm-context-memory` | `context`, `memory`, `explain` |
25
25
  | Turn a repeated practice into a governed skill | `kxm-skill-lifecycle` | `skills` |
26
26
  | What KXM learned, repeated asks, recorded route spend | `kxm-routing-improve` | `routing`, `improve` |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: kxm-runs
3
- description: Create, drive, and inspect local KXM runs, and manage worktree lanes. kxm runs drive with --simulated executes a run model-free and settles it with a verified receipt. Use when asked to start a workflow run, check its status, read its receipt, cancel it, smoke-test a workflow, or create a lane.
3
+ description: Create, drive, and inspect local KXM runs, manage worktree lanes, and land a branch. kxm runs drive with --simulated executes a run model-free and settles it with a verified receipt. Use when asked to start a workflow run, check its status, read its receipt, cancel it, smoke-test a workflow, create a lane, or land the current branch.
4
4
  ---
5
5
 
6
6
  # KXM runs
@@ -26,6 +26,7 @@ create, or logs verbs under `runs`.
26
26
  | `kxm lane status <unit>` | One lane plus its last run status, or unknown when the supervisor is not answering | `--json` |
27
27
  | `kxm lane drop <unit>` | Remove the worktree and the record. The branch is not deleted | `--force`, `--json` |
28
28
  | `kxm lane run <unit>` | Create the lane if needed, start a run from a brief, and drive it | `--brief <file>` (required), `--workflow <id>`, `--base <ref>`, `--wait`, `--timeout-ms <n>`, `--json` |
29
+ | `kxm land` | Verify, regenerate docs, push, open or reuse a pull request, rebase, unblock, squash-merge, watch the release, and note a milestone | `--pr <n>`, `--stage <name>`, `--body-file <path>`, `--json`, `--dry-run` |
29
30
 
30
31
  The run record and its events keep only the prompt's hash, but the full
31
32
  prompt text is kept in a local `run-events.db.run-prompts.json` file (mode
@@ -65,6 +66,21 @@ file. `kxm run --lane <unit>` and `kxm runs status|drive|receipt|cancel --lane`
65
66
  discover the project from the lane worktree. `kxm lane run <unit> --brief <file>`
66
67
  creates the lane when it is missing, starts the run, and drives it.
67
68
 
69
+ `kxm land` lands the current branch. With no `--stage` it runs these stages in
70
+ order: `verify`, `docs`, `push`, `pr`, `rebase`, `unblock`, `merge`,
71
+ `release`, `milestone`. `verify` runs `npm run verify` on a clean tree and is
72
+ not replaced by the later stages. `docs` regenerates the roadmap when
73
+ `plans/kxm-roadmap/update-dashboard.mjs` is present and commits only those
74
+ generated pages. `push` publishes the branch. `pr` reuses the open pull
75
+ request or creates one from `--body-file`. `rebase` rebases onto
76
+ `origin/main` for at most five rounds, resolving only the dist rebuild, the
77
+ CHANGELOG Unreleased union, and the tracker "Landed in this tree" union.
78
+ `unblock` reruns one failed check and reports a required review. `merge`
79
+ squash-merges. `release` waits for the tag and the npm publish. `milestone`
80
+ reports `deep_review_required` when a phase flips to done or the body contains
81
+ a `Milestone:` line, and does not run the review. `--dry-run` prints each
82
+ stage's plan and does not mutate.
83
+
68
84
  ## Refusals
69
85
 
70
86
  - `run_workflow_unknown`: the workflow ID is not a project workflow. Run only
@@ -0,0 +1,48 @@
1
+ import { spawn } from "node:child_process";
2
+ import { join } from "node:path";
3
+ import { discoverKxmProjectRoot } from "../project-config.ts";
4
+ import { findKxmRepoRoot } from "../repo-root.ts";
5
+ import { print, type Runtime } from "./types.ts";
6
+
7
+ export interface LandOptions {
8
+ pr?: string;
9
+ stage?: string;
10
+ bodyFile?: string;
11
+ }
12
+
13
+ function childEnv(): NodeJS.ProcessEnv {
14
+ const env: NodeJS.ProcessEnv = {};
15
+ for (const [name, value] of Object.entries(process.env)) {
16
+ if (value === undefined) continue;
17
+ if (name.toUpperCase().startsWith("GIT_")) continue;
18
+ env[name] = value;
19
+ }
20
+ return env;
21
+ }
22
+
23
+ function refuse(runtime: Runtime, error: string, text: string): number {
24
+ print(runtime.io, runtime.json, { ok: false, command: "land", error }, text);
25
+ return 1;
26
+ }
27
+
28
+ /** Spawn scripts/pr-land.mjs and stream its JSON lines. The exit code is the script's. */
29
+ export function cmdLand(runtime: Runtime, options: LandOptions = {}): Promise<number> {
30
+ const root = discoverKxmProjectRoot(runtime.cwd);
31
+ if (!root) {
32
+ return Promise.resolve(refuse(runtime, "project_required", "land requires a KXM project (run kxm init first)"));
33
+ }
34
+ const script = join(findKxmRepoRoot(import.meta.url), "scripts", "pr-land.mjs");
35
+ const args = [script];
36
+ if (options.pr) args.push("--pr", options.pr);
37
+ if (options.stage) args.push("--stage", options.stage);
38
+ if (options.bodyFile) args.push("--body-file", options.bodyFile);
39
+ if (runtime.json) args.push("--json");
40
+ if (runtime.dryRun) args.push("--dry-run");
41
+ return new Promise((resolveExit) => {
42
+ const child = spawn(process.execPath, args, { cwd: root, env: childEnv(), windowsHide: true });
43
+ child.stdout.on("data", (chunk: Buffer) => runtime.io.stdout(chunk.toString("utf8")));
44
+ child.stderr.on("data", (chunk: Buffer) => runtime.io.stderr(chunk.toString("utf8")));
45
+ child.once("error", () => resolveExit(1));
46
+ child.once("close", (code) => resolveExit(code ?? 1));
47
+ });
48
+ }
@@ -131,6 +131,8 @@ import {
131
131
  cmdLaneStatus,
132
132
  } from "./cli/lanes.ts";
133
133
 
134
+ import { cmdLand } from "./cli/land.ts";
135
+
134
136
  import {
135
137
  cmdStatus,
136
138
  cmdDash,
@@ -197,6 +199,7 @@ const USAGE_ERROR_CODES = new Set([
197
199
  const DRY_RUN_COMMANDS: ReadonlySet<string> = new Set([
198
200
  "init", "backup", "restore", "run", "explain", "suggest", "update", "dash", "completion", "completion install",
199
201
  "lane create", "lane list", "lane status", "lane drop", "lane run",
202
+ "land",
200
203
  "plugin install", "plugin",
201
204
  "runs status", "runs drive", "runs receipt", "runs cancel", "runs list",
202
205
  "tenant status", "models inventory-refresh", "harness list", "auth token",
@@ -485,6 +488,18 @@ function createProgram(ctx: CliContext, result: { code: number }): Command {
485
488
  });
486
489
  });
487
490
 
491
+ addGlobalOptions(program.command("land").description("Land the current branch: verify, regenerate docs, push, pull request, rebase, unblock, squash-merge, release, and milestone"))
492
+ .option("--pr <n>", "Existing pull request number")
493
+ .option("--stage <name>", "Run one stage: verify, docs, push, pr, rebase, unblock, merge, release, or milestone")
494
+ .option("--body-file <path>", "Pull request body file used when creating a pull request")
495
+ .action(async function landAction(this: Command, options: { pr?: string; stage?: string; bodyFile?: string }) {
496
+ result.code = await cmdLand(runtimeFrom(ctx, this), {
497
+ ...(options.pr !== undefined ? { pr: options.pr } : {}),
498
+ ...(options.stage !== undefined ? { stage: options.stage } : {}),
499
+ ...(options.bodyFile !== undefined ? { bodyFile: options.bodyFile } : {}),
500
+ });
501
+ });
502
+
488
503
  addGlobalOptions(program.command("run").description("Create a KXM run without executing steps; follow its prerequisites, then kxm runs drive <runId> --wait")
489
504
  .argument("[workflow]", "Workflow id to run")
490
505
  .argument("[prompt...]", "Run prompt (events keep its hash; the full text is kept in a local 0600 sidecar file)")
@@ -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.120";
14
+ const VERSION = "0.7.121";
15
15
  const CONFIGURE_PLUGIN = "/plugin configure kxm@kxm";
16
16
  const inbox = new Map<string, MessageRecord>();
17
17
  const notifiedInbox = new Set<string>();
@@ -0,0 +1,2 @@
1
+ export function unionChangelogUnreleased(ours: string, theirs: string): string;
2
+ export function unionLandedTracker(ours: string, theirs: string): string;