moveSession

tcmts.cli.mcp.moveSession · #xngxgkxs · term · runs on the server

uses node:path

Move a session's server (server, its record) onto to without a restart (tcm_cli ["switch", <branch>] in a session): a branch it owns, such as an earlier session's that holds its work, as long as no other server works on it, and not the codebase's own (work lands there with tcm_merge). Claimed as startSession claims one; the branch it leaves, one a server made for itself, goes if main has all of it (endSession). What it did, or why not.

import { sessionDirFor } from "#codebase/tcmts/cli/codebase";
import {
  endSession, isSessionBranch, liveMcpServers, withCodebase, writeLease, writeServerRecord,
} from "#codebase/tcmts/cli/mcp";
import type { McpServer } from "#codebase/tcmts/cli/mcp";
import path from "node:path";

export function moveSession(
  root: string,
  server: McpServer,
  to: string,
): { moved: boolean; text: string } {
  const from = server.branch;
  if (from === to) return { moved: false, text: `this session is on ${to} already` };
  const refused = withCodebase(root, (cb) =>
    cb.store.transaction(() => {
      if (!cb.store.hasBranch(to)) return `no branch named '${to}'`;
      const own = cb.store.branch().name;
      if (to === own)
        return `${to} is the codebase's own branch: a session's work lands there with tcm_merge, when the user says to, and the session doesn't work on it`;
      const on = liveMcpServers(root).find((s) => s.pid !== server.pid && s.branch === to);
      if (on)
        return `a session's server (process ${on.pid}) works on ${to}: two servers don't share a branch`;
      writeServerRecord(root, { ...server, branch: to });
      if (server.client) writeLease(root, to, server.client);
      return undefined;
    }),
  );
  if (refused) return { moved: false, text: refused };
  const left = from && isSessionBranch(from) && endSession(root, from);
  return {
    moved: true,
    text: `this session works on ${to} now: every tool is on it, its scratch files are in ${path
      .relative(root, sessionDirFor(root, to))
      .split(path.sep)
      .join(
        "/",
      )}/, and it lands with tcm_merge when the user says to.${from ? (left ? ` ${from}, which it leaves, is gone: main has all of it.` : ` ${from}, which it leaves, stays (tcm_status lists it if it holds work main doesn't have).`) : ""}`,
  };
}

uses

used by