@staff0rd/assist 0.362.1 → 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/README.md +4 -1
- package/dist/commands/sessions/web/bundle.js +1 -1
- package/dist/index.js +209 -117
- package/package.json +1 -1
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.
|
|
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((
|
|
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
|
-
|
|
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((
|
|
4270
|
-
child.on("close", (code) =>
|
|
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
|
|
4441
|
+
import { execSync as execSync22 } from "child_process";
|
|
4358
4442
|
import chalk35 from "chalk";
|
|
4359
4443
|
function gitPullBacklog(dir) {
|
|
4360
4444
|
try {
|
|
4361
|
-
|
|
4445
|
+
execSync22("git pull --ff-only", {
|
|
4362
4446
|
cwd: dir,
|
|
4363
4447
|
stdio: ["pipe", "pipe", "pipe"]
|
|
4364
4448
|
});
|
|
@@ -4925,6 +5009,7 @@ async function searchItemIds(orm, query, origin) {
|
|
|
4925
5009
|
ilike(items.name, pattern2),
|
|
4926
5010
|
ilike(items.description, pattern2),
|
|
4927
5011
|
ilike(items.acceptanceCriteria, pattern2),
|
|
5012
|
+
ilike(items.jiraKey, pattern2),
|
|
4928
5013
|
ilike(comments.text, pattern2),
|
|
4929
5014
|
ilike(planPhases.name, pattern2)
|
|
4930
5015
|
)
|
|
@@ -5082,9 +5167,9 @@ Failed to launch Claude for ${context}: ${message}`)
|
|
|
5082
5167
|
// src/commands/sessions/daemon/connectToDaemon.ts
|
|
5083
5168
|
import * as net from "net";
|
|
5084
5169
|
function connectToDaemon() {
|
|
5085
|
-
return new Promise((
|
|
5170
|
+
return new Promise((resolve18, reject) => {
|
|
5086
5171
|
const socket = net.connect(daemonPaths.socket);
|
|
5087
|
-
socket.once("connect", () =>
|
|
5172
|
+
socket.once("connect", () => resolve18(socket));
|
|
5088
5173
|
socket.once("error", reject);
|
|
5089
5174
|
});
|
|
5090
5175
|
}
|
|
@@ -5531,6 +5616,7 @@ async function runOnce(item, startPhase, plan2, spawnOptions) {
|
|
|
5531
5616
|
async function run2(id2, spawnOptions) {
|
|
5532
5617
|
const prepared = await prepareRun(id2);
|
|
5533
5618
|
if (!prepared) return false;
|
|
5619
|
+
await ensureStoryBranch(prepared.item);
|
|
5534
5620
|
await setStatus(id2, "in-progress");
|
|
5535
5621
|
discardStalePause(prepared.item.id);
|
|
5536
5622
|
logProgress(id2, prepared);
|
|
@@ -5925,7 +6011,7 @@ import chalk59 from "chalk";
|
|
|
5925
6011
|
import { WebSocketServer } from "ws";
|
|
5926
6012
|
|
|
5927
6013
|
// src/shared/getInstallDir.ts
|
|
5928
|
-
import { execSync as
|
|
6014
|
+
import { execSync as execSync23 } from "child_process";
|
|
5929
6015
|
import { dirname as dirname16, resolve as resolve7 } from "path";
|
|
5930
6016
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
5931
6017
|
var __filename2 = fileURLToPath2(import.meta.url);
|
|
@@ -5935,7 +6021,7 @@ function getInstallDir() {
|
|
|
5935
6021
|
}
|
|
5936
6022
|
function isGitRepo(dir) {
|
|
5937
6023
|
try {
|
|
5938
|
-
const result =
|
|
6024
|
+
const result = execSync23("git rev-parse --show-toplevel", {
|
|
5939
6025
|
cwd: dir,
|
|
5940
6026
|
stdio: "pipe"
|
|
5941
6027
|
}).toString().trim();
|
|
@@ -5952,11 +6038,11 @@ import {
|
|
|
5952
6038
|
import chalk54 from "chalk";
|
|
5953
6039
|
|
|
5954
6040
|
// src/lib/openBrowser.ts
|
|
5955
|
-
import { execSync as
|
|
6041
|
+
import { execSync as execSync24 } from "child_process";
|
|
5956
6042
|
function tryExec(commands) {
|
|
5957
6043
|
for (const cmd of commands) {
|
|
5958
6044
|
try {
|
|
5959
|
-
|
|
6045
|
+
execSync24(cmd, { stdio: "ignore" });
|
|
5960
6046
|
return true;
|
|
5961
6047
|
} catch {
|
|
5962
6048
|
}
|
|
@@ -6144,7 +6230,7 @@ function spawnDaemon(reason) {
|
|
|
6144
6230
|
child.unref();
|
|
6145
6231
|
}
|
|
6146
6232
|
function delay(ms) {
|
|
6147
|
-
return new Promise((
|
|
6233
|
+
return new Promise((resolve18) => setTimeout(resolve18, ms));
|
|
6148
6234
|
}
|
|
6149
6235
|
|
|
6150
6236
|
// src/shared/createBundleHandler.ts
|
|
@@ -6354,12 +6440,12 @@ async function loadVisibleItems(req) {
|
|
|
6354
6440
|
|
|
6355
6441
|
// src/commands/backlog/web/parseStatusBody.ts
|
|
6356
6442
|
function readBody(req) {
|
|
6357
|
-
return new Promise((
|
|
6443
|
+
return new Promise((resolve18, reject) => {
|
|
6358
6444
|
let body = "";
|
|
6359
6445
|
req.on("data", (chunk) => {
|
|
6360
6446
|
body += chunk.toString();
|
|
6361
6447
|
});
|
|
6362
|
-
req.on("end", () =>
|
|
6448
|
+
req.on("end", () => resolve18(body));
|
|
6363
6449
|
req.on("error", reject);
|
|
6364
6450
|
});
|
|
6365
6451
|
}
|
|
@@ -7106,17 +7192,17 @@ async function stopDaemon() {
|
|
|
7106
7192
|
}
|
|
7107
7193
|
}
|
|
7108
7194
|
function closedBeforeTimeout(socket) {
|
|
7109
|
-
return new Promise((
|
|
7195
|
+
return new Promise((resolve18) => {
|
|
7110
7196
|
const timer = setTimeout(() => {
|
|
7111
7197
|
socket.destroy();
|
|
7112
|
-
|
|
7198
|
+
resolve18(false);
|
|
7113
7199
|
}, STOP_TIMEOUT_MS);
|
|
7114
7200
|
socket.resume();
|
|
7115
7201
|
socket.on("error", () => {
|
|
7116
7202
|
});
|
|
7117
7203
|
socket.once("close", () => {
|
|
7118
7204
|
clearTimeout(timer);
|
|
7119
|
-
|
|
7205
|
+
resolve18(true);
|
|
7120
7206
|
});
|
|
7121
7207
|
});
|
|
7122
7208
|
}
|
|
@@ -7167,8 +7253,8 @@ async function restartWeb(req, res, deps2 = {}) {
|
|
|
7167
7253
|
respondJson(res, 400, { error: "Invalid target" });
|
|
7168
7254
|
return;
|
|
7169
7255
|
}
|
|
7170
|
-
await new Promise((
|
|
7171
|
-
res.once("finish",
|
|
7256
|
+
await new Promise((resolve18) => {
|
|
7257
|
+
res.once("finish", resolve18);
|
|
7172
7258
|
respondJson(res, 200, { ok: true });
|
|
7173
7259
|
});
|
|
7174
7260
|
if (target === "daemon" || target === "both") {
|
|
@@ -7617,12 +7703,12 @@ import chalk61 from "chalk";
|
|
|
7617
7703
|
import { eq as eq17 } from "drizzle-orm";
|
|
7618
7704
|
|
|
7619
7705
|
// src/commands/jira/fetchIssue.ts
|
|
7620
|
-
import { execSync as
|
|
7706
|
+
import { execSync as execSync25 } from "child_process";
|
|
7621
7707
|
import chalk60 from "chalk";
|
|
7622
7708
|
function fetchIssue(issueKey, fields) {
|
|
7623
7709
|
let result;
|
|
7624
7710
|
try {
|
|
7625
|
-
result =
|
|
7711
|
+
result = execSync25(
|
|
7626
7712
|
`acli jira workitem view ${issueKey} -f ${fields} --json`,
|
|
7627
7713
|
{ encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }
|
|
7628
7714
|
);
|
|
@@ -8224,7 +8310,10 @@ function registerItemCommands(cmd) {
|
|
|
8224
8310
|
"--status <type>",
|
|
8225
8311
|
"Filter by status (todo, in-progress, done, wontdo)"
|
|
8226
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);
|
|
8227
|
-
cmd.command("add").description("Add a new backlog item").option("--name <name>", "Item name").option("--type <type>", "Item type (story or bug)").option(
|
|
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);
|
|
8228
8317
|
cmd.command("add-phase <id> <name>").description("Add a phase to an existing backlog item").option("--task <task...>", "Task description (repeatable)").option(
|
|
8229
8318
|
"--manual-check <check...>",
|
|
8230
8319
|
"Manual check description (repeatable)"
|
|
@@ -8847,7 +8936,8 @@ async function addSubtask(id2, options2) {
|
|
|
8847
8936
|
return;
|
|
8848
8937
|
}
|
|
8849
8938
|
const { orm, item } = found;
|
|
8850
|
-
|
|
8939
|
+
const description = options2.desc?.replaceAll(String.raw`\n`, "\n");
|
|
8940
|
+
await insertSubtask(orm, item.id, title, description);
|
|
8851
8941
|
console.log(chalk91.green(`Added sub-task to item #${id2}: ${title}`));
|
|
8852
8942
|
}
|
|
8853
8943
|
|
|
@@ -8896,7 +8986,10 @@ async function subtaskStatus(id2, index3, status2) {
|
|
|
8896
8986
|
|
|
8897
8987
|
// src/commands/backlog/registerSubtaskCommands.ts
|
|
8898
8988
|
function registerSubtaskCommands(cmd) {
|
|
8899
|
-
cmd.command("add-subtask <id>").description("Add a sub-task to an existing backlog item").requiredOption("--title <title>", "Sub-task title").option(
|
|
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);
|
|
8900
8993
|
cmd.command("subtask-status <id> <idx> <status>").description(
|
|
8901
8994
|
"Set a sub-task's status (todo, in-progress, done) by its 1-based index"
|
|
8902
8995
|
).action(subtaskStatus);
|
|
@@ -9271,7 +9364,7 @@ function buildUpdateValues(options2) {
|
|
|
9271
9364
|
fieldNames.push("name");
|
|
9272
9365
|
}
|
|
9273
9366
|
if (desc6) {
|
|
9274
|
-
set.description = desc6;
|
|
9367
|
+
set.description = desc6.replaceAll(String.raw`\n`, "\n");
|
|
9275
9368
|
fieldNames.push("description");
|
|
9276
9369
|
}
|
|
9277
9370
|
if (type) {
|
|
@@ -9319,7 +9412,10 @@ function collect2(value, previous) {
|
|
|
9319
9412
|
return [...previous, value];
|
|
9320
9413
|
}
|
|
9321
9414
|
function registerUpdateCommands(cmd) {
|
|
9322
|
-
cmd.command("update-field <id>").description("Update fields on a backlog item").option("--name <name>", "New item name").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(
|
|
9323
9419
|
"--add-ac <text>",
|
|
9324
9420
|
"Append one acceptance criterion (repeatable)",
|
|
9325
9421
|
collect2,
|
|
@@ -9371,40 +9467,6 @@ function registerBacklog(program2) {
|
|
|
9371
9467
|
}
|
|
9372
9468
|
}
|
|
9373
9469
|
|
|
9374
|
-
// src/commands/branch/branch.ts
|
|
9375
|
-
import { execSync as execSync25 } from "child_process";
|
|
9376
|
-
|
|
9377
|
-
// src/commands/branch/buildBranchName.ts
|
|
9378
|
-
function buildBranchName({
|
|
9379
|
-
prefix: prefix2,
|
|
9380
|
-
jira,
|
|
9381
|
-
slug
|
|
9382
|
-
}) {
|
|
9383
|
-
const segments = [];
|
|
9384
|
-
if (prefix2) segments.push(`${prefix2}/`);
|
|
9385
|
-
if (jira) segments.push(`${jira}-`);
|
|
9386
|
-
segments.push(slug);
|
|
9387
|
-
return segments.join("");
|
|
9388
|
-
}
|
|
9389
|
-
|
|
9390
|
-
// src/commands/branch/resolveDefaultBranch.ts
|
|
9391
|
-
import { execSync as execSync24 } from "child_process";
|
|
9392
|
-
var REMOTE_HEAD_REGEX = /^ref:\s+refs\/heads\/(\S+)\s+HEAD$/m;
|
|
9393
|
-
function resolveDefaultBranch(override, cwd) {
|
|
9394
|
-
if (override) return override;
|
|
9395
|
-
try {
|
|
9396
|
-
const output = execSync24("git ls-remote --symref origin HEAD", {
|
|
9397
|
-
encoding: "utf8",
|
|
9398
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
9399
|
-
cwd
|
|
9400
|
-
});
|
|
9401
|
-
const match = output.match(REMOTE_HEAD_REGEX);
|
|
9402
|
-
if (match) return match[1];
|
|
9403
|
-
} catch {
|
|
9404
|
-
}
|
|
9405
|
-
return "main";
|
|
9406
|
-
}
|
|
9407
|
-
|
|
9408
9470
|
// src/commands/branch/validateSlug.ts
|
|
9409
9471
|
var KEBAB_CASE_REGEX = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
9410
9472
|
var HASH_REF_REGEX = /#\d+/;
|
|
@@ -9432,23 +9494,14 @@ async function branch(slug, options2) {
|
|
|
9432
9494
|
console.error(`Error: ${slugError}`);
|
|
9433
9495
|
process.exit(1);
|
|
9434
9496
|
}
|
|
9435
|
-
const config = loadConfig();
|
|
9436
|
-
const branchName = buildBranchName({
|
|
9437
|
-
prefix: config.branch?.prefix,
|
|
9438
|
-
jira: options2.jira,
|
|
9439
|
-
slug
|
|
9440
|
-
});
|
|
9441
9497
|
try {
|
|
9442
|
-
const defaultBranch =
|
|
9443
|
-
|
|
9444
|
-
|
|
9445
|
-
|
|
9446
|
-
{ stdio: "inherit" }
|
|
9447
|
-
);
|
|
9498
|
+
const { branchName, defaultBranch } = await createBranch({
|
|
9499
|
+
slug,
|
|
9500
|
+
jira: options2.jira
|
|
9501
|
+
});
|
|
9448
9502
|
console.log(
|
|
9449
9503
|
`Created and switched to ${branchName} (from origin/${defaultBranch})`
|
|
9450
9504
|
);
|
|
9451
|
-
await recordBranchActivity(branchName);
|
|
9452
9505
|
process.exit(0);
|
|
9453
9506
|
} catch (error) {
|
|
9454
9507
|
console.error(
|
|
@@ -9457,12 +9510,6 @@ async function branch(slug, options2) {
|
|
|
9457
9510
|
process.exit(1);
|
|
9458
9511
|
}
|
|
9459
9512
|
}
|
|
9460
|
-
async function recordBranchActivity(branchName) {
|
|
9461
|
-
if (resolveSessionItemId() === null) return;
|
|
9462
|
-
await recordSessionRefs([
|
|
9463
|
-
{ kind: "branch", ref: branchName, url: gitRefUrl("branch", branchName) }
|
|
9464
|
-
]);
|
|
9465
|
-
}
|
|
9466
9513
|
|
|
9467
9514
|
// src/commands/registerBranch.ts
|
|
9468
9515
|
function registerBranch(program2) {
|
|
@@ -10245,12 +10292,12 @@ function hasSubcommands(helpText) {
|
|
|
10245
10292
|
// src/commands/permitCliReads/runHelp.ts
|
|
10246
10293
|
import { exec as exec2 } from "child_process";
|
|
10247
10294
|
function runHelp(args) {
|
|
10248
|
-
return new Promise((
|
|
10295
|
+
return new Promise((resolve18) => {
|
|
10249
10296
|
exec2(
|
|
10250
10297
|
`${args.join(" ")} --help`,
|
|
10251
10298
|
{ encoding: "utf8", timeout: 3e4 },
|
|
10252
10299
|
(_err, stdout, stderr) => {
|
|
10253
|
-
|
|
10300
|
+
resolve18(stdout || stderr || "");
|
|
10254
10301
|
}
|
|
10255
10302
|
);
|
|
10256
10303
|
});
|
|
@@ -13889,25 +13936,25 @@ function isVisibleText(t) {
|
|
|
13889
13936
|
return /[a-zA-Z]{3,}/.test(t);
|
|
13890
13937
|
}
|
|
13891
13938
|
var isHashtag = (t) => /^#[A-Za-z0-9_]+$/.test(t);
|
|
13892
|
-
function collectRscText(v,
|
|
13939
|
+
function collectRscText(v, resolve18, sink2, seen) {
|
|
13893
13940
|
if (v == null) return;
|
|
13894
13941
|
if (typeof v === "string") {
|
|
13895
13942
|
if (isRscRef(v)) {
|
|
13896
13943
|
if (!seen.has(v)) {
|
|
13897
13944
|
seen.add(v);
|
|
13898
|
-
collectRscText(
|
|
13945
|
+
collectRscText(resolve18(v), resolve18, sink2, seen);
|
|
13899
13946
|
}
|
|
13900
13947
|
} else if (isHashtag(v)) sink2.hashtags.push(v);
|
|
13901
13948
|
else if (isVisibleText(v)) sink2.text.push(v);
|
|
13902
13949
|
return;
|
|
13903
13950
|
}
|
|
13904
13951
|
if (Array.isArray(v)) {
|
|
13905
|
-
for (const x of v) collectRscText(x,
|
|
13952
|
+
for (const x of v) collectRscText(x, resolve18, sink2, seen);
|
|
13906
13953
|
return;
|
|
13907
13954
|
}
|
|
13908
13955
|
if (typeof v === "object") {
|
|
13909
13956
|
for (const val of Object.values(v)) {
|
|
13910
|
-
collectRscText(val,
|
|
13957
|
+
collectRscText(val, resolve18, sink2, seen);
|
|
13911
13958
|
}
|
|
13912
13959
|
}
|
|
13913
13960
|
}
|
|
@@ -13939,7 +13986,7 @@ function visitObjects(root, fn) {
|
|
|
13939
13986
|
}
|
|
13940
13987
|
}
|
|
13941
13988
|
}
|
|
13942
|
-
function buildMentionMap(rows,
|
|
13989
|
+
function buildMentionMap(rows, resolve18) {
|
|
13943
13990
|
const map = /* @__PURE__ */ new Map();
|
|
13944
13991
|
visitObjects(rows, (o) => {
|
|
13945
13992
|
const url = profileActionUrl(o);
|
|
@@ -13947,7 +13994,7 @@ function buildMentionMap(rows, resolve17) {
|
|
|
13947
13994
|
const slug = slugFromProfileUrl(url);
|
|
13948
13995
|
if (!slug || map.has(slug)) return;
|
|
13949
13996
|
const sink2 = { text: [], hashtags: [] };
|
|
13950
|
-
collectRscText(o.children,
|
|
13997
|
+
collectRscText(o.children, resolve18, sink2, /* @__PURE__ */ new Set());
|
|
13951
13998
|
const name = sink2.text.join(" ").replace(/\s+/g, " ").trim();
|
|
13952
13999
|
map.set(slug, name ? { slug, name, url } : { slug, url });
|
|
13953
14000
|
});
|
|
@@ -14033,10 +14080,10 @@ function buildPost(raw, mentionMap, author) {
|
|
|
14033
14080
|
|
|
14034
14081
|
// src/commands/netcap/walkPostRow.ts
|
|
14035
14082
|
var isCommentary = (o) => asObject(o.viewTrackingSpecs)?.viewName === "feed-commentary";
|
|
14036
|
-
function walkPostRow(v,
|
|
14083
|
+
function walkPostRow(v, resolve18, raw) {
|
|
14037
14084
|
if (v == null || typeof v !== "object") return;
|
|
14038
14085
|
if (Array.isArray(v)) {
|
|
14039
|
-
for (const x of v) walkPostRow(x,
|
|
14086
|
+
for (const x of v) walkPostRow(x, resolve18, raw);
|
|
14040
14087
|
return;
|
|
14041
14088
|
}
|
|
14042
14089
|
const o = v;
|
|
@@ -14050,9 +14097,9 @@ function walkPostRow(v, resolve17, raw) {
|
|
|
14050
14097
|
}
|
|
14051
14098
|
if (isCommentary(o)) {
|
|
14052
14099
|
const sink2 = { text: raw.text, hashtags: raw.hashtags };
|
|
14053
|
-
collectRscText(o.children,
|
|
14100
|
+
collectRscText(o.children, resolve18, sink2, /* @__PURE__ */ new Set());
|
|
14054
14101
|
}
|
|
14055
|
-
for (const val of Object.values(o)) walkPostRow(val,
|
|
14102
|
+
for (const val of Object.values(o)) walkPostRow(val, resolve18, raw);
|
|
14056
14103
|
}
|
|
14057
14104
|
|
|
14058
14105
|
// src/commands/netcap/extractLinkedInPosts.ts
|
|
@@ -14066,8 +14113,8 @@ function findCommentaryRows(rows) {
|
|
|
14066
14113
|
}
|
|
14067
14114
|
function extractLinkedInPosts(flight, author = findAuthorSlug(flight)) {
|
|
14068
14115
|
const rows = parseRscRows(flight);
|
|
14069
|
-
const
|
|
14070
|
-
const mentionMap = buildMentionMap(rows,
|
|
14116
|
+
const resolve18 = makeRscResolver(rows);
|
|
14117
|
+
const mentionMap = buildMentionMap(rows, resolve18);
|
|
14071
14118
|
const posts = [];
|
|
14072
14119
|
for (const id2 of findCommentaryRows(rows)) {
|
|
14073
14120
|
const raw = {
|
|
@@ -14077,7 +14124,7 @@ function extractLinkedInPosts(flight, author = findAuthorSlug(flight)) {
|
|
|
14077
14124
|
links: [],
|
|
14078
14125
|
related: []
|
|
14079
14126
|
};
|
|
14080
|
-
walkPostRow(rows[id2],
|
|
14127
|
+
walkPostRow(rows[id2], resolve18, raw);
|
|
14081
14128
|
const post = buildPost(raw, mentionMap, author);
|
|
14082
14129
|
if (post) posts.push(post);
|
|
14083
14130
|
}
|
|
@@ -15956,7 +16003,7 @@ function getViolations(pattern2, options2 = {}, maxLines = DEFAULT_MAX_LINES) {
|
|
|
15956
16003
|
|
|
15957
16004
|
// src/commands/refactor/check/index.ts
|
|
15958
16005
|
function runScript(script, cwd) {
|
|
15959
|
-
return new Promise((
|
|
16006
|
+
return new Promise((resolve18) => {
|
|
15960
16007
|
const child = spawn5("npm", ["run", script], {
|
|
15961
16008
|
stdio: "pipe",
|
|
15962
16009
|
shell: true,
|
|
@@ -15970,7 +16017,7 @@ function runScript(script, cwd) {
|
|
|
15970
16017
|
output += data.toString();
|
|
15971
16018
|
});
|
|
15972
16019
|
child.on("close", (code) => {
|
|
15973
|
-
|
|
16020
|
+
resolve18({ script, code: code ?? 1, output });
|
|
15974
16021
|
});
|
|
15975
16022
|
});
|
|
15976
16023
|
}
|
|
@@ -18716,12 +18763,12 @@ function onCloseResult(ctx, code) {
|
|
|
18716
18763
|
return { ...closed, stderr: ctx.stderr.value, stdout: ctx.stdout.value };
|
|
18717
18764
|
}
|
|
18718
18765
|
function waitForChildExit(ctx) {
|
|
18719
|
-
return new Promise((
|
|
18766
|
+
return new Promise((resolve18) => {
|
|
18720
18767
|
let settled = false;
|
|
18721
18768
|
const settle = (result) => {
|
|
18722
18769
|
if (settled) return;
|
|
18723
18770
|
settled = true;
|
|
18724
|
-
|
|
18771
|
+
resolve18(result);
|
|
18725
18772
|
};
|
|
18726
18773
|
ctx.child.on("error", (err) => settle(onErrorResult(ctx, err)));
|
|
18727
18774
|
ctx.child.on("close", (code) => settle(onCloseResult(ctx, code)));
|
|
@@ -19798,9 +19845,9 @@ function createReadlineInterface() {
|
|
|
19798
19845
|
});
|
|
19799
19846
|
}
|
|
19800
19847
|
function askQuestion(rl, question) {
|
|
19801
|
-
return new Promise((
|
|
19848
|
+
return new Promise((resolve18) => {
|
|
19802
19849
|
rl.question(question, (answer) => {
|
|
19803
|
-
|
|
19850
|
+
resolve18(answer.trim());
|
|
19804
19851
|
});
|
|
19805
19852
|
});
|
|
19806
19853
|
}
|
|
@@ -20448,7 +20495,7 @@ function extractCode(url, expectedState) {
|
|
|
20448
20495
|
return code;
|
|
20449
20496
|
}
|
|
20450
20497
|
function waitForCallback(port, expectedState) {
|
|
20451
|
-
return new Promise((
|
|
20498
|
+
return new Promise((resolve18, reject) => {
|
|
20452
20499
|
const timeout = setTimeout(() => {
|
|
20453
20500
|
server.close();
|
|
20454
20501
|
reject(new Error("Authorization timed out after 120 seconds"));
|
|
@@ -20465,7 +20512,7 @@ function waitForCallback(port, expectedState) {
|
|
|
20465
20512
|
const code = extractCode(url, expectedState);
|
|
20466
20513
|
respondHtml(res, 200, "Authorization successful!");
|
|
20467
20514
|
server.close();
|
|
20468
|
-
|
|
20515
|
+
resolve18(code);
|
|
20469
20516
|
} catch (error) {
|
|
20470
20517
|
respondHtml(res, 400, error.message);
|
|
20471
20518
|
server.close();
|
|
@@ -21214,10 +21261,10 @@ var STATUS_TIMEOUT_MS = 5e3;
|
|
|
21214
21261
|
function queryDaemon(socket) {
|
|
21215
21262
|
socket.write(`${JSON.stringify({ type: "ping" })}
|
|
21216
21263
|
`);
|
|
21217
|
-
return new Promise((
|
|
21264
|
+
return new Promise((resolve18) => {
|
|
21218
21265
|
const result = { sessions: [] };
|
|
21219
21266
|
const pending = /* @__PURE__ */ new Set(["sessions", "pong"]);
|
|
21220
|
-
const timer = setTimeout(() =>
|
|
21267
|
+
const timer = setTimeout(() => resolve18(result), STATUS_TIMEOUT_MS);
|
|
21221
21268
|
const lines = createInterface5({ input: socket });
|
|
21222
21269
|
lines.on("error", () => {
|
|
21223
21270
|
});
|
|
@@ -21225,7 +21272,7 @@ function queryDaemon(socket) {
|
|
|
21225
21272
|
applyLine(result, pending, line);
|
|
21226
21273
|
if (pending.size === 0) {
|
|
21227
21274
|
clearTimeout(timer);
|
|
21228
|
-
|
|
21275
|
+
resolve18(result);
|
|
21229
21276
|
}
|
|
21230
21277
|
});
|
|
21231
21278
|
});
|
|
@@ -21411,8 +21458,8 @@ async function drainDaemon() {
|
|
|
21411
21458
|
function requestDrain(socket) {
|
|
21412
21459
|
socket.write(`${JSON.stringify({ type: "drain" })}
|
|
21413
21460
|
`);
|
|
21414
|
-
return new Promise((
|
|
21415
|
-
const timer = setTimeout(() =>
|
|
21461
|
+
return new Promise((resolve18) => {
|
|
21462
|
+
const timer = setTimeout(() => resolve18(0), DRAIN_TIMEOUT_MS);
|
|
21416
21463
|
const lines = createInterface6({ input: socket });
|
|
21417
21464
|
lines.on("error", () => {
|
|
21418
21465
|
});
|
|
@@ -21421,7 +21468,7 @@ function requestDrain(socket) {
|
|
|
21421
21468
|
const data = JSON.parse(line);
|
|
21422
21469
|
if (data.type === "drained") {
|
|
21423
21470
|
clearTimeout(timer);
|
|
21424
|
-
|
|
21471
|
+
resolve18(data.count ?? 0);
|
|
21425
21472
|
}
|
|
21426
21473
|
} catch {
|
|
21427
21474
|
}
|
|
@@ -22507,7 +22554,7 @@ function windowsDaemonHost() {
|
|
|
22507
22554
|
var CONNECT_TIMEOUT_MS = 2e3;
|
|
22508
22555
|
var KEEPALIVE_PROBE_MS = 1e4;
|
|
22509
22556
|
function connectToWindowsDaemon() {
|
|
22510
|
-
return new Promise((
|
|
22557
|
+
return new Promise((resolve18, reject) => {
|
|
22511
22558
|
const socket = net2.connect(windowsDaemonPort(), windowsDaemonHost());
|
|
22512
22559
|
socket.setTimeout(CONNECT_TIMEOUT_MS);
|
|
22513
22560
|
socket.once("timeout", () => {
|
|
@@ -22517,7 +22564,7 @@ function connectToWindowsDaemon() {
|
|
|
22517
22564
|
socket.once("connect", () => {
|
|
22518
22565
|
socket.setTimeout(0);
|
|
22519
22566
|
socket.setKeepAlive(true, KEEPALIVE_PROBE_MS);
|
|
22520
|
-
|
|
22567
|
+
resolve18(socket);
|
|
22521
22568
|
});
|
|
22522
22569
|
socket.once("error", reject);
|
|
22523
22570
|
});
|
|
@@ -22595,7 +22642,7 @@ async function waitForWindowsDaemon() {
|
|
|
22595
22642
|
);
|
|
22596
22643
|
}
|
|
22597
22644
|
function delay2(ms) {
|
|
22598
|
-
return new Promise((
|
|
22645
|
+
return new Promise((resolve18) => setTimeout(resolve18, ms));
|
|
22599
22646
|
}
|
|
22600
22647
|
|
|
22601
22648
|
// src/commands/sessions/daemon/defaultConnect.ts
|
|
@@ -22843,7 +22890,7 @@ async function healWindowsDaemon() {
|
|
|
22843
22890
|
daemonLog("windows daemon: auto-heal: stale daemon stopped");
|
|
22844
22891
|
}
|
|
22845
22892
|
function runOnWindowsHost(command, timeoutMs) {
|
|
22846
|
-
return new Promise((
|
|
22893
|
+
return new Promise((resolve18, reject) => {
|
|
22847
22894
|
const child = spawn11("pwsh.exe", ["-Command", command], {
|
|
22848
22895
|
stdio: ["ignore", "pipe", "pipe"]
|
|
22849
22896
|
});
|
|
@@ -22863,7 +22910,7 @@ function runOnWindowsHost(command, timeoutMs) {
|
|
|
22863
22910
|
});
|
|
22864
22911
|
child.on("exit", (code) => {
|
|
22865
22912
|
clearTimeout(timer);
|
|
22866
|
-
if (code === 0)
|
|
22913
|
+
if (code === 0) resolve18();
|
|
22867
22914
|
else
|
|
22868
22915
|
reject(
|
|
22869
22916
|
new Error(
|
|
@@ -24132,6 +24179,48 @@ function buildLimitsSegment(rateLimits) {
|
|
|
24132
24179
|
return ` | Limits - ${fiveHr}, ${sevenDay}`;
|
|
24133
24180
|
}
|
|
24134
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
|
+
|
|
24135
24224
|
// src/commands/relayRateLimits.ts
|
|
24136
24225
|
async function relayRateLimits(rateLimits) {
|
|
24137
24226
|
if (!rateLimits) return;
|
|
@@ -24167,8 +24256,11 @@ async function statusLine() {
|
|
|
24167
24256
|
const model = data.model.display_name;
|
|
24168
24257
|
const { total_input_tokens: totalIn, total_output_tokens: totalOut } = data.context_window;
|
|
24169
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)} | ` : "";
|
|
24170
24262
|
console.log(
|
|
24171
|
-
`${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)}`
|
|
24172
24264
|
);
|
|
24173
24265
|
await relayRateLimits(data.rate_limits);
|
|
24174
24266
|
await relayUsage(data.session_id, totalIn, totalOut);
|