@staff0rd/assist 0.795.1 → 0.796.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.795.1",
9
+ version: "0.796.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -593,7 +593,7 @@ var LEGACY_SESSIONS_KEYS = [
593
593
  "windowsDaemonPort",
594
594
  "windowsVersionCheck"
595
595
  ];
596
- var LEGACY_WORKTREE_KEYS = ["watcher"];
596
+ var LEGACY_WORKTREE_KEYS = ["watcher", "includeDrafts"];
597
597
  function withoutKeys(value, keys) {
598
598
  if (!value || typeof value !== "object") return value;
599
599
  const rest = { ...value };
@@ -965,7 +965,6 @@ var assistConfigShape = {
965
965
  worktree: z5.strictObject({
966
966
  enabled: z5.boolean().default(false),
967
967
  trunk: z5.boolean().default(false),
968
- includeDrafts: z5.boolean().default(false),
969
968
  root: z5.string().optional(),
970
969
  install: z5.union([z5.boolean(), z5.string(), z5.array(z5.string())]).default(true),
971
970
  commitBeforeManualChecks: z5.boolean().default(false),
@@ -13217,18 +13216,13 @@ var sessionsConfigHelp = [
13217
13216
  {
13218
13217
  key: "worktree.enabled",
13219
13218
  setter: "assist config set worktree.enabled true -g --repo",
13220
- note: "opt in per repo: spill concurrent sessions into adjacent <clone>-N worktrees (default off)"
13219
+ note: "opt in per repo: spill concurrent prompt sessions into adjacent <clone>-N worktrees, and give every assist-command session (draft, bug, backlog run, review, \u2026) a fresh one (default off)"
13221
13220
  },
13222
13221
  {
13223
13222
  key: "worktree.trunk",
13224
13223
  setter: "assist config set worktree.trunk true -g --repo",
13225
13224
  note: "trunk-based: a spilled worktree lands on the mainline, and committing jobs (backlog run <id>, review/review-pr-comments) never run in the clone \u2014 they always get a <clone>-N (default off: a worktree starts off the remote default with no mainline tracking, so the session raises its own branch and PR)"
13226
13225
  },
13227
- {
13228
- key: "worktree.includeDrafts",
13229
- setter: "assist config set worktree.includeDrafts true -g --repo",
13230
- note: "draft/bug/refine sessions get their own <clone>-N too (default off: they run in the clone, since they change no code)"
13231
- },
13232
13226
  {
13233
13227
  key: "worktree.root",
13234
13228
  setter: "assist config set worktree.root ~/git -g --repo",
@@ -18816,6 +18810,52 @@ function tokenize(command) {
18816
18810
  return tokens;
18817
18811
  }
18818
18812
 
18813
+ // src/commands/cliHook/extractQuotedSubstitutions.ts
18814
+ function extractQuotedSubstitutions(command) {
18815
+ const bodies = [];
18816
+ scanUnquoted(command, 0, (i, inDouble) => {
18817
+ if (!inDouble) return void 0;
18818
+ if (command[i] === "$" && command[i + 1] === "(") {
18819
+ const end = findClosingParen(command, i + 2);
18820
+ bodies.push(command.slice(i + 2, end));
18821
+ return end;
18822
+ }
18823
+ if (command[i] === "`") {
18824
+ const end = command.indexOf("`", i + 1);
18825
+ const stop2 = end === -1 ? command.length : end;
18826
+ bodies.push(command.slice(i + 1, stop2));
18827
+ return stop2;
18828
+ }
18829
+ return void 0;
18830
+ });
18831
+ return bodies;
18832
+ }
18833
+ function findClosingParen(command, start2) {
18834
+ let depth = 1;
18835
+ let close = command.length;
18836
+ scanUnquoted(command, start2, (i, inDouble) => {
18837
+ if (inDouble) return void 0;
18838
+ if (command[i] === "(") depth++;
18839
+ else if (command[i] === ")" && --depth === 0) {
18840
+ close = i;
18841
+ return command.length;
18842
+ }
18843
+ return void 0;
18844
+ });
18845
+ return close;
18846
+ }
18847
+ function scanUnquoted(command, start2, visit2) {
18848
+ let inSingle = false;
18849
+ let inDouble = false;
18850
+ for (let i = start2; i < command.length; i++) {
18851
+ const ch = command[i];
18852
+ if (ch === "\\" && !inSingle) i++;
18853
+ else if (ch === "'" && !inDouble) inSingle = !inSingle;
18854
+ else if (ch === '"' && !inSingle) inDouble = !inDouble;
18855
+ else if (!inSingle) i = visit2(i, inDouble) ?? i;
18856
+ }
18857
+ }
18858
+
18819
18859
  // src/commands/cliHook/isGhGraphqlIssueMutation.ts
18820
18860
  import { readFileSync as readFileSync26 } from "fs";
18821
18861
  var ISSUE_MUTATION = /\bmutation\b[\s\S]*\b(?:createIssue|updateIssue|deleteIssue|closeIssue|reopenIssue|transferIssue|pinIssue|unpinIssue|addComment|updateIssueComment|deleteIssueComment|addSubIssue|removeSubIssue|reprioritizeSubIssue)\s*\(/;
@@ -18895,7 +18935,7 @@ function isGhIssueApiWrite(command) {
18895
18935
  if (targetsIssueEndpoint(args) && isWrite(args)) return true;
18896
18936
  if (isGhGraphqlIssueMutation(args, command)) return true;
18897
18937
  }
18898
- return false;
18938
+ return extractQuotedSubstitutions(command).some(isGhIssueApiWrite);
18899
18939
  }
18900
18940
  function argsUntilNextCommand(tokens) {
18901
18941
  const end = tokens.findIndex((token) => COMMAND_OPERATORS.has(token));
@@ -26242,7 +26282,7 @@ function registerRefineLaunch(program2, resumeFlag) {
26242
26282
  import { randomUUID as randomUUID12 } from "crypto";
26243
26283
 
26244
26284
  // src/commands/review/checkoutPr.ts
26245
- import { execFileSync as execFileSync16 } from "child_process";
26285
+ import { execFileSync as execFileSync17 } from "child_process";
26246
26286
  import chalk173 from "chalk";
26247
26287
 
26248
26288
  // src/commands/sessions/daemon/daemonLog.ts
@@ -26272,6 +26312,22 @@ function recentDaemonLogLines(includeRelayed = true) {
26272
26312
  import { existsSync as existsSync58 } from "fs";
26273
26313
  import { basename as basename20, dirname as dirname30 } from "path";
26274
26314
 
26315
+ // src/commands/watch/fetchQuietly.ts
26316
+ import { execFileSync as execFileSync15 } from "child_process";
26317
+ var MIN_FETCH_TIMEOUT_MS = 6e4;
26318
+ function fetchQuietly(cwd, intervalMs) {
26319
+ try {
26320
+ execFileSync15("git", ["fetch", "--quiet"], {
26321
+ stdio: ["pipe", "pipe", "pipe"],
26322
+ cwd,
26323
+ timeout: Math.max(intervalMs, MIN_FETCH_TIMEOUT_MS)
26324
+ });
26325
+ return void 0;
26326
+ } catch (error) {
26327
+ return error instanceof Error ? error.message : String(error);
26328
+ }
26329
+ }
26330
+
26275
26331
  // src/commands/sessions/daemon/worktree/planAllocation.ts
26276
26332
  import { basename as basename19, join as join68 } from "path";
26277
26333
  function planAllocation(clone, boundTreeRoots2) {
@@ -26318,6 +26374,11 @@ function createWorktree(clone, strategy, boundTreeRoots2, preferredPath) {
26318
26374
  const branches = new Set(listLocalBranches(clone));
26319
26375
  const isTaken = (candidate) => registered.has(candidate) || existsSync58(candidate) || boundTreeRoots2.has(candidate) || branches.has(basename20(candidate));
26320
26376
  const path106 = preferredPath && !isTaken(preferredPath) ? preferredPath : nextWorktreePath(clone, base, isTaken);
26377
+ const fetchError = fetchQuietly(clone, 0);
26378
+ if (fetchError)
26379
+ daemonLog(
26380
+ `fetch before allocating a worktree for clone ${clone} failed, branching off local refs: ${fetchError}`
26381
+ );
26321
26382
  const start2 = worktreeStartPoint(clone, strategy.trunk);
26322
26383
  gitSync(clone, [
26323
26384
  "worktree",
@@ -26389,12 +26450,6 @@ function checkDurabilitySync(cwd) {
26389
26450
 
26390
26451
  // src/commands/sessions/daemon/worktree/reusesClone.ts
26391
26452
  function reusesClone(clone, boundTreeRoots2, options2) {
26392
- if (options2.draftLike === true && options2.includeDrafts !== true) {
26393
- daemonLog(
26394
- `draft-type session kept in the clone ${clone}: worktree.includeDrafts is off`
26395
- );
26396
- return true;
26397
- }
26398
26453
  if (planAllocation(clone, boundTreeRoots2) !== "primary") {
26399
26454
  daemonLog(
26400
26455
  `clone ${clone} is held by a live session \u2014 spilling to a worktree`
@@ -26426,7 +26481,6 @@ function wouldDisturbWorkInProgress(clone, forCheckout) {
26426
26481
  var DISABLED = {
26427
26482
  enabled: false,
26428
26483
  trunk: false,
26429
- includeDrafts: false,
26430
26484
  install: true,
26431
26485
  commitBeforeManualChecks: false,
26432
26486
  copy: [".env", "settings.local.json", ".claude/settings.local.json"]
@@ -26447,6 +26501,8 @@ function forcedSpillReason(clone, trunk, options2) {
26447
26501
  return `backlog run spilled out of the clone ${clone}: backlog runs never use the clone`;
26448
26502
  if (trunk === true && options2.commits === true)
26449
26503
  return `committing session spilled out of the clone ${clone}: worktree.trunk is on, so a commit here would land on the local mainline`;
26504
+ if (options2.assistCommand !== void 0)
26505
+ return `assist ${options2.assistCommand} session spilled out of the clone ${clone}: only prompt sessions use the clone`;
26450
26506
  return void 0;
26451
26507
  }
26452
26508
 
@@ -26469,10 +26525,9 @@ function allocateTree(requestedCwd, boundTreeRoots2, options2 = {}) {
26469
26525
  `worktree.enabled is off for ${repoRoot2}, so every session shares this tree`
26470
26526
  );
26471
26527
  const clone = canonicalTreePath(mainWorktree(repoRoot2) ?? repoRoot2);
26472
- const reuse = { ...options2, includeDrafts: cfg.includeDrafts };
26473
26528
  const forcedSpill = forcedSpillReason(clone, cfg.trunk, options2);
26474
26529
  if (forcedSpill) daemonLog(forcedSpill);
26475
- else if (reusesClone(clone, boundTreeRoots2, reuse))
26530
+ else if (reusesClone(clone, boundTreeRoots2, options2))
26476
26531
  return { cwd: clone, kind: "primary", created: false, clone };
26477
26532
  const path106 = createWorktree(
26478
26533
  clone,
@@ -26849,10 +26904,10 @@ async function moveToPrCheckoutTree() {
26849
26904
  }
26850
26905
 
26851
26906
  // src/commands/review/prHeadBranch.ts
26852
- import { execFileSync as execFileSync15 } from "child_process";
26907
+ import { execFileSync as execFileSync16 } from "child_process";
26853
26908
  function prHeadBranch(number) {
26854
26909
  try {
26855
- const out = execFileSync15(
26910
+ const out = execFileSync16(
26856
26911
  "gh",
26857
26912
  ["pr", "view", number, "--json", "headRefName", "-q", ".headRefName"],
26858
26913
  { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }
@@ -26914,7 +26969,7 @@ async function checkoutPr(number) {
26914
26969
  if (headRef && await moveToExistingCheckout(number, headRef)) return;
26915
26970
  await moveToPrCheckoutTree();
26916
26971
  try {
26917
- execFileSync16("gh", ["pr", "checkout", number], { stdio: "inherit" });
26972
+ execFileSync17("gh", ["pr", "checkout", number], { stdio: "inherit" });
26918
26973
  } catch {
26919
26974
  console.error(chalk173.red(`gh pr checkout ${number} failed; aborting.`));
26920
26975
  process.exit(1);
@@ -29638,7 +29693,7 @@ function buildValidatedBody(options2, usage) {
29638
29693
  }
29639
29694
 
29640
29695
  // src/commands/prs/placePr.ts
29641
- import { execFileSync as execFileSync17 } from "child_process";
29696
+ import { execFileSync as execFileSync18 } from "child_process";
29642
29697
 
29643
29698
  // src/commands/prs/buildCreateArgs.ts
29644
29699
  function buildCreateArgs(title, body, options2, attachments = []) {
@@ -29724,7 +29779,7 @@ function buildEditArgs(number, title, body, attachments = []) {
29724
29779
  // src/commands/prs/placePr.ts
29725
29780
  function hasUpstream2() {
29726
29781
  try {
29727
- execFileSync17(
29782
+ execFileSync18(
29728
29783
  "git",
29729
29784
  ["rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"],
29730
29785
  { stdio: "pipe" }
@@ -29736,7 +29791,7 @@ function hasUpstream2() {
29736
29791
  }
29737
29792
  function ensureBranchPushed() {
29738
29793
  const args = hasUpstream2() ? ["push"] : ["push", "--set-upstream", "origin", "HEAD"];
29739
- execFileSync17("git", args, { stdio: "inherit" });
29794
+ execFileSync18("git", args, { stdio: "inherit" });
29740
29795
  }
29741
29796
  async function placePr(prNumber, title, body, options2, attachments = []) {
29742
29797
  const args = prNumber !== null ? buildEditArgs(prNumber, title, body, attachments) : buildCreateArgs(title, body, options2, attachments);
@@ -29882,10 +29937,10 @@ function warn(reason4) {
29882
29937
  }
29883
29938
 
29884
29939
  // src/commands/prs/enableAutoMerge.ts
29885
- import { execFileSync as execFileSync18 } from "child_process";
29940
+ import { execFileSync as execFileSync19 } from "child_process";
29886
29941
  function enableAutoMerge() {
29887
29942
  try {
29888
- execFileSync18(
29943
+ execFileSync19(
29889
29944
  "gh",
29890
29945
  ["pr", "merge", getCurrentBranch2(), "--auto", "--squash"],
29891
29946
  { stdio: "inherit" }
@@ -34344,7 +34399,7 @@ function exitWith(message3) {
34344
34399
  }
34345
34400
 
34346
34401
  // src/commands/review/highLevel/proposeHighLevelGlobs.ts
34347
- import { execFileSync as execFileSync20 } from "child_process";
34402
+ import { execFileSync as execFileSync21 } from "child_process";
34348
34403
  import chalk231 from "chalk";
34349
34404
 
34350
34405
  // src/commands/review/highLevel/buildGlobProposalPrompt.ts
@@ -34392,7 +34447,7 @@ function readGlobs(value) {
34392
34447
  }
34393
34448
 
34394
34449
  // src/commands/review/highLevel/summariseRepoTree.ts
34395
- import { execFileSync as execFileSync19 } from "child_process";
34450
+ import { execFileSync as execFileSync20 } from "child_process";
34396
34451
  import { dirname as dirname37, extname as extname4 } from "path";
34397
34452
  var MAX_DIRECTORIES = 200;
34398
34453
  var MAX_EXTENSIONS_PER_DIRECTORY = 6;
@@ -34408,7 +34463,7 @@ function summariseRepoTree(cwd = process.cwd()) {
34408
34463
  }
34409
34464
  function listTrackedFiles(cwd) {
34410
34465
  try {
34411
- return execFileSync19("git", ["ls-files"], {
34466
+ return execFileSync20("git", ["ls-files"], {
34412
34467
  cwd,
34413
34468
  encoding: "utf8",
34414
34469
  maxBuffer: 64 * 1024 * 1024
@@ -34453,7 +34508,7 @@ function proposeHighLevelGlobs(cwd = process.cwd()) {
34453
34508
  }
34454
34509
  function askClaude(prompt, cwd) {
34455
34510
  try {
34456
- return execFileSync20("claude", ["-p", "--model", "sonnet", prompt], {
34511
+ return execFileSync21("claude", ["-p", "--model", "sonnet", prompt], {
34457
34512
  cwd,
34458
34513
  encoding: "utf8",
34459
34514
  timeout: 12e4,
@@ -41171,20 +41226,6 @@ function consumeSimulatedDivergence(cwd) {
41171
41226
  }
41172
41227
  }
41173
41228
 
41174
- // src/commands/watch/fetchQuietly.ts
41175
- import { execFileSync as execFileSync21 } from "child_process";
41176
- var MIN_FETCH_TIMEOUT_MS = 6e4;
41177
- function fetchQuietly(cwd, intervalMs) {
41178
- try {
41179
- execFileSync21("git", ["fetch", "--quiet"], {
41180
- stdio: ["pipe", "pipe", "pipe"],
41181
- cwd,
41182
- timeout: Math.max(intervalMs, MIN_FETCH_TIMEOUT_MS)
41183
- });
41184
- } catch {
41185
- }
41186
- }
41187
-
41188
41229
  // src/commands/watch/detectMovement.ts
41189
41230
  function detectMovement(from, to, count8) {
41190
41231
  if (from === to) return void 0;
@@ -43665,9 +43706,7 @@ function isDraftCommand(command) {
43665
43706
  function isCloneBoundDraft(session) {
43666
43707
  if (session.worktree || !session.cwd) return false;
43667
43708
  if (session.commandType !== "assist") return false;
43668
- if (!isDraftCommand(session.assistArgs?.[0])) return false;
43669
- const cfg = worktreeConfigFor(session.cwd);
43670
- return cfg.enabled !== true || cfg.includeDrafts !== true;
43709
+ return isDraftCommand(session.assistArgs?.[0]);
43671
43710
  }
43672
43711
 
43673
43712
  // src/commands/sessions/daemon/worktree/closeGateApplies.ts
@@ -47672,7 +47711,7 @@ function spawnAssistInTree(ctx, assistArgs, cwd, meta, context) {
47672
47711
  forCheckout: isPrCheckoutArgs(assistArgs),
47673
47712
  commits: isCommittingArgs(assistArgs),
47674
47713
  backlogRun: isBacklogRunArgs(assistArgs),
47675
- draftLike: isDraftCommand(assistArgs[0]),
47714
+ assistCommand: assistArgs[0] ?? "",
47676
47715
  inPlace: meta?.inPlace
47677
47716
  },
47678
47717
  context
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.795.1",
3
+ "version": "0.796.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {