@staff0rd/assist 0.468.1 → 0.469.1

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.js CHANGED
@@ -6,7 +6,7 @@ import { Command } from "commander";
6
6
  // package.json
7
7
  var package_default = {
8
8
  name: "@staff0rd/assist",
9
- version: "0.468.1",
9
+ version: "0.469.1",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -18504,6 +18504,7 @@ import { z as z6 } from "zod";
18504
18504
  var persistedSessionSchema = z6.object({
18505
18505
  name: z6.string(),
18506
18506
  title: z6.string().optional(),
18507
+ generatedTitle: z6.string().optional(),
18507
18508
  subtitle: z6.string().optional(),
18508
18509
  commandType: z6.enum(["claude", "run", "assist"]),
18509
18510
  harness: z6.enum(["claude", "codex", "pi"]).optional(),
@@ -18526,6 +18527,7 @@ function toPersistedSession(session) {
18526
18527
  return {
18527
18528
  name: session.name,
18528
18529
  title: session.title,
18530
+ generatedTitle: session.generatedTitle,
18529
18531
  subtitle: session.subtitle,
18530
18532
  commandType: session.commandType,
18531
18533
  harness: session.harness,
@@ -27484,6 +27486,7 @@ function toSessionInfo({
27484
27486
  id,
27485
27487
  name,
27486
27488
  title,
27489
+ generatedTitle,
27487
27490
  subtitle,
27488
27491
  commandType,
27489
27492
  harness,
@@ -27515,6 +27518,7 @@ function toSessionInfo({
27515
27518
  id,
27516
27519
  name,
27517
27520
  title,
27521
+ generatedTitle,
27518
27522
  subtitle,
27519
27523
  commandType,
27520
27524
  harness,
@@ -27774,7 +27778,7 @@ function createSession(id, prompt, cwd, design, harness, holdPty) {
27774
27778
  const claudeSessionId = randomUUID7();
27775
27779
  return {
27776
27780
  ...sessionBase(id, prompt ? "running" : "waiting"),
27777
- name: prompt?.slice(0, 40) || `Session ${id}`,
27781
+ name: `Session ${id}`,
27778
27782
  commandType: "claude",
27779
27783
  ...startOrHoldPty(
27780
27784
  () => spawnClaude2({ prompt, cwd, sessionId: id, claudeSessionId, design }),
@@ -27789,7 +27793,7 @@ function createSession(id, prompt, cwd, design, harness, holdPty) {
27789
27793
  function createPiSession(id, prompt, cwd, holdPty) {
27790
27794
  return {
27791
27795
  ...sessionBase(id, prompt ? "running" : "waiting"),
27792
- name: prompt?.slice(0, 40) || `Session ${id}`,
27796
+ name: `Session ${id}`,
27793
27797
  commandType: "claude",
27794
27798
  harness: "pi",
27795
27799
  ...startOrHoldPty(() => spawnPi2({ prompt, cwd, sessionId: id }), holdPty),
@@ -29195,6 +29199,7 @@ function restoreBase(id, persisted) {
29195
29199
  id,
29196
29200
  name: persisted.name,
29197
29201
  title: persisted.title,
29202
+ generatedTitle: persisted.generatedTitle,
29198
29203
  subtitle: persisted.subtitle,
29199
29204
  commandType: persisted.commandType,
29200
29205
  harness: persisted.harness,
@@ -30610,6 +30615,73 @@ function resumeSession(id, sessionId, cwd, name) {
30610
30615
  };
30611
30616
  }
30612
30617
 
30618
+ // src/commands/sessions/daemon/generateSessionTitle.ts
30619
+ import { execFile as execFile9 } from "child_process";
30620
+ import { promisify as promisify8 } from "util";
30621
+ var execFileAsync7 = promisify8(execFile9);
30622
+ var MAX_LENGTH2 = 48;
30623
+ async function generateSessionTitle(prompt) {
30624
+ try {
30625
+ const { stdout } = await execFileAsync7(
30626
+ "claude",
30627
+ ["-p", "--model", "haiku", buildPrompt3(prompt)],
30628
+ { encoding: "utf8", timeout: 3e4 }
30629
+ );
30630
+ return normaliseTitle(stdout);
30631
+ } catch {
30632
+ return void 0;
30633
+ }
30634
+ }
30635
+ function normaliseTitle(stdout) {
30636
+ const title = (stdout.trim().split(/\r?\n/)[0] ?? "").trim().replace(/^["'`]+/, "").replace(/["'`]+$/, "").replace(/[.,:;!?]+$/, "").trim().slice(0, MAX_LENGTH2).trim();
30637
+ return title || void 0;
30638
+ }
30639
+ function buildPrompt3(prompt) {
30640
+ return [
30641
+ "Summarise the task below as a short title for a session card.",
30642
+ "Rules:",
30643
+ "- 2 to 5 words that capture the essence of the task",
30644
+ "- sentence case, no trailing punctuation",
30645
+ "- reply with ONLY the title, no quotes or explanation",
30646
+ "",
30647
+ `Task: ${prompt}`
30648
+ ].join("\n");
30649
+ }
30650
+
30651
+ // src/commands/sessions/daemon/startSessionTitleGeneration.ts
30652
+ function startSessionTitleGeneration(session, notify2) {
30653
+ if (!session || session.generatedTitle) return;
30654
+ const prompt = titlePrompt(session);
30655
+ if (!prompt) return;
30656
+ void generateSessionTitle(prompt).then((title) => {
30657
+ if (!title) {
30658
+ daemonLog(`session ${session.id} title generation failed`);
30659
+ return;
30660
+ }
30661
+ session.generatedTitle = title;
30662
+ daemonLog(`session ${session.id} generated title: ${title}`);
30663
+ notify2();
30664
+ }).catch((error) => {
30665
+ daemonLog(`session ${session.id} title generation errored: ${error}`);
30666
+ });
30667
+ }
30668
+ function titlePrompt(session) {
30669
+ if (session.commandType === "claude")
30670
+ return session.initialPrompt?.trim() || void 0;
30671
+ if (session.commandType !== "assist") return void 0;
30672
+ if (!isDraftCommand(session.assistArgs?.[0])) return void 0;
30673
+ return assistPromptArg(session.assistArgs);
30674
+ }
30675
+ function assistPromptArg(args) {
30676
+ const rest = args?.slice(1).filter((a) => !a.startsWith("--"));
30677
+ const text17 = rest?.[rest.length - 1]?.trim();
30678
+ if (!text17 || isBacklogItemId(text17)) return void 0;
30679
+ return text17;
30680
+ }
30681
+ function isBacklogItemId(text17) {
30682
+ return /^\d+$/.test(text17);
30683
+ }
30684
+
30613
30685
  // src/commands/sessions/daemon/worktree/isPrCheckoutArgs.ts
30614
30686
  var CHECKOUT_COMMANDS = /* @__PURE__ */ new Set(["review", "review-pr-comments"]);
30615
30687
  function isPrCheckoutArgs(args) {
@@ -30624,6 +30696,7 @@ function allocateAndBind(ctx, cwd, create, options2 = {}) {
30624
30696
  const needsSeeding = alloc.kind === "worktree" && alloc.created === true;
30625
30697
  const id = ctx.spawnWith((sid) => create(sid, alloc.cwd, needsSeeding));
30626
30698
  bindNewWorktree(ctx.sessions.get(id), alloc, ctx.notify, ctx.startHeld);
30699
+ startSessionTitleGeneration(ctx.sessions.get(id), ctx.notify);
30627
30700
  return id;
30628
30701
  }
30629
30702
  function spawnInTree(ctx, prompt, cwd, design, harness) {
@@ -31445,7 +31518,7 @@ function summariseSession(jsonlPath2) {
31445
31518
  if (!firstMessage && backlogIds.length === 0) {
31446
31519
  return void 0;
31447
31520
  }
31448
- const prompt = buildPrompt3(firstMessage, backlogIds);
31521
+ const prompt = buildPrompt4(firstMessage, backlogIds);
31449
31522
  try {
31450
31523
  const output = execFileSync14("claude", ["-p", "--model", "haiku", prompt], {
31451
31524
  encoding: "utf8",
@@ -31459,7 +31532,7 @@ function summariseSession(jsonlPath2) {
31459
31532
  return void 0;
31460
31533
  }
31461
31534
  }
31462
- function buildPrompt3(firstMessage, backlogIds) {
31535
+ function buildPrompt4(firstMessage, backlogIds) {
31463
31536
  const parts = [
31464
31537
  "Summarise this Claude Code session in ONE short sentence (under 100 chars).",
31465
31538
  "Return ONLY the summary, no quotes or explanation."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.468.1",
3
+ "version": "0.469.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {