@staff0rd/assist 0.233.1 → 0.234.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 +1 -0
- package/dist/index.js +63 -51
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -117,6 +117,7 @@ The first backlog command in a repository that still has a local `.assist/backlo
|
|
|
117
117
|
- `assist backlog update-phase <id> <phase> [--add-task <text>] [--edit-task <n> <text>] [--remove-task <n>] [--add-check <text>] [--edit-check <n> <text>] [--remove-check <n>]` - Granular task and manual-check edits using 1-based indices matching `backlog show`: `--add-*` appends (repeatable), `--edit-*` replaces entry n in place, `--remove-*` deletes entry n and renumbers the rest (task ops cannot be combined with `--task`; check ops cannot be combined with `--manual-check`)
|
|
118
118
|
- `assist backlog remove-phase <id> <phase>` - Remove a plan phase from a backlog item
|
|
119
119
|
- `assist backlog next` - Pick and run the next backlog item, or open `/draft` if none remain
|
|
120
|
+
- `assist backlog refine [id]` - Alias for `refine`
|
|
120
121
|
- `assist backlog start <id>` - Set a backlog item to in-progress
|
|
121
122
|
- `assist backlog stop` - Revert all in-progress backlog items to todo and reset their phase to 1
|
|
122
123
|
- `assist backlog done <id>` - Set a backlog item to done
|
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.234.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -4933,13 +4933,13 @@ async function activity(options2) {
|
|
|
4933
4933
|
const activeDays = data.filter((d) => d.count > 0).length;
|
|
4934
4934
|
console.log(`${total} commits across ${activeDays} active days.`);
|
|
4935
4935
|
const weekly = /* @__PURE__ */ new Map();
|
|
4936
|
-
for (const { date, count:
|
|
4936
|
+
for (const { date, count: count5 } of data) {
|
|
4937
4937
|
const d = new Date(date);
|
|
4938
4938
|
d.setDate(d.getDate() - d.getDay());
|
|
4939
4939
|
const weekStart = d.toISOString().slice(0, 10);
|
|
4940
|
-
weekly.set(weekStart, (weekly.get(weekStart) ?? 0) +
|
|
4940
|
+
weekly.set(weekStart, (weekly.get(weekStart) ?? 0) + count5);
|
|
4941
4941
|
}
|
|
4942
|
-
const weeklyData = [...weekly.entries()].map(([date,
|
|
4942
|
+
const weeklyData = [...weekly.entries()].map(([date, count5]) => ({ date, count: count5 })).sort((a, b) => a.date.localeCompare(b.date));
|
|
4943
4943
|
const until = data[data.length - 1].date;
|
|
4944
4944
|
activityChart(weeklyData, { since, until });
|
|
4945
4945
|
}
|
|
@@ -5399,7 +5399,7 @@ async function add(options2) {
|
|
|
5399
5399
|
import chalk55 from "chalk";
|
|
5400
5400
|
|
|
5401
5401
|
// src/commands/backlog/insertPhaseAt.ts
|
|
5402
|
-
import { eq as eq14 } from "drizzle-orm";
|
|
5402
|
+
import { count, eq as eq14 } from "drizzle-orm";
|
|
5403
5403
|
|
|
5404
5404
|
// src/commands/backlog/shiftPhasesUp.ts
|
|
5405
5405
|
import { and as and3, desc, eq as eq13, gte } from "drizzle-orm";
|
|
@@ -5414,22 +5414,25 @@ async function shiftPhasesUp(db, itemId, fromIdx) {
|
|
|
5414
5414
|
// src/commands/backlog/insertPhaseAt.ts
|
|
5415
5415
|
async function insertPhaseAt(orm, itemId, phaseIdx, name, tasks, manualChecks, currentPhase) {
|
|
5416
5416
|
await orm.transaction(async (tx) => {
|
|
5417
|
+
const [row] = await tx.select({ cnt: count() }).from(planPhases).where(eq14(planPhases.itemId, itemId));
|
|
5418
|
+
const phaseCount = row?.cnt ?? 0;
|
|
5417
5419
|
await shiftPhasesUp(tx, itemId, phaseIdx);
|
|
5418
5420
|
await tx.insert(planPhases).values({ itemId, idx: phaseIdx, name, manualChecks });
|
|
5419
5421
|
if (tasks.length) {
|
|
5420
5422
|
await tx.insert(planTasks).values(tasks.map((task, i) => ({ itemId, phaseIdx, idx: i, task })));
|
|
5421
5423
|
}
|
|
5422
5424
|
if (currentPhase !== void 0 && currentPhase - 1 >= phaseIdx) {
|
|
5423
|
-
|
|
5425
|
+
const atReviewSlot = currentPhase - 1 >= phaseCount;
|
|
5426
|
+
await tx.update(items).set({ currentPhase: atReviewSlot ? phaseIdx + 1 : currentPhase + 1 }).where(eq14(items.id, itemId));
|
|
5424
5427
|
}
|
|
5425
5428
|
});
|
|
5426
5429
|
}
|
|
5427
5430
|
|
|
5428
5431
|
// src/commands/backlog/resolveInsertPosition.ts
|
|
5429
5432
|
import chalk54 from "chalk";
|
|
5430
|
-
import { count, eq as eq15 } from "drizzle-orm";
|
|
5433
|
+
import { count as count2, eq as eq15 } from "drizzle-orm";
|
|
5431
5434
|
async function resolveInsertPosition(orm, itemId, position) {
|
|
5432
|
-
const [row] = await orm.select({ cnt:
|
|
5435
|
+
const [row] = await orm.select({ cnt: count2() }).from(planPhases).where(eq15(planPhases.itemId, itemId));
|
|
5433
5436
|
const phaseCount = row?.cnt ?? 0;
|
|
5434
5437
|
if (position === void 0) return phaseCount;
|
|
5435
5438
|
const pos = Number.parseInt(position, 10);
|
|
@@ -5883,14 +5886,14 @@ import { and as and8, eq as eq21 } from "drizzle-orm";
|
|
|
5883
5886
|
|
|
5884
5887
|
// src/commands/backlog/findPhase.ts
|
|
5885
5888
|
import chalk68 from "chalk";
|
|
5886
|
-
import { and as and6, count as
|
|
5889
|
+
import { and as and6, count as count3, eq as eq19 } from "drizzle-orm";
|
|
5887
5890
|
async function findPhase(id, phase) {
|
|
5888
5891
|
const found = await findOneItem(id);
|
|
5889
5892
|
if (!found) return void 0;
|
|
5890
5893
|
const { orm, item } = found;
|
|
5891
5894
|
const itemId = item.id;
|
|
5892
5895
|
const phaseIdx = Number.parseInt(phase, 10) - 1;
|
|
5893
|
-
const [row] = await orm.select({ cnt:
|
|
5896
|
+
const [row] = await orm.select({ cnt: count3() }).from(planPhases).where(and6(eq19(planPhases.itemId, itemId), eq19(planPhases.idx, phaseIdx)));
|
|
5894
5897
|
if (!row || row.cnt === 0) {
|
|
5895
5898
|
console.log(
|
|
5896
5899
|
chalk68.red(`Phase ${phaseIdx + 1} not found on item #${itemId}.`)
|
|
@@ -5902,7 +5905,7 @@ async function findPhase(id, phase) {
|
|
|
5902
5905
|
}
|
|
5903
5906
|
|
|
5904
5907
|
// src/commands/backlog/reindexPhases.ts
|
|
5905
|
-
import { and as and7, asc as asc4, count as
|
|
5908
|
+
import { and as and7, asc as asc4, count as count4, eq as eq20 } from "drizzle-orm";
|
|
5906
5909
|
async function reindexPhases(db, itemId) {
|
|
5907
5910
|
const remaining = await db.select({ idx: planPhases.idx }).from(planPhases).where(eq20(planPhases.itemId, itemId)).orderBy(asc4(planPhases.idx));
|
|
5908
5911
|
for (let i = 0; i < remaining.length; i++) {
|
|
@@ -5921,7 +5924,7 @@ async function adjustCurrentPhase(db, item, removedIdx) {
|
|
|
5921
5924
|
return;
|
|
5922
5925
|
}
|
|
5923
5926
|
if (removedIdx !== currentIdx) return;
|
|
5924
|
-
const [row] = await db.select({ cnt:
|
|
5927
|
+
const [row] = await db.select({ cnt: count4() }).from(planPhases).where(eq20(planPhases.itemId, item.id));
|
|
5925
5928
|
const cnt = row?.cnt ?? 0;
|
|
5926
5929
|
await db.update(items).set({ currentPhase: cnt === 0 ? null : Math.min(currentPhase, cnt) }).where(eq20(items.id, item.id));
|
|
5927
5930
|
}
|
|
@@ -6240,29 +6243,38 @@ function registerShowCommands(cmd) {
|
|
|
6240
6243
|
function registerWebCommand(cmd) {
|
|
6241
6244
|
cmd.command("web").description("Open the backlog tab in the web dashboard").option("-p, --port <number>", "Port to listen on", "3100").action(web2);
|
|
6242
6245
|
}
|
|
6246
|
+
function registerRefineCommand(cmd) {
|
|
6247
|
+
cmd.command("refine").argument("[id]", "Backlog item ID").description("Alias for refine").action((id) => refine(id));
|
|
6248
|
+
}
|
|
6243
6249
|
function registerNextCommand(cmd) {
|
|
6244
6250
|
cmd.command("next").description("Pick and run the next backlog item, or open /draft if none").option("-w, --write", "Run Claude with auto permission mode (default)").option("--no-write", "Run Claude without auto permission mode").action(
|
|
6245
6251
|
(opts) => next({ allowEdits: opts.write !== false })
|
|
6246
6252
|
);
|
|
6247
6253
|
}
|
|
6254
|
+
var registrars = [
|
|
6255
|
+
registerItemCommands,
|
|
6256
|
+
registerShowCommands,
|
|
6257
|
+
registerStatusCommands,
|
|
6258
|
+
registerWebCommand,
|
|
6259
|
+
registerCommentCommands,
|
|
6260
|
+
registerLinkCommands,
|
|
6261
|
+
registerPlanCommands,
|
|
6262
|
+
registerRewindCommand,
|
|
6263
|
+
registerNextCommand,
|
|
6264
|
+
registerRefineCommand,
|
|
6265
|
+
registerRunCommand,
|
|
6266
|
+
registerSearchCommand,
|
|
6267
|
+
registerUpdateCommands,
|
|
6268
|
+
registerExportCommand,
|
|
6269
|
+
registerImportCommand
|
|
6270
|
+
];
|
|
6248
6271
|
function registerBacklog(program2) {
|
|
6249
6272
|
const cmd = program2.command("backlog").description("Manage a backlog of work items").option("--dir <path>", "Override directory for backlog file discovery").hook("preAction", (thisCommand) => {
|
|
6250
6273
|
setBacklogDir(thisCommand.opts().dir);
|
|
6251
6274
|
}).action(() => web2({ port: "3100" }));
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
registerWebCommand(cmd);
|
|
6256
|
-
registerCommentCommands(cmd);
|
|
6257
|
-
registerLinkCommands(cmd);
|
|
6258
|
-
registerPlanCommands(cmd);
|
|
6259
|
-
registerRewindCommand(cmd);
|
|
6260
|
-
registerNextCommand(cmd);
|
|
6261
|
-
registerRunCommand(cmd);
|
|
6262
|
-
registerSearchCommand(cmd);
|
|
6263
|
-
registerUpdateCommands(cmd);
|
|
6264
|
-
registerExportCommand(cmd);
|
|
6265
|
-
registerImportCommand(cmd);
|
|
6275
|
+
for (const register of registrars) {
|
|
6276
|
+
register(cmd);
|
|
6277
|
+
}
|
|
6266
6278
|
}
|
|
6267
6279
|
|
|
6268
6280
|
// src/commands/cliHook/index.ts
|
|
@@ -7482,7 +7494,7 @@ function calculateHalstead(node) {
|
|
|
7482
7494
|
// src/commands/complexity/shared/countSloc.ts
|
|
7483
7495
|
function countSloc(content) {
|
|
7484
7496
|
let inMultiLineComment = false;
|
|
7485
|
-
let
|
|
7497
|
+
let count5 = 0;
|
|
7486
7498
|
for (const line of content.split("\n")) {
|
|
7487
7499
|
const trimmed = line.trim();
|
|
7488
7500
|
if (inMultiLineComment) {
|
|
@@ -7490,7 +7502,7 @@ function countSloc(content) {
|
|
|
7490
7502
|
inMultiLineComment = false;
|
|
7491
7503
|
const afterComment = trimmed.substring(trimmed.indexOf("*/") + 2);
|
|
7492
7504
|
if (afterComment.trim().length > 0) {
|
|
7493
|
-
|
|
7505
|
+
count5++;
|
|
7494
7506
|
}
|
|
7495
7507
|
}
|
|
7496
7508
|
continue;
|
|
@@ -7502,7 +7514,7 @@ function countSloc(content) {
|
|
|
7502
7514
|
if (trimmed.includes("*/")) {
|
|
7503
7515
|
const afterComment = trimmed.substring(trimmed.indexOf("*/") + 2);
|
|
7504
7516
|
if (afterComment.trim().length > 0) {
|
|
7505
|
-
|
|
7517
|
+
count5++;
|
|
7506
7518
|
}
|
|
7507
7519
|
} else {
|
|
7508
7520
|
inMultiLineComment = true;
|
|
@@ -7510,10 +7522,10 @@ function countSloc(content) {
|
|
|
7510
7522
|
continue;
|
|
7511
7523
|
}
|
|
7512
7524
|
if (trimmed.length > 0) {
|
|
7513
|
-
|
|
7525
|
+
count5++;
|
|
7514
7526
|
}
|
|
7515
7527
|
}
|
|
7516
|
-
return
|
|
7528
|
+
return count5;
|
|
7517
7529
|
}
|
|
7518
7530
|
|
|
7519
7531
|
// src/commands/complexity/shared/index.ts
|
|
@@ -9916,11 +9928,11 @@ function printPromptsTable(rows) {
|
|
|
9916
9928
|
console.log(chalk111.dim(header));
|
|
9917
9929
|
console.log(chalk111.dim("-".repeat(header.length)));
|
|
9918
9930
|
for (const row of rows) {
|
|
9919
|
-
const
|
|
9931
|
+
const count5 = String(row.count).padStart(countWidth);
|
|
9920
9932
|
const tool = row.tool.padEnd(toolWidth);
|
|
9921
9933
|
const command = truncate(row.command, 60).padEnd(commandWidth);
|
|
9922
9934
|
console.log(
|
|
9923
|
-
`${chalk111.yellow(
|
|
9935
|
+
`${chalk111.yellow(count5)} ${tool} ${command} ${chalk111.dim(row.repos)}`
|
|
9924
9936
|
);
|
|
9925
9937
|
}
|
|
9926
9938
|
}
|
|
@@ -10530,8 +10542,8 @@ async function promptNavigation(currentPage, totalPages) {
|
|
|
10530
10542
|
});
|
|
10531
10543
|
return parseAction(action);
|
|
10532
10544
|
}
|
|
10533
|
-
function computeTotalPages(
|
|
10534
|
-
return Math.ceil(
|
|
10545
|
+
function computeTotalPages(count5) {
|
|
10546
|
+
return Math.ceil(count5 / PAGE_SIZE);
|
|
10535
10547
|
}
|
|
10536
10548
|
async function navigateAndDisplay(pullRequests, totalPages, currentPage) {
|
|
10537
10549
|
const delta = await promptNavigation(currentPage, totalPages);
|
|
@@ -13035,9 +13047,9 @@ function warnUnlocated(unlocated) {
|
|
|
13035
13047
|
}
|
|
13036
13048
|
|
|
13037
13049
|
// src/commands/review/postReviewToPr.ts
|
|
13038
|
-
async function confirmPost(prNumber,
|
|
13050
|
+
async function confirmPost(prNumber, count5, options2) {
|
|
13039
13051
|
if (!options2.prompt) return true;
|
|
13040
|
-
return promptConfirm(`Post ${
|
|
13052
|
+
return promptConfirm(`Post ${count5} comment(s) to PR #${prNumber}?`, false);
|
|
13041
13053
|
}
|
|
13042
13054
|
async function postReviewToPr(synthesisPath, options2) {
|
|
13043
13055
|
const prNumber = findCurrentPrNumber();
|
|
@@ -14061,9 +14073,9 @@ async function runReviewPipeline(paths, options2) {
|
|
|
14061
14073
|
}
|
|
14062
14074
|
|
|
14063
14075
|
// src/commands/review/reviewPr.ts
|
|
14064
|
-
function logPriorComments(
|
|
14065
|
-
if (
|
|
14066
|
-
console.log(`Including ${
|
|
14076
|
+
function logPriorComments(count5) {
|
|
14077
|
+
if (count5 === 0) return;
|
|
14078
|
+
console.log(`Including ${count5} prior review comment(s) in request.md.`);
|
|
14067
14079
|
}
|
|
14068
14080
|
function gatherChangedContext() {
|
|
14069
14081
|
const context = gatherContext();
|
|
@@ -14305,9 +14317,9 @@ function filterToSql(filter) {
|
|
|
14305
14317
|
}
|
|
14306
14318
|
|
|
14307
14319
|
// src/commands/seq/fetchSeqData.ts
|
|
14308
|
-
async function fetchSeqData(conn, filter,
|
|
14320
|
+
async function fetchSeqData(conn, filter, count5, from, to) {
|
|
14309
14321
|
const sqlFilter = filterToSql(filter);
|
|
14310
|
-
const sql4 = `select @Timestamp, @Level, @Exception, @Message from stream where ${sqlFilter} order by @Timestamp desc limit ${
|
|
14322
|
+
const sql4 = `select @Timestamp, @Level, @Exception, @Message from stream where ${sqlFilter} order by @Timestamp desc limit ${count5}`;
|
|
14311
14323
|
const params = new URLSearchParams({ q: sql4 });
|
|
14312
14324
|
if (from) params.set("fromDateUtc", from);
|
|
14313
14325
|
if (to) params.set("toDateUtc", to);
|
|
@@ -14477,12 +14489,12 @@ function resolveConnection2(name) {
|
|
|
14477
14489
|
async function seqQuery(filter, options2) {
|
|
14478
14490
|
rejectTimestampFilter(filter);
|
|
14479
14491
|
const conn = resolveConnection2(options2.connection);
|
|
14480
|
-
const
|
|
14492
|
+
const count5 = Number.parseInt(options2.count ?? "1000", 10);
|
|
14481
14493
|
const from = options2.from ? parseRelativeTime(options2.from) : void 0;
|
|
14482
14494
|
const to = options2.to ? parseRelativeTime(options2.to) : void 0;
|
|
14483
|
-
const events = from || to ? await fetchSeqData(conn, filter,
|
|
14495
|
+
const events = from || to ? await fetchSeqData(conn, filter, count5, from, to) : await fetchSeqEvents(
|
|
14484
14496
|
conn,
|
|
14485
|
-
new URLSearchParams({ filter, count: String(
|
|
14497
|
+
new URLSearchParams({ filter, count: String(count5) })
|
|
14486
14498
|
);
|
|
14487
14499
|
if (events.length === 0) {
|
|
14488
14500
|
console.log(chalk142.yellow("No events found."));
|
|
@@ -14498,10 +14510,10 @@ async function seqQuery(filter, options2) {
|
|
|
14498
14510
|
}
|
|
14499
14511
|
console.log(chalk142.dim(`
|
|
14500
14512
|
${events.length} events`));
|
|
14501
|
-
if (events.length >=
|
|
14513
|
+
if (events.length >= count5) {
|
|
14502
14514
|
console.log(
|
|
14503
14515
|
chalk142.yellow(
|
|
14504
|
-
`Results limited to ${
|
|
14516
|
+
`Results limited to ${count5}. Use --count to retrieve more.`
|
|
14505
14517
|
)
|
|
14506
14518
|
);
|
|
14507
14519
|
}
|
|
@@ -15536,13 +15548,13 @@ function logs(options2) {
|
|
|
15536
15548
|
console.log("No voice log file found");
|
|
15537
15549
|
return;
|
|
15538
15550
|
}
|
|
15539
|
-
const
|
|
15551
|
+
const count5 = Number.parseInt(options2.lines ?? "150", 10);
|
|
15540
15552
|
const content = readFileSync33(voicePaths.log, "utf-8").trim();
|
|
15541
15553
|
if (!content) {
|
|
15542
15554
|
console.log("Voice log is empty");
|
|
15543
15555
|
return;
|
|
15544
15556
|
}
|
|
15545
|
-
const lines = content.split("\n").slice(-
|
|
15557
|
+
const lines = content.split("\n").slice(-count5);
|
|
15546
15558
|
for (const line of lines) {
|
|
15547
15559
|
try {
|
|
15548
15560
|
const event = JSON.parse(line);
|
|
@@ -15689,10 +15701,10 @@ function isProcessAlive3(pid) {
|
|
|
15689
15701
|
return false;
|
|
15690
15702
|
}
|
|
15691
15703
|
}
|
|
15692
|
-
function readRecentLogs(
|
|
15704
|
+
function readRecentLogs(count5) {
|
|
15693
15705
|
if (!existsSync45(voicePaths.log)) return [];
|
|
15694
15706
|
const lines = readFileSync35(voicePaths.log, "utf-8").trim().split("\n");
|
|
15695
|
-
return lines.slice(-
|
|
15707
|
+
return lines.slice(-count5);
|
|
15696
15708
|
}
|
|
15697
15709
|
function status() {
|
|
15698
15710
|
if (!existsSync45(voicePaths.pid)) {
|