@mtreeai/msapling-cli 2.3.6-beta.22 → 2.3.6-beta.23

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 +202 -6
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -266,8 +266,45 @@ var init_src = __esm({
266
266
  body: JSON.stringify(symbol)
267
267
  });
268
268
  }
269
+ // CLI-PROJECT-CREATE-01 (Iter 34): create a new project. Per LAB
270
+ // projects.py:239 — POST /api/projects/ with {project_name}.
271
+ async createProject(name) {
272
+ return await this.request("/api/projects/", {
273
+ method: "POST",
274
+ body: JSON.stringify({ project_name: name })
275
+ });
276
+ }
277
+ // CLI-CHAT-CREATE-01 (Iter 34): create a new chat in a project. Per LAB
278
+ // projects.py:365 — POST /api/projects/chat/new with
279
+ // {project_name, slot_label?, chat_name?, model?, client_type?}.
280
+ async createChat(opts) {
281
+ return await this.request("/api/projects/chat/new", {
282
+ method: "POST",
283
+ body: JSON.stringify({
284
+ project_name: opts.projectName,
285
+ slot_label: opts.title,
286
+ chat_name: opts.title,
287
+ model: opts.model,
288
+ client_type: "cli"
289
+ })
290
+ });
291
+ }
292
+ // CLI-BROADCAST-01 (Iter 34): broadcast a prompt to sibling chats in a
293
+ // project. Per LAB broadcast.py:145 — POST /api/broadcast/execute with
294
+ // {project_name, prompt, source_chat_id?, max_targets?}.
295
+ async broadcastExecute(opts) {
296
+ return await this.request("/api/broadcast/execute", {
297
+ method: "POST",
298
+ body: JSON.stringify({
299
+ project_name: opts.projectName,
300
+ prompt: opts.prompt,
301
+ source_chat_id: opts.sourceChatId,
302
+ max_targets: opts.maxTargets
303
+ })
304
+ });
305
+ }
269
306
  async getModels() {
270
- return await this.request("/api/models");
307
+ return await this.request("/api/benchmark/models");
271
308
  }
272
309
  /**
273
310
  * Fetch the canonical tool registry from the backend.
@@ -8588,7 +8625,41 @@ function resolveChat(arg, chats) {
8588
8625
  }
8589
8626
  return { kind: "error", message: `no chat matches '${trimmed}'. Run /chat (no args) for the list.` };
8590
8627
  }
8628
+ async function createChat(args2, context) {
8629
+ let title = "";
8630
+ let model;
8631
+ for (let i = 0; i < args2.length; i++) {
8632
+ if (args2[i] === "--model" && i + 1 < args2.length) {
8633
+ model = args2[i + 1];
8634
+ i++;
8635
+ } else {
8636
+ title += (title ? " " : "") + args2[i];
8637
+ }
8638
+ }
8639
+ try {
8640
+ const overview = await context.client.me();
8641
+ const currentId = context.getProjectId();
8642
+ const project = overview.projects.find((p) => p.id === currentId) ?? overview.projects[0];
8643
+ if (!project) {
8644
+ context.addMessage("error", "No active project. Use /project new <name> or /project <id> first.");
8645
+ return;
8646
+ }
8647
+ const result = await context.client.createChat({
8648
+ projectName: project.name,
8649
+ title: title || void 0,
8650
+ model: model || void 0
8651
+ });
8652
+ context.addMessage("system", `Created chat "${result.title}" (${result.chat_id}) using ${result.model}`);
8653
+ context.setActiveChatId(result.chat_id);
8654
+ await context.refreshOverview();
8655
+ } catch (e) {
8656
+ context.addMessage("error", `Failed to create chat: ${e.message}`);
8657
+ }
8658
+ }
8591
8659
  async function listChats(args2, context) {
8660
+ if (args2[0] === "new" || args2[0] === "create") {
8661
+ return createChat(args2.slice(1), context);
8662
+ }
8592
8663
  const arg = args2.join(" ").trim();
8593
8664
  const result = await fetchChatsForCurrentProject(context);
8594
8665
  if ("error" in result) {
@@ -8643,6 +8714,74 @@ var init_chat = __esm({
8643
8714
  }
8644
8715
  });
8645
8716
 
8717
+ // src/commands/broadcast.ts
8718
+ var broadcastCommand;
8719
+ var init_broadcast = __esm({
8720
+ "src/commands/broadcast.ts"() {
8721
+ "use strict";
8722
+ init_esm_shims();
8723
+ broadcastCommand = {
8724
+ name: "broadcast",
8725
+ aliases: ["bcast"],
8726
+ args: "[--max N] [--exclude-current] <prompt>",
8727
+ description: "Send a prompt to every sibling chat in the active project (rate-limited 10/min).",
8728
+ category: "chat",
8729
+ handler: async (args2, context) => {
8730
+ let maxTargets = 8;
8731
+ let excludeCurrent = false;
8732
+ const promptParts = [];
8733
+ for (let i = 0; i < args2.length; i++) {
8734
+ if (args2[i] === "--max" && i + 1 < args2.length) {
8735
+ const n = Number(args2[i + 1]);
8736
+ if (Number.isFinite(n) && n > 0) maxTargets = Math.min(32, Math.floor(n));
8737
+ i++;
8738
+ continue;
8739
+ }
8740
+ if (args2[i] === "--exclude-current") {
8741
+ excludeCurrent = true;
8742
+ continue;
8743
+ }
8744
+ promptParts.push(args2[i]);
8745
+ }
8746
+ const prompt4 = promptParts.join(" ").trim();
8747
+ if (!prompt4) {
8748
+ context.addMessage("system", "Usage: /broadcast [--max N] [--exclude-current] <prompt>");
8749
+ return;
8750
+ }
8751
+ try {
8752
+ const overview = await context.client.me();
8753
+ const currentId = context.getProjectId();
8754
+ const project = overview.projects.find((p) => p.id === currentId) ?? overview.projects[0];
8755
+ if (!project) {
8756
+ context.addMessage("error", "No active project. Use /project <id> first.");
8757
+ return;
8758
+ }
8759
+ const result = await context.client.broadcastExecute({
8760
+ projectName: project.name,
8761
+ prompt: prompt4,
8762
+ sourceChatId: excludeCurrent ? context.activeChatId ?? void 0 : void 0,
8763
+ maxTargets
8764
+ });
8765
+ context.addMessage(
8766
+ "system",
8767
+ `Broadcast queued: ${result.broadcast_id} \u2192 ${result.target_chat_ids?.length ?? 0} chat(s) in project '${project.name}'.`
8768
+ );
8769
+ if (Array.isArray(result.target_chat_ids) && result.target_chat_ids.length > 0) {
8770
+ for (const cid of result.target_chat_ids.slice(0, 8)) {
8771
+ context.addMessage("system", ` - ${cid}`);
8772
+ }
8773
+ if (result.target_chat_ids.length > 8) {
8774
+ context.addMessage("system", ` \u2026and ${result.target_chat_ids.length - 8} more.`);
8775
+ }
8776
+ }
8777
+ } catch (e) {
8778
+ context.addMessage("error", `Broadcast failed: ${e.message}`);
8779
+ }
8780
+ }
8781
+ };
8782
+ }
8783
+ });
8784
+
8646
8785
  // src/commands/clear.ts
8647
8786
  var clearCommand;
8648
8787
  var init_clear = __esm({
@@ -8800,8 +8939,47 @@ Current: ${current}`);
8800
8939
  }
8801
8940
  return;
8802
8941
  }
8803
- context.setModel(newModel);
8804
- context.addMessage("system", `Model switched to: ${newModel}`);
8942
+ try {
8943
+ const models = await context.client.getModels();
8944
+ const list = models.filter((m) => !!m.id);
8945
+ const trimmed = newModel.trim();
8946
+ const exact = list.find((m) => m.id === trimmed);
8947
+ if (exact) {
8948
+ context.setModel(exact.id);
8949
+ context.addMessage("system", `Model switched to: ${exact.id}`);
8950
+ return;
8951
+ }
8952
+ if (/^\d+$/.test(trimmed)) {
8953
+ const idx = parseInt(trimmed, 10) - 1;
8954
+ if (idx >= 0 && idx < list.length && list[idx].id) {
8955
+ context.setModel(list[idx].id);
8956
+ context.addMessage("system", `Model switched to: ${list[idx].id}`);
8957
+ return;
8958
+ }
8959
+ }
8960
+ const lower = trimmed.toLowerCase();
8961
+ const subs = list.filter((m) => (m.id ?? "").toLowerCase().includes(lower));
8962
+ if (subs.length === 1) {
8963
+ context.setModel(subs[0].id);
8964
+ context.addMessage("system", `Model switched to: ${subs[0].id}`);
8965
+ return;
8966
+ }
8967
+ if (subs.length > 1 && subs.length <= 10) {
8968
+ context.addMessage(
8969
+ "error",
8970
+ `'${trimmed}' matches ${subs.length} models: ${subs.map((m) => m.id).join(", ")}`
8971
+ );
8972
+ return;
8973
+ }
8974
+ if (subs.length > 10) {
8975
+ context.addMessage("error", `'${trimmed}' matches ${subs.length} models \u2014 be more specific.`);
8976
+ return;
8977
+ }
8978
+ context.addMessage("error", `No model matches '${trimmed}'. Run /model (no args) for the list of ${list.length} models.`);
8979
+ } catch (e) {
8980
+ context.setModel(newModel);
8981
+ context.addMessage("system", `Model switched to: ${newModel} (unverified \u2014 model catalog unreachable: ${e.message})`);
8982
+ }
8805
8983
  }
8806
8984
  };
8807
8985
  }
@@ -8946,6 +9124,22 @@ var init_project = __esm({
8946
9124
  handler: async (args2, context) => {
8947
9125
  const arg = args2.join(" ").trim();
8948
9126
  const currentId = context.getProjectId() || null;
9127
+ if (args2[0] === "new" || args2[0] === "create") {
9128
+ const name = args2.slice(1).join(" ").trim();
9129
+ if (!name) {
9130
+ context.addMessage("system", "Usage: /project new <name>");
9131
+ return;
9132
+ }
9133
+ try {
9134
+ const result = await context.client.createProject(name);
9135
+ context.addMessage("system", `Created project "${result.project}" (${result.project_id})`);
9136
+ context.setProjectId(result.project_id);
9137
+ await context.refreshOverview();
9138
+ } catch (e) {
9139
+ context.addMessage("error", `Failed to create project: ${e.message}`);
9140
+ }
9141
+ return;
9142
+ }
8949
9143
  let projects = [];
8950
9144
  try {
8951
9145
  const overview = await context.client.me();
@@ -9876,7 +10070,7 @@ var init_version = __esm({
9876
10070
  description: "Show version information for CLI and core packages",
9877
10071
  category: "debug",
9878
10072
  handler: async (_args, context) => {
9879
- const cliVersion = true ? "2.3.6-beta.22" : "(dev)";
10073
+ const cliVersion = true ? "2.3.6-beta.23" : "(dev)";
9880
10074
  const coreVersion = true ? "2.3.2" : "(dev)";
9881
10075
  const runtime = process.version;
9882
10076
  context.addMessage("system", "MSapling Version Info");
@@ -9885,7 +10079,7 @@ var init_version = __esm({
9885
10079
  context.addMessage("system", row2("Core (@msapling/core)", coreVersion));
9886
10080
  context.addMessage("system", row2("Runtime (Node/Bun)", runtime));
9887
10081
  try {
9888
- const ts = "2026-05-28T19:10:28.448Z";
10082
+ const ts = "2026-05-28T19:20:38.494Z";
9889
10083
  if (ts && ts !== "__BUILD_TIMESTAMP__") {
9890
10084
  context.addMessage("system", row2("Build Timestamp", ts));
9891
10085
  }
@@ -10624,6 +10818,7 @@ var init_commands = __esm({
10624
10818
  init_exit();
10625
10819
  init_help();
10626
10820
  init_chat();
10821
+ init_broadcast();
10627
10822
  init_clear();
10628
10823
  init_mode();
10629
10824
  init_model();
@@ -10659,6 +10854,7 @@ var init_commands = __esm({
10659
10854
  helpCommand,
10660
10855
  chatCommand,
10661
10856
  chatsCommand,
10857
+ broadcastCommand,
10662
10858
  clearCommand,
10663
10859
  modeCommand,
10664
10860
  modelCommand,
@@ -14288,7 +14484,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
14288
14484
  var Header = () => /* @__PURE__ */ jsxs(Box, { borderStyle: "single", borderColor: "cyan", paddingX: 1, marginBottom: 1, children: [
14289
14485
  /* @__PURE__ */ jsxs(Text, { bold: true, color: "cyan", children: [
14290
14486
  "\u25CF MSapling CLI v",
14291
- "2.3.6-beta.22"
14487
+ "2.3.6-beta.23"
14292
14488
  ] }),
14293
14489
  /* @__PURE__ */ jsx(Box, { marginLeft: 2, children: /* @__PURE__ */ jsx(Text, { color: "gray", children: "Platinum Tier Architecture" }) })
14294
14490
  ] });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mtreeai/msapling-cli",
3
- "version": "2.3.6-beta.22",
3
+ "version": "2.3.6-beta.23",
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",