@mtreeai/msapling-cli 2.3.6-beta.20 → 2.3.6-beta.21

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.
Files changed (2) hide show
  1. package/dist/index.js +154 -32
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -8534,26 +8534,101 @@ var init_help = __esm({
8534
8534
  });
8535
8535
 
8536
8536
  // src/commands/chat.ts
8537
- var chatCommand;
8537
+ function labelFor(i) {
8538
+ return i < 9 ? String(i + 1) : LETTERS[i - 9] ?? `#${i + 1}`;
8539
+ }
8540
+ async function fetchChatsForCurrentProject(context) {
8541
+ try {
8542
+ const data = await context.client.request("/api/projects/");
8543
+ const currentId = context.getProjectId() || null;
8544
+ const overview = await context.client.me();
8545
+ const activeProject = overview.projects.find((p) => p.id === currentId) ?? overview.projects[0];
8546
+ if (!activeProject) return { error: "No active project; use /project first." };
8547
+ const bucket = data.projects?.[activeProject.name];
8548
+ return {
8549
+ projectName: activeProject.name,
8550
+ chats: bucket?.chats ?? []
8551
+ };
8552
+ } catch (e) {
8553
+ return { error: `Failed to fetch chats: ${e.message}` };
8554
+ }
8555
+ }
8556
+ function resolveChat(arg, chats) {
8557
+ const trimmed = arg.trim();
8558
+ if (!trimmed) return { kind: "error", message: "empty argument" };
8559
+ const uuidHit = chats.find((c) => c.id === trimmed);
8560
+ if (uuidHit) return { kind: "ok", id: uuidHit.id, title: uuidHit.title };
8561
+ if (/^\d+$/.test(trimmed)) {
8562
+ const n = parseInt(trimmed, 10);
8563
+ if (n >= 1 && n <= chats.length) return { kind: "ok", id: chats[n - 1].id, title: chats[n - 1].title };
8564
+ return { kind: "error", message: `no chat at index ${n} (have ${chats.length})` };
8565
+ }
8566
+ if (/^[a-zA-Z]$/.test(trimmed)) {
8567
+ const idx = 9 + LETTERS.indexOf(trimmed.toLowerCase());
8568
+ if (idx >= 9 && idx < chats.length) return { kind: "ok", id: chats[idx].id, title: chats[idx].title };
8569
+ }
8570
+ const lower = trimmed.toLowerCase();
8571
+ const matches2 = chats.filter((c) => (c.title ?? "").toLowerCase().includes(lower));
8572
+ if (matches2.length === 1) return { kind: "ok", id: matches2[0].id, title: matches2[0].title };
8573
+ if (matches2.length > 1) {
8574
+ return {
8575
+ kind: "error",
8576
+ message: `'${trimmed}' matches ${matches2.length} chats: ${matches2.map((m) => m.title).join(", ")}`
8577
+ };
8578
+ }
8579
+ return { kind: "error", message: `no chat matches '${trimmed}'. Run /chat (no args) for the list.` };
8580
+ }
8581
+ async function listChats(args2, context) {
8582
+ const arg = args2.join(" ").trim();
8583
+ const result = await fetchChatsForCurrentProject(context);
8584
+ if ("error" in result) {
8585
+ context.addMessage("error", result.error);
8586
+ return;
8587
+ }
8588
+ const { projectName, chats } = result;
8589
+ if (!arg) {
8590
+ if (chats.length === 0) {
8591
+ context.addMessage("system", `No chats in project '${projectName}'. Send a message to start one.`);
8592
+ return;
8593
+ }
8594
+ context.addMessage("system", `Chats in '${projectName}':`);
8595
+ chats.forEach((c, i) => {
8596
+ const label = labelFor(i);
8597
+ const star = c.id === context.activeChatId ? " \u2605" : "";
8598
+ const model = c.model ? ` [${c.model}]` : "";
8599
+ context.addMessage("system", ` ${label}. ${c.title ?? c.id}${model}${star}`);
8600
+ });
8601
+ context.addMessage("system", "");
8602
+ context.addMessage("system", "Switch via /chat <number|letter|title> (e.g. /chat 1 or /chat audit)");
8603
+ return;
8604
+ }
8605
+ const resolved = resolveChat(arg, chats);
8606
+ if (resolved.kind === "error") {
8607
+ context.addMessage("error", resolved.message);
8608
+ return;
8609
+ }
8610
+ context.setActiveChatId(resolved.id);
8611
+ context.addMessage("system", `Switched to chat: ${resolved.title ?? resolved.id}`);
8612
+ await context.refreshOverview();
8613
+ }
8614
+ var LETTERS, chatCommand, chatsCommand;
8538
8615
  var init_chat = __esm({
8539
8616
  "src/commands/chat.ts"() {
8540
8617
  "use strict";
8541
8618
  init_esm_shims();
8619
+ LETTERS = "abcdefghijklmnopqrstuvwxyz";
8542
8620
  chatCommand = {
8543
8621
  name: "chat",
8544
- args: "<chat_id>",
8545
- description: "Switch to a specific chat session",
8622
+ args: "[number|letter|title|id]",
8623
+ description: "List chats in the current project, or switch to one",
8546
8624
  category: "chat",
8547
- handler: async (args2, context) => {
8548
- const chatId = args2[0];
8549
- if (!chatId) {
8550
- context.addMessage("system", "Usage: /chat <chat_id>");
8551
- return;
8552
- }
8553
- context.setActiveChatId(chatId);
8554
- context.addMessage("system", `Switched to chat: ${chatId}`);
8555
- await context.refreshOverview();
8556
- }
8625
+ handler: async (args2, context) => listChats(args2, context)
8626
+ };
8627
+ chatsCommand = {
8628
+ name: "chats",
8629
+ description: "List chats in the current project (alias for /chat with no args)",
8630
+ category: "chat",
8631
+ handler: async (_args, context) => listChats([], context)
8557
8632
  };
8558
8633
  }
8559
8634
  });
@@ -8819,34 +8894,80 @@ var init_memory = __esm({
8819
8894
  });
8820
8895
 
8821
8896
  // src/commands/project.ts
8822
- var projectCommand;
8897
+ function labelFor2(i) {
8898
+ return i < 9 ? String(i + 1) : LETTERS2[i - 9] ?? `#${i + 1}`;
8899
+ }
8900
+ function resolveProject(arg, list) {
8901
+ const trimmed = arg.trim();
8902
+ if (!trimmed) return { kind: "error", message: "empty argument" };
8903
+ const uuidHit = list.find((p) => p.id === trimmed);
8904
+ if (uuidHit) return { kind: "ok", id: uuidHit.id };
8905
+ if (/^\d+$/.test(trimmed)) {
8906
+ const n = parseInt(trimmed, 10);
8907
+ if (n >= 1 && n <= list.length) return { kind: "ok", id: list[n - 1].id };
8908
+ return { kind: "error", message: `no project at index ${n} (have ${list.length})` };
8909
+ }
8910
+ if (/^[a-zA-Z]$/.test(trimmed)) {
8911
+ const idx = 9 + LETTERS2.indexOf(trimmed.toLowerCase());
8912
+ if (idx >= 9 && idx < list.length) return { kind: "ok", id: list[idx].id };
8913
+ }
8914
+ const lower = trimmed.toLowerCase();
8915
+ const matches2 = list.filter((p) => (p.name ?? "").toLowerCase().includes(lower));
8916
+ if (matches2.length === 1) return { kind: "ok", id: matches2[0].id };
8917
+ if (matches2.length > 1) {
8918
+ return {
8919
+ kind: "error",
8920
+ message: `'${trimmed}' matches ${matches2.length} projects: ${matches2.map((m) => m.name).join(", ")}`
8921
+ };
8922
+ }
8923
+ return { kind: "error", message: `no project matches '${trimmed}'. Run /project (no args) for the list.` };
8924
+ }
8925
+ var LETTERS2, projectCommand;
8823
8926
  var init_project = __esm({
8824
8927
  "src/commands/project.ts"() {
8825
8928
  "use strict";
8826
8929
  init_esm_shims();
8930
+ LETTERS2 = "abcdefghijklmnopqrstuvwxyz";
8827
8931
  projectCommand = {
8828
8932
  name: "project",
8829
- args: "[project_id]",
8933
+ args: "[number|letter|name|id]",
8830
8934
  description: "List or switch active project",
8831
8935
  category: "project",
8832
8936
  handler: async (args2, context) => {
8833
- const newProjectId = args2[0];
8834
- if (!newProjectId) {
8835
- try {
8836
- const overview = await context.client.me();
8837
- context.addMessage("system", "Available Projects:");
8838
- for (const p of overview.projects) {
8839
- context.addMessage("system", ` - ${p.id} (${p.name})`);
8840
- }
8841
- context.addMessage("system", `
8842
- Current Project: ${context.getProjectId() || "none"}`);
8843
- } catch (e) {
8844
- context.addMessage("error", `Failed to fetch projects: ${e.message}`);
8937
+ const arg = args2.join(" ").trim();
8938
+ const currentId = context.getProjectId() || null;
8939
+ let projects = [];
8940
+ try {
8941
+ const overview = await context.client.me();
8942
+ projects = overview.projects;
8943
+ } catch (e) {
8944
+ context.addMessage("error", `Failed to fetch projects: ${e.message}`);
8945
+ return;
8946
+ }
8947
+ if (!arg) {
8948
+ if (projects.length === 0) {
8949
+ context.addMessage("system", "No projects found.");
8950
+ return;
8845
8951
  }
8952
+ context.addMessage("system", "Available Projects:");
8953
+ projects.forEach((p, i) => {
8954
+ const label = labelFor2(i);
8955
+ const star = p.id === currentId ? " \u2605" : "";
8956
+ const usage = p.chat_count != null && p.chat_limit != null ? ` (${p.chat_count}/${p.chat_limit} chats)` : "";
8957
+ context.addMessage("system", ` ${label}. ${p.name ?? p.id}${usage}${star}`);
8958
+ });
8959
+ context.addMessage("system", "");
8960
+ context.addMessage("system", "Switch via /project <number|letter|name> (e.g. /project 2 or /project audit)");
8961
+ return;
8962
+ }
8963
+ const resolved = resolveProject(arg, projects);
8964
+ if (resolved.kind === "error") {
8965
+ context.addMessage("error", resolved.message);
8846
8966
  return;
8847
8967
  }
8848
- context.setProjectId(newProjectId);
8849
- context.addMessage("system", `Project switched to: ${newProjectId}`);
8968
+ const picked = projects.find((p) => p.id === resolved.id);
8969
+ context.setProjectId(resolved.id);
8970
+ context.addMessage("system", `Project switched to: ${picked.name ?? resolved.id}`);
8850
8971
  await context.refreshOverview();
8851
8972
  }
8852
8973
  };
@@ -9745,7 +9866,7 @@ var init_version = __esm({
9745
9866
  description: "Show version information for CLI and core packages",
9746
9867
  category: "debug",
9747
9868
  handler: async (_args, context) => {
9748
- const cliVersion = true ? "2.3.6-beta.20" : "(dev)";
9869
+ const cliVersion = true ? "2.3.6-beta.21" : "(dev)";
9749
9870
  const coreVersion = true ? "2.3.2" : "(dev)";
9750
9871
  const runtime = process.version;
9751
9872
  context.addMessage("system", "MSapling Version Info");
@@ -9754,7 +9875,7 @@ var init_version = __esm({
9754
9875
  context.addMessage("system", row2("Core (@msapling/core)", coreVersion));
9755
9876
  context.addMessage("system", row2("Runtime (Node/Bun)", runtime));
9756
9877
  try {
9757
- const ts = "2026-05-28T18:54:30.369Z";
9878
+ const ts = "2026-05-28T18:59:22.883Z";
9758
9879
  if (ts && ts !== "__BUILD_TIMESTAMP__") {
9759
9880
  context.addMessage("system", row2("Build Timestamp", ts));
9760
9881
  }
@@ -10527,6 +10648,7 @@ var init_commands = __esm({
10527
10648
  exitCommand,
10528
10649
  helpCommand,
10529
10650
  chatCommand,
10651
+ chatsCommand,
10530
10652
  clearCommand,
10531
10653
  modeCommand,
10532
10654
  modelCommand,
@@ -14143,7 +14265,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
14143
14265
  var Header = () => /* @__PURE__ */ jsxs(Box, { borderStyle: "single", borderColor: "cyan", paddingX: 1, marginBottom: 1, children: [
14144
14266
  /* @__PURE__ */ jsxs(Text, { bold: true, color: "cyan", children: [
14145
14267
  "\u25CF MSapling CLI v",
14146
- "2.3.6-beta.20"
14268
+ "2.3.6-beta.21"
14147
14269
  ] }),
14148
14270
  /* @__PURE__ */ jsx(Box, { marginLeft: 2, children: /* @__PURE__ */ jsx(Text, { color: "gray", children: "Platinum Tier Architecture" }) })
14149
14271
  ] });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mtreeai/msapling-cli",
3
- "version": "2.3.6-beta.20",
3
+ "version": "2.3.6-beta.21",
4
4
  "description": "MSapling CLI — React/Ink terminal client for the MSapling backend (chat, projects, MDrive, agent tools). Proprietary; redistribution prohibited.",
5
5
  "license": "UNLICENSED",
6
6
  "author": "MSapling Team",