@staff0rd/assist 0.542.1 → 0.543.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.542.1",
9
+ version: "0.543.1",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -8215,7 +8215,8 @@ function deriveHistoryFields(commandName, commandArgs, name) {
8215
8215
  return fields;
8216
8216
  }
8217
8217
  function deriveSessionType(commandName, name) {
8218
- if (commandName === "review-pr-comments") return "review";
8218
+ if (commandName === "review-pr-comments" || commandName === "fix-conflict")
8219
+ return "review";
8219
8220
  if (KNOWN.includes(commandName))
8220
8221
  return commandName;
8221
8222
  if (commandName || name) return "prompt";
@@ -20633,41 +20634,59 @@ function validateAnnounce(number, announce) {
20633
20634
  }
20634
20635
  async function reviewPrComments(number, options2 = {}) {
20635
20636
  const announce = options2.announce === true;
20637
+ const resumeSessionId = options2.resumeSessionId;
20636
20638
  validateAnnounce(number, announce);
20637
- if (number) await checkoutPr(number);
20638
- const claudeSessionId = randomUUID6();
20639
+ if (number && !resumeSessionId) await checkoutPr(number);
20640
+ const claudeSessionId = resumeSessionId ?? randomUUID6();
20639
20641
  emitActivity({
20640
20642
  kind: "command",
20641
20643
  name: "review-pr-comments",
20642
20644
  claudeSessionId
20643
20645
  });
20644
- const { done: done2 } = spawnClaude(buildPrompt2(number, announce), {
20645
- permissionMode: "acceptEdits",
20646
- sessionId: claudeSessionId
20647
- });
20646
+ const { done: done2 } = spawnClaude(
20647
+ resumeSessionId ? resumeNudge() : buildPrompt2(number, announce),
20648
+ {
20649
+ permissionMode: "acceptEdits",
20650
+ sessionId: claudeSessionId,
20651
+ resumeSessionId
20652
+ }
20653
+ );
20648
20654
  await done2;
20649
20655
  }
20650
20656
 
20651
20657
  // src/commands/fixConflict.ts
20652
20658
  import { randomUUID as randomUUID7 } from "crypto";
20653
- async function fixConflict(number) {
20654
- if (number) await checkoutPr(number);
20655
- const claudeSessionId = randomUUID7();
20659
+ function buildPrompt3(rebase) {
20660
+ return rebase ? "/fix-conflict --rebase" : "/fix-conflict";
20661
+ }
20662
+ async function fixConflict(number, options2 = {}) {
20663
+ const { resumeSessionId } = options2;
20664
+ if (number && !resumeSessionId) await checkoutPr(number);
20665
+ const claudeSessionId = resumeSessionId ?? randomUUID7();
20656
20666
  emitActivity({
20657
20667
  kind: "command",
20658
20668
  name: "fix-conflict",
20659
20669
  claudeSessionId
20660
20670
  });
20661
- const { done: done2 } = spawnClaude("/fix-conflict", {
20662
- permissionMode: "auto",
20663
- sessionId: claudeSessionId
20664
- });
20671
+ const { done: done2 } = spawnClaude(
20672
+ resumeSessionId ? resumeNudge() : buildPrompt3(options2.rebase === true),
20673
+ {
20674
+ permissionMode: "auto",
20675
+ sessionId: claudeSessionId,
20676
+ resumeSessionId
20677
+ }
20678
+ );
20665
20679
  await done2;
20666
20680
  }
20667
20681
 
20668
20682
  // src/commands/registerFixConflict.ts
20669
- function registerFixConflict(program2) {
20670
- program2.command("fix-conflict").argument("[number]", "PR number to check out first").description("Launch Claude in /fix-conflict mode (single session)").action((number) => fixConflict(number));
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
+ })
20689
+ );
20671
20690
  }
20672
20691
 
20673
20692
  // src/commands/registerLaunch.ts
@@ -20694,8 +20713,11 @@ function registerReviewPrComments(program2) {
20694
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(
20695
20714
  "--announce",
20696
20715
  "After every comment thread is processed, announce the PR in Slack via /prs-slack <number> --no-confirm (requires a PR number)"
20697
- ).action(
20698
- (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
+ })
20699
20721
  );
20700
20722
  }
20701
20723
  function registerLaunch(program2) {
@@ -20714,7 +20736,7 @@ function registerLaunch(program2) {
20714
20736
  "Launch Claude in /bug mode, chain into next on /next signal"
20715
20737
  );
20716
20738
  registerReviewPrComments(program2);
20717
- registerFixConflict(program2);
20739
+ registerFixConflict(program2, RESUME_SESSION_FLAG);
20718
20740
  registerRefineLaunch(program2, RESUME_SESSION_FLAG);
20719
20741
  }
20720
20742
 
@@ -28078,7 +28100,7 @@ function askQuestion(rl, question) {
28078
28100
  }
28079
28101
 
28080
28102
  // src/commands/transcript/configure.ts
28081
- function buildPrompt3(label2, current) {
28103
+ function buildPrompt4(label2, current) {
28082
28104
  return current ? `${label2} [${current}]: ` : `${label2}: `;
28083
28105
  }
28084
28106
  function printExisting(existing) {
@@ -28091,15 +28113,15 @@ function printExisting(existing) {
28091
28113
  async function promptDirectories(rl, existing) {
28092
28114
  const vttDir = await askQuestion(
28093
28115
  rl,
28094
- buildPrompt3("VTT directory", existing?.vttDir)
28116
+ buildPrompt4("VTT directory", existing?.vttDir)
28095
28117
  );
28096
28118
  const transcriptsDir = await askQuestion(
28097
28119
  rl,
28098
- buildPrompt3("Transcripts directory", existing?.transcriptsDir)
28120
+ buildPrompt4("Transcripts directory", existing?.transcriptsDir)
28099
28121
  );
28100
28122
  const summaryDir = await askQuestion(
28101
28123
  rl,
28102
- buildPrompt3("Summary directory", existing?.summaryDir)
28124
+ buildPrompt4("Summary directory", existing?.summaryDir)
28103
28125
  );
28104
28126
  return {
28105
28127
  vttDir: vttDir || existing?.vttDir || "",
@@ -31345,7 +31367,7 @@ async function generateSessionTitle(prompt) {
31345
31367
  try {
31346
31368
  const { stdout } = await execFileAsync8(
31347
31369
  "claude",
31348
- ["-p", "--model", "haiku", buildPrompt4(prompt)],
31370
+ ["-p", "--model", "haiku", buildPrompt5(prompt)],
31349
31371
  { encoding: "utf8", windowsHide: true, timeout: 3e4 }
31350
31372
  );
31351
31373
  return normaliseTitle(stdout);
@@ -31357,7 +31379,7 @@ function normaliseTitle(stdout) {
31357
31379
  const title = (stdout.trim().split(/\r?\n/)[0] ?? "").trim().replace(/^["'`]+/, "").replace(/["'`]+$/, "").replace(/[.,:;!?]+$/, "").trim().slice(0, SESSION_TITLE_MAX_LENGTH).trim();
31358
31380
  return title || void 0;
31359
31381
  }
31360
- function buildPrompt4(prompt) {
31382
+ function buildPrompt5(prompt) {
31361
31383
  return [
31362
31384
  "Summarise the task below as a short title for a session card.",
31363
31385
  "Rules:",
@@ -31443,6 +31465,30 @@ function missingRunConfigCwd(session) {
31443
31465
  return `run config "${config.name}": cwd ${configured} does not exist`;
31444
31466
  }
31445
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
+
31446
31492
  // src/commands/sessions/daemon/handleFailedResume.ts
31447
31493
  function handleFailedResume(session, exitCode, onStatusChange) {
31448
31494
  const failed2 = session.restored === true && exitCode !== 0 && session.scrollback.length === 0;
@@ -31589,12 +31635,7 @@ function handlePtyExit(session, exitCode, onStatusChange) {
31589
31635
  if (handleFailedResume(session, exitCode, onStatusChange)) return;
31590
31636
  const priorStatus = session.status;
31591
31637
  if (exitCode !== 0) {
31592
- const detail = exitDetail(session);
31593
- session.error = exitReason(exitCode, detail);
31594
- daemonLog(
31595
- `session ${session.id} ("${session.name}") pty exited with code ${exitCode} from status "${priorStatus}" \u2014 unexpected exit, marking error${detail ? `: ${detail}` : ""}`
31596
- );
31597
- onStatusChange(session, "error", exitCode);
31638
+ handleErroredExit(session, exitCode, priorStatus, onStatusChange);
31598
31639
  return;
31599
31640
  }
31600
31641
  const unexpected = priorStatus === "waiting";
@@ -32465,10 +32506,26 @@ function harnessResumesConversation(harness) {
32465
32506
  return RESUMES_CONVERSATION[resolveHarness(harness)];
32466
32507
  }
32467
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
+
32468
32525
  // src/commands/sessions/daemon/assistResumeArgs.ts
32469
32526
  function assistResumeArgs(session) {
32470
32527
  const args = ["assist", ...session.assistArgs];
32471
- return session.claudeSessionId ? [...args, "--resume-session", session.claudeSessionId] : args;
32528
+ return session.claudeSessionId && acceptsResumeSession(session.assistArgs) ? [...args, "--resume-session", session.claudeSessionId] : args;
32472
32529
  }
32473
32530
 
32474
32531
  // src/commands/sessions/daemon/interactiveRespawnPlan.ts
@@ -33400,7 +33457,11 @@ function isBacklogRunArgs(args) {
33400
33457
  }
33401
33458
 
33402
33459
  // src/commands/sessions/daemon/worktree/isPrCheckoutArgs.ts
33403
- var CHECKOUT_COMMANDS = /* @__PURE__ */ new Set(["review", "review-pr-comments"]);
33460
+ var CHECKOUT_COMMANDS = /* @__PURE__ */ new Set([
33461
+ "review",
33462
+ "review-pr-comments",
33463
+ "fix-conflict"
33464
+ ]);
33404
33465
  function isPrCheckoutArgs(args) {
33405
33466
  const [command, ...rest] = args;
33406
33467
  if (!command || !CHECKOUT_COMMANDS.has(command)) return false;
@@ -35152,7 +35213,7 @@ function summariseSession(jsonlPath2) {
35152
35213
  if (!firstMessage && backlogIds.length === 0) {
35153
35214
  return void 0;
35154
35215
  }
35155
- const prompt = buildPrompt5(firstMessage, backlogIds);
35216
+ const prompt = buildPrompt6(firstMessage, backlogIds);
35156
35217
  try {
35157
35218
  const output = execFileSync15("claude", ["-p", "--model", "haiku", prompt], {
35158
35219
  encoding: "utf8",
@@ -35166,7 +35227,7 @@ function summariseSession(jsonlPath2) {
35166
35227
  return void 0;
35167
35228
  }
35168
35229
  }
35169
- function buildPrompt5(firstMessage, backlogIds) {
35230
+ function buildPrompt6(firstMessage, backlogIds) {
35170
35231
  const parts = [
35171
35232
  "Summarise this Claude Code session in ONE short sentence (under 100 chars).",
35172
35233
  "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.542.1",
3
+ "version": "0.543.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {