@staff0rd/assist 0.363.0 → 0.364.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.363.0",
9
+ version: "0.364.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -254,7 +254,8 @@ var assistConfigSchema = z2.strictObject({
254
254
  tokenExpiresAt: z2.number().optional()
255
255
  }).optional(),
256
256
  prs: z2.strictObject({
257
- slack: z2.string()
257
+ slack: z2.string().optional(),
258
+ required: z2.boolean().default(false)
258
259
  }).optional(),
259
260
  run: z2.array(z2.union([runConfigSchema, runLinkSchema])).optional(),
260
261
  subtasks: z2.array(
@@ -3120,7 +3121,7 @@ ${failed2.length} script(s) failed:`);
3120
3121
  }
3121
3122
  }
3122
3123
  function runEntry(entry) {
3123
- return new Promise((resolve17) => {
3124
+ return new Promise((resolve18) => {
3124
3125
  const startTime = Date.now();
3125
3126
  const child = spawnCommand(
3126
3127
  entry.fullCommand,
@@ -3132,7 +3133,7 @@ function runEntry(entry) {
3132
3133
  child.on("close", (code) => {
3133
3134
  const exitCode = code ?? 1;
3134
3135
  flushIfFailed(exitCode, chunks);
3135
- resolve17({
3136
+ resolve18({
3136
3137
  script: entry.name,
3137
3138
  code: exitCode,
3138
3139
  durationMs: Date.now() - startTime
@@ -4266,8 +4267,8 @@ function spawnClaude(prompt, options2 = {}) {
4266
4267
  stdio: "inherit",
4267
4268
  env
4268
4269
  });
4269
- const done2 = new Promise((resolve17, reject) => {
4270
- child.on("close", (code) => resolve17(code ?? 0));
4270
+ const done2 = new Promise((resolve18, reject) => {
4271
+ child.on("close", (code) => resolve18(code ?? 0));
4271
4272
  child.on("error", reject);
4272
4273
  });
4273
4274
  return { child, done: done2 };
@@ -4329,6 +4330,89 @@ function consumePause(itemId) {
4329
4330
  return true;
4330
4331
  }
4331
4332
 
4333
+ // src/commands/branch/createBranch.ts
4334
+ import { execSync as execSync21 } from "child_process";
4335
+
4336
+ // src/commands/branch/buildBranchName.ts
4337
+ function buildBranchName({
4338
+ prefix: prefix2,
4339
+ jira,
4340
+ slug
4341
+ }) {
4342
+ const segments = [];
4343
+ if (prefix2) segments.push(`${prefix2}/`);
4344
+ if (jira) segments.push(`${jira}-`);
4345
+ segments.push(slug);
4346
+ return segments.join("");
4347
+ }
4348
+
4349
+ // src/commands/branch/resolveDefaultBranch.ts
4350
+ import { execSync as execSync20 } from "child_process";
4351
+ var REMOTE_HEAD_REGEX = /^ref:\s+refs\/heads\/(\S+)\s+HEAD$/m;
4352
+ function resolveDefaultBranch(override, cwd) {
4353
+ if (override) return override;
4354
+ try {
4355
+ const output = execSync20("git ls-remote --symref origin HEAD", {
4356
+ encoding: "utf8",
4357
+ stdio: ["pipe", "pipe", "pipe"],
4358
+ cwd
4359
+ });
4360
+ const match = output.match(REMOTE_HEAD_REGEX);
4361
+ if (match) return match[1];
4362
+ } catch {
4363
+ }
4364
+ return "main";
4365
+ }
4366
+
4367
+ // src/commands/branch/createBranch.ts
4368
+ async function createBranch({
4369
+ slug,
4370
+ jira
4371
+ }) {
4372
+ const config = loadConfig();
4373
+ const branchName = buildBranchName({
4374
+ prefix: config.branch?.prefix,
4375
+ jira,
4376
+ slug
4377
+ });
4378
+ const defaultBranch = resolveDefaultBranch(config.branch?.defaultBranch);
4379
+ execSync21("git fetch", { stdio: "inherit" });
4380
+ execSync21(
4381
+ `git switch -c ${shellQuote(branchName)} ${shellQuote(`origin/${defaultBranch}`)}`,
4382
+ { stdio: "inherit" }
4383
+ );
4384
+ await recordBranchActivity(branchName);
4385
+ return { branchName, defaultBranch };
4386
+ }
4387
+ async function recordBranchActivity(branchName) {
4388
+ if (resolveSessionItemId() === null) return;
4389
+ await recordSessionRefs([
4390
+ { kind: "branch", ref: branchName, url: gitRefUrl("branch", branchName) }
4391
+ ]);
4392
+ }
4393
+
4394
+ // src/commands/branch/deriveBranchSlug.ts
4395
+ function deriveBranchSlug(name) {
4396
+ const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
4397
+ return slug || "story";
4398
+ }
4399
+
4400
+ // src/commands/backlog/ensureStoryBranch.ts
4401
+ async function ensureStoryBranch(item) {
4402
+ const config = loadConfig();
4403
+ if (!config.prs?.required) return;
4404
+ if (hasBranchRef(item)) return;
4405
+ process.env.ASSIST_BACKLOG_ITEM_ID = String(item.id);
4406
+ const slug = deriveBranchSlug(item.name);
4407
+ const { branchName } = await createBranch({ slug, jira: item.jiraKey });
4408
+ appendDaemonLog(
4409
+ `backlog run ${item.id}: prs.required set and no branch recorded; created ${branchName}`
4410
+ );
4411
+ }
4412
+ function hasBranchRef(item) {
4413
+ return (item.gitRefs ?? []).some((ref) => ref.kind === "branch");
4414
+ }
4415
+
4332
4416
  // src/commands/backlog/shared.ts
4333
4417
  import chalk37 from "chalk";
4334
4418
 
@@ -4354,11 +4438,11 @@ function backupLocalBacklogFiles(dir) {
4354
4438
  }
4355
4439
 
4356
4440
  // src/commands/backlog/gitPullBacklog.ts
4357
- import { execSync as execSync20 } from "child_process";
4441
+ import { execSync as execSync22 } from "child_process";
4358
4442
  import chalk35 from "chalk";
4359
4443
  function gitPullBacklog(dir) {
4360
4444
  try {
4361
- execSync20("git pull --ff-only", {
4445
+ execSync22("git pull --ff-only", {
4362
4446
  cwd: dir,
4363
4447
  stdio: ["pipe", "pipe", "pipe"]
4364
4448
  });
@@ -5083,9 +5167,9 @@ Failed to launch Claude for ${context}: ${message}`)
5083
5167
  // src/commands/sessions/daemon/connectToDaemon.ts
5084
5168
  import * as net from "net";
5085
5169
  function connectToDaemon() {
5086
- return new Promise((resolve17, reject) => {
5170
+ return new Promise((resolve18, reject) => {
5087
5171
  const socket = net.connect(daemonPaths.socket);
5088
- socket.once("connect", () => resolve17(socket));
5172
+ socket.once("connect", () => resolve18(socket));
5089
5173
  socket.once("error", reject);
5090
5174
  });
5091
5175
  }
@@ -5532,6 +5616,7 @@ async function runOnce(item, startPhase, plan2, spawnOptions) {
5532
5616
  async function run2(id2, spawnOptions) {
5533
5617
  const prepared = await prepareRun(id2);
5534
5618
  if (!prepared) return false;
5619
+ await ensureStoryBranch(prepared.item);
5535
5620
  await setStatus(id2, "in-progress");
5536
5621
  discardStalePause(prepared.item.id);
5537
5622
  logProgress(id2, prepared);
@@ -5926,7 +6011,7 @@ import chalk59 from "chalk";
5926
6011
  import { WebSocketServer } from "ws";
5927
6012
 
5928
6013
  // src/shared/getInstallDir.ts
5929
- import { execSync as execSync21 } from "child_process";
6014
+ import { execSync as execSync23 } from "child_process";
5930
6015
  import { dirname as dirname16, resolve as resolve7 } from "path";
5931
6016
  import { fileURLToPath as fileURLToPath2 } from "url";
5932
6017
  var __filename2 = fileURLToPath2(import.meta.url);
@@ -5936,7 +6021,7 @@ function getInstallDir() {
5936
6021
  }
5937
6022
  function isGitRepo(dir) {
5938
6023
  try {
5939
- const result = execSync21("git rev-parse --show-toplevel", {
6024
+ const result = execSync23("git rev-parse --show-toplevel", {
5940
6025
  cwd: dir,
5941
6026
  stdio: "pipe"
5942
6027
  }).toString().trim();
@@ -5953,11 +6038,11 @@ import {
5953
6038
  import chalk54 from "chalk";
5954
6039
 
5955
6040
  // src/lib/openBrowser.ts
5956
- import { execSync as execSync22 } from "child_process";
6041
+ import { execSync as execSync24 } from "child_process";
5957
6042
  function tryExec(commands) {
5958
6043
  for (const cmd of commands) {
5959
6044
  try {
5960
- execSync22(cmd, { stdio: "ignore" });
6045
+ execSync24(cmd, { stdio: "ignore" });
5961
6046
  return true;
5962
6047
  } catch {
5963
6048
  }
@@ -6145,7 +6230,7 @@ function spawnDaemon(reason) {
6145
6230
  child.unref();
6146
6231
  }
6147
6232
  function delay(ms) {
6148
- return new Promise((resolve17) => setTimeout(resolve17, ms));
6233
+ return new Promise((resolve18) => setTimeout(resolve18, ms));
6149
6234
  }
6150
6235
 
6151
6236
  // src/shared/createBundleHandler.ts
@@ -6355,12 +6440,12 @@ async function loadVisibleItems(req) {
6355
6440
 
6356
6441
  // src/commands/backlog/web/parseStatusBody.ts
6357
6442
  function readBody(req) {
6358
- return new Promise((resolve17, reject) => {
6443
+ return new Promise((resolve18, reject) => {
6359
6444
  let body = "";
6360
6445
  req.on("data", (chunk) => {
6361
6446
  body += chunk.toString();
6362
6447
  });
6363
- req.on("end", () => resolve17(body));
6448
+ req.on("end", () => resolve18(body));
6364
6449
  req.on("error", reject);
6365
6450
  });
6366
6451
  }
@@ -7107,17 +7192,17 @@ async function stopDaemon() {
7107
7192
  }
7108
7193
  }
7109
7194
  function closedBeforeTimeout(socket) {
7110
- return new Promise((resolve17) => {
7195
+ return new Promise((resolve18) => {
7111
7196
  const timer = setTimeout(() => {
7112
7197
  socket.destroy();
7113
- resolve17(false);
7198
+ resolve18(false);
7114
7199
  }, STOP_TIMEOUT_MS);
7115
7200
  socket.resume();
7116
7201
  socket.on("error", () => {
7117
7202
  });
7118
7203
  socket.once("close", () => {
7119
7204
  clearTimeout(timer);
7120
- resolve17(true);
7205
+ resolve18(true);
7121
7206
  });
7122
7207
  });
7123
7208
  }
@@ -7168,8 +7253,8 @@ async function restartWeb(req, res, deps2 = {}) {
7168
7253
  respondJson(res, 400, { error: "Invalid target" });
7169
7254
  return;
7170
7255
  }
7171
- await new Promise((resolve17) => {
7172
- res.once("finish", resolve17);
7256
+ await new Promise((resolve18) => {
7257
+ res.once("finish", resolve18);
7173
7258
  respondJson(res, 200, { ok: true });
7174
7259
  });
7175
7260
  if (target === "daemon" || target === "both") {
@@ -7618,12 +7703,12 @@ import chalk61 from "chalk";
7618
7703
  import { eq as eq17 } from "drizzle-orm";
7619
7704
 
7620
7705
  // src/commands/jira/fetchIssue.ts
7621
- import { execSync as execSync23 } from "child_process";
7706
+ import { execSync as execSync25 } from "child_process";
7622
7707
  import chalk60 from "chalk";
7623
7708
  function fetchIssue(issueKey, fields) {
7624
7709
  let result;
7625
7710
  try {
7626
- result = execSync23(
7711
+ result = execSync25(
7627
7712
  `acli jira workitem view ${issueKey} -f ${fields} --json`,
7628
7713
  { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }
7629
7714
  );
@@ -8225,7 +8310,10 @@ function registerItemCommands(cmd) {
8225
8310
  "--status <type>",
8226
8311
  "Filter by status (todo, in-progress, done, wontdo)"
8227
8312
  ).option("-a, --all", "Include done/wontdo items").option("--all-repos", "List items across all repositories").option("-v, --verbose", "Show all item details").action(list2);
8228
- cmd.command("add").description("Add a new backlog item").option("--name <name>", "Item name").option("--type <type>", "Item type (story or bug)").option("--desc <description>", "Item description").option("--ac <criterion...>", "Acceptance criteria (repeatable)").action(add);
8313
+ cmd.command("add").description("Add a new backlog item").option("--name <name>", "Item name").option("--type <type>", "Item type (story or bug)").option(
8314
+ "--desc <description>",
8315
+ String.raw`Item description (Markdown supported; use \n for line breaks)`
8316
+ ).option("--ac <criterion...>", "Acceptance criteria (repeatable)").action(add);
8229
8317
  cmd.command("add-phase <id> <name>").description("Add a phase to an existing backlog item").option("--task <task...>", "Task description (repeatable)").option(
8230
8318
  "--manual-check <check...>",
8231
8319
  "Manual check description (repeatable)"
@@ -8848,7 +8936,8 @@ async function addSubtask(id2, options2) {
8848
8936
  return;
8849
8937
  }
8850
8938
  const { orm, item } = found;
8851
- await insertSubtask(orm, item.id, title, options2.desc);
8939
+ const description = options2.desc?.replaceAll(String.raw`\n`, "\n");
8940
+ await insertSubtask(orm, item.id, title, description);
8852
8941
  console.log(chalk91.green(`Added sub-task to item #${id2}: ${title}`));
8853
8942
  }
8854
8943
 
@@ -8897,7 +8986,10 @@ async function subtaskStatus(id2, index3, status2) {
8897
8986
 
8898
8987
  // src/commands/backlog/registerSubtaskCommands.ts
8899
8988
  function registerSubtaskCommands(cmd) {
8900
- cmd.command("add-subtask <id>").description("Add a sub-task to an existing backlog item").requiredOption("--title <title>", "Sub-task title").option("--desc <description>", "Sub-task description").action(addSubtask);
8989
+ cmd.command("add-subtask <id>").description("Add a sub-task to an existing backlog item").requiredOption("--title <title>", "Sub-task title").option(
8990
+ "--desc <description>",
8991
+ String.raw`Sub-task description (Markdown supported; use \n for line breaks)`
8992
+ ).action(addSubtask);
8901
8993
  cmd.command("subtask-status <id> <idx> <status>").description(
8902
8994
  "Set a sub-task's status (todo, in-progress, done) by its 1-based index"
8903
8995
  ).action(subtaskStatus);
@@ -9272,7 +9364,7 @@ function buildUpdateValues(options2) {
9272
9364
  fieldNames.push("name");
9273
9365
  }
9274
9366
  if (desc6) {
9275
- set.description = desc6;
9367
+ set.description = desc6.replaceAll(String.raw`\n`, "\n");
9276
9368
  fieldNames.push("description");
9277
9369
  }
9278
9370
  if (type) {
@@ -9320,7 +9412,10 @@ function collect2(value, previous) {
9320
9412
  return [...previous, value];
9321
9413
  }
9322
9414
  function registerUpdateCommands(cmd) {
9323
- cmd.command("update-field <id>").description("Update fields on a backlog item").option("--name <name>", "New item name").option("--desc <description>", "New description").option("--type <type>", "New type (story or bug)").option("--ac <criterion...>", "Replace acceptance criteria (repeatable)").option(
9415
+ cmd.command("update-field <id>").description("Update fields on a backlog item").option("--name <name>", "New item name").option(
9416
+ "--desc <description>",
9417
+ String.raw`New description (Markdown supported; use \n for line breaks)`
9418
+ ).option("--type <type>", "New type (story or bug)").option("--ac <criterion...>", "Replace acceptance criteria (repeatable)").option(
9324
9419
  "--add-ac <text>",
9325
9420
  "Append one acceptance criterion (repeatable)",
9326
9421
  collect2,
@@ -9372,40 +9467,6 @@ function registerBacklog(program2) {
9372
9467
  }
9373
9468
  }
9374
9469
 
9375
- // src/commands/branch/branch.ts
9376
- import { execSync as execSync25 } from "child_process";
9377
-
9378
- // src/commands/branch/buildBranchName.ts
9379
- function buildBranchName({
9380
- prefix: prefix2,
9381
- jira,
9382
- slug
9383
- }) {
9384
- const segments = [];
9385
- if (prefix2) segments.push(`${prefix2}/`);
9386
- if (jira) segments.push(`${jira}-`);
9387
- segments.push(slug);
9388
- return segments.join("");
9389
- }
9390
-
9391
- // src/commands/branch/resolveDefaultBranch.ts
9392
- import { execSync as execSync24 } from "child_process";
9393
- var REMOTE_HEAD_REGEX = /^ref:\s+refs\/heads\/(\S+)\s+HEAD$/m;
9394
- function resolveDefaultBranch(override, cwd) {
9395
- if (override) return override;
9396
- try {
9397
- const output = execSync24("git ls-remote --symref origin HEAD", {
9398
- encoding: "utf8",
9399
- stdio: ["pipe", "pipe", "pipe"],
9400
- cwd
9401
- });
9402
- const match = output.match(REMOTE_HEAD_REGEX);
9403
- if (match) return match[1];
9404
- } catch {
9405
- }
9406
- return "main";
9407
- }
9408
-
9409
9470
  // src/commands/branch/validateSlug.ts
9410
9471
  var KEBAB_CASE_REGEX = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
9411
9472
  var HASH_REF_REGEX = /#\d+/;
@@ -9433,23 +9494,14 @@ async function branch(slug, options2) {
9433
9494
  console.error(`Error: ${slugError}`);
9434
9495
  process.exit(1);
9435
9496
  }
9436
- const config = loadConfig();
9437
- const branchName = buildBranchName({
9438
- prefix: config.branch?.prefix,
9439
- jira: options2.jira,
9440
- slug
9441
- });
9442
9497
  try {
9443
- const defaultBranch = resolveDefaultBranch(config.branch?.defaultBranch);
9444
- execSync25("git fetch", { stdio: "inherit" });
9445
- execSync25(
9446
- `git switch -c ${shellQuote(branchName)} ${shellQuote(`origin/${defaultBranch}`)}`,
9447
- { stdio: "inherit" }
9448
- );
9498
+ const { branchName, defaultBranch } = await createBranch({
9499
+ slug,
9500
+ jira: options2.jira
9501
+ });
9449
9502
  console.log(
9450
9503
  `Created and switched to ${branchName} (from origin/${defaultBranch})`
9451
9504
  );
9452
- await recordBranchActivity(branchName);
9453
9505
  process.exit(0);
9454
9506
  } catch (error) {
9455
9507
  console.error(
@@ -9458,12 +9510,6 @@ async function branch(slug, options2) {
9458
9510
  process.exit(1);
9459
9511
  }
9460
9512
  }
9461
- async function recordBranchActivity(branchName) {
9462
- if (resolveSessionItemId() === null) return;
9463
- await recordSessionRefs([
9464
- { kind: "branch", ref: branchName, url: gitRefUrl("branch", branchName) }
9465
- ]);
9466
- }
9467
9513
 
9468
9514
  // src/commands/registerBranch.ts
9469
9515
  function registerBranch(program2) {
@@ -10246,12 +10292,12 @@ function hasSubcommands(helpText) {
10246
10292
  // src/commands/permitCliReads/runHelp.ts
10247
10293
  import { exec as exec2 } from "child_process";
10248
10294
  function runHelp(args) {
10249
- return new Promise((resolve17) => {
10295
+ return new Promise((resolve18) => {
10250
10296
  exec2(
10251
10297
  `${args.join(" ")} --help`,
10252
10298
  { encoding: "utf8", timeout: 3e4 },
10253
10299
  (_err, stdout, stderr) => {
10254
- resolve17(stdout || stderr || "");
10300
+ resolve18(stdout || stderr || "");
10255
10301
  }
10256
10302
  );
10257
10303
  });
@@ -13890,25 +13936,25 @@ function isVisibleText(t) {
13890
13936
  return /[a-zA-Z]{3,}/.test(t);
13891
13937
  }
13892
13938
  var isHashtag = (t) => /^#[A-Za-z0-9_]+$/.test(t);
13893
- function collectRscText(v, resolve17, sink2, seen) {
13939
+ function collectRscText(v, resolve18, sink2, seen) {
13894
13940
  if (v == null) return;
13895
13941
  if (typeof v === "string") {
13896
13942
  if (isRscRef(v)) {
13897
13943
  if (!seen.has(v)) {
13898
13944
  seen.add(v);
13899
- collectRscText(resolve17(v), resolve17, sink2, seen);
13945
+ collectRscText(resolve18(v), resolve18, sink2, seen);
13900
13946
  }
13901
13947
  } else if (isHashtag(v)) sink2.hashtags.push(v);
13902
13948
  else if (isVisibleText(v)) sink2.text.push(v);
13903
13949
  return;
13904
13950
  }
13905
13951
  if (Array.isArray(v)) {
13906
- for (const x of v) collectRscText(x, resolve17, sink2, seen);
13952
+ for (const x of v) collectRscText(x, resolve18, sink2, seen);
13907
13953
  return;
13908
13954
  }
13909
13955
  if (typeof v === "object") {
13910
13956
  for (const val of Object.values(v)) {
13911
- collectRscText(val, resolve17, sink2, seen);
13957
+ collectRscText(val, resolve18, sink2, seen);
13912
13958
  }
13913
13959
  }
13914
13960
  }
@@ -13940,7 +13986,7 @@ function visitObjects(root, fn) {
13940
13986
  }
13941
13987
  }
13942
13988
  }
13943
- function buildMentionMap(rows, resolve17) {
13989
+ function buildMentionMap(rows, resolve18) {
13944
13990
  const map = /* @__PURE__ */ new Map();
13945
13991
  visitObjects(rows, (o) => {
13946
13992
  const url = profileActionUrl(o);
@@ -13948,7 +13994,7 @@ function buildMentionMap(rows, resolve17) {
13948
13994
  const slug = slugFromProfileUrl(url);
13949
13995
  if (!slug || map.has(slug)) return;
13950
13996
  const sink2 = { text: [], hashtags: [] };
13951
- collectRscText(o.children, resolve17, sink2, /* @__PURE__ */ new Set());
13997
+ collectRscText(o.children, resolve18, sink2, /* @__PURE__ */ new Set());
13952
13998
  const name = sink2.text.join(" ").replace(/\s+/g, " ").trim();
13953
13999
  map.set(slug, name ? { slug, name, url } : { slug, url });
13954
14000
  });
@@ -14034,10 +14080,10 @@ function buildPost(raw, mentionMap, author) {
14034
14080
 
14035
14081
  // src/commands/netcap/walkPostRow.ts
14036
14082
  var isCommentary = (o) => asObject(o.viewTrackingSpecs)?.viewName === "feed-commentary";
14037
- function walkPostRow(v, resolve17, raw) {
14083
+ function walkPostRow(v, resolve18, raw) {
14038
14084
  if (v == null || typeof v !== "object") return;
14039
14085
  if (Array.isArray(v)) {
14040
- for (const x of v) walkPostRow(x, resolve17, raw);
14086
+ for (const x of v) walkPostRow(x, resolve18, raw);
14041
14087
  return;
14042
14088
  }
14043
14089
  const o = v;
@@ -14051,9 +14097,9 @@ function walkPostRow(v, resolve17, raw) {
14051
14097
  }
14052
14098
  if (isCommentary(o)) {
14053
14099
  const sink2 = { text: raw.text, hashtags: raw.hashtags };
14054
- collectRscText(o.children, resolve17, sink2, /* @__PURE__ */ new Set());
14100
+ collectRscText(o.children, resolve18, sink2, /* @__PURE__ */ new Set());
14055
14101
  }
14056
- for (const val of Object.values(o)) walkPostRow(val, resolve17, raw);
14102
+ for (const val of Object.values(o)) walkPostRow(val, resolve18, raw);
14057
14103
  }
14058
14104
 
14059
14105
  // src/commands/netcap/extractLinkedInPosts.ts
@@ -14067,8 +14113,8 @@ function findCommentaryRows(rows) {
14067
14113
  }
14068
14114
  function extractLinkedInPosts(flight, author = findAuthorSlug(flight)) {
14069
14115
  const rows = parseRscRows(flight);
14070
- const resolve17 = makeRscResolver(rows);
14071
- const mentionMap = buildMentionMap(rows, resolve17);
14116
+ const resolve18 = makeRscResolver(rows);
14117
+ const mentionMap = buildMentionMap(rows, resolve18);
14072
14118
  const posts = [];
14073
14119
  for (const id2 of findCommentaryRows(rows)) {
14074
14120
  const raw = {
@@ -14078,7 +14124,7 @@ function extractLinkedInPosts(flight, author = findAuthorSlug(flight)) {
14078
14124
  links: [],
14079
14125
  related: []
14080
14126
  };
14081
- walkPostRow(rows[id2], resolve17, raw);
14127
+ walkPostRow(rows[id2], resolve18, raw);
14082
14128
  const post = buildPost(raw, mentionMap, author);
14083
14129
  if (post) posts.push(post);
14084
14130
  }
@@ -15957,7 +16003,7 @@ function getViolations(pattern2, options2 = {}, maxLines = DEFAULT_MAX_LINES) {
15957
16003
 
15958
16004
  // src/commands/refactor/check/index.ts
15959
16005
  function runScript(script, cwd) {
15960
- return new Promise((resolve17) => {
16006
+ return new Promise((resolve18) => {
15961
16007
  const child = spawn5("npm", ["run", script], {
15962
16008
  stdio: "pipe",
15963
16009
  shell: true,
@@ -15971,7 +16017,7 @@ function runScript(script, cwd) {
15971
16017
  output += data.toString();
15972
16018
  });
15973
16019
  child.on("close", (code) => {
15974
- resolve17({ script, code: code ?? 1, output });
16020
+ resolve18({ script, code: code ?? 1, output });
15975
16021
  });
15976
16022
  });
15977
16023
  }
@@ -18717,12 +18763,12 @@ function onCloseResult(ctx, code) {
18717
18763
  return { ...closed, stderr: ctx.stderr.value, stdout: ctx.stdout.value };
18718
18764
  }
18719
18765
  function waitForChildExit(ctx) {
18720
- return new Promise((resolve17) => {
18766
+ return new Promise((resolve18) => {
18721
18767
  let settled = false;
18722
18768
  const settle = (result) => {
18723
18769
  if (settled) return;
18724
18770
  settled = true;
18725
- resolve17(result);
18771
+ resolve18(result);
18726
18772
  };
18727
18773
  ctx.child.on("error", (err) => settle(onErrorResult(ctx, err)));
18728
18774
  ctx.child.on("close", (code) => settle(onCloseResult(ctx, code)));
@@ -19799,9 +19845,9 @@ function createReadlineInterface() {
19799
19845
  });
19800
19846
  }
19801
19847
  function askQuestion(rl, question) {
19802
- return new Promise((resolve17) => {
19848
+ return new Promise((resolve18) => {
19803
19849
  rl.question(question, (answer) => {
19804
- resolve17(answer.trim());
19850
+ resolve18(answer.trim());
19805
19851
  });
19806
19852
  });
19807
19853
  }
@@ -20449,7 +20495,7 @@ function extractCode(url, expectedState) {
20449
20495
  return code;
20450
20496
  }
20451
20497
  function waitForCallback(port, expectedState) {
20452
- return new Promise((resolve17, reject) => {
20498
+ return new Promise((resolve18, reject) => {
20453
20499
  const timeout = setTimeout(() => {
20454
20500
  server.close();
20455
20501
  reject(new Error("Authorization timed out after 120 seconds"));
@@ -20466,7 +20512,7 @@ function waitForCallback(port, expectedState) {
20466
20512
  const code = extractCode(url, expectedState);
20467
20513
  respondHtml(res, 200, "Authorization successful!");
20468
20514
  server.close();
20469
- resolve17(code);
20515
+ resolve18(code);
20470
20516
  } catch (error) {
20471
20517
  respondHtml(res, 400, error.message);
20472
20518
  server.close();
@@ -21215,10 +21261,10 @@ var STATUS_TIMEOUT_MS = 5e3;
21215
21261
  function queryDaemon(socket) {
21216
21262
  socket.write(`${JSON.stringify({ type: "ping" })}
21217
21263
  `);
21218
- return new Promise((resolve17) => {
21264
+ return new Promise((resolve18) => {
21219
21265
  const result = { sessions: [] };
21220
21266
  const pending = /* @__PURE__ */ new Set(["sessions", "pong"]);
21221
- const timer = setTimeout(() => resolve17(result), STATUS_TIMEOUT_MS);
21267
+ const timer = setTimeout(() => resolve18(result), STATUS_TIMEOUT_MS);
21222
21268
  const lines = createInterface5({ input: socket });
21223
21269
  lines.on("error", () => {
21224
21270
  });
@@ -21226,7 +21272,7 @@ function queryDaemon(socket) {
21226
21272
  applyLine(result, pending, line);
21227
21273
  if (pending.size === 0) {
21228
21274
  clearTimeout(timer);
21229
- resolve17(result);
21275
+ resolve18(result);
21230
21276
  }
21231
21277
  });
21232
21278
  });
@@ -21412,8 +21458,8 @@ async function drainDaemon() {
21412
21458
  function requestDrain(socket) {
21413
21459
  socket.write(`${JSON.stringify({ type: "drain" })}
21414
21460
  `);
21415
- return new Promise((resolve17) => {
21416
- const timer = setTimeout(() => resolve17(0), DRAIN_TIMEOUT_MS);
21461
+ return new Promise((resolve18) => {
21462
+ const timer = setTimeout(() => resolve18(0), DRAIN_TIMEOUT_MS);
21417
21463
  const lines = createInterface6({ input: socket });
21418
21464
  lines.on("error", () => {
21419
21465
  });
@@ -21422,7 +21468,7 @@ function requestDrain(socket) {
21422
21468
  const data = JSON.parse(line);
21423
21469
  if (data.type === "drained") {
21424
21470
  clearTimeout(timer);
21425
- resolve17(data.count ?? 0);
21471
+ resolve18(data.count ?? 0);
21426
21472
  }
21427
21473
  } catch {
21428
21474
  }
@@ -22508,7 +22554,7 @@ function windowsDaemonHost() {
22508
22554
  var CONNECT_TIMEOUT_MS = 2e3;
22509
22555
  var KEEPALIVE_PROBE_MS = 1e4;
22510
22556
  function connectToWindowsDaemon() {
22511
- return new Promise((resolve17, reject) => {
22557
+ return new Promise((resolve18, reject) => {
22512
22558
  const socket = net2.connect(windowsDaemonPort(), windowsDaemonHost());
22513
22559
  socket.setTimeout(CONNECT_TIMEOUT_MS);
22514
22560
  socket.once("timeout", () => {
@@ -22518,7 +22564,7 @@ function connectToWindowsDaemon() {
22518
22564
  socket.once("connect", () => {
22519
22565
  socket.setTimeout(0);
22520
22566
  socket.setKeepAlive(true, KEEPALIVE_PROBE_MS);
22521
- resolve17(socket);
22567
+ resolve18(socket);
22522
22568
  });
22523
22569
  socket.once("error", reject);
22524
22570
  });
@@ -22596,7 +22642,7 @@ async function waitForWindowsDaemon() {
22596
22642
  );
22597
22643
  }
22598
22644
  function delay2(ms) {
22599
- return new Promise((resolve17) => setTimeout(resolve17, ms));
22645
+ return new Promise((resolve18) => setTimeout(resolve18, ms));
22600
22646
  }
22601
22647
 
22602
22648
  // src/commands/sessions/daemon/defaultConnect.ts
@@ -22844,7 +22890,7 @@ async function healWindowsDaemon() {
22844
22890
  daemonLog("windows daemon: auto-heal: stale daemon stopped");
22845
22891
  }
22846
22892
  function runOnWindowsHost(command, timeoutMs) {
22847
- return new Promise((resolve17, reject) => {
22893
+ return new Promise((resolve18, reject) => {
22848
22894
  const child = spawn11("pwsh.exe", ["-Command", command], {
22849
22895
  stdio: ["ignore", "pipe", "pipe"]
22850
22896
  });
@@ -22864,7 +22910,7 @@ function runOnWindowsHost(command, timeoutMs) {
22864
22910
  });
22865
22911
  child.on("exit", (code) => {
22866
22912
  clearTimeout(timer);
22867
- if (code === 0) resolve17();
22913
+ if (code === 0) resolve18();
22868
22914
  else
22869
22915
  reject(
22870
22916
  new Error(
@@ -24133,6 +24179,48 @@ function buildLimitsSegment(rateLimits) {
24133
24179
  return ` | Limits - ${fiveHr}, ${sevenDay}`;
24134
24180
  }
24135
24181
 
24182
+ // src/commands/readGitBranch.ts
24183
+ import { readFileSync as readFileSync47, statSync as statSync11 } from "fs";
24184
+ import { isAbsolute as isAbsolute2, join as join63, resolve as resolve16 } from "path";
24185
+ function resolveGitDir(cwd) {
24186
+ const dotGit = join63(cwd, ".git");
24187
+ let stat2;
24188
+ try {
24189
+ stat2 = statSync11(dotGit);
24190
+ } catch {
24191
+ return null;
24192
+ }
24193
+ if (stat2.isDirectory()) {
24194
+ return dotGit;
24195
+ }
24196
+ let contents;
24197
+ try {
24198
+ contents = readFileSync47(dotGit, "utf8");
24199
+ } catch {
24200
+ return null;
24201
+ }
24202
+ const match = /^gitdir:\s*(.+)$/m.exec(contents.trim());
24203
+ if (!match) {
24204
+ return null;
24205
+ }
24206
+ const gitDir = match[1].trim();
24207
+ return isAbsolute2(gitDir) ? gitDir : resolve16(cwd, gitDir);
24208
+ }
24209
+ function readGitBranch(cwd) {
24210
+ const gitDir = resolveGitDir(cwd);
24211
+ if (!gitDir) {
24212
+ return null;
24213
+ }
24214
+ let head;
24215
+ try {
24216
+ head = readFileSync47(join63(gitDir, "HEAD"), "utf8");
24217
+ } catch {
24218
+ return null;
24219
+ }
24220
+ const match = /^ref:\s*refs\/heads\/(.+)$/m.exec(head.trim());
24221
+ return match ? match[1] : null;
24222
+ }
24223
+
24136
24224
  // src/commands/relayRateLimits.ts
24137
24225
  async function relayRateLimits(rateLimits) {
24138
24226
  if (!rateLimits) return;
@@ -24168,8 +24256,11 @@ async function statusLine() {
24168
24256
  const model = data.model.display_name;
24169
24257
  const { total_input_tokens: totalIn, total_output_tokens: totalOut } = data.context_window;
24170
24258
  const usedPct = data.context_window.used_percentage ?? 0;
24259
+ const dir = data.workspace?.current_dir ?? data.cwd;
24260
+ const branch2 = dir ? readGitBranch(windowsCwdToWslPath(dir)) : null;
24261
+ const branchSegment = branch2 ? `\u{1F343}\uFE0F ${chalk191.cyan(branch2)} | ` : "";
24171
24262
  console.log(
24172
- `${model} | Tokens - ${formatNumber(totalOut)} \u2191 : ${formatNumber(totalIn)} \u2193 | Context - ${colorizePercent(usedPct)}${buildLimitsSegment(data.rate_limits)}`
24263
+ `${branchSegment}${model} | Tokens - ${formatNumber(totalOut)} \u2191 : ${formatNumber(totalIn)} \u2193 | Context - ${colorizePercent(usedPct)}${buildLimitsSegment(data.rate_limits)}`
24173
24264
  );
24174
24265
  await relayRateLimits(data.rate_limits);
24175
24266
  await relayUsage(data.session_id, totalIn, totalOut);