@staff0rd/assist 0.543.0 → 0.544.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.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.543.0",
9
+ version: "0.544.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -20634,45 +20634,58 @@ function validateAnnounce(number, announce) {
20634
20634
  }
20635
20635
  async function reviewPrComments(number, options2 = {}) {
20636
20636
  const announce = options2.announce === true;
20637
+ const resumeSessionId = options2.resumeSessionId;
20637
20638
  validateAnnounce(number, announce);
20638
- if (number) await checkoutPr(number);
20639
- const claudeSessionId = randomUUID6();
20639
+ if (number && !resumeSessionId) await checkoutPr(number);
20640
+ const claudeSessionId = resumeSessionId ?? randomUUID6();
20640
20641
  emitActivity({
20641
20642
  kind: "command",
20642
20643
  name: "review-pr-comments",
20643
20644
  claudeSessionId
20644
20645
  });
20645
- const { done: done2 } = spawnClaude(buildPrompt2(number, announce), {
20646
- permissionMode: "acceptEdits",
20647
- sessionId: claudeSessionId
20648
- });
20646
+ const { done: done2 } = spawnClaude(
20647
+ resumeSessionId ? resumeNudge() : buildPrompt2(number, announce),
20648
+ {
20649
+ permissionMode: "acceptEdits",
20650
+ sessionId: claudeSessionId,
20651
+ resumeSessionId
20652
+ }
20653
+ );
20649
20654
  await done2;
20650
20655
  }
20651
20656
 
20652
20657
  // src/commands/fixConflict.ts
20653
20658
  import { randomUUID as randomUUID7 } from "crypto";
20659
+ function buildPrompt3(rebase) {
20660
+ return rebase ? "/fix-conflict --rebase" : "/fix-conflict";
20661
+ }
20654
20662
  async function fixConflict(number, options2 = {}) {
20655
- if (number) await checkoutPr(number);
20656
- const claudeSessionId = randomUUID7();
20663
+ const { resumeSessionId } = options2;
20664
+ if (number && !resumeSessionId) await checkoutPr(number);
20665
+ const claudeSessionId = resumeSessionId ?? randomUUID7();
20657
20666
  emitActivity({
20658
20667
  kind: "command",
20659
20668
  name: "fix-conflict",
20660
20669
  claudeSessionId
20661
20670
  });
20662
20671
  const { done: done2 } = spawnClaude(
20663
- options2.rebase === true ? "/fix-conflict --rebase" : "/fix-conflict",
20672
+ resumeSessionId ? resumeNudge() : buildPrompt3(options2.rebase === true),
20664
20673
  {
20665
20674
  permissionMode: "auto",
20666
- sessionId: claudeSessionId
20675
+ sessionId: claudeSessionId,
20676
+ resumeSessionId
20667
20677
  }
20668
20678
  );
20669
20679
  await done2;
20670
20680
  }
20671
20681
 
20672
20682
  // src/commands/registerFixConflict.ts
20673
- function registerFixConflict(program2) {
20674
- program2.command("fix-conflict").argument("[number]", "PR number to check out first").option("--rebase", "Rebase onto the remote default instead of merging").description("Launch Claude in /fix-conflict mode (single session)").action(
20675
- (number, options2) => fixConflict(number, options2)
20683
+ function registerFixConflict(program2, resumeFlag) {
20684
+ program2.command("fix-conflict").argument("[number]", "PR number to check out first").option("--rebase", "Rebase onto the remote default instead of merging").option("--resume-session <id>", resumeFlag).description("Launch Claude in /fix-conflict mode (single session)").action(
20685
+ (number, options2) => fixConflict(number, {
20686
+ rebase: options2.rebase,
20687
+ resumeSessionId: options2.resumeSession
20688
+ })
20676
20689
  );
20677
20690
  }
20678
20691
 
@@ -20700,8 +20713,11 @@ function registerReviewPrComments(program2) {
20700
20713
  program2.command("review-pr-comments").argument("[number]", "PR number to check out first").description("Launch Claude in /review-pr-comments mode (single session)").option(
20701
20714
  "--announce",
20702
20715
  "After every comment thread is processed, announce the PR in Slack via /prs-slack <number> --no-confirm (requires a PR number)"
20703
- ).action(
20704
- (number, opts) => reviewPrComments(number, opts)
20716
+ ).option("--resume-session <id>", RESUME_SESSION_FLAG).action(
20717
+ (number, opts) => reviewPrComments(number, {
20718
+ announce: opts.announce,
20719
+ resumeSessionId: opts.resumeSession
20720
+ })
20705
20721
  );
20706
20722
  }
20707
20723
  function registerLaunch(program2) {
@@ -20720,7 +20736,7 @@ function registerLaunch(program2) {
20720
20736
  "Launch Claude in /bug mode, chain into next on /next signal"
20721
20737
  );
20722
20738
  registerReviewPrComments(program2);
20723
- registerFixConflict(program2);
20739
+ registerFixConflict(program2, RESUME_SESSION_FLAG);
20724
20740
  registerRefineLaunch(program2, RESUME_SESSION_FLAG);
20725
20741
  }
20726
20742
 
@@ -28084,7 +28100,7 @@ function askQuestion(rl, question) {
28084
28100
  }
28085
28101
 
28086
28102
  // src/commands/transcript/configure.ts
28087
- function buildPrompt3(label2, current) {
28103
+ function buildPrompt4(label2, current) {
28088
28104
  return current ? `${label2} [${current}]: ` : `${label2}: `;
28089
28105
  }
28090
28106
  function printExisting(existing) {
@@ -28097,15 +28113,15 @@ function printExisting(existing) {
28097
28113
  async function promptDirectories(rl, existing) {
28098
28114
  const vttDir = await askQuestion(
28099
28115
  rl,
28100
- buildPrompt3("VTT directory", existing?.vttDir)
28116
+ buildPrompt4("VTT directory", existing?.vttDir)
28101
28117
  );
28102
28118
  const transcriptsDir = await askQuestion(
28103
28119
  rl,
28104
- buildPrompt3("Transcripts directory", existing?.transcriptsDir)
28120
+ buildPrompt4("Transcripts directory", existing?.transcriptsDir)
28105
28121
  );
28106
28122
  const summaryDir = await askQuestion(
28107
28123
  rl,
28108
- buildPrompt3("Summary directory", existing?.summaryDir)
28124
+ buildPrompt4("Summary directory", existing?.summaryDir)
28109
28125
  );
28110
28126
  return {
28111
28127
  vttDir: vttDir || existing?.vttDir || "",
@@ -31351,7 +31367,7 @@ async function generateSessionTitle(prompt) {
31351
31367
  try {
31352
31368
  const { stdout } = await execFileAsync8(
31353
31369
  "claude",
31354
- ["-p", "--model", "haiku", buildPrompt4(prompt)],
31370
+ ["-p", "--model", "haiku", buildPrompt5(prompt)],
31355
31371
  { encoding: "utf8", windowsHide: true, timeout: 3e4 }
31356
31372
  );
31357
31373
  return normaliseTitle(stdout);
@@ -31363,7 +31379,7 @@ function normaliseTitle(stdout) {
31363
31379
  const title = (stdout.trim().split(/\r?\n/)[0] ?? "").trim().replace(/^["'`]+/, "").replace(/["'`]+$/, "").replace(/[.,:;!?]+$/, "").trim().slice(0, SESSION_TITLE_MAX_LENGTH).trim();
31364
31380
  return title || void 0;
31365
31381
  }
31366
- function buildPrompt4(prompt) {
31382
+ function buildPrompt5(prompt) {
31367
31383
  return [
31368
31384
  "Summarise the task below as a short title for a session card.",
31369
31385
  "Rules:",
@@ -31449,6 +31465,30 @@ function missingRunConfigCwd(session) {
31449
31465
  return `run config "${config.name}": cwd ${configured} does not exist`;
31450
31466
  }
31451
31467
 
31468
+ // src/commands/sessions/daemon/exitOutputTail.ts
31469
+ var ANSI = new RegExp(
31470
+ `${String.fromCharCode(27)}\\[[0-9;?]*[ -/]*[@-~]`,
31471
+ "g"
31472
+ );
31473
+ var MAX_TAIL_LINES = 5;
31474
+ var MAX_TAIL_CHARS = 500;
31475
+ function exitOutputTail(scrollback) {
31476
+ const lines2 = scrollback.replace(ANSI, "").split(/\r?\n|\r/).map((line) => line.trim()).filter((line) => line.length > 0);
31477
+ if (lines2.length === 0) return void 0;
31478
+ return lines2.slice(-MAX_TAIL_LINES).join(" | ").slice(-MAX_TAIL_CHARS);
31479
+ }
31480
+
31481
+ // src/commands/sessions/daemon/handleErroredExit.ts
31482
+ function handleErroredExit(session, exitCode, priorStatus, onStatusChange) {
31483
+ const detail = exitDetail(session);
31484
+ session.error = exitReason(exitCode, detail);
31485
+ const output = exitOutputTail(session.scrollback);
31486
+ daemonLog(
31487
+ `session ${session.id} ("${session.name}") pty exited with code ${exitCode} from status "${priorStatus}" \u2014 unexpected exit, marking error${detail ? `: ${detail}` : ""}${output ? `; output: ${output}` : ""}`
31488
+ );
31489
+ onStatusChange(session, "error", exitCode);
31490
+ }
31491
+
31452
31492
  // src/commands/sessions/daemon/handleFailedResume.ts
31453
31493
  function handleFailedResume(session, exitCode, onStatusChange) {
31454
31494
  const failed2 = session.restored === true && exitCode !== 0 && session.scrollback.length === 0;
@@ -31595,12 +31635,7 @@ function handlePtyExit(session, exitCode, onStatusChange) {
31595
31635
  if (handleFailedResume(session, exitCode, onStatusChange)) return;
31596
31636
  const priorStatus = session.status;
31597
31637
  if (exitCode !== 0) {
31598
- const detail = exitDetail(session);
31599
- session.error = exitReason(exitCode, detail);
31600
- daemonLog(
31601
- `session ${session.id} ("${session.name}") pty exited with code ${exitCode} from status "${priorStatus}" \u2014 unexpected exit, marking error${detail ? `: ${detail}` : ""}`
31602
- );
31603
- onStatusChange(session, "error", exitCode);
31638
+ handleErroredExit(session, exitCode, priorStatus, onStatusChange);
31604
31639
  return;
31605
31640
  }
31606
31641
  const unexpected = priorStatus === "waiting";
@@ -32471,10 +32506,26 @@ function harnessResumesConversation(harness) {
32471
32506
  return RESUMES_CONVERSATION[resolveHarness(harness)];
32472
32507
  }
32473
32508
 
32509
+ // src/shared/acceptsResumeSession.ts
32510
+ var RESUME_SESSION_COMMANDS = /* @__PURE__ */ new Set([
32511
+ "draft",
32512
+ "feat",
32513
+ "bug",
32514
+ "refine",
32515
+ "fix-conflict",
32516
+ "review-pr-comments"
32517
+ ]);
32518
+ function acceptsResumeSession(assistArgs) {
32519
+ const [command, subcommand] = assistArgs;
32520
+ if (!command) return false;
32521
+ if (command === "backlog") return subcommand === "run";
32522
+ return RESUME_SESSION_COMMANDS.has(command);
32523
+ }
32524
+
32474
32525
  // src/commands/sessions/daemon/assistResumeArgs.ts
32475
32526
  function assistResumeArgs(session) {
32476
32527
  const args = ["assist", ...session.assistArgs];
32477
- return session.claudeSessionId ? [...args, "--resume-session", session.claudeSessionId] : args;
32528
+ return session.claudeSessionId && acceptsResumeSession(session.assistArgs) ? [...args, "--resume-session", session.claudeSessionId] : args;
32478
32529
  }
32479
32530
 
32480
32531
  // src/commands/sessions/daemon/interactiveRespawnPlan.ts
@@ -34267,8 +34318,6 @@ function joinableStream(sessions, targetId) {
34267
34318
  if (target.commandType === "run")
34268
34319
  return { reason: "a server run has no agent stream" };
34269
34320
  if (target.closing === true) return { reason: "the session is closing" };
34270
- if (target.status !== "running" && target.status !== "waiting")
34271
- return { reason: `the session is ${target.status}` };
34272
34321
  if (!target.cwd) return { reason: "the session has no working directory" };
34273
34322
  return { session: target };
34274
34323
  }
@@ -35162,7 +35211,7 @@ function summariseSession(jsonlPath2) {
35162
35211
  if (!firstMessage && backlogIds.length === 0) {
35163
35212
  return void 0;
35164
35213
  }
35165
- const prompt = buildPrompt5(firstMessage, backlogIds);
35214
+ const prompt = buildPrompt6(firstMessage, backlogIds);
35166
35215
  try {
35167
35216
  const output = execFileSync15("claude", ["-p", "--model", "haiku", prompt], {
35168
35217
  encoding: "utf8",
@@ -35176,7 +35225,7 @@ function summariseSession(jsonlPath2) {
35176
35225
  return void 0;
35177
35226
  }
35178
35227
  }
35179
- function buildPrompt5(firstMessage, backlogIds) {
35228
+ function buildPrompt6(firstMessage, backlogIds) {
35180
35229
  const parts = [
35181
35230
  "Summarise this Claude Code session in ONE short sentence (under 100 chars).",
35182
35231
  "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.543.0",
3
+ "version": "0.544.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {