@staff0rd/assist 0.745.0 → 0.746.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.745.0",
9
+ version: "0.746.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -2863,6 +2863,215 @@ function registerAdvise(program2) {
2863
2863
  configHelp(adviseCommand, adviceConfigHelp);
2864
2864
  }
2865
2865
 
2866
+ // src/commands/ask.ts
2867
+ import { randomUUID } from "crypto";
2868
+
2869
+ // src/commands/backlog/import/readStdinBuffer.ts
2870
+ async function readStdinBuffer() {
2871
+ const chunks = [];
2872
+ for await (const chunk of process.stdin) {
2873
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
2874
+ }
2875
+ return Buffer.concat(chunks);
2876
+ }
2877
+
2878
+ // src/commands/prs/readBodyArgument.ts
2879
+ async function readBodyArgument(value) {
2880
+ if (value !== "-") return value;
2881
+ const body = (await readStdinBuffer()).toString("utf8").replace(/\n+$/, "");
2882
+ if (body.trim().length === 0) {
2883
+ console.error("Error: No body was provided on stdin.");
2884
+ process.exit(1);
2885
+ }
2886
+ return body;
2887
+ }
2888
+
2889
+ // src/commands/sessions/shared/formatPreviewComments.ts
2890
+ function formatPreviewComments(comments3) {
2891
+ return comments3.map((c, i) => {
2892
+ const quoted = c.quote.split("\n").map((line) => ` > ${line}`).join("\n");
2893
+ return `${i + 1}. On:
2894
+ ${quoted}
2895
+ Comment: ${c.note}
2896
+ `;
2897
+ });
2898
+ }
2899
+
2900
+ // src/commands/sessions/shared/reportPreviewRejection.ts
2901
+ function reportPreviewRejection(subject, decision, advice) {
2902
+ console.error(
2903
+ `${subject} rejected${decision.reason ? `: ${decision.reason}` : "."}`
2904
+ );
2905
+ const comments3 = decision.comments ?? [];
2906
+ if (comments3.length > 0) {
2907
+ console.error(
2908
+ `
2909
+ The reviewer left ${comments3.length} comment${comments3.length === 1 ? "" : "s"} on the preview. Address each one, then re-run this command:
2910
+ `
2911
+ );
2912
+ for (const line of formatPreviewComments(comments3)) console.error(line);
2913
+ }
2914
+ if (advice) console.error(advice);
2915
+ process.exit(1);
2916
+ }
2917
+
2918
+ // src/commands/sessions/daemon/readSocketLines.ts
2919
+ function readSocketLines(socket, onLine) {
2920
+ let buffer = "";
2921
+ socket.on("data", (chunk) => {
2922
+ buffer += chunk.toString("utf8");
2923
+ let newline = buffer.indexOf("\n");
2924
+ while (newline !== -1) {
2925
+ onLine(buffer.slice(0, newline));
2926
+ buffer = buffer.slice(newline + 1);
2927
+ newline = buffer.indexOf("\n");
2928
+ }
2929
+ });
2930
+ }
2931
+
2932
+ // src/commands/sessions/shared/toPreviewDecision.ts
2933
+ function toSelection(value) {
2934
+ const selection = value;
2935
+ if (typeof selection?.topLeft !== "string" || typeof selection.bottomRight !== "string")
2936
+ return void 0;
2937
+ return { topLeft: selection.topLeft, bottomRight: selection.bottomRight };
2938
+ }
2939
+ function toChecklist(value) {
2940
+ if (!Array.isArray(value)) return void 0;
2941
+ return value.flatMap((entry) => {
2942
+ const { id, ticked, comment: comment3 } = entry ?? {};
2943
+ if (typeof id !== "string") return [];
2944
+ return [
2945
+ {
2946
+ id,
2947
+ ticked: ticked === true,
2948
+ ...typeof comment3 === "string" && comment3 !== "" ? { comment: comment3 } : {}
2949
+ }
2950
+ ];
2951
+ });
2952
+ }
2953
+ function toPreviewDecision(msg) {
2954
+ if (msg.decision !== "approve" && msg.decision !== "reject") return null;
2955
+ return {
2956
+ decision: msg.decision,
2957
+ reason: msg.reason,
2958
+ comments: Array.isArray(msg.comments) ? msg.comments : void 0,
2959
+ screenshots: Array.isArray(msg.screenshots) ? msg.screenshots : void 0,
2960
+ body: typeof msg.body === "string" ? msg.body : void 0,
2961
+ reviewAfter: msg.reviewAfter === true,
2962
+ announceAfter: msg.announceAfter === true,
2963
+ draft: typeof msg.draft === "boolean" ? msg.draft : void 0,
2964
+ autoMerge: msg.autoMerge === true,
2965
+ selection: toSelection(msg.selection),
2966
+ checklist: toChecklist(msg.checklist)
2967
+ };
2968
+ }
2969
+
2970
+ // src/commands/sessions/shared/parsePreviewDecision.ts
2971
+ function parsePreviewDecision(line, requestId) {
2972
+ try {
2973
+ const msg = JSON.parse(line);
2974
+ if (msg.type === "error" && (msg.message ?? "").includes("pr-preview"))
2975
+ return { kind: "error", message: msg.message ?? "pr-preview failed" };
2976
+ if (msg.type !== "pr-decision" || msg.requestId !== requestId) return null;
2977
+ const decision = toPreviewDecision(msg);
2978
+ return decision ? { kind: "decision", decision } : null;
2979
+ } catch {
2980
+ return null;
2981
+ }
2982
+ }
2983
+
2984
+ // src/commands/sessions/shared/requestPreviewDecision.ts
2985
+ function requestPreviewDecision(request) {
2986
+ return new Promise((resolve26, reject) => {
2987
+ connectToDaemon().then((socket) => {
2988
+ let settled = false;
2989
+ const finish2 = (error, decision) => {
2990
+ if (settled) return;
2991
+ settled = true;
2992
+ socket.destroy();
2993
+ if (error) reject(error);
2994
+ else resolve26(decision);
2995
+ };
2996
+ readSocketLines(socket, (line) => {
2997
+ const incoming = parsePreviewDecision(line, request.requestId);
2998
+ if (!incoming) return;
2999
+ if (incoming.kind === "error") finish2(new Error(incoming.message));
3000
+ else finish2(void 0, incoming.decision);
3001
+ });
3002
+ socket.on("error", (error) => finish2(error));
3003
+ socket.on(
3004
+ "close",
3005
+ () => finish2(new Error("daemon closed before a decision was made"))
3006
+ );
3007
+ socket.write(`${JSON.stringify({ type: "pr-preview", ...request })}
3008
+ `);
3009
+ }, reject);
3010
+ });
3011
+ }
3012
+
3013
+ // src/commands/sessions/shared/awaitPreviewApproval.ts
3014
+ async function awaitPreviewApproval(subject, request, options2 = {}) {
3015
+ console.log("Awaiting your approval in the assist web UI preview pane\u2026");
3016
+ let decision;
3017
+ try {
3018
+ decision = await requestPreviewDecision(request);
3019
+ } catch (error) {
3020
+ console.error(
3021
+ `Error: ${error instanceof Error ? error.message : String(error)}`
3022
+ );
3023
+ process.exit(1);
3024
+ }
3025
+ if (decision.body !== void 0) options2.saveEditedBody?.(decision.body);
3026
+ if (decision.decision === "reject" && !options2.rejectIsOutcome)
3027
+ reportPreviewRejection(subject, decision, options2.rejectionAdvice);
3028
+ return decision;
3029
+ }
3030
+
3031
+ // src/commands/ask.ts
3032
+ async function ask(options2) {
3033
+ const body = await readBodyArgument(options2.body);
3034
+ if (body.trim().length === 0) {
3035
+ console.error("Error: --body is empty; there is nothing to ask about.");
3036
+ process.exit(1);
3037
+ }
3038
+ const sessionId = process.env.ASSIST_SESSION_ID;
3039
+ if (process.env.ASSIST_SESSION !== "1" || !sessionId) {
3040
+ console.log(body);
3041
+ return;
3042
+ }
3043
+ const decision = await awaitPreviewApproval(
3044
+ options2.title,
3045
+ {
3046
+ sessionId,
3047
+ requestId: randomUUID(),
3048
+ title: options2.title,
3049
+ body,
3050
+ prNumber: null,
3051
+ kind: "ask"
3052
+ },
3053
+ {
3054
+ rejectionAdvice: "Revise the update to address the reason and every comment above, then re-run `assist ask` with the revision."
3055
+ }
3056
+ );
3057
+ console.log("Approved.");
3058
+ const comments3 = decision.comments ?? [];
3059
+ if (comments3.length === 0) return;
3060
+ console.log(
3061
+ `
3062
+ The reviewer left ${comments3.length} comment${comments3.length === 1 ? "" : "s"} on the preview. Act on each one:
3063
+ `
3064
+ );
3065
+ for (const line of formatPreviewComments(comments3)) console.log(line);
3066
+ }
3067
+
3068
+ // src/commands/registerAsk.ts
3069
+ function registerAsk(program2) {
3070
+ program2.command("ask").description(
3071
+ "Open markdown in the session's web preview pane for the user to approve or reject, with inline comments, and wait for the decision; prints it outside a web session"
3072
+ ).requiredOption("--title <title>", "Pane title").requiredOption("--body <markdown|->", "Markdown to review, or - for stdin").action(ask);
3073
+ }
3074
+
2866
3075
  // src/commands/registerBackup.ts
2867
3076
  import { mkdir as mkdir2, stat } from "fs/promises";
2868
3077
  import { join as join16, resolve as resolve7 } from "path";
@@ -5599,153 +5808,14 @@ async function appendComment(orm, itemId2, text18, opts = {}) {
5599
5808
  }
5600
5809
 
5601
5810
  // src/commands/backlog/comment/reviewProposedComment.ts
5602
- import { randomUUID } from "crypto";
5603
-
5604
- // src/commands/sessions/shared/reportPreviewRejection.ts
5605
- function reportPreviewRejection(subject, decision, advice) {
5606
- console.error(
5607
- `${subject} rejected${decision.reason ? `: ${decision.reason}` : "."}`
5608
- );
5609
- const comments3 = decision.comments ?? [];
5610
- if (comments3.length > 0) {
5611
- console.error(
5612
- `
5613
- The reviewer left ${comments3.length} comment${comments3.length === 1 ? "" : "s"} on the preview. Address each one, then re-run this command:
5614
- `
5615
- );
5616
- for (const [i, c] of comments3.entries()) {
5617
- const quoted = c.quote.split("\n").map((line) => ` > ${line}`).join("\n");
5618
- console.error(`${i + 1}. On:
5619
- ${quoted}
5620
- Comment: ${c.note}
5621
- `);
5622
- }
5623
- }
5624
- if (advice) console.error(advice);
5625
- process.exit(1);
5626
- }
5627
-
5628
- // src/commands/sessions/daemon/readSocketLines.ts
5629
- function readSocketLines(socket, onLine) {
5630
- let buffer = "";
5631
- socket.on("data", (chunk) => {
5632
- buffer += chunk.toString("utf8");
5633
- let newline = buffer.indexOf("\n");
5634
- while (newline !== -1) {
5635
- onLine(buffer.slice(0, newline));
5636
- buffer = buffer.slice(newline + 1);
5637
- newline = buffer.indexOf("\n");
5638
- }
5639
- });
5640
- }
5641
-
5642
- // src/commands/sessions/shared/toPreviewDecision.ts
5643
- function toSelection(value) {
5644
- const selection = value;
5645
- if (typeof selection?.topLeft !== "string" || typeof selection.bottomRight !== "string")
5646
- return void 0;
5647
- return { topLeft: selection.topLeft, bottomRight: selection.bottomRight };
5648
- }
5649
- function toChecklist(value) {
5650
- if (!Array.isArray(value)) return void 0;
5651
- return value.flatMap((entry) => {
5652
- const { id, ticked, comment: comment3 } = entry ?? {};
5653
- if (typeof id !== "string") return [];
5654
- return [
5655
- {
5656
- id,
5657
- ticked: ticked === true,
5658
- ...typeof comment3 === "string" && comment3 !== "" ? { comment: comment3 } : {}
5659
- }
5660
- ];
5661
- });
5662
- }
5663
- function toPreviewDecision(msg) {
5664
- if (msg.decision !== "approve" && msg.decision !== "reject") return null;
5665
- return {
5666
- decision: msg.decision,
5667
- reason: msg.reason,
5668
- comments: Array.isArray(msg.comments) ? msg.comments : void 0,
5669
- screenshots: Array.isArray(msg.screenshots) ? msg.screenshots : void 0,
5670
- body: typeof msg.body === "string" ? msg.body : void 0,
5671
- reviewAfter: msg.reviewAfter === true,
5672
- announceAfter: msg.announceAfter === true,
5673
- draft: typeof msg.draft === "boolean" ? msg.draft : void 0,
5674
- autoMerge: msg.autoMerge === true,
5675
- selection: toSelection(msg.selection),
5676
- checklist: toChecklist(msg.checklist)
5677
- };
5678
- }
5679
-
5680
- // src/commands/sessions/shared/parsePreviewDecision.ts
5681
- function parsePreviewDecision(line, requestId) {
5682
- try {
5683
- const msg = JSON.parse(line);
5684
- if (msg.type === "error" && (msg.message ?? "").includes("pr-preview"))
5685
- return { kind: "error", message: msg.message ?? "pr-preview failed" };
5686
- if (msg.type !== "pr-decision" || msg.requestId !== requestId) return null;
5687
- const decision = toPreviewDecision(msg);
5688
- return decision ? { kind: "decision", decision } : null;
5689
- } catch {
5690
- return null;
5691
- }
5692
- }
5693
-
5694
- // src/commands/sessions/shared/requestPreviewDecision.ts
5695
- function requestPreviewDecision(request) {
5696
- return new Promise((resolve26, reject) => {
5697
- connectToDaemon().then((socket) => {
5698
- let settled = false;
5699
- const finish2 = (error, decision) => {
5700
- if (settled) return;
5701
- settled = true;
5702
- socket.destroy();
5703
- if (error) reject(error);
5704
- else resolve26(decision);
5705
- };
5706
- readSocketLines(socket, (line) => {
5707
- const incoming = parsePreviewDecision(line, request.requestId);
5708
- if (!incoming) return;
5709
- if (incoming.kind === "error") finish2(new Error(incoming.message));
5710
- else finish2(void 0, incoming.decision);
5711
- });
5712
- socket.on("error", (error) => finish2(error));
5713
- socket.on(
5714
- "close",
5715
- () => finish2(new Error("daemon closed before a decision was made"))
5716
- );
5717
- socket.write(`${JSON.stringify({ type: "pr-preview", ...request })}
5718
- `);
5719
- }, reject);
5720
- });
5721
- }
5722
-
5723
- // src/commands/sessions/shared/awaitPreviewApproval.ts
5724
- async function awaitPreviewApproval(subject, request, options2 = {}) {
5725
- console.log("Awaiting your approval in the assist web UI preview pane\u2026");
5726
- let decision;
5727
- try {
5728
- decision = await requestPreviewDecision(request);
5729
- } catch (error) {
5730
- console.error(
5731
- `Error: ${error instanceof Error ? error.message : String(error)}`
5732
- );
5733
- process.exit(1);
5734
- }
5735
- if (decision.body !== void 0) options2.saveEditedBody?.(decision.body);
5736
- if (decision.decision === "reject" && !options2.rejectIsOutcome)
5737
- reportPreviewRejection(subject, decision, options2.rejectionAdvice);
5738
- return decision;
5739
- }
5740
-
5741
- // src/commands/backlog/comment/reviewProposedComment.ts
5811
+ import { randomUUID as randomUUID2 } from "crypto";
5742
5812
  async function reviewProposedComment(item, text18) {
5743
5813
  if (loadConfig().backlog?.previewComments !== true) return;
5744
5814
  const sessionId = process.env.ASSIST_SESSION_ID;
5745
5815
  if (process.env.ASSIST_SESSION !== "1" || !sessionId) return;
5746
5816
  await awaitPreviewApproval("Backlog comment preview", {
5747
5817
  sessionId,
5748
- requestId: randomUUID(),
5818
+ requestId: randomUUID2(),
5749
5819
  title: `Comment on ${formatItemId(item.id)}: ${item.name}`,
5750
5820
  body: text18,
5751
5821
  prNumber: null,
@@ -5964,15 +6034,6 @@ async function confirmReplace(client, tables, incoming, fromStdin) {
5964
6034
  return promptConfirm("Replace all backlog data with this dump?", false);
5965
6035
  }
5966
6036
 
5967
- // src/commands/backlog/import/readStdinBuffer.ts
5968
- async function readStdinBuffer() {
5969
- const chunks = [];
5970
- for await (const chunk of process.stdin) {
5971
- chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
5972
- }
5973
- return Buffer.concat(chunks);
5974
- }
5975
-
5976
6037
  // src/commands/backlog/dump/copyTableIn.ts
5977
6038
  import { finished } from "stream/promises";
5978
6039
  import { from as copyFrom } from "pg-copy-streams";
@@ -6292,7 +6353,7 @@ async function resolveInsertPosition(orm, itemId2, position) {
6292
6353
  }
6293
6354
 
6294
6355
  // src/commands/backlog/addPhase/reviewProposedPhase.ts
6295
- import { randomUUID as randomUUID2 } from "crypto";
6356
+ import { randomUUID as randomUUID3 } from "crypto";
6296
6357
 
6297
6358
  // src/commands/backlog/renderPhaseSection.ts
6298
6359
  function renderPhaseSection(phase, idx) {
@@ -6316,7 +6377,7 @@ async function reviewProposedPhase(item, phaseIdx, phase) {
6316
6377
  return;
6317
6378
  await awaitPreviewApproval("Backlog phase preview", {
6318
6379
  sessionId,
6319
- requestId: randomUUID2(),
6380
+ requestId: randomUUID3(),
6320
6381
  title: `Add a phase to ${formatItemId(item.id)}: ${item.name}`,
6321
6382
  body: renderPhaseSection(phase, phaseIdx),
6322
6383
  prNumber: null,
@@ -6669,7 +6730,7 @@ function readProposedItem(source) {
6669
6730
  }
6670
6731
 
6671
6732
  // src/commands/backlog/propose/reviewProposal.ts
6672
- import { randomUUID as randomUUID3 } from "crypto";
6733
+ import { randomUUID as randomUUID4 } from "crypto";
6673
6734
  import chalk52 from "chalk";
6674
6735
 
6675
6736
  // src/shared/renderMarkdownTerminal.ts
@@ -6711,7 +6772,7 @@ async function reviewProposal(item, sessionId, confirmed) {
6711
6772
  if (sessionId) {
6712
6773
  await awaitPreviewApproval("Backlog item preview", {
6713
6774
  sessionId,
6714
- requestId: randomUUID3(),
6775
+ requestId: randomUUID4(),
6715
6776
  title: item.name,
6716
6777
  body,
6717
6778
  prNumber: null,
@@ -8125,7 +8186,7 @@ Phase ${phaseNumber} completed.`));
8125
8186
  }
8126
8187
 
8127
8188
  // src/commands/backlog/preparePhaseSession.ts
8128
- import { randomUUID as randomUUID4 } from "crypto";
8189
+ import { randomUUID as randomUUID5 } from "crypto";
8129
8190
 
8130
8191
  // src/commands/backlog/persistPhaseSession.ts
8131
8192
  import os3 from "os";
@@ -8589,7 +8650,7 @@ async function verifyPhaseResume(itemId2, resumeSessionId, phaseLabel2) {
8589
8650
  // src/commands/backlog/preparePhaseSession.ts
8590
8651
  async function preparePhaseSession(item, phase, phaseIndex, phaseNumber, totalPhases, phaseLabel2, spawnOptions) {
8591
8652
  const resumeSessionId = spawnOptions?.resumeSessionId;
8592
- const claudeSessionId = resumeSessionId ?? randomUUID4();
8653
+ const claudeSessionId = resumeSessionId ?? randomUUID5();
8593
8654
  if (resumeSessionId && !await verifyPhaseResume(item.id, resumeSessionId, phaseLabel2)) {
8594
8655
  return void 0;
8595
8656
  }
@@ -8979,7 +9040,7 @@ import chalk76 from "chalk";
8979
9040
  import enquirer7 from "enquirer";
8980
9041
 
8981
9042
  // src/commands/backlog/launchMode.ts
8982
- import { randomUUID as randomUUID5 } from "crypto";
9043
+ import { randomUUID as randomUUID6 } from "crypto";
8983
9044
 
8984
9045
  // src/commands/backlog/handleLaunchSignal.ts
8985
9046
  import chalk75 from "chalk";
@@ -9176,7 +9237,7 @@ async function launchMode(slashCommand, options2) {
9176
9237
  const resumeSessionId = options2?.resumeSessionId;
9177
9238
  if (!resumeSessionId) pullIfConfigured();
9178
9239
  process.env.ASSIST_SESSION_ID ??= String(process.pid);
9179
- const claudeSessionId = resumeSessionId ?? randomUUID5();
9240
+ const claudeSessionId = resumeSessionId ?? randomUUID6();
9180
9241
  const harness = options2?.harness ?? "claude";
9181
9242
  reportLaunchActivity(slashCommand, claudeSessionId, harness, options2);
9182
9243
  const prompt = resumeSessionId ? resumeNudge() : buildSlashCommand(slashCommand, options2?.description);
@@ -10259,7 +10320,7 @@ async function replacePlan(orm, itemId2, phases, currentPhase) {
10259
10320
  }
10260
10321
 
10261
10322
  // src/commands/backlog/updatePlan/reviewPlanUpdate.ts
10262
- import { randomUUID as randomUUID6 } from "crypto";
10323
+ import { randomUUID as randomUUID7 } from "crypto";
10263
10324
  import chalk101 from "chalk";
10264
10325
 
10265
10326
  // src/commands/backlog/updatePlan/isCompleted.ts
@@ -10416,7 +10477,7 @@ async function reviewPlanUpdate(item, phases) {
10416
10477
  if (process.env.ASSIST_SESSION === "1" && sessionId) {
10417
10478
  await awaitPreviewApproval("Plan update preview", {
10418
10479
  sessionId,
10419
- requestId: randomUUID6(),
10480
+ requestId: randomUUID7(),
10420
10481
  title: `Update the plan for ${formatItemId(item.id)}: ${item.name}`,
10421
10482
  body,
10422
10483
  prNumber: null,
@@ -14907,10 +14968,10 @@ function findLinkSpec(name) {
14907
14968
  }
14908
14969
 
14909
14970
  // src/commands/sessions/shared/newTraceId.ts
14910
- import { randomUUID as randomUUID7 } from "crypto";
14971
+ import { randomUUID as randomUUID8 } from "crypto";
14911
14972
  var TRACE_HEADER = "x-assist-trace-id";
14912
14973
  function newTraceId() {
14913
- return randomUUID7().slice(0, 8);
14974
+ return randomUUID8().slice(0, 8);
14914
14975
  }
14915
14976
 
14916
14977
  // src/commands/sessions/web/forwardToPeer.ts
@@ -23599,17 +23660,6 @@ Anything nested below the leaf level fails the run before a single write, naming
23599
23660
  ).action(fixStructure);
23600
23661
  }
23601
23662
 
23602
- // src/commands/prs/readBodyArgument.ts
23603
- async function readBodyArgument(value) {
23604
- if (value !== "-") return value;
23605
- const body = (await readStdinBuffer()).toString("utf8").replace(/\n+$/, "");
23606
- if (body.trim().length === 0) {
23607
- console.error("Error: No body was provided on stdin.");
23608
- process.exit(1);
23609
- }
23610
- return body;
23611
- }
23612
-
23613
23663
  // src/commands/github/issue/commentIssue.ts
23614
23664
  import { execFileSync as execFileSync8 } from "child_process";
23615
23665
 
@@ -23639,13 +23689,13 @@ function validateProposedContent(labels, title, body) {
23639
23689
  }
23640
23690
 
23641
23691
  // src/commands/github/issue/reviewProposedIssueComment.ts
23642
- import { randomUUID as randomUUID8 } from "crypto";
23692
+ import { randomUUID as randomUUID9 } from "crypto";
23643
23693
  async function reviewProposedIssueComment(title, body) {
23644
23694
  const sessionId = process.env.ASSIST_SESSION_ID;
23645
23695
  if (process.env.ASSIST_SESSION !== "1" || !sessionId) return;
23646
23696
  await awaitPreviewApproval("GitHub issue comment preview", {
23647
23697
  sessionId,
23648
- requestId: randomUUID8(),
23698
+ requestId: randomUUID9(),
23649
23699
  title,
23650
23700
  body,
23651
23701
  prNumber: null,
@@ -24047,13 +24097,13 @@ function resolveCreateIssueMetadata(options2) {
24047
24097
  }
24048
24098
 
24049
24099
  // src/commands/github/issue/reviewProposedIssue.ts
24050
- import { randomUUID as randomUUID9 } from "crypto";
24100
+ import { randomUUID as randomUUID10 } from "crypto";
24051
24101
  async function reviewProposedIssue(title, body, metadata2 = []) {
24052
24102
  const sessionId = process.env.ASSIST_SESSION_ID;
24053
24103
  if (process.env.ASSIST_SESSION !== "1" || !sessionId) return void 0;
24054
24104
  return await awaitPreviewApproval("GitHub issue preview", {
24055
24105
  sessionId,
24056
- requestId: randomUUID9(),
24106
+ requestId: randomUUID10(),
24057
24107
  title,
24058
24108
  body,
24059
24109
  prNumber: null,
@@ -24276,7 +24326,7 @@ function pushUnchangedIssue(number, repo, target, fetchedAt, bodyPath) {
24276
24326
  }
24277
24327
 
24278
24328
  // src/commands/github/issue/reviewProposedIssueEdit.ts
24279
- import { randomUUID as randomUUID10 } from "crypto";
24329
+ import { randomUUID as randomUUID11 } from "crypto";
24280
24330
  async function reviewProposedIssueEdit(title, body, working) {
24281
24331
  const sessionId = process.env.ASSIST_SESSION_ID;
24282
24332
  if (process.env.ASSIST_SESSION !== "1" || !sessionId) return body;
@@ -24284,7 +24334,7 @@ async function reviewProposedIssueEdit(title, body, working) {
24284
24334
  "GitHub issue edit preview",
24285
24335
  {
24286
24336
  sessionId,
24287
- requestId: randomUUID10(),
24337
+ requestId: randomUUID11(),
24288
24338
  title,
24289
24339
  body,
24290
24340
  prNumber: null,
@@ -25004,7 +25054,7 @@ function registerRefineLaunch(program2, resumeFlag) {
25004
25054
  }
25005
25055
 
25006
25056
  // src/commands/reviewPrComments.ts
25007
- import { randomUUID as randomUUID11 } from "crypto";
25057
+ import { randomUUID as randomUUID12 } from "crypto";
25008
25058
 
25009
25059
  // src/commands/review/checkoutPr.ts
25010
25060
  import { execFileSync as execFileSync15 } from "child_process";
@@ -25710,7 +25760,7 @@ async function reviewPrComments(number, options2 = {}) {
25710
25760
  const resumeSessionId = options2.resumeSessionId;
25711
25761
  validateAnnounce(number, announce);
25712
25762
  if (number && !resumeSessionId) await checkoutPr(number);
25713
- const claudeSessionId = resumeSessionId ?? randomUUID11();
25763
+ const claudeSessionId = resumeSessionId ?? randomUUID12();
25714
25764
  emitActivity({
25715
25765
  kind: "command",
25716
25766
  name: "review-pr-comments",
@@ -25728,14 +25778,14 @@ async function reviewPrComments(number, options2 = {}) {
25728
25778
  }
25729
25779
 
25730
25780
  // src/commands/fixConflict.ts
25731
- import { randomUUID as randomUUID12 } from "crypto";
25781
+ import { randomUUID as randomUUID13 } from "crypto";
25732
25782
  function buildPrompt3(rebase) {
25733
25783
  return rebase ? "/fix-conflict --rebase" : "/fix-conflict";
25734
25784
  }
25735
25785
  async function fixConflict(number, options2 = {}) {
25736
25786
  const { resumeSessionId } = options2;
25737
25787
  if (number && !resumeSessionId) await checkoutPr(number);
25738
- const claudeSessionId = resumeSessionId ?? randomUUID12();
25788
+ const claudeSessionId = resumeSessionId ?? randomUUID13();
25739
25789
  emitActivity({
25740
25790
  kind: "command",
25741
25791
  name: "fix-conflict",
@@ -26279,7 +26329,7 @@ async function offerSaveExtract(extract2, options2, paths = {}) {
26279
26329
  }
26280
26330
 
26281
26331
  // src/commands/miro/pickAnchors.ts
26282
- import { randomUUID as randomUUID13 } from "crypto";
26332
+ import { randomUUID as randomUUID14 } from "crypto";
26283
26333
 
26284
26334
  // src/commands/miro/isBox.ts
26285
26335
  var boxTypes = /* @__PURE__ */ new Set(["shape", "sticky_note"]);
@@ -26300,7 +26350,7 @@ async function pickAnchors(sessionId, items2) {
26300
26350
  "Miro anchor selection",
26301
26351
  {
26302
26352
  sessionId,
26303
- requestId: randomUUID13(),
26353
+ requestId: randomUUID14(),
26304
26354
  title: "Pick the top-left then the bottom-right box",
26305
26355
  body: encodeMiroBoardPreview(items2),
26306
26356
  prNumber: null,
@@ -27490,13 +27540,13 @@ function postReviewComment(vars) {
27490
27540
  }
27491
27541
 
27492
27542
  // src/commands/prs/reviewProposedPrComment.ts
27493
- import { randomUUID as randomUUID14 } from "crypto";
27543
+ import { randomUUID as randomUUID15 } from "crypto";
27494
27544
  async function reviewProposedPrComment(title, body, prNumber) {
27495
27545
  const sessionId = process.env.ASSIST_SESSION_ID;
27496
27546
  if (process.env.ASSIST_SESSION !== "1" || !sessionId) return;
27497
27547
  await awaitPreviewApproval("PR comment preview", {
27498
27548
  sessionId,
27499
- requestId: randomUUID14(),
27549
+ requestId: randomUUID15(),
27500
27550
  title,
27501
27551
  body,
27502
27552
  prNumber,
@@ -28116,7 +28166,7 @@ function registerPrsComments(prsCommand) {
28116
28166
  }
28117
28167
 
28118
28168
  // src/commands/prs/edit.ts
28119
- import { randomUUID as randomUUID15 } from "crypto";
28169
+ import { randomUUID as randomUUID16 } from "crypto";
28120
28170
 
28121
28171
  // src/commands/prs/applyEdit.ts
28122
28172
  import { execFileSync as execFileSync16 } from "child_process";
@@ -28311,7 +28361,7 @@ async function edit(options2) {
28311
28361
  if (process.env.ASSIST_SESSION === "1" && sessionId) {
28312
28362
  const decision = await awaitPreviewApproval("PR preview", {
28313
28363
  sessionId,
28314
- requestId: randomUUID15(),
28364
+ requestId: randomUUID16(),
28315
28365
  title: options2.title ?? title,
28316
28366
  body: newBody,
28317
28367
  prNumber: number
@@ -28510,7 +28560,7 @@ async function placePr(prNumber, title, body, options2) {
28510
28560
  }
28511
28561
 
28512
28562
  // src/commands/prs/previewAndPlace.ts
28513
- import { randomUUID as randomUUID16 } from "crypto";
28563
+ import { randomUUID as randomUUID17 } from "crypto";
28514
28564
 
28515
28565
  // src/commands/sessions/shared/requestSession.ts
28516
28566
  function parseIncoming(line, type) {
@@ -28661,7 +28711,7 @@ function enableAutoMerge() {
28661
28711
  async function previewAndPlace(args) {
28662
28712
  const decision = await awaitPreviewApproval("PR preview", {
28663
28713
  sessionId: args.sessionId,
28664
- requestId: randomUUID16(),
28714
+ requestId: randomUUID17(),
28665
28715
  title: args.title,
28666
28716
  body: args.body,
28667
28717
  prNumber: args.prNumber,
@@ -32976,10 +33026,10 @@ function registerRefactor(program2) {
32976
33026
  }
32977
33027
 
32978
33028
  // src/commands/review/checkoutOnlySession.ts
32979
- import { randomUUID as randomUUID17 } from "crypto";
33029
+ import { randomUUID as randomUUID18 } from "crypto";
32980
33030
  async function checkoutOnlySession(number) {
32981
33031
  await checkoutPr(number);
32982
- const claudeSessionId = randomUUID17();
33032
+ const claudeSessionId = randomUUID18();
32983
33033
  emitActivity({ kind: "command", name: "review", claudeSessionId });
32984
33034
  const { done: done2 } = spawnClaude("", {
32985
33035
  permissionMode: "acceptEdits",
@@ -33716,7 +33766,7 @@ function gatherHighLevelSubject(prNumber, force) {
33716
33766
  }
33717
33767
 
33718
33768
  // src/commands/review/highLevel/openHighLevelOverlay.ts
33719
- import { randomUUID as randomUUID18 } from "crypto";
33769
+ import { randomUUID as randomUUID19 } from "crypto";
33720
33770
 
33721
33771
  // src/commands/review/highLevel/buildHighLevelRecord.ts
33722
33772
  function toItem2(check2, decision) {
@@ -33803,7 +33853,7 @@ async function openHighLevelOverlay(sessionId, subject) {
33803
33853
  "High-level review",
33804
33854
  {
33805
33855
  sessionId,
33806
- requestId: randomUUID18(),
33856
+ requestId: randomUUID19(),
33807
33857
  title: `${subject.repo}#${subject.prNumber} \u2014 ${subject.title}`,
33808
33858
  body: JSON.stringify(highLevelPreviewPayload(subject)),
33809
33859
  prNumber: subject.prNumber,
@@ -36681,7 +36731,7 @@ function registerSeq(program2) {
36681
36731
  }
36682
36732
 
36683
36733
  // src/commands/show.ts
36684
- import { randomUUID as randomUUID19 } from "crypto";
36734
+ import { randomUUID as randomUUID20 } from "crypto";
36685
36735
 
36686
36736
  // src/commands/sessions/shared/sendShowPreview.ts
36687
36737
  async function sendShowPreview(request) {
@@ -36733,7 +36783,7 @@ async function show2(options2) {
36733
36783
  try {
36734
36784
  await sendShowPreview({
36735
36785
  sessionId,
36736
- requestId: randomUUID19(),
36786
+ requestId: randomUUID20(),
36737
36787
  title: options2.title ?? "Show",
36738
36788
  body
36739
36789
  });
@@ -36808,7 +36858,7 @@ function readSlackParts(files) {
36808
36858
  }
36809
36859
 
36810
36860
  // src/commands/slack/reviewProposedSlackMessage.ts
36811
- import { randomUUID as randomUUID20 } from "crypto";
36861
+ import { randomUUID as randomUUID21 } from "crypto";
36812
36862
  async function reviewProposedSlackMessage(target, body, workingPath) {
36813
36863
  const sessionId = process.env.ASSIST_SESSION_ID;
36814
36864
  if (process.env.ASSIST_SESSION !== "1" || !sessionId) return;
@@ -36818,7 +36868,7 @@ async function reviewProposedSlackMessage(target, body, workingPath) {
36818
36868
  part ? `Slack message ${part.index} of ${part.total}` : "Slack message preview",
36819
36869
  {
36820
36870
  sessionId,
36821
- requestId: randomUUID20(),
36871
+ requestId: randomUUID21(),
36822
36872
  title: part ? `${destination} (${part.index}/${part.total})` : destination,
36823
36873
  body,
36824
36874
  prNumber: null,
@@ -41023,7 +41073,7 @@ var ClientHub = class extends Set {
41023
41073
  };
41024
41074
 
41025
41075
  // src/commands/sessions/daemon/createSession.ts
41026
- import { randomUUID as randomUUID21 } from "crypto";
41076
+ import { randomUUID as randomUUID22 } from "crypto";
41027
41077
 
41028
41078
  // src/commands/sessions/daemon/sessionBase.ts
41029
41079
  function sessionBase(id, status3) {
@@ -41229,7 +41279,7 @@ function spawnRun(opts) {
41229
41279
  function createSession(id, { prompt, cwd, design, auto, harness, holdPty } = {}) {
41230
41280
  if (harness && harness !== "claude")
41231
41281
  return createHarnessSession(id, harness, prompt, cwd, holdPty);
41232
- const claudeSessionId = randomUUID21();
41282
+ const claudeSessionId = randomUUID22();
41233
41283
  return {
41234
41284
  ...sessionBase(id, prompt ? "running" : "waiting"),
41235
41285
  name: `Session ${id}`,
@@ -41943,7 +41993,8 @@ var PREVIEW_KINDS = [
41943
41993
  "miro-board",
41944
41994
  "slack-post",
41945
41995
  "high-level-review",
41946
- "show"
41996
+ "show",
41997
+ "ask"
41947
41998
  ];
41948
41999
  function isPreviewKind(value) {
41949
42000
  return PREVIEW_KINDS.includes(value);
@@ -41960,6 +42011,7 @@ function previewTargetLabel(kind, itemType, prNumber, draft) {
41960
42011
  if (kind === "slack-post") return "slack post";
41961
42012
  if (kind === "high-level-review") return "high-level review";
41962
42013
  if (kind === "show") return "show";
42014
+ if (kind === "ask") return "ask";
41963
42015
  if (kind === "backlog-item") return `backlog ${itemType}`;
41964
42016
  if (prNumber !== null) return `edit #${prNumber}`;
41965
42017
  return draft ? "create draft" : "create";
@@ -43501,7 +43553,7 @@ function codexRespawnPlan(session) {
43501
43553
  }
43502
43554
 
43503
43555
  // src/commands/sessions/daemon/interactiveRespawnPlan.ts
43504
- import { randomUUID as randomUUID22 } from "crypto";
43556
+ import { randomUUID as randomUUID23 } from "crypto";
43505
43557
  function interactiveRespawnPlan(session, resumes) {
43506
43558
  const { claudeSessionId, cwd, initialPrompt, design, auto } = session;
43507
43559
  if (!resumes) return null;
@@ -43521,7 +43573,7 @@ function interactiveRespawnPlan(session, resumes) {
43521
43573
  return null;
43522
43574
  }
43523
43575
  function freshClaudePlan(session, prompt, cwd) {
43524
- const claudeSessionId = randomUUID22();
43576
+ const claudeSessionId = randomUUID23();
43525
43577
  return {
43526
43578
  spawn: () => {
43527
43579
  session.claudeSessionId = claudeSessionId;
@@ -44531,10 +44583,10 @@ function startReusedRunPty(session, assistArgs, itemId2, hold, clients, onStatus
44531
44583
  }
44532
44584
 
44533
44585
  // src/commands/sessions/daemon/createWatcherSession.ts
44534
- import { randomUUID as randomUUID23 } from "crypto";
44586
+ import { randomUUID as randomUUID24 } from "crypto";
44535
44587
  var WATCH_PROMPT = "/watch";
44536
44588
  function createWatcherSession(id, cwd) {
44537
- const claudeSessionId = randomUUID23();
44589
+ const claudeSessionId = randomUUID24();
44538
44590
  return {
44539
44591
  ...sessionBase(id, "running"),
44540
44592
  name: `Session ${id}`,
@@ -47916,6 +47968,7 @@ registerLitellm(program);
47916
47968
  registerRavendb(program);
47917
47969
  registerSeq(program);
47918
47970
  registerShow(program);
47971
+ registerAsk(program);
47919
47972
  registerSlack(program);
47920
47973
  registerSql(program);
47921
47974
  registerTranscript(program);