@staff0rd/assist 0.958.0 → 0.960.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.958.0",
9
+ version: "0.960.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -906,6 +906,7 @@ import { z as z6 } from "zod";
906
906
  // src/shared/adviceFragmentNames.ts
907
907
  var adviceFragmentTitles = {
908
908
  ask: "Asking for sign-off",
909
+ "ask-question": "Asking questions",
909
910
  "assist-global": "Using assist",
910
911
  "backlog-ids": "Backlog item IDs",
911
912
  "backlog-prs": "Backlog items, PRs, and commits",
@@ -924,6 +925,7 @@ var adviceFragmentTitles = {
924
925
  };
925
926
  var adviceFragmentNames = [
926
927
  "ask",
928
+ "ask-question",
927
929
  "assist-global",
928
930
  "backlog-ids",
929
931
  "backlog-prs",
@@ -1366,7 +1368,8 @@ var assistConfigShape = {
1366
1368
  includeCommittedChanges: z6.boolean().default(true),
1367
1369
  maxLive: z6.number().default(24),
1368
1370
  newSessionMode: z6.enum(["draft", "bug", "prompt", "design"]).default("draft"),
1369
- hotkeys: hotkeysSchema.optional()
1371
+ hotkeys: hotkeysSchema.optional(),
1372
+ askQuestion: z6.boolean().default(false)
1370
1373
  }).optional(),
1371
1374
  database: z6.strictObject({
1372
1375
  url: secretConfigValue(z6.string()).optional()
@@ -6182,6 +6185,15 @@ var adviceConfigHelp = [
6182
6185
  }
6183
6186
  ];
6184
6187
 
6188
+ // src/commands/askQuestion/askQuestionConfigHelp.ts
6189
+ var askQuestionConfigHelp = [
6190
+ {
6191
+ key: "sessions.askQuestion",
6192
+ setter: "assist config set sessions.askQuestion true -g",
6193
+ note: "opt in: assist ask-question answers AskUserQuestion questions from the session's web preview pane; when on, assist cli-hook denies AskUserQuestion in assist sessions and an advice fragment points Claude at assist ask-question; when off it exits non-zero so Claude uses the built-in tool (default off)"
6194
+ }
6195
+ ];
6196
+
6185
6197
  // src/commands/backlog/backlogConfigHelp.ts
6186
6198
  var backlogConfigHelp = [
6187
6199
  {
@@ -6820,6 +6832,7 @@ var verifyConfigHelp = [
6820
6832
  var configHelpEntries = [
6821
6833
  ...Object.values(rootConfigHelp).flat(),
6822
6834
  ...adviceConfigHelp,
6835
+ ...askQuestionConfigHelp,
6823
6836
  ...autoUpdateConfigHelp,
6824
6837
  ...backlogConfigHelp,
6825
6838
  ...backupConfigHelp,
@@ -14466,6 +14479,11 @@ var adviceConditions = {
14466
14479
  whenUnmet: "jira is not configured",
14467
14480
  matches: ({ config }) => config.jira !== void 0
14468
14481
  },
14482
+ askQuestion: {
14483
+ whenMet: "sessions.askQuestion is on",
14484
+ whenUnmet: "sessions.askQuestion is off",
14485
+ matches: ({ config }) => config.sessions?.askQuestion === true
14486
+ },
14469
14487
  typescript: repoFile("tsconfig.json", "a tsconfig.json"),
14470
14488
  filenameConvention: repoFile(
14471
14489
  join40("oxlint-rules", "filenameConvention.ts"),
@@ -14667,6 +14685,17 @@ The reviewer left ${comments3.length} comment${comments3.length === 1 ? "" : "s"
14667
14685
  process.exit(1);
14668
14686
  }
14669
14687
 
14688
+ // src/commands/sessions/shared/toAnswers.ts
14689
+ function toAnswers(value) {
14690
+ if (typeof value !== "object" || value === null || Array.isArray(value))
14691
+ return void 0;
14692
+ return Object.fromEntries(
14693
+ Object.entries(value).filter(
14694
+ (entry) => typeof entry[1] === "string"
14695
+ )
14696
+ );
14697
+ }
14698
+
14670
14699
  // src/commands/sessions/shared/toAttachments.ts
14671
14700
  function toAttachments(value) {
14672
14701
  if (!Array.isArray(value)) return void 0;
@@ -14746,7 +14775,8 @@ function toPreviewDecision(msg) {
14746
14775
  checklist: toChecklist(msg.checklist),
14747
14776
  reviewEvent: REVIEW_EVENTS.find((event) => event === msg.reviewEvent),
14748
14777
  reviewComments: toReviewComments(msg.reviewComments),
14749
- dismissed: msg.dismissed === true
14778
+ dismissed: msg.dismissed === true,
14779
+ answers: toAnswers(msg.answers)
14750
14780
  };
14751
14781
  }
14752
14782
 
@@ -14871,10 +14901,133 @@ function registerAsk(program) {
14871
14901
  );
14872
14902
  }
14873
14903
 
14904
+ // src/commands/askQuestion.ts
14905
+ import { randomUUID as randomUUID4 } from "crypto";
14906
+
14907
+ // src/commands/askQuestion/formatAskQuestionAnswers.ts
14908
+ function formatAskQuestionAnswers(questions, answers) {
14909
+ const pairs = questions.map(({ question }) => `"${question}"="${answers[question] ?? ""}"`).join(", ");
14910
+ return `User has answered your questions: ${pairs}. You can now continue with the user's answers in mind.`;
14911
+ }
14912
+
14913
+ // src/commands/backlog/readJsonPayload.ts
14914
+ import { readFileSync as readFileSync21 } from "fs";
14915
+ import chalk36 from "chalk";
14916
+ function fail(message3) {
14917
+ console.error(chalk36.red(message3));
14918
+ process.exit(1);
14919
+ }
14920
+ function describe(error) {
14921
+ return error instanceof Error ? error.message : String(error);
14922
+ }
14923
+ async function readSource(source) {
14924
+ try {
14925
+ if (source === "-") return (await readStdinBuffer()).toString("utf8");
14926
+ return readFileSync21(source, "utf8");
14927
+ } catch (error) {
14928
+ return fail(
14929
+ `Cannot read the payload from ${source === "-" ? "stdin" : source}: ${describe(error)}`
14930
+ );
14931
+ }
14932
+ }
14933
+ async function readJsonPayload(source, schema2, subject) {
14934
+ const raw = await readSource(source);
14935
+ let json;
14936
+ try {
14937
+ json = JSON.parse(raw);
14938
+ } catch (error) {
14939
+ return fail(`The payload is not valid JSON: ${describe(error)}`);
14940
+ }
14941
+ const parsed = schema2.safeParse(json);
14942
+ if (!parsed.success) {
14943
+ const issues = parsed.error.issues.map((i) => ` ${i.path.join(".") || "(root)"}: ${i.message}`).join("\n");
14944
+ return fail(`The payload is not a valid ${subject}:
14945
+ ${issues}`);
14946
+ }
14947
+ return parsed.data;
14948
+ }
14949
+
14950
+ // src/commands/sessions/shared/askQuestionInputSchema.ts
14951
+ import { z as z9 } from "zod";
14952
+ var askQuestionOptionSchema = z9.object({
14953
+ label: z9.string().min(1),
14954
+ description: z9.string(),
14955
+ preview: z9.string().optional()
14956
+ });
14957
+ var askQuestionSchema = z9.object({
14958
+ question: z9.string().min(1),
14959
+ header: z9.string().min(1),
14960
+ multiSelect: z9.boolean(),
14961
+ options: z9.array(askQuestionOptionSchema).min(2, "Each question needs at least 2 options").max(4, "Each question allows at most 4 options").refine(
14962
+ (options2) => new Set(options2.map((option) => option.label)).size === options2.length,
14963
+ "Option labels must be unique within a question"
14964
+ )
14965
+ });
14966
+ var askQuestionInputSchema = z9.object({
14967
+ questions: z9.array(askQuestionSchema).min(1, "Ask at least 1 question").max(4, "Ask at most 4 questions").refine(
14968
+ (questions) => new Set(questions.map((q) => q.question)).size === questions.length,
14969
+ "Question texts must be unique"
14970
+ )
14971
+ });
14972
+
14973
+ // src/commands/askQuestion.ts
14974
+ function useBuiltIn(reason4) {
14975
+ console.error(`Error: ${reason4}; use the built-in AskUserQuestion tool.`);
14976
+ process.exit(1);
14977
+ }
14978
+ async function askQuestion(options2) {
14979
+ const { questions } = await readJsonPayload(
14980
+ options2.json,
14981
+ askQuestionInputSchema,
14982
+ "AskUserQuestion input"
14983
+ );
14984
+ const sessionId = process.env.ASSIST_SESSION_ID;
14985
+ if (process.env.ASSIST_SESSION !== "1" || !sessionId)
14986
+ useBuiltIn("not running in an assist session");
14987
+ if (!loadConfig().sessions?.askQuestion)
14988
+ useBuiltIn("assist ask-question is disabled (sessions.askQuestion)");
14989
+ const title = questions.length === 1 ? "Claude is asking a question" : `Claude is asking ${questions.length} questions`;
14990
+ const decision = await awaitPreviewApproval(
14991
+ title,
14992
+ {
14993
+ sessionId,
14994
+ requestId: randomUUID4(),
14995
+ title,
14996
+ body: JSON.stringify({ questions }),
14997
+ prNumber: null,
14998
+ kind: "question"
14999
+ },
15000
+ { rejectIsOutcome: true }
15001
+ );
15002
+ if (decision.decision === "reject") {
15003
+ console.error(
15004
+ "The user declined to answer the questions. Do not assume answers; continue without them or ask again in chat if they are essential."
15005
+ );
15006
+ process.exit(1);
15007
+ }
15008
+ console.log(formatAskQuestionAnswers(questions, decision.answers ?? {}));
15009
+ }
15010
+
15011
+ // src/commands/registerAskQuestion.ts
15012
+ function registerAskQuestion(program) {
15013
+ internalCommand(
15014
+ configHelp(
15015
+ program.command("ask-question").description(
15016
+ "Ask the AskUserQuestion questions in the session's web preview pane and wait for the answers; prints the same result text as the built-in tool"
15017
+ ).requiredOption(
15018
+ "--json <file|->",
15019
+ "AskUserQuestion input JSON ({questions: [...]}), or - for stdin"
15020
+ ).action(askQuestion),
15021
+ askQuestionConfigHelp
15022
+ ),
15023
+ "Claude in place of AskUserQuestion"
15024
+ );
15025
+ }
15026
+
14874
15027
  // src/commands/registerBackup.ts
14875
15028
  import { mkdir as mkdir3, stat as stat4 } from "fs/promises";
14876
15029
  import { join as join42, resolve as resolve15 } from "path";
14877
- import chalk38 from "chalk";
15030
+ import chalk39 from "chalk";
14878
15031
 
14879
15032
  // src/shared/db/recordBackup.ts
14880
15033
  async function recordBackup(db, {
@@ -14888,7 +15041,7 @@ async function recordBackup(db, {
14888
15041
  // src/commands/backup/scheduleBackup.ts
14889
15042
  import { mkdir as mkdir2 } from "fs/promises";
14890
15043
  import { join as join41 } from "path";
14891
- import chalk36 from "chalk";
15044
+ import chalk37 from "chalk";
14892
15045
 
14893
15046
  // src/commands/backup/readCrontab.ts
14894
15047
  import { execSync as execSync15 } from "child_process";
@@ -15013,15 +15166,15 @@ function readScheduleBlock(crontab) {
15013
15166
  }
15014
15167
 
15015
15168
  // src/commands/backup/scheduleBackup.ts
15016
- function fail(message3) {
15017
- console.error(chalk36.red(message3));
15169
+ function fail2(message3) {
15170
+ console.error(chalk37.red(message3));
15018
15171
  process.exit(1);
15019
15172
  }
15020
15173
  async function scheduleBackup({
15021
15174
  every
15022
15175
  }) {
15023
15176
  if (!every) {
15024
- fail(
15177
+ fail2(
15025
15178
  "Missing --every <duration>. Run `assist backup schedule --every 6h`, or `assist backup schedule status` to inspect the current schedule."
15026
15179
  );
15027
15180
  }
@@ -15033,12 +15186,12 @@ async function scheduleBackup({
15033
15186
  const cronLine = `${cronExpr} ${resolveAssistCommand()} backup >> ${logPath2} 2>&1`;
15034
15187
  writeCrontab(upsertScheduleBlock(readCrontab(), every, cronLine));
15035
15188
  console.error(
15036
- chalk36.green(
15189
+ chalk37.green(
15037
15190
  `Scheduled assist backup every ${every} (${cronExpr}). Output is appended to ${logPath2}.`
15038
15191
  )
15039
15192
  );
15040
15193
  } catch (error) {
15041
- fail(error.message);
15194
+ fail2(error.message);
15042
15195
  }
15043
15196
  }
15044
15197
  function scheduleStatus() {
@@ -15060,14 +15213,14 @@ function scheduleRemove() {
15060
15213
  try {
15061
15214
  writeCrontab(removeScheduleBlock(current));
15062
15215
  } catch (error) {
15063
- fail(error.message);
15216
+ fail2(error.message);
15064
15217
  }
15065
- console.error(chalk36.green("Removed the assist backup schedule."));
15218
+ console.error(chalk37.green("Removed the assist backup schedule."));
15066
15219
  }
15067
15220
 
15068
15221
  // src/commands/backlog/exportBacklog.ts
15069
15222
  import { writeFile as writeFile3 } from "fs/promises";
15070
- import chalk37 from "chalk";
15223
+ import chalk38 from "chalk";
15071
15224
 
15072
15225
  // src/commands/backlog/dump/DumpTable.ts
15073
15226
  var DUMP_FORMAT = "assist-backlog-dump";
@@ -15195,7 +15348,7 @@ async function exportBacklog(file) {
15195
15348
  if (file) {
15196
15349
  await writeFile3(file, dump);
15197
15350
  console.error(
15198
- chalk37.green(`Exported backlog to ${file} (${dump.length} bytes).`)
15351
+ chalk38.green(`Exported backlog to ${file} (${dump.length} bytes).`)
15199
15352
  );
15200
15353
  return;
15201
15354
  }
@@ -15216,7 +15369,7 @@ async function backup({ out }) {
15216
15369
  await recordBackup(db, { filePath, sizeBytes: size, durationMs });
15217
15370
  const elapsed = (durationMs / 1e3).toFixed(1);
15218
15371
  console.error(
15219
- chalk38.green(`Recorded backup ${filePath} (${size} bytes) in ${elapsed}s.`)
15372
+ chalk39.green(`Recorded backup ${filePath} (${size} bytes) in ${elapsed}s.`)
15220
15373
  );
15221
15374
  }
15222
15375
  function registerBackup(program) {
@@ -15349,7 +15502,7 @@ function markAgentCommands(cmd) {
15349
15502
  }
15350
15503
 
15351
15504
  // src/commands/backlog/addActivity.ts
15352
- import chalk39 from "chalk";
15505
+ import chalk40 from "chalk";
15353
15506
 
15354
15507
  // src/shared/db/recordGitRef.ts
15355
15508
  async function recordGitRef(db, itemId2, ref) {
@@ -15444,7 +15597,7 @@ async function addActivity(id, kind, ref, options2) {
15444
15597
  const parsedKind = gitRefKindSchema.safeParse(kind);
15445
15598
  if (!parsedKind.success) {
15446
15599
  console.log(
15447
- chalk39.red(
15600
+ chalk40.red(
15448
15601
  `Invalid kind "${kind}". Expected one of: ${gitRefKindSchema.options.join(", ")}.`
15449
15602
  )
15450
15603
  );
@@ -15467,14 +15620,14 @@ async function addActivity(id, kind, ref, options2) {
15467
15620
  state: options2.state
15468
15621
  });
15469
15622
  console.log(
15470
- chalk39.green(
15623
+ chalk40.green(
15471
15624
  `Attached ${parsedKind.data} "${ref}" to item ${formatItemId(item.id)}.`
15472
15625
  )
15473
15626
  );
15474
15627
  }
15475
15628
 
15476
15629
  // src/commands/backlog/recordSlack.ts
15477
- import chalk40 from "chalk";
15630
+ import chalk41 from "chalk";
15478
15631
 
15479
15632
  // src/shared/resolveSessionItemId.ts
15480
15633
  var ITEM_ID_ENV = "ASSIST_BACKLOG_ITEM_ID";
@@ -15523,14 +15676,14 @@ async function recordSlack(url, options2) {
15523
15676
  return;
15524
15677
  case "recorded":
15525
15678
  console.log(
15526
- chalk40.green(
15679
+ chalk41.green(
15527
15680
  `Attached Slack link to item ${formatItemId(result.itemId)}.`
15528
15681
  )
15529
15682
  );
15530
15683
  return;
15531
15684
  case "failed":
15532
15685
  console.error(
15533
- chalk40.red(
15686
+ chalk41.red(
15534
15687
  `Failed to record Slack link against item ${formatItemId(result.itemId)}: ${errorMessage2(result.error)}`
15535
15688
  )
15536
15689
  );
@@ -15558,11 +15711,11 @@ function registerActivityCommands(cmd) {
15558
15711
  }
15559
15712
 
15560
15713
  // src/commands/backlog/associateGithub.ts
15561
- import chalk42 from "chalk";
15714
+ import chalk43 from "chalk";
15562
15715
  import { eq as eq26 } from "drizzle-orm";
15563
15716
 
15564
15717
  // src/commands/backlog/beginAssociation.ts
15565
- import chalk41 from "chalk";
15718
+ import chalk42 from "chalk";
15566
15719
  import { eq as eq25 } from "drizzle-orm";
15567
15720
  async function beginAssociation(id, options2, clearPatch, label) {
15568
15721
  const found = await findOneItem(id);
@@ -15575,7 +15728,7 @@ async function beginAssociation(id, options2, clearPatch, label) {
15575
15728
  if (options2.clear) {
15576
15729
  await orm.update(items).set(clearPatch).where(eq25(items.id, itemId2));
15577
15730
  console.log(
15578
- chalk41.green(
15731
+ chalk42.green(
15579
15732
  `Cleared ${label} association on item ${formatItemId(itemId2)}.`
15580
15733
  )
15581
15734
  );
@@ -15625,7 +15778,7 @@ async function associateGithub(id, issue, options2) {
15625
15778
  const { orm, itemId: itemId2 } = target;
15626
15779
  if (!issue) {
15627
15780
  console.log(
15628
- chalk42.red("Provide a GitHub issue, or use --clear to remove one.")
15781
+ chalk43.red("Provide a GitHub issue, or use --clear to remove one.")
15629
15782
  );
15630
15783
  process.exitCode = 1;
15631
15784
  return;
@@ -15633,7 +15786,7 @@ async function associateGithub(id, issue, options2) {
15633
15786
  const normalized = normalizeGithubIssue(issue);
15634
15787
  if (!normalized) {
15635
15788
  console.log(
15636
- chalk42.red(
15789
+ chalk43.red(
15637
15790
  `Malformed GitHub issue "${issue}". Expected owner/repo#number or a github.com issue URL.`
15638
15791
  )
15639
15792
  );
@@ -15643,8 +15796,8 @@ async function associateGithub(id, issue, options2) {
15643
15796
  const title = fetchGithubIssueTitle(normalized);
15644
15797
  await orm.update(items).set({ githubIssue: normalized, jiraKey: null }).where(eq26(items.id, itemId2));
15645
15798
  console.log(
15646
- chalk42.green(`Associated ${normalized} with item ${formatItemId(itemId2)}.`),
15647
- title ? chalk42.dim(`(${title})`) : ""
15799
+ chalk43.green(`Associated ${normalized} with item ${formatItemId(itemId2)}.`),
15800
+ title ? chalk43.dim(`(${title})`) : ""
15648
15801
  );
15649
15802
  }
15650
15803
 
@@ -15654,12 +15807,12 @@ function registerAssociateGithubCommand(cmd) {
15654
15807
  }
15655
15808
 
15656
15809
  // src/commands/backlog/associateJira.ts
15657
- import chalk44 from "chalk";
15810
+ import chalk45 from "chalk";
15658
15811
  import { eq as eq27 } from "drizzle-orm";
15659
15812
 
15660
15813
  // src/commands/jira/fetchIssue.ts
15661
15814
  import { execSync as execSync17 } from "child_process";
15662
- import chalk43 from "chalk";
15815
+ import chalk44 from "chalk";
15663
15816
  function fetchIssue(issueKey, fields) {
15664
15817
  let result;
15665
15818
  try {
@@ -15672,15 +15825,15 @@ function fetchIssue(issueKey, fields) {
15672
15825
  const stderr = error.stderr;
15673
15826
  if (stderr.includes("unauthorized")) {
15674
15827
  console.error(
15675
- chalk43.red("Jira authentication expired."),
15828
+ chalk44.red("Jira authentication expired."),
15676
15829
  "Run",
15677
- chalk43.cyan("assist jira auth"),
15830
+ chalk44.cyan("assist jira auth"),
15678
15831
  "to re-authenticate."
15679
15832
  );
15680
15833
  process.exit(1);
15681
15834
  }
15682
15835
  }
15683
- console.error(chalk43.red(`Failed to fetch ${issueKey}.`));
15836
+ console.error(chalk44.red(`Failed to fetch ${issueKey}.`));
15684
15837
  process.exit(1);
15685
15838
  }
15686
15839
  return JSON.parse(result);
@@ -15703,14 +15856,14 @@ async function associateJira(id, key, options2) {
15703
15856
  if (!target) return;
15704
15857
  const { orm, itemId: itemId2 } = target;
15705
15858
  if (!key) {
15706
- console.log(chalk44.red("Provide a Jira key, or use --clear to remove one."));
15859
+ console.log(chalk45.red("Provide a Jira key, or use --clear to remove one."));
15707
15860
  process.exitCode = 1;
15708
15861
  return;
15709
15862
  }
15710
15863
  const normalized = normalizeJiraKey(key);
15711
15864
  if (!normalized) {
15712
15865
  console.log(
15713
- chalk44.red(
15866
+ chalk45.red(
15714
15867
  `Malformed Jira key "${key}". Expected a key like PROJ-123 or a browse URL.`
15715
15868
  )
15716
15869
  );
@@ -15722,8 +15875,8 @@ async function associateJira(id, key, options2) {
15722
15875
  const summary = fields?.summary;
15723
15876
  await orm.update(items).set({ jiraKey: normalized, githubIssue: null }).where(eq27(items.id, itemId2));
15724
15877
  console.log(
15725
- chalk44.green(`Associated ${normalized} with item ${formatItemId(itemId2)}.`),
15726
- summary ? chalk44.dim(`(${summary})`) : ""
15878
+ chalk45.green(`Associated ${normalized} with item ${formatItemId(itemId2)}.`),
15879
+ summary ? chalk45.dim(`(${summary})`) : ""
15727
15880
  );
15728
15881
  }
15729
15882
 
@@ -15736,7 +15889,7 @@ function registerAssociateJiraCommand(cmd) {
15736
15889
  import { spawnSync as spawnSync4 } from "child_process";
15737
15890
  import { existsSync as existsSync38 } from "fs";
15738
15891
  import { mkdir as mkdir4 } from "fs/promises";
15739
- import chalk45 from "chalk";
15892
+ import chalk46 from "chalk";
15740
15893
 
15741
15894
  // src/commands/backlog/originToSshUrl.ts
15742
15895
  function originToSshUrl(origin) {
@@ -15750,43 +15903,43 @@ function originToSshUrl(origin) {
15750
15903
  }
15751
15904
 
15752
15905
  // src/commands/backlog/cloneRepo.ts
15753
- function fail2(message3) {
15754
- console.log(chalk45.red(message3));
15906
+ function fail3(message3) {
15907
+ console.log(chalk46.red(message3));
15755
15908
  process.exitCode = 1;
15756
15909
  }
15757
15910
  async function cloneRepo(originRaw) {
15758
15911
  if (originRaw.trim().startsWith("local:")) {
15759
- return fail2(
15912
+ return fail3(
15760
15913
  `"${originRaw.trim()}" has no remote and cannot be cloned (local: origins are not clonable).`
15761
15914
  );
15762
15915
  }
15763
15916
  const origin = normalizeOrigin(originRaw);
15764
15917
  const sshUrl = originToSshUrl(origin);
15765
15918
  if (!sshUrl) {
15766
- return fail2(`Could not derive an SSH remote from "${origin}".`);
15919
+ return fail3(`Could not derive an SSH remote from "${origin}".`);
15767
15920
  }
15768
15921
  const baseDir = expandTilde(loadConfig().clone.baseDir);
15769
15922
  const target = cloneTargetDir(origin, baseDir);
15770
15923
  if (!target) {
15771
- return fail2(`Could not derive a repository name from "${origin}".`);
15924
+ return fail3(`Could not derive a repository name from "${origin}".`);
15772
15925
  }
15773
15926
  if (existsSync38(target)) {
15774
- return fail2(`Clone target already exists: ${target}`);
15927
+ return fail3(`Clone target already exists: ${target}`);
15775
15928
  }
15776
15929
  await mkdir4(baseDir, { recursive: true });
15777
- console.error(chalk45.dim(`Cloning ${sshUrl} into ${target}`));
15930
+ console.error(chalk46.dim(`Cloning ${sshUrl} into ${target}`));
15778
15931
  const result = spawnSync4("git", ["clone", sshUrl, target], {
15779
15932
  stdio: "inherit"
15780
15933
  });
15781
15934
  if (result.error) {
15782
- return fail2(`Failed to run git clone: ${result.error.message}`);
15935
+ return fail3(`Failed to run git clone: ${result.error.message}`);
15783
15936
  }
15784
15937
  if (result.status !== 0) {
15785
- return fail2(
15938
+ return fail3(
15786
15939
  `git clone failed with exit code ${result.status ?? "unknown"}.`
15787
15940
  );
15788
15941
  }
15789
- console.error(chalk45.green(`Cloned ${origin} into ${target}`));
15942
+ console.error(chalk46.green(`Cloned ${origin} into ${target}`));
15790
15943
  }
15791
15944
 
15792
15945
  // src/commands/backlog/registerCloneCommand.ts
@@ -15797,26 +15950,26 @@ function registerCloneCommand(cmd) {
15797
15950
  }
15798
15951
 
15799
15952
  // src/commands/backlog/comment.ts
15800
- import chalk46 from "chalk";
15953
+ import chalk47 from "chalk";
15801
15954
  async function comment(id, text18) {
15802
15955
  const found = await findOneItem(id);
15803
15956
  if (!found) process.exit(1);
15804
15957
  await appendComment(found.orm, found.item.id, text18);
15805
15958
  console.log(
15806
- chalk46.green(`Comment added to item ${formatItemId(found.item.id)}.`)
15959
+ chalk47.green(`Comment added to item ${formatItemId(found.item.id)}.`)
15807
15960
  );
15808
15961
  }
15809
15962
 
15810
15963
  // src/commands/backlog/comments.ts
15811
- import chalk48 from "chalk";
15964
+ import chalk49 from "chalk";
15812
15965
 
15813
15966
  // src/commands/backlog/formatComment.ts
15814
- import chalk47 from "chalk";
15967
+ import chalk48 from "chalk";
15815
15968
  function formatComment(entry) {
15816
- const id = entry.id !== void 0 ? chalk47.dim(`#${entry.id} `) : "";
15817
- const tag = entry.type === "summary" ? chalk47.magenta("[summary]") : chalk47.cyan("[comment]");
15818
- const phase = entry.phase !== void 0 ? chalk47.dim(` (phase ${entry.phase})`) : "";
15819
- const time = chalk47.dim(entry.timestamp);
15969
+ const id = entry.id !== void 0 ? chalk48.dim(`#${entry.id} `) : "";
15970
+ const tag = entry.type === "summary" ? chalk48.magenta("[summary]") : chalk48.cyan("[comment]");
15971
+ const phase = entry.phase !== void 0 ? chalk48.dim(` (phase ${entry.phase})`) : "";
15972
+ const time = chalk48.dim(entry.timestamp);
15820
15973
  return `${id}${tag}${phase} ${time}
15821
15974
  ${entry.text}`;
15822
15975
  }
@@ -15828,11 +15981,11 @@ async function comments2(id) {
15828
15981
  const { item } = found;
15829
15982
  const entries = item.comments ?? [];
15830
15983
  if (entries.length === 0) {
15831
- console.log(chalk48.dim(`No comments on item ${formatItemId(item.id)}.`));
15984
+ console.log(chalk49.dim(`No comments on item ${formatItemId(item.id)}.`));
15832
15985
  return;
15833
15986
  }
15834
15987
  console.log(
15835
- chalk48.bold(`Comments for ${formatItemId(item.id)}: ${item.name}
15988
+ chalk49.bold(`Comments for ${formatItemId(item.id)}: ${item.name}
15836
15989
  `)
15837
15990
  );
15838
15991
  for (const entry of entries) {
@@ -15842,7 +15995,7 @@ async function comments2(id) {
15842
15995
  }
15843
15996
 
15844
15997
  // src/commands/backlog/deleteCommentCmd.ts
15845
- import chalk49 from "chalk";
15998
+ import chalk50 from "chalk";
15846
15999
  async function deleteCommentCmd(id, commentId) {
15847
16000
  const found = await findOneItem(id);
15848
16001
  if (!found) process.exit(1);
@@ -15855,14 +16008,14 @@ async function deleteCommentCmd(id, commentId) {
15855
16008
  switch (outcome) {
15856
16009
  case "deleted":
15857
16010
  console.log(
15858
- chalk49.green(
16011
+ chalk50.green(
15859
16012
  `Comment #${commentId} deleted from item ${formatItemId(itemId2)}.`
15860
16013
  )
15861
16014
  );
15862
16015
  break;
15863
16016
  case "not-found":
15864
16017
  console.log(
15865
- chalk49.red(
16018
+ chalk50.red(
15866
16019
  `Comment #${commentId} not found on item ${formatItemId(itemId2)}.`
15867
16020
  )
15868
16021
  );
@@ -15870,7 +16023,7 @@ async function deleteCommentCmd(id, commentId) {
15870
16023
  break;
15871
16024
  case "is-summary":
15872
16025
  console.log(
15873
- chalk49.red(
16026
+ chalk50.red(
15874
16027
  `Comment #${commentId} is a phase summary and cannot be deleted.`
15875
16028
  )
15876
16029
  );
@@ -15898,7 +16051,7 @@ function registerExportCommand(cmd) {
15898
16051
 
15899
16052
  // src/commands/backlog/importBacklog.ts
15900
16053
  import { readFile as readFile3 } from "fs/promises";
15901
- import chalk51 from "chalk";
16054
+ import chalk52 from "chalk";
15902
16055
 
15903
16056
  // src/commands/backlog/dump/countCopyRows.ts
15904
16057
  function countCopyRows(data) {
@@ -15970,7 +16123,7 @@ function validateDump({ header, sections }) {
15970
16123
  }
15971
16124
 
15972
16125
  // src/commands/backlog/import/confirmReplace.ts
15973
- import chalk50 from "chalk";
16126
+ import chalk51 from "chalk";
15974
16127
  async function countRows(client, table) {
15975
16128
  const { rows } = await client.query(
15976
16129
  `SELECT count(*)::int AS n FROM ${table}`
@@ -15981,7 +16134,7 @@ function printSummary(tables, current, incoming) {
15981
16134
  const lines2 = tables.map(
15982
16135
  (t, i) => ` ${t.name}: ${current[i]} \u2192 ${incoming[i]} rows`
15983
16136
  );
15984
- console.error(chalk50.bold("\nThis will REPLACE all backlog data:"));
16137
+ console.error(chalk51.bold("\nThis will REPLACE all backlog data:"));
15985
16138
  console.error(`${lines2.join("\n")}
15986
16139
  `);
15987
16140
  }
@@ -16074,13 +16227,13 @@ async function importBacklog(file, options2 = {}) {
16074
16227
  );
16075
16228
  await withDbClient(async (client) => {
16076
16229
  if (!options2.yes && !await confirmReplace(client, tables, incoming, !file)) {
16077
- console.error(chalk51.yellow("Import cancelled; no changes made."));
16230
+ console.error(chalk52.yellow("Import cancelled; no changes made."));
16078
16231
  return;
16079
16232
  }
16080
16233
  await restore(client, parsed);
16081
16234
  const total2 = incoming.reduce((sum3, n) => sum3 + n, 0);
16082
16235
  console.error(
16083
- chalk51.green(
16236
+ chalk52.green(
16084
16237
  `Imported backlog: ${total2} rows restored across ${tables.length} tables.`
16085
16238
  )
16086
16239
  );
@@ -16097,7 +16250,7 @@ function registerImportCommand(cmd) {
16097
16250
  }
16098
16251
 
16099
16252
  // src/commands/backlog/add.ts
16100
- import chalk53 from "chalk";
16253
+ import chalk54 from "chalk";
16101
16254
 
16102
16255
  // src/lib/isClaudeCode.ts
16103
16256
  function isClaudeCode() {
@@ -16171,11 +16324,11 @@ async function createItemWithDefaults(fields) {
16171
16324
  }
16172
16325
 
16173
16326
  // src/commands/backlog/ensureRemoteOrigin.ts
16174
- import chalk52 from "chalk";
16327
+ import chalk53 from "chalk";
16175
16328
  function ensureRemoteOrigin() {
16176
16329
  if (getRemoteOriginUrl(getBacklogDir())) return true;
16177
16330
  console.log(
16178
- chalk52.red(
16331
+ chalk53.red(
16179
16332
  "Backlog requires a git remote so items get a stable origin.\nAdd one with: git remote add origin <url>"
16180
16333
  )
16181
16334
  );
@@ -16185,7 +16338,7 @@ function ensureRemoteOrigin() {
16185
16338
 
16186
16339
  // src/commands/backlog/add/shared.ts
16187
16340
  import { spawnSync as spawnSync5 } from "child_process";
16188
- import { mkdtempSync, readFileSync as readFileSync21, unlinkSync as unlinkSync3, writeFileSync as writeFileSync18 } from "fs";
16341
+ import { mkdtempSync, readFileSync as readFileSync22, unlinkSync as unlinkSync3, writeFileSync as writeFileSync18 } from "fs";
16189
16342
  import { tmpdir } from "os";
16190
16343
  import { join as join45 } from "path";
16191
16344
  import enquirer4 from "enquirer";
@@ -16235,7 +16388,7 @@ function openEditor() {
16235
16388
  unlinkSync3(filePath);
16236
16389
  return void 0;
16237
16390
  }
16238
- const content = readFileSync21(filePath, "utf8").trim();
16391
+ const content = readFileSync22(filePath, "utf8").trim();
16239
16392
  unlinkSync3(filePath);
16240
16393
  return content || void 0;
16241
16394
  }
@@ -16257,7 +16410,7 @@ async function promptAcceptanceCriteria() {
16257
16410
  async function add(options2) {
16258
16411
  if (isClaudeCode()) {
16259
16412
  console.error(
16260
- chalk53.red(
16413
+ chalk54.red(
16261
16414
  "Error: 'assist backlog add' is for human use. Compose the whole item \u2014 name, type, description, acceptance criteria and every phase \u2014 and run 'assist backlog propose --json <file|->' so it is previewed and approved before anything is written."
16262
16415
  )
16263
16416
  );
@@ -16275,14 +16428,14 @@ async function add(options2) {
16275
16428
  description,
16276
16429
  acceptanceCriteria: acceptanceCriteria2
16277
16430
  });
16278
- console.log(chalk53.green(`Added item ${formatItemId(id)}: ${name}`));
16431
+ console.log(chalk54.green(`Added item ${formatItemId(id)}: ${name}`));
16279
16432
  }
16280
16433
 
16281
16434
  // src/commands/backlog/addPhase.ts
16282
- import chalk55 from "chalk";
16435
+ import chalk56 from "chalk";
16283
16436
 
16284
16437
  // src/commands/backlog/resolveInsertPosition.ts
16285
- import chalk54 from "chalk";
16438
+ import chalk55 from "chalk";
16286
16439
  import { count as count3, eq as eq30 } from "drizzle-orm";
16287
16440
  async function resolveInsertPosition(orm, itemId2, position) {
16288
16441
  const [row3] = await orm.select({ cnt: count3() }).from(planPhases).where(eq30(planPhases.itemId, itemId2));
@@ -16291,7 +16444,7 @@ async function resolveInsertPosition(orm, itemId2, position) {
16291
16444
  const pos = Number.parseInt(position, 10);
16292
16445
  if (pos < 1 || pos > phaseCount + 1) {
16293
16446
  console.log(
16294
- chalk54.red(
16447
+ chalk55.red(
16295
16448
  `Position ${pos} is out of range. Must be between 1 and ${phaseCount + 1}.`
16296
16449
  )
16297
16450
  );
@@ -16302,7 +16455,7 @@ async function resolveInsertPosition(orm, itemId2, position) {
16302
16455
  }
16303
16456
 
16304
16457
  // src/commands/backlog/addPhase/reviewProposedPhase.ts
16305
- import { randomUUID as randomUUID4 } from "crypto";
16458
+ import { randomUUID as randomUUID5 } from "crypto";
16306
16459
 
16307
16460
  // src/commands/backlog/renderPhaseSection.ts
16308
16461
  function renderPhaseSection(phase, idx) {
@@ -16326,7 +16479,7 @@ async function reviewProposedPhase(item, phaseIdx, phase) {
16326
16479
  return;
16327
16480
  await awaitPreviewApproval("Backlog phase preview", {
16328
16481
  sessionId,
16329
- requestId: randomUUID4(),
16482
+ requestId: randomUUID5(),
16330
16483
  title: `Add a phase to ${formatItemId(item.id)}: ${item.name}`,
16331
16484
  body: renderPhaseSection(phase, phaseIdx),
16332
16485
  prNumber: null,
@@ -16342,7 +16495,7 @@ async function addPhase(id, name, options2) {
16342
16495
  if (!found) return;
16343
16496
  const tasks = options2.task ?? [];
16344
16497
  if (tasks.length === 0) {
16345
- console.log(chalk55.red("At least one --task is required."));
16498
+ console.log(chalk56.red("At least one --task is required."));
16346
16499
  process.exitCode = 1;
16347
16500
  return;
16348
16501
  }
@@ -16366,43 +16519,43 @@ async function addPhase(id, name, options2) {
16366
16519
  );
16367
16520
  const verb = options2.position !== void 0 ? "Inserted" : "Added";
16368
16521
  console.log(
16369
- chalk55.green(
16522
+ chalk56.green(
16370
16523
  `${verb} phase ${phaseIdx + 1} "${name}" to item ${formatItemId(itemId2)} with ${tasks.length} task(s).`
16371
16524
  )
16372
16525
  );
16373
16526
  }
16374
16527
 
16375
16528
  // src/commands/backlog/list.ts
16376
- import chalk57 from "chalk";
16529
+ import chalk58 from "chalk";
16377
16530
 
16378
16531
  // src/commands/backlog/list/shared.ts
16379
- import chalk56 from "chalk";
16532
+ import chalk57 from "chalk";
16380
16533
  function statusIcon(status2) {
16381
16534
  switch (status2) {
16382
16535
  case "todo":
16383
- return chalk56.dim("[ ]");
16536
+ return chalk57.dim("[ ]");
16384
16537
  case "in-progress":
16385
- return chalk56.yellow("[~]");
16538
+ return chalk57.yellow("[~]");
16386
16539
  case "done":
16387
- return chalk56.green("[x]");
16540
+ return chalk57.green("[x]");
16388
16541
  case "wontdo":
16389
- return chalk56.dim("[-]");
16542
+ return chalk57.dim("[-]");
16390
16543
  }
16391
16544
  }
16392
16545
  function starMarker(item) {
16393
- return item.starred ? `${chalk56.yellow("\u2605")} ` : "";
16546
+ return item.starred ? `${chalk57.yellow("\u2605")} ` : "";
16394
16547
  }
16395
16548
  function typeLabel(type) {
16396
16549
  switch (type) {
16397
16550
  case "bug":
16398
- return chalk56.magenta("Bug");
16551
+ return chalk57.magenta("Bug");
16399
16552
  case "story":
16400
- return chalk56.cyan("Story");
16553
+ return chalk57.cyan("Story");
16401
16554
  }
16402
16555
  }
16403
16556
  function phaseLabel(item) {
16404
16557
  if (!item.plan) return "";
16405
- return chalk56.dim(` (phase ${item.currentPhase ?? 1}/${item.plan.length})`);
16558
+ return chalk57.dim(` (phase ${item.currentPhase ?? 1}/${item.plan.length})`);
16406
16559
  }
16407
16560
  function isBlocked(item, items2) {
16408
16561
  const deps2 = (item.links ?? []).filter((l) => l.type === "depends-on");
@@ -16414,15 +16567,15 @@ function isBlocked(item, items2) {
16414
16567
  function dependencyLabel(item, items2) {
16415
16568
  const deps2 = (item.links ?? []).filter((l) => l.type === "depends-on");
16416
16569
  if (deps2.length === 0) return "";
16417
- if (isBlocked(item, items2)) return chalk56.red(" [blocked]");
16418
- return chalk56.dim(` [${deps2.length} dep${deps2.length > 1 ? "s" : ""}]`);
16570
+ if (isBlocked(item, items2)) return chalk57.red(" [blocked]");
16571
+ return chalk57.dim(` [${deps2.length} dep${deps2.length > 1 ? "s" : ""}]`);
16419
16572
  }
16420
16573
  function printVerboseDetails(item) {
16421
16574
  if (item.description) {
16422
- console.log(` ${chalk56.dim("Description:")} ${item.description}`);
16575
+ console.log(` ${chalk57.dim("Description:")} ${item.description}`);
16423
16576
  }
16424
16577
  if (item.acceptanceCriteria.length > 0) {
16425
- console.log(` ${chalk56.dim("Acceptance criteria:")}`);
16578
+ console.log(` ${chalk57.dim("Acceptance criteria:")}`);
16426
16579
  for (const [i, criterion] of item.acceptanceCriteria.entries()) {
16427
16580
  console.log(` ${i + 1}. ${criterion}`);
16428
16581
  }
@@ -16444,19 +16597,19 @@ function repoPrefixer(items2, allRepos) {
16444
16597
  );
16445
16598
  const repoNameOf = (item) => item.origin ? labels.get(item.origin) ?? "" : "";
16446
16599
  const width2 = Math.max(0, ...items2.map((i) => repoNameOf(i).length));
16447
- return (item) => `${chalk57.dim(repoNameOf(item).padEnd(width2))} `;
16600
+ return (item) => `${chalk58.dim(repoNameOf(item).padEnd(width2))} `;
16448
16601
  }
16449
16602
  async function list(options2) {
16450
16603
  const allItems = await loadBacklog(options2.allRepos);
16451
16604
  const items2 = filterItems(allItems, options2);
16452
16605
  if (items2.length === 0) {
16453
- console.log(chalk57.dim("Backlog is empty."));
16606
+ console.log(chalk58.dim("Backlog is empty."));
16454
16607
  return;
16455
16608
  }
16456
16609
  const prefixOf = repoPrefixer(items2, !!options2.allRepos);
16457
16610
  for (const item of items2) {
16458
16611
  console.log(
16459
- `${prefixOf(item)}${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk57.dim(formatItemId(item.id))} ${starMarker(item)}${item.name}${phaseLabel(item)}${dependencyLabel(item, allItems)}`
16612
+ `${prefixOf(item)}${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk58.dim(formatItemId(item.id))} ${starMarker(item)}${item.name}${phaseLabel(item)}${dependencyLabel(item, allItems)}`
16460
16613
  );
16461
16614
  if (options2.verbose) {
16462
16615
  printVerboseDetails(item);
@@ -16467,59 +16620,22 @@ async function list(options2) {
16467
16620
  // src/commands/backlog/propose.ts
16468
16621
  import chalk60 from "chalk";
16469
16622
 
16470
- // src/commands/backlog/readJsonPayload.ts
16471
- import { readFileSync as readFileSync22 } from "fs";
16472
- import chalk58 from "chalk";
16473
- function fail3(message3) {
16474
- console.error(chalk58.red(message3));
16475
- process.exit(1);
16476
- }
16477
- function describe(error) {
16478
- return error instanceof Error ? error.message : String(error);
16479
- }
16480
- async function readSource(source) {
16481
- try {
16482
- if (source === "-") return (await readStdinBuffer()).toString("utf8");
16483
- return readFileSync22(source, "utf8");
16484
- } catch (error) {
16485
- return fail3(
16486
- `Cannot read the payload from ${source === "-" ? "stdin" : source}: ${describe(error)}`
16487
- );
16488
- }
16489
- }
16490
- async function readJsonPayload(source, schema2, subject) {
16491
- const raw = await readSource(source);
16492
- let json;
16493
- try {
16494
- json = JSON.parse(raw);
16495
- } catch (error) {
16496
- return fail3(`The payload is not valid JSON: ${describe(error)}`);
16497
- }
16498
- const parsed = schema2.safeParse(json);
16499
- if (!parsed.success) {
16500
- const issues = parsed.error.issues.map((i) => ` ${i.path.join(".") || "(root)"}: ${i.message}`).join("\n");
16501
- return fail3(`The payload is not a valid ${subject}:
16502
- ${issues}`);
16503
- }
16504
- return parsed.data;
16505
- }
16506
-
16507
16623
  // src/commands/backlog/propose/proposedItemSchema.ts
16508
- import { z as z9 } from "zod";
16509
- var proposedPhaseSchema = z9.strictObject({
16510
- name: z9.string().trim().min(1, "phase name is required").refine(
16624
+ import { z as z10 } from "zod";
16625
+ var proposedPhaseSchema = z10.strictObject({
16626
+ name: z10.string().trim().min(1, "phase name is required").refine(
16511
16627
  (name) => name.toLowerCase() !== REVIEW_PHASE_NAME.toLowerCase(),
16512
16628
  `"${REVIEW_PHASE_NAME}" is owned by the runner and appended to every plan automatically \u2014 remove this phase`
16513
16629
  ),
16514
- tasks: z9.array(z9.string().trim().min(1)).min(1, "a phase needs at least one task"),
16515
- manualChecks: z9.array(z9.string().trim().min(1)).default([])
16630
+ tasks: z10.array(z10.string().trim().min(1)).min(1, "a phase needs at least one task"),
16631
+ manualChecks: z10.array(z10.string().trim().min(1)).default([])
16516
16632
  });
16517
- var proposedItemSchema = z9.strictObject({
16518
- name: z9.string().trim().min(1, "name is required"),
16519
- type: z9.enum(["story", "bug"]),
16520
- description: z9.string().optional(),
16521
- acceptanceCriteria: z9.array(z9.string().trim().min(1)).default([]),
16522
- phases: z9.array(proposedPhaseSchema).default([])
16633
+ var proposedItemSchema = z10.strictObject({
16634
+ name: z10.string().trim().min(1, "name is required"),
16635
+ type: z10.enum(["story", "bug"]),
16636
+ description: z10.string().optional(),
16637
+ acceptanceCriteria: z10.array(z10.string().trim().min(1)).default([]),
16638
+ phases: z10.array(proposedPhaseSchema).default([])
16523
16639
  });
16524
16640
 
16525
16641
  // src/commands/backlog/propose/readProposedItem.ts
@@ -16528,7 +16644,7 @@ function readProposedItem(source) {
16528
16644
  }
16529
16645
 
16530
16646
  // src/commands/backlog/propose/reviewProposal.ts
16531
- import { randomUUID as randomUUID5 } from "crypto";
16647
+ import { randomUUID as randomUUID6 } from "crypto";
16532
16648
  import chalk59 from "chalk";
16533
16649
 
16534
16650
  // src/shared/renderMarkdownTerminal.ts
@@ -16570,7 +16686,7 @@ async function reviewProposal(item, sessionId, confirmed) {
16570
16686
  if (sessionId) {
16571
16687
  const decision = await awaitPreviewApproval("Backlog item preview", {
16572
16688
  sessionId,
16573
- requestId: randomUUID5(),
16689
+ requestId: randomUUID6(),
16574
16690
  title: item.name,
16575
16691
  body,
16576
16692
  prNumber: null,
@@ -17959,7 +18075,7 @@ Phase ${phaseNumber} completed.`));
17959
18075
  }
17960
18076
 
17961
18077
  // src/commands/backlog/preparePhaseSession.ts
17962
- import { randomUUID as randomUUID6 } from "crypto";
18078
+ import { randomUUID as randomUUID7 } from "crypto";
17963
18079
 
17964
18080
  // src/commands/backlog/persistPhaseSession.ts
17965
18081
  import os4 from "os";
@@ -18019,19 +18135,19 @@ async function persistPhaseSessionId(itemId2, phaseIdx, claudeSessionId) {
18019
18135
  import { mkdirSync as mkdirSync13, readFileSync as readFileSync26, rmSync as rmSync4, writeFileSync as writeFileSync22 } from "fs";
18020
18136
  import { homedir as homedir16 } from "os";
18021
18137
  import { dirname as dirname26, join as join48 } from "path";
18022
- import { z as z10 } from "zod";
18023
- var activitySchema = z10.object({
18024
- kind: z10.enum(["command", "backlog"]),
18025
- harness: z10.enum(["claude", "codex", "pi"]).optional(),
18026
- name: z10.string().optional(),
18027
- itemId: z10.number().optional(),
18028
- itemName: z10.string().optional(),
18029
- phase: z10.number().optional(),
18030
- phaseName: z10.string().optional(),
18031
- totalPhases: z10.number().optional(),
18032
- claudeSessionId: z10.string().optional(),
18033
- watchState: z10.enum(["waiting", "updating"]).optional(),
18034
- startedAt: z10.number()
18138
+ import { z as z11 } from "zod";
18139
+ var activitySchema = z11.object({
18140
+ kind: z11.enum(["command", "backlog"]),
18141
+ harness: z11.enum(["claude", "codex", "pi"]).optional(),
18142
+ name: z11.string().optional(),
18143
+ itemId: z11.number().optional(),
18144
+ itemName: z11.string().optional(),
18145
+ phase: z11.number().optional(),
18146
+ phaseName: z11.string().optional(),
18147
+ totalPhases: z11.number().optional(),
18148
+ claudeSessionId: z11.string().optional(),
18149
+ watchState: z11.enum(["waiting", "updating"]).optional(),
18150
+ startedAt: z11.number()
18035
18151
  });
18036
18152
  function activityPath(sessionId) {
18037
18153
  return join48(homedir16(), ".assist", "activity", `activity-${sessionId}.json`);
@@ -18130,7 +18246,7 @@ async function verifyPhaseResume(itemId2, resumeSessionId, phaseLabel2) {
18130
18246
  // src/commands/backlog/preparePhaseSession.ts
18131
18247
  async function preparePhaseSession(item, phase, phaseIndex, phaseNumber, totalPhases, phaseLabel2, spawnOptions) {
18132
18248
  const resumeSessionId = spawnOptions?.resumeSessionId;
18133
- const claudeSessionId = resumeSessionId ?? randomUUID6();
18249
+ const claudeSessionId = resumeSessionId ?? randomUUID7();
18134
18250
  if (resumeSessionId && !await verifyPhaseResume(item.id, resumeSessionId, phaseLabel2)) {
18135
18251
  return void 0;
18136
18252
  }
@@ -18474,7 +18590,7 @@ import chalk83 from "chalk";
18474
18590
  import enquirer7 from "enquirer";
18475
18591
 
18476
18592
  // src/commands/backlog/launchMode.ts
18477
- import { randomUUID as randomUUID7 } from "crypto";
18593
+ import { randomUUID as randomUUID8 } from "crypto";
18478
18594
 
18479
18595
  // src/commands/backlog/handleLaunchSignal.ts
18480
18596
  import chalk82 from "chalk";
@@ -18579,7 +18695,7 @@ async function launchMode(slashCommand, options2) {
18579
18695
  const resumeSessionId = options2?.resumeSessionId;
18580
18696
  if (!resumeSessionId) pullIfConfigured();
18581
18697
  process.env.ASSIST_SESSION_ID ??= String(process.pid);
18582
- const claudeSessionId = resumeSessionId ?? randomUUID7();
18698
+ const claudeSessionId = resumeSessionId ?? randomUUID8();
18583
18699
  const harness = options2?.harness ?? "claude";
18584
18700
  reportLaunchActivity(slashCommand, claudeSessionId, harness, options2);
18585
18701
  const prompt = resumeSessionId ? resumeNudge() : buildSlashCommand(slashCommand, options2?.description);
@@ -19372,9 +19488,9 @@ function registerUpdateFieldCommand(cmd) {
19372
19488
  import chalk104 from "chalk";
19373
19489
 
19374
19490
  // src/commands/backlog/updatePlan/planUpdateSchema.ts
19375
- import { z as z11 } from "zod";
19376
- var planUpdateSchema = z11.strictObject({
19377
- phases: z11.array(proposedPhaseSchema).min(1, "a plan needs at least one phase")
19491
+ import { z as z12 } from "zod";
19492
+ var planUpdateSchema = z12.strictObject({
19493
+ phases: z12.array(proposedPhaseSchema).min(1, "a plan needs at least one phase")
19378
19494
  });
19379
19495
 
19380
19496
  // src/commands/backlog/updatePlan/readPlanUpdate.ts
@@ -19418,7 +19534,7 @@ async function replacePlan(orm, itemId2, phases, currentPhase) {
19418
19534
  }
19419
19535
 
19420
19536
  // src/commands/backlog/updatePlan/reviewPlanUpdate.ts
19421
- import { randomUUID as randomUUID8 } from "crypto";
19537
+ import { randomUUID as randomUUID9 } from "crypto";
19422
19538
  import chalk103 from "chalk";
19423
19539
 
19424
19540
  // src/commands/backlog/updatePlan/isCompleted.ts
@@ -19575,7 +19691,7 @@ async function reviewPlanUpdate(item, phases) {
19575
19691
  if (process.env.ASSIST_SESSION === "1" && sessionId) {
19576
19692
  const decision = await awaitPreviewApproval("Plan update preview", {
19577
19693
  sessionId,
19578
- requestId: randomUUID8(),
19694
+ requestId: randomUUID9(),
19579
19695
  title: `Update the plan for ${formatItemId(item.id)}: ${item.name}`,
19580
19696
  body,
19581
19697
  prNumber: null,
@@ -20843,6 +20959,17 @@ function decideCommand(toolName, rawCommand) {
20843
20959
  return findRestrictedPathDenyRaw(rawCommand) ?? findTruncatedReadDenyRaw(rawCommand) ?? findDeny(toolName, [rawCommand]);
20844
20960
  }
20845
20961
 
20962
+ // src/commands/cliHook/findAskQuestionDeny.ts
20963
+ function findAskQuestionDeny(questionsJson) {
20964
+ if (process.env.ASSIST_SESSION !== "1") return void 0;
20965
+ if (!loadConfig().sessions?.askQuestion) return void 0;
20966
+ return {
20967
+ permissionDecision: "deny",
20968
+ permissionDecisionReason: `Do not use AskUserQuestion in assist sessions: the user answers from the web preview pane, which cannot drive the terminal prompt. Write the same input as JSON to a scratch file and run \`assist ask-question --json - < <file>\` as a background task, doing no other work until it returns. It prints the same answer text AskUserQuestion would. The input to write:
20969
+ ${questionsJson}`
20970
+ };
20971
+ }
20972
+
20846
20973
  // src/commands/cliHook/logDeniedToolCall.ts
20847
20974
  import { mkdirSync as mkdirSync14 } from "fs";
20848
20975
  import { homedir as homedir18 } from "os";
@@ -20918,6 +21045,14 @@ function tryParseInput(raw) {
20918
21045
  paths
20919
21046
  };
20920
21047
  }
21048
+ if (data.tool_name === "AskUserQuestion") {
21049
+ if (!Array.isArray(toolInput.questions)) return void 0;
21050
+ return {
21051
+ kind: "question",
21052
+ toolName: data.tool_name,
21053
+ command: JSON.stringify({ questions: toolInput.questions })
21054
+ };
21055
+ }
20921
21056
  return void 0;
20922
21057
  } catch {
20923
21058
  return void 0;
@@ -20928,7 +21063,7 @@ function tryParseInput(raw) {
20928
21063
  async function cliHook() {
20929
21064
  const input = tryParseInput(await readStdin());
20930
21065
  if (!input) return;
20931
- const decision = input.kind === "command" ? decideCommand(input.toolName, input.command) : findRestrictedPathDeny(input.paths);
21066
+ const decision = input.kind === "command" ? decideCommand(input.toolName, input.command) : input.kind === "question" ? findAskQuestionDeny(input.command) : findRestrictedPathDeny(input.paths);
20932
21067
  if (!decision) return;
20933
21068
  console.log(
20934
21069
  JSON.stringify({
@@ -26652,13 +26787,13 @@ function validateProposedContent(labels, title, body) {
26652
26787
  }
26653
26788
 
26654
26789
  // src/commands/github/issue/reviewProposedIssueComment.ts
26655
- import { randomUUID as randomUUID9 } from "crypto";
26790
+ import { randomUUID as randomUUID10 } from "crypto";
26656
26791
  async function reviewProposedIssueComment(title, body) {
26657
26792
  const sessionId = process.env.ASSIST_SESSION_ID;
26658
26793
  if (process.env.ASSIST_SESSION !== "1" || !sessionId) return;
26659
26794
  await awaitPreviewApproval("GitHub issue comment preview", {
26660
26795
  sessionId,
26661
- requestId: randomUUID9(),
26796
+ requestId: randomUUID10(),
26662
26797
  title,
26663
26798
  body,
26664
26799
  prNumber: null,
@@ -27176,13 +27311,13 @@ function resolveCreateIssueMetadata(options2) {
27176
27311
  }
27177
27312
 
27178
27313
  // src/commands/github/issue/reviewProposedIssue.ts
27179
- import { randomUUID as randomUUID10 } from "crypto";
27314
+ import { randomUUID as randomUUID11 } from "crypto";
27180
27315
  async function reviewProposedIssue(title, body, metadata2 = []) {
27181
27316
  const sessionId = process.env.ASSIST_SESSION_ID;
27182
27317
  if (process.env.ASSIST_SESSION !== "1" || !sessionId) return void 0;
27183
27318
  return await awaitPreviewApproval("GitHub issue preview", {
27184
27319
  sessionId,
27185
- requestId: randomUUID10(),
27320
+ requestId: randomUUID11(),
27186
27321
  title,
27187
27322
  body,
27188
27323
  prNumber: null,
@@ -27487,7 +27622,7 @@ function pushUnchangedIssue(number, repo, target, fetchedAt, bodyPath) {
27487
27622
  }
27488
27623
 
27489
27624
  // src/commands/github/issue/reviewProposedIssueEdit.ts
27490
- import { randomUUID as randomUUID11 } from "crypto";
27625
+ import { randomUUID as randomUUID12 } from "crypto";
27491
27626
  async function reviewProposedIssueEdit(title, body, working) {
27492
27627
  const sessionId = process.env.ASSIST_SESSION_ID;
27493
27628
  if (process.env.ASSIST_SESSION !== "1" || !sessionId) return body;
@@ -27495,7 +27630,7 @@ async function reviewProposedIssueEdit(title, body, working) {
27495
27630
  "GitHub issue edit preview",
27496
27631
  {
27497
27632
  sessionId,
27498
- requestId: randomUUID11(),
27633
+ requestId: randomUUID12(),
27499
27634
  title,
27500
27635
  body,
27501
27636
  prNumber: null,
@@ -27924,7 +28059,7 @@ async function writeInboxLastScan(orm, at2) {
27924
28059
  // src/commands/inbox/runInboxScanClaude.ts
27925
28060
  import { execFile as execFile12 } from "child_process";
27926
28061
  import { promisify as promisify12 } from "util";
27927
- import { z as z13 } from "zod";
28062
+ import { z as z14 } from "zod";
27928
28063
 
27929
28064
  // src/commands/inbox/buildInboxScanPrompt.ts
27930
28065
  function buildInboxScanPrompt(since) {
@@ -27960,17 +28095,17 @@ function buildInboxScanPrompt(since) {
27960
28095
  }
27961
28096
 
27962
28097
  // src/commands/inbox/inboxScanSchema.ts
27963
- import { z as z12 } from "zod";
27964
- var flaggedMessageSchema = z12.object({
27965
- source: z12.enum(["gmail", "slack"]),
27966
- messageId: z12.string().min(1),
27967
- sender: z12.string().min(1),
27968
- summary: z12.string().min(1),
27969
- link: z12.string().min(1),
27970
- receivedAt: z12.string().optional()
28098
+ import { z as z13 } from "zod";
28099
+ var flaggedMessageSchema = z13.object({
28100
+ source: z13.enum(["gmail", "slack"]),
28101
+ messageId: z13.string().min(1),
28102
+ sender: z13.string().min(1),
28103
+ summary: z13.string().min(1),
28104
+ link: z13.string().min(1),
28105
+ receivedAt: z13.string().optional()
27971
28106
  });
27972
- var inboxScanSchema = z12.object({
27973
- messages: z12.array(flaggedMessageSchema)
28107
+ var inboxScanSchema = z13.object({
28108
+ messages: z13.array(flaggedMessageSchema)
27974
28109
  });
27975
28110
 
27976
28111
  // src/commands/inbox/inboxScanTools.ts
@@ -28039,7 +28174,7 @@ function buildInboxScanArgs(since) {
28039
28174
  "--output-format",
28040
28175
  "json",
28041
28176
  "--json-schema",
28042
- JSON.stringify(z13.toJSONSchema(inboxScanSchema, { target: "draft-07" })),
28177
+ JSON.stringify(z14.toJSONSchema(inboxScanSchema, { target: "draft-07" })),
28043
28178
  "--",
28044
28179
  buildInboxScanPrompt(since)
28045
28180
  ];
@@ -28285,7 +28420,7 @@ function registerRefineLaunch(program, resumeFlag) {
28285
28420
  }
28286
28421
 
28287
28422
  // src/commands/fixConflict.ts
28288
- import { randomUUID as randomUUID12 } from "crypto";
28423
+ import { randomUUID as randomUUID13 } from "crypto";
28289
28424
 
28290
28425
  // src/commands/review/checkoutPr.ts
28291
28426
  import { execFileSync as execFileSync18 } from "child_process";
@@ -28481,39 +28616,39 @@ function stringOrUndefined(value) {
28481
28616
  }
28482
28617
 
28483
28618
  // src/commands/sessions/daemon/persistedSessionSchema.ts
28484
- import { z as z14 } from "zod";
28485
- var persistedSessionSchema = z14.object({
28486
- id: z14.string().optional(),
28487
- name: z14.string(),
28488
- title: z14.string().optional(),
28489
- generatedTitle: z14.string().optional(),
28490
- subtitle: z14.string().optional(),
28491
- commandType: z14.enum(["claude", "run", "assist"]),
28492
- harness: z14.enum(["claude", "codex", "pi"]).optional(),
28493
- status: z14.enum(["running", "waiting", "done", "error", "stopped"]).optional(),
28494
- cwd: z14.string(),
28495
- startedAt: z14.number(),
28496
- runningMs: z14.number().optional(),
28497
- claudeSessionId: z14.string().optional(),
28498
- harnessSessionId: z14.string().optional(),
28499
- initialPrompt: z14.string().optional(),
28500
- runName: z14.string().optional(),
28501
- runArgs: z14.array(z14.string()).optional(),
28502
- assistArgs: z14.array(z14.string()).optional(),
28619
+ import { z as z15 } from "zod";
28620
+ var persistedSessionSchema = z15.object({
28621
+ id: z15.string().optional(),
28622
+ name: z15.string(),
28623
+ title: z15.string().optional(),
28624
+ generatedTitle: z15.string().optional(),
28625
+ subtitle: z15.string().optional(),
28626
+ commandType: z15.enum(["claude", "run", "assist"]),
28627
+ harness: z15.enum(["claude", "codex", "pi"]).optional(),
28628
+ status: z15.enum(["running", "waiting", "done", "error", "stopped"]).optional(),
28629
+ cwd: z15.string(),
28630
+ startedAt: z15.number(),
28631
+ runningMs: z15.number().optional(),
28632
+ claudeSessionId: z15.string().optional(),
28633
+ harnessSessionId: z15.string().optional(),
28634
+ initialPrompt: z15.string().optional(),
28635
+ runName: z15.string().optional(),
28636
+ runArgs: z15.array(z15.string()).optional(),
28637
+ assistArgs: z15.array(z15.string()).optional(),
28503
28638
  activity: activitySchema.optional(),
28504
- starred: z14.boolean().optional(),
28505
- watcher: z14.boolean().optional(),
28506
- divergenceEscalation: z14.boolean().optional(),
28507
- design: z14.boolean().optional(),
28508
- auto: z14.boolean().optional(),
28509
- autoAdvance: z14.boolean().optional(),
28510
- autoApprove: z14.boolean().optional(),
28511
- reviewStarted: z14.boolean().optional(),
28512
- launchedFrom: z14.string().optional(),
28513
- pendingPrompts: z14.array(z14.string()).optional(),
28514
- interrupted: z14.object({ reason: z14.string(), at: z14.number() }).optional(),
28515
- awaitingSeed: z14.boolean().optional(),
28516
- undurable: z14.object({ reason: z14.string(), removesTree: z14.boolean().optional() }).optional()
28639
+ starred: z15.boolean().optional(),
28640
+ watcher: z15.boolean().optional(),
28641
+ divergenceEscalation: z15.boolean().optional(),
28642
+ design: z15.boolean().optional(),
28643
+ auto: z15.boolean().optional(),
28644
+ autoAdvance: z15.boolean().optional(),
28645
+ autoApprove: z15.boolean().optional(),
28646
+ reviewStarted: z15.boolean().optional(),
28647
+ launchedFrom: z15.string().optional(),
28648
+ pendingPrompts: z15.array(z15.string()).optional(),
28649
+ interrupted: z15.object({ reason: z15.string(), at: z15.number() }).optional(),
28650
+ awaitingSeed: z15.boolean().optional(),
28651
+ undurable: z15.object({ reason: z15.string(), removesTree: z15.boolean().optional() }).optional()
28517
28652
  });
28518
28653
 
28519
28654
  // src/commands/sessions/daemon/toPersistedSession.ts
@@ -29070,7 +29205,7 @@ function buildPrompt2(rebase) {
29070
29205
  async function fixConflict(number, options2 = {}) {
29071
29206
  const { resumeSessionId } = options2;
29072
29207
  if (number && !resumeSessionId) await checkoutPr(number);
29073
- const claudeSessionId = resumeSessionId ?? randomUUID12();
29208
+ const claudeSessionId = resumeSessionId ?? randomUUID13();
29074
29209
  emitActivity({
29075
29210
  kind: "command",
29076
29211
  name: "fix-conflict",
@@ -29098,7 +29233,7 @@ function registerFixConflict(program, resumeFlag) {
29098
29233
  }
29099
29234
 
29100
29235
  // src/commands/reviewPrComments.ts
29101
- import { randomUUID as randomUUID13 } from "crypto";
29236
+ import { randomUUID as randomUUID14 } from "crypto";
29102
29237
  function buildPrompt3(number, announce, options2) {
29103
29238
  const args = [
29104
29239
  "/review-pr-comments",
@@ -29124,7 +29259,7 @@ async function reviewPrComments(number, options2 = {}) {
29124
29259
  validateAnnounce(number, announce);
29125
29260
  validateMode(options2);
29126
29261
  if (number && !resumeSessionId) await checkoutPr(number);
29127
- const claudeSessionId = resumeSessionId ?? randomUUID13();
29262
+ const claudeSessionId = resumeSessionId ?? randomUUID14();
29128
29263
  emitActivity({
29129
29264
  kind: "command",
29130
29265
  name: "review-pr-comments",
@@ -29666,7 +29801,7 @@ async function offerSaveExtract(extract2, options2, paths = {}) {
29666
29801
  }
29667
29802
 
29668
29803
  // src/commands/miro/pickAnchors.ts
29669
- import { randomUUID as randomUUID14 } from "crypto";
29804
+ import { randomUUID as randomUUID15 } from "crypto";
29670
29805
 
29671
29806
  // src/commands/miro/isBox.ts
29672
29807
  var boxTypes = /* @__PURE__ */ new Set(["shape", "sticky_note"]);
@@ -29687,7 +29822,7 @@ async function pickAnchors(sessionId, items2) {
29687
29822
  "Miro anchor selection",
29688
29823
  {
29689
29824
  sessionId,
29690
- requestId: randomUUID14(),
29825
+ requestId: randomUUID15(),
29691
29826
  title: "Pick the top-left then the bottom-right box",
29692
29827
  body: encodeMiroBoardPreview(items2),
29693
29828
  prNumber: null,
@@ -30915,13 +31050,13 @@ function postReviewComment(vars) {
30915
31050
  }
30916
31051
 
30917
31052
  // src/commands/prs/reviewProposedPrComment.ts
30918
- import { randomUUID as randomUUID15 } from "crypto";
31053
+ import { randomUUID as randomUUID16 } from "crypto";
30919
31054
  async function reviewProposedPrComment(title, body, prNumber) {
30920
31055
  const sessionId = process.env.ASSIST_SESSION_ID;
30921
31056
  if (process.env.ASSIST_SESSION !== "1" || !sessionId) return;
30922
31057
  await awaitPreviewApproval("PR comment preview", {
30923
31058
  sessionId,
30924
- requestId: randomUUID15(),
31059
+ requestId: randomUUID16(),
30925
31060
  title,
30926
31061
  body,
30927
31062
  prNumber,
@@ -31956,7 +32091,7 @@ function parseScreenshotSpecs(specs) {
31956
32091
  }
31957
32092
 
31958
32093
  // src/commands/prs/previewAndApplyEdit.ts
31959
- import { randomUUID as randomUUID16 } from "crypto";
32094
+ import { randomUUID as randomUUID17 } from "crypto";
31960
32095
 
31961
32096
  // src/commands/prs/stageScreenshots.ts
31962
32097
  import { readFile as readFile8 } from "fs/promises";
@@ -31978,7 +32113,7 @@ function stageScreenshots(screenshots = []) {
31978
32113
  async function previewAndApplyEdit(args) {
31979
32114
  const decision = await awaitPreviewApproval("PR preview", {
31980
32115
  sessionId: args.sessionId,
31981
- requestId: randomUUID16(),
32116
+ requestId: randomUUID17(),
31982
32117
  title: args.title ?? args.currentTitle,
31983
32118
  body: args.body,
31984
32119
  prNumber: args.number,
@@ -32313,7 +32448,7 @@ async function placePr(prNumber, title, body, options2, attachments = []) {
32313
32448
  }
32314
32449
 
32315
32450
  // src/commands/prs/previewAndPlace.ts
32316
- import { randomUUID as randomUUID17 } from "crypto";
32451
+ import { randomUUID as randomUUID18 } from "crypto";
32317
32452
 
32318
32453
  // src/commands/review/announcePr.ts
32319
32454
  function announcePr(prNumber) {
@@ -32389,7 +32524,7 @@ function enableAutoMerge() {
32389
32524
  async function previewAndPlace(args) {
32390
32525
  const decision = await awaitPreviewApproval("PR preview", {
32391
32526
  sessionId: args.sessionId,
32392
- requestId: randomUUID17(),
32527
+ requestId: randomUUID18(),
32393
32528
  title: args.title,
32394
32529
  body: args.body,
32395
32530
  prNumber: args.prNumber,
@@ -36803,10 +36938,10 @@ function registerRefactor(program) {
36803
36938
  }
36804
36939
 
36805
36940
  // src/commands/review/checkoutPrSession.ts
36806
- import { randomUUID as randomUUID18 } from "crypto";
36941
+ import { randomUUID as randomUUID19 } from "crypto";
36807
36942
  async function checkoutPrSession(number, prompt = "") {
36808
36943
  await checkoutPr(number);
36809
- const claudeSessionId = randomUUID18();
36944
+ const claudeSessionId = randomUUID19();
36810
36945
  emitActivity({ kind: "command", name: "review", claudeSessionId });
36811
36946
  const { done: done2 } = spawnClaude(prompt, {
36812
36947
  permissionMode: "auto",
@@ -37917,7 +38052,7 @@ function gatherHighLevelSubject(prNumber, force) {
37917
38052
  }
37918
38053
 
37919
38054
  // src/commands/review/highLevel/openHighLevelOverlay.ts
37920
- import { randomUUID as randomUUID20 } from "crypto";
38055
+ import { randomUUID as randomUUID21 } from "crypto";
37921
38056
 
37922
38057
  // src/commands/review/highLevel/highLevelProgress.ts
37923
38058
  function toItem2(check2, decision) {
@@ -38176,7 +38311,7 @@ function splitQueuedComments(record) {
38176
38311
  }
38177
38312
 
38178
38313
  // src/commands/review/highLevel/previewHighLevelReview.ts
38179
- import { randomUUID as randomUUID19 } from "crypto";
38314
+ import { randomUUID as randomUUID20 } from "crypto";
38180
38315
 
38181
38316
  // src/commands/review/highLevel/formatHighLevelReviewPreview.ts
38182
38317
  function formatHighLevelReviewPreview(lineLevel, body) {
@@ -38203,7 +38338,7 @@ async function previewHighLevelReview(sessionId, record, submission) {
38203
38338
  "Review",
38204
38339
  {
38205
38340
  sessionId,
38206
- requestId: randomUUID19(),
38341
+ requestId: randomUUID20(),
38207
38342
  title: `${LABELS[submission.event]} ${record.repo}#${record.prNumber}`,
38208
38343
  body: formatHighLevelReviewPreview(submission.comments, submission.body),
38209
38344
  prNumber: record.prNumber,
@@ -38254,7 +38389,7 @@ async function openHighLevelOverlay(sessionId, subject) {
38254
38389
  "High-level review",
38255
38390
  {
38256
38391
  sessionId,
38257
- requestId: randomUUID20(),
38392
+ requestId: randomUUID21(),
38258
38393
  title: `${subject.repo}#${subject.prNumber} \u2014 ${subject.title}`,
38259
38394
  body: JSON.stringify(highLevelPreviewPayload(subject)),
38260
38395
  prNumber: subject.prNumber,
@@ -41529,7 +41664,7 @@ function registerSeq(program) {
41529
41664
  }
41530
41665
 
41531
41666
  // src/commands/show.ts
41532
- import { randomUUID as randomUUID21 } from "crypto";
41667
+ import { randomUUID as randomUUID22 } from "crypto";
41533
41668
 
41534
41669
  // src/commands/sessions/shared/sendShowPreview.ts
41535
41670
  async function sendShowPreview(request) {
@@ -41581,7 +41716,7 @@ async function show3(options2) {
41581
41716
  try {
41582
41717
  await sendShowPreview({
41583
41718
  sessionId,
41584
- requestId: randomUUID21(),
41719
+ requestId: randomUUID22(),
41585
41720
  title: options2.title ?? "Show",
41586
41721
  body
41587
41722
  });
@@ -41665,7 +41800,7 @@ function readSlackParts(files) {
41665
41800
  }
41666
41801
 
41667
41802
  // src/commands/slack/reviewProposedSlackMessage.ts
41668
- import { randomUUID as randomUUID22 } from "crypto";
41803
+ import { randomUUID as randomUUID23 } from "crypto";
41669
41804
  async function reviewProposedSlackMessage(target, body, workingPath) {
41670
41805
  const sessionId = process.env.ASSIST_SESSION_ID;
41671
41806
  if (process.env.ASSIST_SESSION !== "1" || !sessionId) return;
@@ -41675,7 +41810,7 @@ async function reviewProposedSlackMessage(target, body, workingPath) {
41675
41810
  part ? `Slack message ${part.index} of ${part.total}` : "Slack message preview",
41676
41811
  {
41677
41812
  sessionId,
41678
- requestId: randomUUID22(),
41813
+ requestId: randomUUID23(),
41679
41814
  title: part ? `${destination} (${part.index}/${part.total})` : destination,
41680
41815
  body,
41681
41816
  prNumber: null,
@@ -42812,7 +42947,7 @@ function createReadlineInterface() {
42812
42947
  output: process.stdout
42813
42948
  });
42814
42949
  }
42815
- function askQuestion(rl, question) {
42950
+ function askQuestion2(rl, question) {
42816
42951
  return new Promise((resolve31) => {
42817
42952
  rl.question(question, (answer) => {
42818
42953
  resolve31(answer.trim());
@@ -42832,15 +42967,15 @@ function printExisting(existing) {
42832
42967
  console.log();
42833
42968
  }
42834
42969
  async function promptDirectories(rl, existing) {
42835
- const vttDir = await askQuestion(
42970
+ const vttDir = await askQuestion2(
42836
42971
  rl,
42837
42972
  buildPrompt4("VTT directory", existing?.vttDir)
42838
42973
  );
42839
- const transcriptsDir = await askQuestion(
42974
+ const transcriptsDir = await askQuestion2(
42840
42975
  rl,
42841
42976
  buildPrompt4("Transcripts directory", existing?.transcriptsDir)
42842
42977
  );
42843
- const summaryDir = await askQuestion(
42978
+ const summaryDir = await askQuestion2(
42844
42979
  rl,
42845
42980
  buildPrompt4("Summary directory", existing?.summaryDir)
42846
42981
  );
@@ -43039,16 +43174,16 @@ function selectPassages(sources, selection) {
43039
43174
  }
43040
43175
 
43041
43176
  // src/commands/transcript/selectionSchema.ts
43042
- import { z as z15 } from "zod";
43043
- var selectionSchema = z15.strictObject({
43044
- keep: z15.array(
43045
- z15.strictObject({
43046
- file: z15.string().trim().min(1, "file is required"),
43047
- from: z15.string().trim().min(1, "from is required"),
43048
- to: z15.string().trim().min(1, "to is required")
43177
+ import { z as z16 } from "zod";
43178
+ var selectionSchema = z16.strictObject({
43179
+ keep: z16.array(
43180
+ z16.strictObject({
43181
+ file: z16.string().trim().min(1, "file is required"),
43182
+ from: z16.string().trim().min(1, "from is required"),
43183
+ to: z16.string().trim().min(1, "to is required")
43049
43184
  })
43050
43185
  ).min(1, "a selection needs at least one keep range"),
43051
- removed: z15.array(z15.string().trim().min(1)).default([])
43186
+ removed: z16.array(z16.string().trim().min(1)).default([])
43052
43187
  });
43053
43188
 
43054
43189
  // src/commands/transcript/widenAudienceInText.ts
@@ -45559,9 +45694,9 @@ async function refreshRepoConfigCacheOnStart() {
45559
45694
  }
45560
45695
 
45561
45696
  // src/commands/sessions/daemon/loadActiveSelection.ts
45562
- import { z as z16 } from "zod";
45697
+ import { z as z17 } from "zod";
45563
45698
  var ACTIVE_FILE = "active.json";
45564
- var activeSelectionSchema = z16.record(z16.string(), z16.string());
45699
+ var activeSelectionSchema = z17.record(z17.string(), z17.string());
45565
45700
  function loadActiveSelection() {
45566
45701
  const parsed = activeSelectionSchema.safeParse(
45567
45702
  loadJson(ACTIVE_FILE)
@@ -46361,7 +46496,7 @@ var ClientHub = class extends Set {
46361
46496
  };
46362
46497
 
46363
46498
  // src/commands/sessions/daemon/createSession.ts
46364
- import { randomUUID as randomUUID23 } from "crypto";
46499
+ import { randomUUID as randomUUID24 } from "crypto";
46365
46500
 
46366
46501
  // src/commands/sessions/daemon/sessionBase.ts
46367
46502
  function sessionBase(id, status2) {
@@ -46584,7 +46719,7 @@ function spawnRun(opts) {
46584
46719
  function createSession(id, { prompt, cwd, design, auto, harness, holdPty } = {}) {
46585
46720
  if (harness && harness !== "claude")
46586
46721
  return createHarnessSession(id, harness, prompt, cwd, holdPty);
46587
- const claudeSessionId = randomUUID23();
46722
+ const claudeSessionId = randomUUID24();
46588
46723
  return {
46589
46724
  ...sessionBase(id, prompt ? "running" : "waiting"),
46590
46725
  name: `Session ${id}`,
@@ -47723,7 +47858,7 @@ function count9(value) {
47723
47858
  }
47724
47859
  function logPrDecision(id, requestId, d) {
47725
47860
  daemonLog(
47726
- `pr-decision received: id=${id} requestId=${requestId} decision=${d.decision} comments=${count9(d.comments)} screenshots=${count9(d.screenshots)} checklist=${count9(d.checklist)} reviewEvent=${d.reviewEvent} reviewComments=${count9(d.reviewComments)} reviewAfter=${d.reviewAfter === true} announceAfter=${d.announceAfter === true} draft=${d.draft} autoMerge=${d.autoMerge === true} autostart=${d.autostart === true}`
47861
+ `pr-decision received: id=${id} requestId=${requestId} decision=${d.decision} comments=${count9(d.comments)} screenshots=${count9(d.screenshots)} checklist=${count9(d.checklist)} reviewEvent=${d.reviewEvent} reviewComments=${count9(d.reviewComments)} reviewAfter=${d.reviewAfter === true} announceAfter=${d.announceAfter === true} draft=${d.draft} autoMerge=${d.autoMerge === true} autostart=${d.autostart === true} answers=${d.answers && typeof d.answers === "object" ? Object.keys(d.answers).length : 0}`
47727
47862
  );
47728
47863
  }
47729
47864
 
@@ -47765,7 +47900,8 @@ function decidePrPreview(sessions, waiters, notify2, d) {
47765
47900
  checklist: d.checklist,
47766
47901
  reviewEvent: d.reviewEvent,
47767
47902
  reviewComments: d.reviewComments,
47768
- dismissed: d.dismissed
47903
+ dismissed: d.dismissed,
47904
+ answers: d.answers
47769
47905
  });
47770
47906
  waiters.delete(id);
47771
47907
  session.pendingPrPreview = void 0;
@@ -47834,7 +47970,8 @@ var PREVIEW_KINDS = [
47834
47970
  "slack-post",
47835
47971
  "high-level-review",
47836
47972
  "show",
47837
- "ask"
47973
+ "ask",
47974
+ "question"
47838
47975
  ];
47839
47976
  function isPreviewKind(value) {
47840
47977
  return PREVIEW_KINDS.includes(value);
@@ -47851,6 +47988,7 @@ function previewTargetLabel(kind, itemType, prNumber, draft) {
47851
47988
  if (kind === "high-level-review") return "high-level review";
47852
47989
  if (kind === "show") return "show";
47853
47990
  if (kind === "ask") return "ask";
47991
+ if (kind === "question") return "question";
47854
47992
  if (kind === "backlog-item") return `backlog ${itemType}`;
47855
47993
  if (prNumber !== null) return `edit #${prNumber}`;
47856
47994
  return draft ? "create draft" : "create";
@@ -48056,9 +48194,9 @@ function buildPrompt5(prompt) {
48056
48194
  }
48057
48195
 
48058
48196
  // src/commands/sessions/shared/loadSessionTitles.ts
48059
- import { z as z17 } from "zod";
48197
+ import { z as z18 } from "zod";
48060
48198
  var TITLES_FILE = "session-titles.json";
48061
- var sessionTitlesSchema = z17.record(z17.string(), z17.string());
48199
+ var sessionTitlesSchema = z18.record(z18.string(), z18.string());
48062
48200
  function loadSessionTitles() {
48063
48201
  const parsed = sessionTitlesSchema.safeParse(
48064
48202
  loadJson(TITLES_FILE)
@@ -49449,7 +49587,7 @@ function codexRespawnPlan(session) {
49449
49587
  }
49450
49588
 
49451
49589
  // src/commands/sessions/daemon/interactiveRespawnPlan.ts
49452
- import { randomUUID as randomUUID24 } from "crypto";
49590
+ import { randomUUID as randomUUID25 } from "crypto";
49453
49591
 
49454
49592
  // src/commands/sessions/daemon/hasTranscriptOnDisk.ts
49455
49593
  function hasTranscriptOnDisk(session) {
@@ -49476,7 +49614,7 @@ function interactiveRespawnPlan(session, resumes) {
49476
49614
  return null;
49477
49615
  }
49478
49616
  function freshClaudePlan(session, prompt, cwd) {
49479
- const claudeSessionId = randomUUID24();
49617
+ const claudeSessionId = randomUUID25();
49480
49618
  return {
49481
49619
  spawn: () => {
49482
49620
  session.claudeSessionId = claudeSessionId;
@@ -53693,6 +53831,7 @@ var programRegistrars = [
53693
53831
  registerSeq,
53694
53832
  registerShow,
53695
53833
  registerAsk,
53834
+ registerAskQuestion,
53696
53835
  registerSlack,
53697
53836
  registerSql,
53698
53837
  registerTranscript,