@staff0rd/assist 0.563.0 → 0.565.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.563.0",
9
+ version: "0.565.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -13790,9 +13790,125 @@ function registerCloneCommand(cmd) {
13790
13790
 
13791
13791
  // src/commands/backlog/comment/index.ts
13792
13792
  import chalk71 from "chalk";
13793
+
13794
+ // src/commands/backlog/comment/reviewProposedComment.ts
13795
+ import { randomUUID as randomUUID2 } from "crypto";
13796
+
13797
+ // src/commands/sessions/shared/reportPreviewRejection.ts
13798
+ function reportPreviewRejection(subject, decision) {
13799
+ console.error(
13800
+ `${subject} rejected${decision.reason ? `: ${decision.reason}` : "."}`
13801
+ );
13802
+ const comments3 = decision.comments ?? [];
13803
+ if (comments3.length > 0) {
13804
+ console.error(
13805
+ `
13806
+ The reviewer left ${comments3.length} comment${comments3.length === 1 ? "" : "s"} on the preview. Address each one, then re-run this command:
13807
+ `
13808
+ );
13809
+ for (const [i, c] of comments3.entries()) {
13810
+ const quoted = c.quote.split("\n").map((line) => ` > ${line}`).join("\n");
13811
+ console.error(`${i + 1}. On:
13812
+ ${quoted}
13813
+ Comment: ${c.note}
13814
+ `);
13815
+ }
13816
+ }
13817
+ process.exit(1);
13818
+ }
13819
+
13820
+ // src/commands/sessions/shared/toPreviewDecision.ts
13821
+ function toPreviewDecision(msg) {
13822
+ if (msg.decision !== "approve" && msg.decision !== "reject") return null;
13823
+ return {
13824
+ decision: msg.decision,
13825
+ reason: msg.reason,
13826
+ comments: Array.isArray(msg.comments) ? msg.comments : void 0,
13827
+ screenshots: Array.isArray(msg.screenshots) ? msg.screenshots : void 0,
13828
+ reviewAfter: msg.reviewAfter === true,
13829
+ announceAfter: msg.announceAfter === true,
13830
+ draft: typeof msg.draft === "boolean" ? msg.draft : void 0
13831
+ };
13832
+ }
13833
+
13834
+ // src/commands/sessions/shared/parsePreviewDecision.ts
13835
+ function parsePreviewDecision(line, requestId) {
13836
+ try {
13837
+ const msg = JSON.parse(line);
13838
+ if (msg.type === "error" && (msg.message ?? "").includes("pr-preview"))
13839
+ return { kind: "error", message: msg.message ?? "pr-preview failed" };
13840
+ if (msg.type !== "pr-decision" || msg.requestId !== requestId) return null;
13841
+ const decision = toPreviewDecision(msg);
13842
+ return decision ? { kind: "decision", decision } : null;
13843
+ } catch {
13844
+ return null;
13845
+ }
13846
+ }
13847
+
13848
+ // src/commands/sessions/shared/requestPreviewDecision.ts
13849
+ function requestPreviewDecision(request) {
13850
+ return new Promise((resolve24, reject) => {
13851
+ connectToDaemon().then((socket) => {
13852
+ let settled = false;
13853
+ const finish = (error, decision) => {
13854
+ if (settled) return;
13855
+ settled = true;
13856
+ socket.destroy();
13857
+ if (error) reject(error);
13858
+ else resolve24(decision);
13859
+ };
13860
+ readSocketLines(socket, (line) => {
13861
+ const incoming = parsePreviewDecision(line, request.requestId);
13862
+ if (!incoming) return;
13863
+ if (incoming.kind === "error") finish(new Error(incoming.message));
13864
+ else finish(void 0, incoming.decision);
13865
+ });
13866
+ socket.on("error", (error) => finish(error));
13867
+ socket.on(
13868
+ "close",
13869
+ () => finish(new Error("daemon closed before a decision was made"))
13870
+ );
13871
+ socket.write(`${JSON.stringify({ type: "pr-preview", ...request })}
13872
+ `);
13873
+ }, reject);
13874
+ });
13875
+ }
13876
+
13877
+ // src/commands/sessions/shared/awaitPreviewApproval.ts
13878
+ async function awaitPreviewApproval(subject, request) {
13879
+ console.log("Awaiting your approval in the assist web UI preview pane\u2026");
13880
+ let decision;
13881
+ try {
13882
+ decision = await requestPreviewDecision(request);
13883
+ } catch (error) {
13884
+ console.error(
13885
+ `Error: ${error instanceof Error ? error.message : String(error)}`
13886
+ );
13887
+ process.exit(1);
13888
+ }
13889
+ if (decision.decision === "reject") reportPreviewRejection(subject, decision);
13890
+ return decision;
13891
+ }
13892
+
13893
+ // src/commands/backlog/comment/reviewProposedComment.ts
13894
+ async function reviewProposedComment(item, text18) {
13895
+ const sessionId = process.env.ASSIST_SESSION_ID;
13896
+ if (process.env.ASSIST_SESSION !== "1" || !sessionId) return;
13897
+ await awaitPreviewApproval("Backlog comment preview", {
13898
+ sessionId,
13899
+ requestId: randomUUID2(),
13900
+ title: `Comment on ${formatItemId(item.id)}: ${item.name}`,
13901
+ body: text18,
13902
+ prNumber: null,
13903
+ kind: "backlog-comment"
13904
+ });
13905
+ }
13906
+
13907
+ // src/commands/backlog/comment/index.ts
13793
13908
  async function comment(id, text18) {
13794
13909
  const found = await findOneItem(id);
13795
13910
  if (!found) process.exit(1);
13911
+ await reviewProposedComment(found.item, text18);
13796
13912
  await appendComment(found.orm, found.item.id, text18);
13797
13913
  console.log(
13798
13914
  chalk71.green(`Comment added to item ${formatItemId(found.item.id)}.`)
@@ -14302,103 +14418,7 @@ async function resolveInsertPosition(orm, itemId2, position) {
14302
14418
  }
14303
14419
 
14304
14420
  // src/commands/backlog/addPhase/reviewProposedPhase.ts
14305
- import { randomUUID as randomUUID2 } from "crypto";
14306
-
14307
- // src/commands/sessions/shared/reportPreviewRejection.ts
14308
- function reportPreviewRejection(subject, decision) {
14309
- console.error(
14310
- `${subject} rejected${decision.reason ? `: ${decision.reason}` : "."}`
14311
- );
14312
- const comments3 = decision.comments ?? [];
14313
- if (comments3.length > 0) {
14314
- console.error(
14315
- `
14316
- The reviewer left ${comments3.length} comment${comments3.length === 1 ? "" : "s"} on the preview. Address each one, then re-run this command:
14317
- `
14318
- );
14319
- for (const [i, c] of comments3.entries()) {
14320
- const quoted = c.quote.split("\n").map((line) => ` > ${line}`).join("\n");
14321
- console.error(`${i + 1}. On:
14322
- ${quoted}
14323
- Comment: ${c.note}
14324
- `);
14325
- }
14326
- }
14327
- process.exit(1);
14328
- }
14329
-
14330
- // src/commands/sessions/shared/toPreviewDecision.ts
14331
- function toPreviewDecision(msg) {
14332
- if (msg.decision !== "approve" && msg.decision !== "reject") return null;
14333
- return {
14334
- decision: msg.decision,
14335
- reason: msg.reason,
14336
- comments: Array.isArray(msg.comments) ? msg.comments : void 0,
14337
- screenshots: Array.isArray(msg.screenshots) ? msg.screenshots : void 0,
14338
- reviewAfter: msg.reviewAfter === true,
14339
- announceAfter: msg.announceAfter === true,
14340
- draft: typeof msg.draft === "boolean" ? msg.draft : void 0
14341
- };
14342
- }
14343
-
14344
- // src/commands/sessions/shared/parsePreviewDecision.ts
14345
- function parsePreviewDecision(line, requestId) {
14346
- try {
14347
- const msg = JSON.parse(line);
14348
- if (msg.type === "error" && (msg.message ?? "").includes("pr-preview"))
14349
- return { kind: "error", message: msg.message ?? "pr-preview failed" };
14350
- if (msg.type !== "pr-decision" || msg.requestId !== requestId) return null;
14351
- const decision = toPreviewDecision(msg);
14352
- return decision ? { kind: "decision", decision } : null;
14353
- } catch {
14354
- return null;
14355
- }
14356
- }
14357
-
14358
- // src/commands/sessions/shared/requestPreviewDecision.ts
14359
- function requestPreviewDecision(request) {
14360
- return new Promise((resolve24, reject) => {
14361
- connectToDaemon().then((socket) => {
14362
- let settled = false;
14363
- const finish = (error, decision) => {
14364
- if (settled) return;
14365
- settled = true;
14366
- socket.destroy();
14367
- if (error) reject(error);
14368
- else resolve24(decision);
14369
- };
14370
- readSocketLines(socket, (line) => {
14371
- const incoming = parsePreviewDecision(line, request.requestId);
14372
- if (!incoming) return;
14373
- if (incoming.kind === "error") finish(new Error(incoming.message));
14374
- else finish(void 0, incoming.decision);
14375
- });
14376
- socket.on("error", (error) => finish(error));
14377
- socket.on(
14378
- "close",
14379
- () => finish(new Error("daemon closed before a decision was made"))
14380
- );
14381
- socket.write(`${JSON.stringify({ type: "pr-preview", ...request })}
14382
- `);
14383
- }, reject);
14384
- });
14385
- }
14386
-
14387
- // src/commands/sessions/shared/awaitPreviewApproval.ts
14388
- async function awaitPreviewApproval(subject, request) {
14389
- console.log("Awaiting your approval in the assist web UI preview pane\u2026");
14390
- let decision;
14391
- try {
14392
- decision = await requestPreviewDecision(request);
14393
- } catch (error) {
14394
- console.error(
14395
- `Error: ${error instanceof Error ? error.message : String(error)}`
14396
- );
14397
- process.exit(1);
14398
- }
14399
- if (decision.decision === "reject") reportPreviewRejection(subject, decision);
14400
- return decision;
14401
- }
14421
+ import { randomUUID as randomUUID3 } from "crypto";
14402
14422
 
14403
14423
  // src/commands/backlog/renderPhaseSection.ts
14404
14424
  function renderPhaseSection(phase, idx) {
@@ -14422,7 +14442,7 @@ async function reviewProposedPhase(item, phaseIdx, phase) {
14422
14442
  return;
14423
14443
  await awaitPreviewApproval("Backlog phase preview", {
14424
14444
  sessionId,
14425
- requestId: randomUUID2(),
14445
+ requestId: randomUUID3(),
14426
14446
  title: `Add a phase to ${formatItemId(item.id)}: ${item.name}`,
14427
14447
  body: renderPhaseSection(phase, phaseIdx),
14428
14448
  prNumber: null,
@@ -14564,7 +14584,7 @@ function readProposedItem(source) {
14564
14584
  }
14565
14585
 
14566
14586
  // src/commands/backlog/propose/reviewProposal.ts
14567
- import { randomUUID as randomUUID3 } from "crypto";
14587
+ import { randomUUID as randomUUID4 } from "crypto";
14568
14588
  import chalk82 from "chalk";
14569
14589
 
14570
14590
  // src/commands/backlog/propose/renderProposedItem.ts
@@ -14587,7 +14607,7 @@ async function reviewProposal(item, sessionId, confirmed) {
14587
14607
  if (sessionId) {
14588
14608
  await awaitPreviewApproval("Backlog item preview", {
14589
14609
  sessionId,
14590
- requestId: randomUUID3(),
14610
+ requestId: randomUUID4(),
14591
14611
  title: item.name,
14592
14612
  body,
14593
14613
  prNumber: null,
@@ -14884,7 +14904,7 @@ import chalk91 from "chalk";
14884
14904
  import enquirer7 from "enquirer";
14885
14905
 
14886
14906
  // src/commands/backlog/launchMode.ts
14887
- import { randomUUID as randomUUID4 } from "crypto";
14907
+ import { randomUUID as randomUUID5 } from "crypto";
14888
14908
 
14889
14909
  // src/commands/backlog/handleLaunchSignal.ts
14890
14910
  import chalk90 from "chalk";
@@ -14989,7 +15009,7 @@ async function launchMode(slashCommand, options2) {
14989
15009
  const resumeSessionId = options2?.resumeSessionId;
14990
15010
  if (!resumeSessionId) pullIfConfigured();
14991
15011
  process.env.ASSIST_SESSION_ID ??= String(process.pid);
14992
- const claudeSessionId = resumeSessionId ?? randomUUID4();
15012
+ const claudeSessionId = resumeSessionId ?? randomUUID5();
14993
15013
  const harness = options2?.harness ?? "claude";
14994
15014
  reportLaunchActivity(slashCommand, claudeSessionId, harness, options2);
14995
15015
  const prompt = resumeSessionId ? resumeNudge() : buildSlashCommand(slashCommand, options2?.description);
@@ -16005,7 +16025,7 @@ async function replacePlan(orm, itemId2, phases, currentPhase) {
16005
16025
  }
16006
16026
 
16007
16027
  // src/commands/backlog/updatePlan/reviewPlanUpdate.ts
16008
- import { randomUUID as randomUUID5 } from "crypto";
16028
+ import { randomUUID as randomUUID6 } from "crypto";
16009
16029
  import chalk116 from "chalk";
16010
16030
 
16011
16031
  // src/commands/backlog/updatePlan/isCompleted.ts
@@ -16162,7 +16182,7 @@ async function reviewPlanUpdate(item, phases) {
16162
16182
  if (process.env.ASSIST_SESSION === "1" && sessionId) {
16163
16183
  await awaitPreviewApproval("Plan update preview", {
16164
16184
  sessionId,
16165
- requestId: randomUUID5(),
16185
+ requestId: randomUUID6(),
16166
16186
  title: `Update the plan for ${formatItemId(item.id)}: ${item.name}`,
16167
16187
  body,
16168
16188
  prNumber: null,
@@ -20925,7 +20945,7 @@ function registerRefineLaunch(program2, resumeFlag) {
20925
20945
  }
20926
20946
 
20927
20947
  // src/commands/reviewPrComments.ts
20928
- import { randomUUID as randomUUID6 } from "crypto";
20948
+ import { randomUUID as randomUUID7 } from "crypto";
20929
20949
 
20930
20950
  // src/commands/review/checkoutPr.ts
20931
20951
  import { execFileSync as execFileSync7 } from "child_process";
@@ -21557,7 +21577,7 @@ async function reviewPrComments(number, options2 = {}) {
21557
21577
  const resumeSessionId = options2.resumeSessionId;
21558
21578
  validateAnnounce(number, announce);
21559
21579
  if (number && !resumeSessionId) await checkoutPr(number);
21560
- const claudeSessionId = resumeSessionId ?? randomUUID6();
21580
+ const claudeSessionId = resumeSessionId ?? randomUUID7();
21561
21581
  emitActivity({
21562
21582
  kind: "command",
21563
21583
  name: "review-pr-comments",
@@ -21575,14 +21595,14 @@ async function reviewPrComments(number, options2 = {}) {
21575
21595
  }
21576
21596
 
21577
21597
  // src/commands/fixConflict.ts
21578
- import { randomUUID as randomUUID7 } from "crypto";
21598
+ import { randomUUID as randomUUID8 } from "crypto";
21579
21599
  function buildPrompt3(rebase) {
21580
21600
  return rebase ? "/fix-conflict --rebase" : "/fix-conflict";
21581
21601
  }
21582
21602
  async function fixConflict(number, options2 = {}) {
21583
21603
  const { resumeSessionId } = options2;
21584
21604
  if (number && !resumeSessionId) await checkoutPr(number);
21585
- const claudeSessionId = resumeSessionId ?? randomUUID7();
21605
+ const claudeSessionId = resumeSessionId ?? randomUUID8();
21586
21606
  emitActivity({
21587
21607
  kind: "command",
21588
21608
  name: "fix-conflict",
@@ -22718,7 +22738,7 @@ function comment2(path80, line, body, startLine) {
22718
22738
  }
22719
22739
 
22720
22740
  // src/commands/prs/edit.ts
22721
- import { randomUUID as randomUUID8 } from "crypto";
22741
+ import { randomUUID as randomUUID9 } from "crypto";
22722
22742
 
22723
22743
  // src/commands/prs/appendScreenshots.ts
22724
22744
  function appendScreenshots(body, screenshots) {
@@ -22932,7 +22952,7 @@ async function edit(options2) {
22932
22952
  if (process.env.ASSIST_SESSION === "1" && sessionId) {
22933
22953
  const decision = await awaitPreviewApproval("PR preview", {
22934
22954
  sessionId,
22935
- requestId: randomUUID8(),
22955
+ requestId: randomUUID9(),
22936
22956
  title: options2.title ?? title,
22937
22957
  body: newBody,
22938
22958
  prNumber: number
@@ -23643,7 +23663,7 @@ async function placePr(prNumber, title, body, options2) {
23643
23663
  }
23644
23664
 
23645
23665
  // src/commands/prs/previewAndPlace.ts
23646
- import { randomUUID as randomUUID9 } from "crypto";
23666
+ import { randomUUID as randomUUID10 } from "crypto";
23647
23667
 
23648
23668
  // src/commands/sessions/shared/requestSession.ts
23649
23669
  function parseIncoming(line, type) {
@@ -23778,7 +23798,7 @@ function warn(reason4) {
23778
23798
  async function previewAndPlace(args) {
23779
23799
  const decision = await awaitPreviewApproval("PR preview", {
23780
23800
  sessionId: args.sessionId,
23781
- requestId: randomUUID9(),
23801
+ requestId: randomUUID10(),
23782
23802
  title: args.title,
23783
23803
  body: args.body,
23784
23804
  prNumber: args.prNumber,
@@ -26248,10 +26268,10 @@ function registerRefactor(program2) {
26248
26268
  }
26249
26269
 
26250
26270
  // src/commands/review/checkoutOnlySession.ts
26251
- import { randomUUID as randomUUID10 } from "crypto";
26271
+ import { randomUUID as randomUUID11 } from "crypto";
26252
26272
  async function checkoutOnlySession(number) {
26253
26273
  await checkoutPr(number);
26254
- const claudeSessionId = randomUUID10();
26274
+ const claudeSessionId = randomUUID11();
26255
26275
  emitActivity({ kind: "command", name: "review", claudeSessionId });
26256
26276
  const { done: done2 } = spawnClaude("", {
26257
26277
  permissionMode: "acceptEdits",
@@ -31613,7 +31633,7 @@ var ClientHub = class extends Set {
31613
31633
  };
31614
31634
 
31615
31635
  // src/commands/sessions/daemon/createSession.ts
31616
- import { randomUUID as randomUUID11 } from "crypto";
31636
+ import { randomUUID as randomUUID12 } from "crypto";
31617
31637
 
31618
31638
  // src/commands/sessions/daemon/sessionBase.ts
31619
31639
  function sessionBase(id, status3) {
@@ -31809,7 +31829,7 @@ function spawnRun(opts) {
31809
31829
  function createSession(id, prompt, cwd, design, harness, holdPty) {
31810
31830
  if (harness && harness !== "claude")
31811
31831
  return createHarnessSession(id, harness, prompt, cwd, holdPty);
31812
- const claudeSessionId = randomUUID11();
31832
+ const claudeSessionId = randomUUID12();
31813
31833
  return {
31814
31834
  ...sessionBase(id, prompt ? "running" : "waiting"),
31815
31835
  name: `Session ${id}`,
@@ -32388,6 +32408,14 @@ function decidePrPreview(sessions, waiters, notify2, d) {
32388
32408
  notify2();
32389
32409
  }
32390
32410
 
32411
+ // src/commands/sessions/daemon/previewTargetLabel.ts
32412
+ function previewTargetLabel(kind, itemType, prNumber, draft) {
32413
+ if (kind === "backlog-comment") return "backlog comment";
32414
+ if (kind === "backlog-item") return `backlog ${itemType}`;
32415
+ if (prNumber !== null) return `edit #${prNumber}`;
32416
+ return draft ? "create draft" : "create";
32417
+ }
32418
+
32391
32419
  // src/commands/sessions/daemon/setPrPreview.ts
32392
32420
  function setPrPreview(sessions, waiters, notify2, client, d) {
32393
32421
  const id = d.sessionId;
@@ -32401,7 +32429,7 @@ function setPrPreview(sessions, waiters, notify2, client, d) {
32401
32429
  return;
32402
32430
  }
32403
32431
  const prNumber = typeof d.prNumber === "number" ? d.prNumber : null;
32404
- const kind = d.kind === "backlog-item" ? "backlog-item" : "pr";
32432
+ const kind = d.kind === "backlog-item" || d.kind === "backlog-comment" ? d.kind : "pr";
32405
32433
  const itemType = d.itemType === "bug" ? "bug" : "story";
32406
32434
  const draft = d.draft === true;
32407
32435
  session.pendingPrPreview = {
@@ -32414,7 +32442,7 @@ function setPrPreview(sessions, waiters, notify2, client, d) {
32414
32442
  draft: kind === "pr" && prNumber === null ? draft : void 0
32415
32443
  };
32416
32444
  waiters.set(id, client);
32417
- const target = kind === "backlog-item" ? `backlog ${itemType}` : prNumber === null ? draft ? "create draft" : "create" : `edit #${prNumber}`;
32445
+ const target = previewTargetLabel(kind, itemType, prNumber, draft);
32418
32446
  daemonLog(
32419
32447
  `pr-preview set: id=${id} requestId=${d.requestId} kind=${kind} target=${target}`
32420
32448
  );
@@ -33842,7 +33870,7 @@ function codexRespawnPlan(session) {
33842
33870
  }
33843
33871
 
33844
33872
  // src/commands/sessions/daemon/interactiveRespawnPlan.ts
33845
- import { randomUUID as randomUUID12 } from "crypto";
33873
+ import { randomUUID as randomUUID13 } from "crypto";
33846
33874
  function interactiveRespawnPlan(session, resumes) {
33847
33875
  const { claudeSessionId, cwd, initialPrompt } = session;
33848
33876
  if (!resumes) return null;
@@ -33860,7 +33888,7 @@ function interactiveRespawnPlan(session, resumes) {
33860
33888
  return null;
33861
33889
  }
33862
33890
  function freshClaudePlan(session, prompt, cwd) {
33863
- const claudeSessionId = randomUUID12();
33891
+ const claudeSessionId = randomUUID13();
33864
33892
  return {
33865
33893
  spawn: () => {
33866
33894
  session.claudeSessionId = claudeSessionId;
@@ -34738,10 +34766,10 @@ function startReusedRunPty(session, assistArgs, itemId2, hold, clients, onStatus
34738
34766
  }
34739
34767
 
34740
34768
  // src/commands/sessions/daemon/createWatcherSession.ts
34741
- import { randomUUID as randomUUID13 } from "crypto";
34769
+ import { randomUUID as randomUUID14 } from "crypto";
34742
34770
  var WATCH_PROMPT = "/watch";
34743
34771
  function createWatcherSession(id, cwd) {
34744
- const claudeSessionId = randomUUID13();
34772
+ const claudeSessionId = randomUUID14();
34745
34773
  return {
34746
34774
  ...sessionBase(id, "running"),
34747
34775
  name: `Session ${id}`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.563.0",
3
+ "version": "0.565.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {