@astralform/js 4.6.1 → 4.8.0

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.
package/dist/index.cjs CHANGED
@@ -507,6 +507,12 @@ var AstralformClient = class {
507
507
  return await response.json();
508
508
  });
509
509
  }
510
+ async patch(path, body) {
511
+ return this.withDeadline(async (signal) => {
512
+ const response = await this.send("PATCH", path, body, signal);
513
+ return await response.json();
514
+ });
515
+ }
510
516
  async del(path) {
511
517
  await this.request("DELETE", path);
512
518
  }
@@ -577,6 +583,25 @@ var AstralformClient = class {
577
583
  createdAt: m.created_at
578
584
  }));
579
585
  }
586
+ /**
587
+ * Replace the title the server generated from the conversation's first turn.
588
+ *
589
+ * The server does NOT bump `updated_at` for a rename — conversations list
590
+ * newest-updated first, and relabelling one is not activity — so the
591
+ * timestamp coming back is the original. Callers should merge the response
592
+ * rather than stamp their own, or they reintroduce the reordering the
593
+ * server deliberately avoids.
594
+ */
595
+ async renameConversation(id, title) {
596
+ const c = await this.patch(`/v1/conversations/${encodeURIComponent(id)}`, { title });
597
+ return {
598
+ id: c.id,
599
+ title: c.title,
600
+ messageCount: c.message_count,
601
+ createdAt: c.created_at,
602
+ updatedAt: c.updated_at
603
+ };
604
+ }
580
605
  async deleteConversation(id) {
581
606
  await this.del(`/v1/conversations/${encodeURIComponent(id)}`);
582
607
  }
@@ -1059,6 +1084,16 @@ function translateCustomEvent(name, data) {
1059
1084
  type: "todo_update",
1060
1085
  todos: data.todos ?? []
1061
1086
  };
1087
+ case "plan_update":
1088
+ return {
1089
+ type: "plan_update",
1090
+ plan: data.plan ?? ""
1091
+ };
1092
+ case "note_update":
1093
+ return {
1094
+ type: "note_update",
1095
+ notes: data.notes ?? []
1096
+ };
1062
1097
  case "context_update":
1063
1098
  return {
1064
1099
  type: "context_update",
@@ -1926,6 +1961,26 @@ var ChatSession = class {
1926
1961
  this.isLoadingConversations = false;
1927
1962
  }
1928
1963
  }
1964
+ /**
1965
+ * Rename a conversation, server first.
1966
+ *
1967
+ * Deliberately NOT optimistic, unlike the delete below. A failed delete is
1968
+ * self-correcting (the row is still there on the next page fetch), but a
1969
+ * failed rename that had already been written locally would leave the
1970
+ * sidebar showing a title the server never accepted — and nothing refetches
1971
+ * a conversation that is already in the loaded list.
1972
+ *
1973
+ * Mirrors the `title_generated` path: the entry in `conversations` is
1974
+ * mutated in place, which is what every consumer of the list reads.
1975
+ */
1976
+ async renameConversation(id, title) {
1977
+ const updated = await this.client.renameConversation(id, title);
1978
+ const conv = this.conversations.find((c) => c.id === id);
1979
+ if (conv) {
1980
+ conv.title = updated.title;
1981
+ }
1982
+ await this.storage.updateConversationTitle(id, updated.title);
1983
+ }
1929
1984
  async deleteConversation(id) {
1930
1985
  try {
1931
1986
  await this.client.deleteConversation(id);
@@ -2030,6 +2085,8 @@ var ChatEventType = {
2030
2085
  UserMessage: "user_message",
2031
2086
  TitleGenerated: "title_generated",
2032
2087
  TodoUpdate: "todo_update",
2088
+ PlanUpdate: "plan_update",
2089
+ NoteUpdate: "note_update",
2033
2090
  ContextUpdate: "context_update",
2034
2091
  SubagentStart: "subagent_start",
2035
2092
  SubagentStop: "subagent_stop",
@@ -2216,12 +2273,19 @@ var StreamManager = class {
2216
2273
  }
2217
2274
  await this.restore(conversationId);
2218
2275
  }
2219
- // ── Create / delete conversation ──────────────────────────────
2276
+ // ── Create / rename / delete conversation ─────────────────────
2220
2277
  async createConversation() {
2221
2278
  const id = await this.session.createNewConversation();
2222
2279
  this.setActiveConversation(id);
2223
2280
  return id;
2224
2281
  }
2282
+ /**
2283
+ * Rename a conversation. Purely a relabel — no active-conversation or
2284
+ * background-job bookkeeping to do, unlike delete, so this is a passthrough.
2285
+ */
2286
+ async renameConversation(id, title) {
2287
+ await this.session.renameConversation(id, title);
2288
+ }
2225
2289
  async deleteConversation(id) {
2226
2290
  await this.session.deleteConversation(id);
2227
2291
  this._backgroundJobs.delete(id);