@staff0rd/assist 0.240.0 → 0.242.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 -0
- package/dist/commands/sessions/web/bundle.js +65 -65
- package/dist/index.js +546 -318
- 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.242.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -4113,6 +4113,12 @@ function createFallbackHandler(routes3, htmlHandler2, extra) {
|
|
|
4113
4113
|
};
|
|
4114
4114
|
}
|
|
4115
4115
|
|
|
4116
|
+
// src/commands/backlog/web/applyCwdFromReq.ts
|
|
4117
|
+
function applyCwdFromReq(req) {
|
|
4118
|
+
const url = new URL(req.url ?? "/", "http://localhost");
|
|
4119
|
+
setBacklogDir(url.searchParams.get("cwd") ?? void 0);
|
|
4120
|
+
}
|
|
4121
|
+
|
|
4116
4122
|
// src/commands/backlog/web/parseItemBody.ts
|
|
4117
4123
|
function readBody(req) {
|
|
4118
4124
|
return new Promise((resolve15, reject) => {
|
|
@@ -4137,6 +4143,7 @@ async function parseRewindBody(req) {
|
|
|
4137
4143
|
// src/commands/backlog/web/createItem.ts
|
|
4138
4144
|
async function createItem(req, res) {
|
|
4139
4145
|
const body = await parseItemBody(req);
|
|
4146
|
+
applyCwdFromReq(req);
|
|
4140
4147
|
const orm = await getBacklogOrm();
|
|
4141
4148
|
const newItem = {
|
|
4142
4149
|
type: body.type ?? "story",
|
|
@@ -4149,11 +4156,29 @@ async function createItem(req, res) {
|
|
|
4149
4156
|
respondJson(res, 201, { id, ...newItem });
|
|
4150
4157
|
}
|
|
4151
4158
|
|
|
4159
|
+
// src/commands/backlog/web/getBacklogExists.ts
|
|
4160
|
+
async function getBacklogExists(req, res) {
|
|
4161
|
+
applyCwdFromReq(req);
|
|
4162
|
+
const items2 = await loadBacklog();
|
|
4163
|
+
respondJson(res, 200, { exists: items2.length > 0 });
|
|
4164
|
+
}
|
|
4165
|
+
|
|
4152
4166
|
// src/commands/backlog/web/rewindItemPhase.ts
|
|
4153
|
-
import { eq as
|
|
4167
|
+
import { eq as eq11 } from "drizzle-orm";
|
|
4168
|
+
|
|
4169
|
+
// src/commands/backlog/deleteComment.ts
|
|
4170
|
+
import { and as and2, eq as eq10 } from "drizzle-orm";
|
|
4171
|
+
async function deleteComment(orm, itemId, commentId) {
|
|
4172
|
+
const [row] = await orm.select({ type: comments.type }).from(comments).where(and2(eq10(comments.id, commentId), eq10(comments.itemId, itemId)));
|
|
4173
|
+
if (!row) return "not-found";
|
|
4174
|
+
if (row.type === "summary") return "is-summary";
|
|
4175
|
+
await orm.delete(comments).where(and2(eq10(comments.id, commentId), eq10(comments.itemId, itemId)));
|
|
4176
|
+
return "deleted";
|
|
4177
|
+
}
|
|
4154
4178
|
|
|
4155
4179
|
// src/commands/backlog/web/shared.ts
|
|
4156
4180
|
async function listItems(req, res) {
|
|
4181
|
+
applyCwdFromReq(req);
|
|
4157
4182
|
const url = new URL(req.url ?? "/", "http://localhost");
|
|
4158
4183
|
const q = url.searchParams.get("q");
|
|
4159
4184
|
respondJson(res, 200, q ? await searchBacklog(q) : await loadBacklog());
|
|
@@ -4177,6 +4202,24 @@ async function deleteItem2(res, id) {
|
|
|
4177
4202
|
await deleteItem(result.orm, id);
|
|
4178
4203
|
respondJson(res, 200, result.item);
|
|
4179
4204
|
}
|
|
4205
|
+
async function deleteItemComment(res, itemId, commentId) {
|
|
4206
|
+
const result = await findItemOr404(res, itemId);
|
|
4207
|
+
if (!result) return;
|
|
4208
|
+
const outcome = await deleteComment(result.orm, itemId, commentId);
|
|
4209
|
+
if (outcome === "not-found") {
|
|
4210
|
+
respondJson(res, 404, {
|
|
4211
|
+
error: `Comment #${commentId} not found on item #${itemId}.`
|
|
4212
|
+
});
|
|
4213
|
+
return;
|
|
4214
|
+
}
|
|
4215
|
+
if (outcome === "is-summary") {
|
|
4216
|
+
respondJson(res, 400, {
|
|
4217
|
+
error: `Comment #${commentId} is a phase summary and cannot be deleted.`
|
|
4218
|
+
});
|
|
4219
|
+
return;
|
|
4220
|
+
}
|
|
4221
|
+
respondJson(res, 200, await loadItem(result.orm, itemId));
|
|
4222
|
+
}
|
|
4180
4223
|
async function patchItemStatus(req, res, id) {
|
|
4181
4224
|
const { status: status2 } = await parseStatusBody(req);
|
|
4182
4225
|
const result = await findItemOr404(res, id);
|
|
@@ -4204,7 +4247,7 @@ async function rewindItemPhase(req, res, id) {
|
|
|
4204
4247
|
`Rewound to phase ${phase} (${phaseName}): ${reason}`,
|
|
4205
4248
|
{ phase }
|
|
4206
4249
|
);
|
|
4207
|
-
await orm.update(items).set({ currentPhase: phase, status: "in-progress" }).where(
|
|
4250
|
+
await orm.update(items).set({ currentPhase: phase, status: "in-progress" }).where(eq11(items.id, id));
|
|
4208
4251
|
respondJson(res, 200, await loadItem(orm, id));
|
|
4209
4252
|
}
|
|
4210
4253
|
function validateRewind(item, phase) {
|
|
@@ -4222,7 +4265,7 @@ function validateRewind(item, phase) {
|
|
|
4222
4265
|
}
|
|
4223
4266
|
|
|
4224
4267
|
// src/commands/backlog/web/updateItem.ts
|
|
4225
|
-
import { eq as
|
|
4268
|
+
import { eq as eq12 } from "drizzle-orm";
|
|
4226
4269
|
async function updateItem(req, res, id) {
|
|
4227
4270
|
const body = await parseItemBody(req);
|
|
4228
4271
|
const result = await findItemOr404(res, id);
|
|
@@ -4233,7 +4276,7 @@ async function updateItem(req, res, id) {
|
|
|
4233
4276
|
name: body.name,
|
|
4234
4277
|
description: body.description ?? null,
|
|
4235
4278
|
acceptanceCriteria: JSON.stringify(body.acceptanceCriteria ?? [])
|
|
4236
|
-
}).where(
|
|
4279
|
+
}).where(eq12(items.id, id));
|
|
4237
4280
|
respondJson(res, 200, await loadItem(orm, id));
|
|
4238
4281
|
}
|
|
4239
4282
|
|
|
@@ -4247,17 +4290,47 @@ var itemRoutes = {
|
|
|
4247
4290
|
async function handleItemRoute(req, res, pathname) {
|
|
4248
4291
|
const rewindMatch = pathname.match(/^\/api\/items\/(\d+)\/rewind$/);
|
|
4249
4292
|
if (rewindMatch && req.method === "POST") {
|
|
4293
|
+
applyCwdFromReq(req);
|
|
4250
4294
|
await rewindItemPhase(req, res, Number.parseInt(rewindMatch[1], 10));
|
|
4251
4295
|
return true;
|
|
4252
4296
|
}
|
|
4297
|
+
const commentMatch = pathname.match(/^\/api\/items\/(\d+)\/comments\/(\d+)$/);
|
|
4298
|
+
if (commentMatch && req.method === "DELETE") {
|
|
4299
|
+
applyCwdFromReq(req);
|
|
4300
|
+
await deleteItemComment(
|
|
4301
|
+
res,
|
|
4302
|
+
Number.parseInt(commentMatch[1], 10),
|
|
4303
|
+
Number.parseInt(commentMatch[2], 10)
|
|
4304
|
+
);
|
|
4305
|
+
return true;
|
|
4306
|
+
}
|
|
4253
4307
|
const match = pathname.match(/^\/api\/items\/(\d+)$/);
|
|
4254
4308
|
if (!match) return false;
|
|
4255
4309
|
const handler = itemRoutes[req.method ?? "GET"];
|
|
4256
4310
|
if (!handler) return false;
|
|
4311
|
+
applyCwdFromReq(req);
|
|
4257
4312
|
await handler(req, res, Number.parseInt(match[1], 10));
|
|
4258
4313
|
return true;
|
|
4259
4314
|
}
|
|
4260
4315
|
|
|
4316
|
+
// src/commands/backlog/init/index.ts
|
|
4317
|
+
import chalk44 from "chalk";
|
|
4318
|
+
async function init6() {
|
|
4319
|
+
await getBacklogOrm();
|
|
4320
|
+
console.log(
|
|
4321
|
+
chalk44.green(
|
|
4322
|
+
`Backlog database ready. This repository maps to origin: ${getOrigin()}`
|
|
4323
|
+
)
|
|
4324
|
+
);
|
|
4325
|
+
}
|
|
4326
|
+
|
|
4327
|
+
// src/commands/backlog/web/initBacklog.ts
|
|
4328
|
+
async function initBacklog(req, res) {
|
|
4329
|
+
applyCwdFromReq(req);
|
|
4330
|
+
await init6();
|
|
4331
|
+
respondJson(res, 200, { ok: true });
|
|
4332
|
+
}
|
|
4333
|
+
|
|
4261
4334
|
// src/commands/sessions/web/getHtml.ts
|
|
4262
4335
|
function getHtml() {
|
|
4263
4336
|
return `<!DOCTYPE html>
|
|
@@ -4309,7 +4382,9 @@ var routes = {
|
|
|
4309
4382
|
),
|
|
4310
4383
|
"GET /xterm.css": createCssHandler("@xterm/xterm/css/xterm.css"),
|
|
4311
4384
|
"GET /api/items": listItems,
|
|
4312
|
-
"POST /api/items": createItem
|
|
4385
|
+
"POST /api/items": createItem,
|
|
4386
|
+
"GET /api/backlog/exists": getBacklogExists,
|
|
4387
|
+
"POST /api/backlog/init": initBacklog
|
|
4313
4388
|
};
|
|
4314
4389
|
var handleRequest = createFallbackHandler(
|
|
4315
4390
|
routes,
|
|
@@ -4869,37 +4944,37 @@ async function web2(options2) {
|
|
|
4869
4944
|
}
|
|
4870
4945
|
|
|
4871
4946
|
// src/commands/backlog/refine.ts
|
|
4872
|
-
import
|
|
4947
|
+
import chalk47 from "chalk";
|
|
4873
4948
|
import enquirer6 from "enquirer";
|
|
4874
4949
|
|
|
4875
4950
|
// src/commands/backlog/launchMode.ts
|
|
4876
|
-
import
|
|
4951
|
+
import chalk46 from "chalk";
|
|
4877
4952
|
|
|
4878
4953
|
// src/commands/backlog/tryRunById.ts
|
|
4879
|
-
import
|
|
4954
|
+
import chalk45 from "chalk";
|
|
4880
4955
|
async function tryRunById(id, options2) {
|
|
4881
4956
|
const items2 = await loadBacklog();
|
|
4882
4957
|
const numericId = Number.parseInt(id, 10);
|
|
4883
4958
|
const item = Number.isNaN(numericId) ? void 0 : items2.find((i) => i.id === numericId);
|
|
4884
4959
|
if (!item) {
|
|
4885
|
-
console.log(
|
|
4960
|
+
console.log(chalk45.red(`Item #${id} not found.`));
|
|
4886
4961
|
return false;
|
|
4887
4962
|
}
|
|
4888
4963
|
if (item.status === "done") {
|
|
4889
|
-
console.log(
|
|
4964
|
+
console.log(chalk45.red(`Item #${id} is already done.`));
|
|
4890
4965
|
return false;
|
|
4891
4966
|
}
|
|
4892
4967
|
if (item.status === "wontdo") {
|
|
4893
|
-
console.log(
|
|
4968
|
+
console.log(chalk45.red(`Item #${id} is marked won't do.`));
|
|
4894
4969
|
return false;
|
|
4895
4970
|
}
|
|
4896
4971
|
if (isBlocked(item, items2)) {
|
|
4897
4972
|
console.log(
|
|
4898
|
-
|
|
4973
|
+
chalk45.red(`Item #${id} is blocked by unresolved dependencies.`)
|
|
4899
4974
|
);
|
|
4900
4975
|
return false;
|
|
4901
4976
|
}
|
|
4902
|
-
console.log(
|
|
4977
|
+
console.log(chalk45.bold(`
|
|
4903
4978
|
Running backlog item #${id}...
|
|
4904
4979
|
`));
|
|
4905
4980
|
await run2(id, options2);
|
|
@@ -4920,7 +4995,7 @@ async function launchMode(slashCommand) {
|
|
|
4920
4995
|
if (typeof signal.id === "string" && signal.id) {
|
|
4921
4996
|
if (await tryRunById(signal.id, { allowEdits: true })) return;
|
|
4922
4997
|
}
|
|
4923
|
-
console.log(
|
|
4998
|
+
console.log(chalk46.bold("\nChaining into assist next...\n"));
|
|
4924
4999
|
await next({ allowEdits: true });
|
|
4925
5000
|
}
|
|
4926
5001
|
}
|
|
@@ -4932,12 +5007,12 @@ async function pickItemForRefine() {
|
|
|
4932
5007
|
(i) => i.status === "todo" || i.status === "in-progress"
|
|
4933
5008
|
);
|
|
4934
5009
|
if (active.length === 0) {
|
|
4935
|
-
console.log(
|
|
5010
|
+
console.log(chalk47.yellow("No active backlog items to refine."));
|
|
4936
5011
|
return void 0;
|
|
4937
5012
|
}
|
|
4938
5013
|
if (active.length === 1) {
|
|
4939
5014
|
const item = active[0];
|
|
4940
|
-
console.log(
|
|
5015
|
+
console.log(chalk47.bold(`Auto-selecting item #${item.id}: ${item.name}`));
|
|
4941
5016
|
return String(item.id);
|
|
4942
5017
|
}
|
|
4943
5018
|
const { selected } = await exitOnCancel(
|
|
@@ -4959,26 +5034,26 @@ async function refine(id) {
|
|
|
4959
5034
|
}
|
|
4960
5035
|
|
|
4961
5036
|
// src/commands/backlog/comment/index.ts
|
|
4962
|
-
import
|
|
5037
|
+
import chalk48 from "chalk";
|
|
4963
5038
|
async function comment(id, text2) {
|
|
4964
5039
|
const found = await findOneItem(id);
|
|
4965
5040
|
if (!found) process.exit(1);
|
|
4966
5041
|
await appendComment(found.orm, found.item.id, text2);
|
|
4967
|
-
console.log(
|
|
5042
|
+
console.log(chalk48.green(`Comment added to item #${id}.`));
|
|
4968
5043
|
}
|
|
4969
5044
|
|
|
4970
5045
|
// src/commands/backlog/comments/index.ts
|
|
4971
|
-
import
|
|
5046
|
+
import chalk49 from "chalk";
|
|
4972
5047
|
async function comments2(id) {
|
|
4973
5048
|
const found = await findOneItem(id);
|
|
4974
5049
|
if (!found) process.exit(1);
|
|
4975
5050
|
const { item } = found;
|
|
4976
5051
|
const entries = item.comments ?? [];
|
|
4977
5052
|
if (entries.length === 0) {
|
|
4978
|
-
console.log(
|
|
5053
|
+
console.log(chalk49.dim(`No comments on item #${id}.`));
|
|
4979
5054
|
return;
|
|
4980
5055
|
}
|
|
4981
|
-
console.log(
|
|
5056
|
+
console.log(chalk49.bold(`Comments for #${id}: ${item.name}
|
|
4982
5057
|
`));
|
|
4983
5058
|
for (const entry of entries) {
|
|
4984
5059
|
console.log(`${formatComment(entry)}
|
|
@@ -4987,19 +5062,7 @@ async function comments2(id) {
|
|
|
4987
5062
|
}
|
|
4988
5063
|
|
|
4989
5064
|
// src/commands/backlog/delete-comment/index.ts
|
|
4990
|
-
import
|
|
4991
|
-
|
|
4992
|
-
// src/commands/backlog/deleteComment.ts
|
|
4993
|
-
import { and as and2, eq as eq12 } from "drizzle-orm";
|
|
4994
|
-
async function deleteComment(orm, itemId, commentId) {
|
|
4995
|
-
const [row] = await orm.select({ type: comments.type }).from(comments).where(and2(eq12(comments.id, commentId), eq12(comments.itemId, itemId)));
|
|
4996
|
-
if (!row) return "not-found";
|
|
4997
|
-
if (row.type === "summary") return "is-summary";
|
|
4998
|
-
await orm.delete(comments).where(and2(eq12(comments.id, commentId), eq12(comments.itemId, itemId)));
|
|
4999
|
-
return "deleted";
|
|
5000
|
-
}
|
|
5001
|
-
|
|
5002
|
-
// src/commands/backlog/delete-comment/index.ts
|
|
5065
|
+
import chalk50 from "chalk";
|
|
5003
5066
|
async function deleteCommentCmd(id, commentId) {
|
|
5004
5067
|
const found = await findOneItem(id);
|
|
5005
5068
|
if (!found) process.exit(1);
|
|
@@ -5011,16 +5074,16 @@ async function deleteCommentCmd(id, commentId) {
|
|
|
5011
5074
|
switch (outcome) {
|
|
5012
5075
|
case "deleted":
|
|
5013
5076
|
console.log(
|
|
5014
|
-
|
|
5077
|
+
chalk50.green(`Comment #${commentId} deleted from item #${id}.`)
|
|
5015
5078
|
);
|
|
5016
5079
|
break;
|
|
5017
5080
|
case "not-found":
|
|
5018
|
-
console.log(
|
|
5081
|
+
console.log(chalk50.red(`Comment #${commentId} not found on item #${id}.`));
|
|
5019
5082
|
process.exit(1);
|
|
5020
5083
|
break;
|
|
5021
5084
|
case "is-summary":
|
|
5022
5085
|
console.log(
|
|
5023
|
-
|
|
5086
|
+
chalk50.red(
|
|
5024
5087
|
`Comment #${commentId} is a phase summary and cannot be deleted.`
|
|
5025
5088
|
)
|
|
5026
5089
|
);
|
|
@@ -5038,7 +5101,7 @@ function registerCommentCommands(cmd) {
|
|
|
5038
5101
|
|
|
5039
5102
|
// src/commands/backlog/export/index.ts
|
|
5040
5103
|
import { writeFile } from "fs/promises";
|
|
5041
|
-
import
|
|
5104
|
+
import chalk51 from "chalk";
|
|
5042
5105
|
|
|
5043
5106
|
// src/commands/backlog/dump/DumpTable.ts
|
|
5044
5107
|
var DUMP_FORMAT = "assist-backlog-dump";
|
|
@@ -5105,7 +5168,7 @@ async function exportBacklog(file) {
|
|
|
5105
5168
|
if (file) {
|
|
5106
5169
|
await writeFile(file, dump);
|
|
5107
5170
|
console.error(
|
|
5108
|
-
|
|
5171
|
+
chalk51.green(`Exported backlog to ${file} (${dump.length} bytes).`)
|
|
5109
5172
|
);
|
|
5110
5173
|
return;
|
|
5111
5174
|
}
|
|
@@ -5121,7 +5184,7 @@ function registerExportCommand(cmd) {
|
|
|
5121
5184
|
|
|
5122
5185
|
// src/commands/backlog/import/index.ts
|
|
5123
5186
|
import { readFile } from "fs/promises";
|
|
5124
|
-
import
|
|
5187
|
+
import chalk53 from "chalk";
|
|
5125
5188
|
|
|
5126
5189
|
// src/commands/backlog/dump/countCopyRows.ts
|
|
5127
5190
|
function countCopyRows(data) {
|
|
@@ -5198,7 +5261,7 @@ function validateDump({ header, sections }) {
|
|
|
5198
5261
|
}
|
|
5199
5262
|
|
|
5200
5263
|
// src/commands/backlog/import/confirmReplace.ts
|
|
5201
|
-
import
|
|
5264
|
+
import chalk52 from "chalk";
|
|
5202
5265
|
async function countRows(client, table) {
|
|
5203
5266
|
const { rows } = await client.query(
|
|
5204
5267
|
`SELECT count(*)::int AS n FROM ${table}`
|
|
@@ -5209,7 +5272,7 @@ function printSummary(current, incoming) {
|
|
|
5209
5272
|
const lines = DUMP_TABLES.map(
|
|
5210
5273
|
(t, i) => ` ${t.name}: ${current[i]} \u2192 ${incoming[i]} rows`
|
|
5211
5274
|
);
|
|
5212
|
-
console.error(
|
|
5275
|
+
console.error(chalk52.bold("\nThis will REPLACE all backlog data:"));
|
|
5213
5276
|
console.error(`${lines.join("\n")}
|
|
5214
5277
|
`);
|
|
5215
5278
|
}
|
|
@@ -5285,13 +5348,13 @@ async function importBacklog(file, options2 = {}) {
|
|
|
5285
5348
|
);
|
|
5286
5349
|
await withBacklogClient(async (client) => {
|
|
5287
5350
|
if (!options2.yes && !await confirmReplace(client, incoming, !file)) {
|
|
5288
|
-
console.error(
|
|
5351
|
+
console.error(chalk53.yellow("Import cancelled; no changes made."));
|
|
5289
5352
|
return;
|
|
5290
5353
|
}
|
|
5291
5354
|
await restore(client, parsed);
|
|
5292
5355
|
const total = incoming.reduce((sum, n) => sum + n, 0);
|
|
5293
5356
|
console.error(
|
|
5294
|
-
|
|
5357
|
+
chalk53.green(
|
|
5295
5358
|
`Imported backlog: ${total} rows restored across ${DUMP_TABLES.length} tables.`
|
|
5296
5359
|
)
|
|
5297
5360
|
);
|
|
@@ -5308,7 +5371,7 @@ function registerImportCommand(cmd) {
|
|
|
5308
5371
|
}
|
|
5309
5372
|
|
|
5310
5373
|
// src/commands/backlog/add/index.ts
|
|
5311
|
-
import
|
|
5374
|
+
import chalk54 from "chalk";
|
|
5312
5375
|
|
|
5313
5376
|
// src/commands/backlog/add/shared.ts
|
|
5314
5377
|
import { spawnSync } from "child_process";
|
|
@@ -5398,11 +5461,11 @@ async function add(options2) {
|
|
|
5398
5461
|
},
|
|
5399
5462
|
getOrigin()
|
|
5400
5463
|
);
|
|
5401
|
-
console.log(
|
|
5464
|
+
console.log(chalk54.green(`Added item #${id}: ${name}`));
|
|
5402
5465
|
}
|
|
5403
5466
|
|
|
5404
5467
|
// src/commands/backlog/addPhase.ts
|
|
5405
|
-
import
|
|
5468
|
+
import chalk56 from "chalk";
|
|
5406
5469
|
|
|
5407
5470
|
// src/commands/backlog/insertPhaseAt.ts
|
|
5408
5471
|
import { count, eq as eq14 } from "drizzle-orm";
|
|
@@ -5435,7 +5498,7 @@ async function insertPhaseAt(orm, itemId, phaseIdx, name, tasks, manualChecks, c
|
|
|
5435
5498
|
}
|
|
5436
5499
|
|
|
5437
5500
|
// src/commands/backlog/resolveInsertPosition.ts
|
|
5438
|
-
import
|
|
5501
|
+
import chalk55 from "chalk";
|
|
5439
5502
|
import { count as count2, eq as eq15 } from "drizzle-orm";
|
|
5440
5503
|
async function resolveInsertPosition(orm, itemId, position) {
|
|
5441
5504
|
const [row] = await orm.select({ cnt: count2() }).from(planPhases).where(eq15(planPhases.itemId, itemId));
|
|
@@ -5444,7 +5507,7 @@ async function resolveInsertPosition(orm, itemId, position) {
|
|
|
5444
5507
|
const pos = Number.parseInt(position, 10);
|
|
5445
5508
|
if (pos < 1 || pos > phaseCount + 1) {
|
|
5446
5509
|
console.log(
|
|
5447
|
-
|
|
5510
|
+
chalk55.red(
|
|
5448
5511
|
`Position ${pos} is out of range. Must be between 1 and ${phaseCount + 1}.`
|
|
5449
5512
|
)
|
|
5450
5513
|
);
|
|
@@ -5465,7 +5528,7 @@ async function addPhase(id, name, options2) {
|
|
|
5465
5528
|
if (!found) return;
|
|
5466
5529
|
const tasks = options2.task ?? [];
|
|
5467
5530
|
if (tasks.length === 0) {
|
|
5468
|
-
console.log(
|
|
5531
|
+
console.log(chalk56.red("At least one --task is required."));
|
|
5469
5532
|
process.exitCode = 1;
|
|
5470
5533
|
return;
|
|
5471
5534
|
}
|
|
@@ -5483,20 +5546,9 @@ async function addPhase(id, name, options2) {
|
|
|
5483
5546
|
found.item.currentPhase
|
|
5484
5547
|
);
|
|
5485
5548
|
const verb = options2.position !== void 0 ? "Inserted" : "Added";
|
|
5486
|
-
console.log(
|
|
5487
|
-
chalk55.green(
|
|
5488
|
-
`${verb} phase ${phaseIdx + 1} "${name}" to item #${itemId} with ${tasks.length} task(s).`
|
|
5489
|
-
)
|
|
5490
|
-
);
|
|
5491
|
-
}
|
|
5492
|
-
|
|
5493
|
-
// src/commands/backlog/init/index.ts
|
|
5494
|
-
import chalk56 from "chalk";
|
|
5495
|
-
async function init6() {
|
|
5496
|
-
await getBacklogOrm();
|
|
5497
5549
|
console.log(
|
|
5498
5550
|
chalk56.green(
|
|
5499
|
-
|
|
5551
|
+
`${verb} phase ${phaseIdx + 1} "${name}" to item #${itemId} with ${tasks.length} task(s).`
|
|
5500
5552
|
)
|
|
5501
5553
|
);
|
|
5502
5554
|
}
|
|
@@ -8207,8 +8259,8 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
8207
8259
|
(file) => ignorePaths.some((ignorePath) => file.startsWith(ignorePath))
|
|
8208
8260
|
);
|
|
8209
8261
|
}
|
|
8210
|
-
function printCommitsWithFiles(
|
|
8211
|
-
for (const commit2 of
|
|
8262
|
+
function printCommitsWithFiles(commits2, ignore2, verbose) {
|
|
8263
|
+
for (const commit2 of commits2) {
|
|
8212
8264
|
console.log(` ${chalk88.yellow(commit2.hash)} ${commit2.message}`);
|
|
8213
8265
|
if (verbose) {
|
|
8214
8266
|
const visibleFiles = commit2.files.filter(
|
|
@@ -8419,11 +8471,11 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
8419
8471
|
function logName(repoName) {
|
|
8420
8472
|
console.log(`${chalk91.bold("name:")} ${repoName}`);
|
|
8421
8473
|
}
|
|
8422
|
-
function displayNextEntry(ctx, targetDate,
|
|
8474
|
+
function displayNextEntry(ctx, targetDate, commits2) {
|
|
8423
8475
|
logName(ctx.repoName);
|
|
8424
|
-
printVersionInfo(ctx.config, ctx.lastInfo,
|
|
8476
|
+
printVersionInfo(ctx.config, ctx.lastInfo, commits2[0]?.hash);
|
|
8425
8477
|
console.log(chalk91.bold.blue(targetDate));
|
|
8426
|
-
printCommitsWithFiles(
|
|
8478
|
+
printCommitsWithFiles(commits2, ctx.ignore, ctx.verbose);
|
|
8427
8479
|
}
|
|
8428
8480
|
function logNoCommits(lastInfo) {
|
|
8429
8481
|
console.log(chalk91.dim(noCommitsMessage(!!lastInfo)));
|
|
@@ -9231,9 +9283,211 @@ function registerDotnet(program2) {
|
|
|
9231
9283
|
cmd.command("in-sln").description("Check whether a .csproj is referenced by any .sln file").argument("<csproj>", "Path to a .csproj file").action(inSln);
|
|
9232
9284
|
}
|
|
9233
9285
|
|
|
9286
|
+
// src/commands/github/aggregateCommitters.ts
|
|
9287
|
+
function aggregateCommitters(authorLists) {
|
|
9288
|
+
const totals = /* @__PURE__ */ new Map();
|
|
9289
|
+
for (const authors of authorLists) {
|
|
9290
|
+
for (const { author, commitCount } of authors) {
|
|
9291
|
+
totals.set(author, (totals.get(author) ?? 0) + commitCount);
|
|
9292
|
+
}
|
|
9293
|
+
}
|
|
9294
|
+
return [...totals].map(([author, commitCount]) => ({ author, commitCount })).sort((a, b) => b.commitCount - a.commitCount);
|
|
9295
|
+
}
|
|
9296
|
+
|
|
9297
|
+
// src/shared/runGhGraphql.ts
|
|
9298
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
9299
|
+
import { unlinkSync as unlinkSync6, writeFileSync as writeFileSync18 } from "fs";
|
|
9300
|
+
import { tmpdir as tmpdir4 } from "os";
|
|
9301
|
+
import { join as join27 } from "path";
|
|
9302
|
+
function buildArgs2(queryFile, vars) {
|
|
9303
|
+
const args = ["api", "graphql", "-F", `query=@${queryFile}`];
|
|
9304
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
9305
|
+
const flag = typeof value === "number" ? "-F" : "-f";
|
|
9306
|
+
args.push(flag, `${key}=${value}`);
|
|
9307
|
+
}
|
|
9308
|
+
return args;
|
|
9309
|
+
}
|
|
9310
|
+
function runGhGraphql(mutation, vars) {
|
|
9311
|
+
const queryFile = join27(tmpdir4(), `gh-query-${Date.now()}.graphql`);
|
|
9312
|
+
writeFileSync18(queryFile, mutation);
|
|
9313
|
+
try {
|
|
9314
|
+
const result = spawnSync2("gh", buildArgs2(queryFile, vars), {
|
|
9315
|
+
encoding: "utf-8"
|
|
9316
|
+
});
|
|
9317
|
+
if (result.status !== 0) throw new Error(result.stderr || result.stdout);
|
|
9318
|
+
return result.stdout;
|
|
9319
|
+
} finally {
|
|
9320
|
+
unlinkSync6(queryFile);
|
|
9321
|
+
}
|
|
9322
|
+
}
|
|
9323
|
+
|
|
9324
|
+
// src/commands/github/fetchOrgRepoCommitCounts.ts
|
|
9325
|
+
var REPOS_QUERY = `query($org: String!, $since: GitTimestamp!, $cursor: String) { organization(login: $org) { repositories(first: 50, orderBy: { field: PUSHED_AT, direction: DESC }, after: $cursor) { pageInfo { hasNextPage endCursor } nodes { name pushedAt defaultBranchRef { target { ... on Commit { history(since: $since) { totalCount } } } } } } } }`;
|
|
9326
|
+
function fetchOrgRepoCommitCounts(org, since) {
|
|
9327
|
+
const results = [];
|
|
9328
|
+
let cursor;
|
|
9329
|
+
for (; ; ) {
|
|
9330
|
+
const vars = { org, since };
|
|
9331
|
+
if (cursor) vars.cursor = cursor;
|
|
9332
|
+
const response = JSON.parse(
|
|
9333
|
+
runGhGraphql(REPOS_QUERY, vars)
|
|
9334
|
+
);
|
|
9335
|
+
const repositories = response.data.organization?.repositories;
|
|
9336
|
+
if (!repositories) throw new Error(`Organisation not found: ${org}`);
|
|
9337
|
+
for (const node of repositories.nodes) {
|
|
9338
|
+
const history = node.defaultBranchRef?.target?.history;
|
|
9339
|
+
if (!history) continue;
|
|
9340
|
+
results.push({ name: node.name, commitCount: history.totalCount });
|
|
9341
|
+
}
|
|
9342
|
+
const lastNode = repositories.nodes[repositories.nodes.length - 1];
|
|
9343
|
+
const exhausted = lastNode && new Date(lastNode.pushedAt) < new Date(since);
|
|
9344
|
+
if (!repositories.pageInfo.hasNextPage || exhausted) break;
|
|
9345
|
+
cursor = repositories.pageInfo.endCursor ?? void 0;
|
|
9346
|
+
}
|
|
9347
|
+
return results;
|
|
9348
|
+
}
|
|
9349
|
+
|
|
9350
|
+
// src/commands/github/fetchRepoCommitAuthors.ts
|
|
9351
|
+
var HISTORY_QUERY = `query($org: String!, $repo: String!, $since: GitTimestamp!, $cursor: String) { repository(owner: $org, name: $repo) { defaultBranchRef { target { ... on Commit { history(since: $since, first: 100, after: $cursor) { pageInfo { hasNextPage endCursor } nodes { author { user { login } name } } } } } } } }`;
|
|
9352
|
+
function fetchRepoCommitAuthors(org, repo, since) {
|
|
9353
|
+
const counts = /* @__PURE__ */ new Map();
|
|
9354
|
+
let cursor;
|
|
9355
|
+
for (; ; ) {
|
|
9356
|
+
const vars = { org, repo, since };
|
|
9357
|
+
if (cursor) vars.cursor = cursor;
|
|
9358
|
+
const response = JSON.parse(
|
|
9359
|
+
runGhGraphql(HISTORY_QUERY, vars)
|
|
9360
|
+
);
|
|
9361
|
+
const history = response.data.repository?.defaultBranchRef?.target?.history;
|
|
9362
|
+
if (!history) break;
|
|
9363
|
+
for (const node of history.nodes) {
|
|
9364
|
+
const author = node.author?.user?.login ?? node.author?.name ?? "unknown";
|
|
9365
|
+
counts.set(author, (counts.get(author) ?? 0) + 1);
|
|
9366
|
+
}
|
|
9367
|
+
if (!history.pageInfo.hasNextPage) break;
|
|
9368
|
+
cursor = history.pageInfo.endCursor ?? void 0;
|
|
9369
|
+
}
|
|
9370
|
+
return [...counts].map(([author, commitCount]) => ({ author, commitCount })).sort((a, b) => b.commitCount - a.commitCount);
|
|
9371
|
+
}
|
|
9372
|
+
|
|
9373
|
+
// src/commands/github/printCountTable.ts
|
|
9374
|
+
import chalk105 from "chalk";
|
|
9375
|
+
function printCountTable(labelHeader, rows) {
|
|
9376
|
+
const labelWidth = Math.max(
|
|
9377
|
+
labelHeader.length,
|
|
9378
|
+
...rows.map((row) => row.label.length)
|
|
9379
|
+
);
|
|
9380
|
+
const header = `${labelHeader.padEnd(labelWidth)} Commits`;
|
|
9381
|
+
console.log(chalk105.dim(header));
|
|
9382
|
+
console.log(chalk105.dim("-".repeat(header.length)));
|
|
9383
|
+
for (const row of rows) {
|
|
9384
|
+
console.log(`${row.label.padEnd(labelWidth)} ${row.count}`);
|
|
9385
|
+
}
|
|
9386
|
+
}
|
|
9387
|
+
|
|
9388
|
+
// src/commands/github/printRepoAuthorBreakdown.ts
|
|
9389
|
+
import chalk106 from "chalk";
|
|
9390
|
+
function printRepoAuthorBreakdown(repos2) {
|
|
9391
|
+
for (const repo of repos2) {
|
|
9392
|
+
console.log(chalk106.bold(repo.name));
|
|
9393
|
+
const authorWidth = Math.max(
|
|
9394
|
+
0,
|
|
9395
|
+
...repo.authors.map((a) => a.author.length)
|
|
9396
|
+
);
|
|
9397
|
+
for (const { author, commitCount } of repo.authors) {
|
|
9398
|
+
console.log(` ${author.padEnd(authorWidth)} ${commitCount}`);
|
|
9399
|
+
}
|
|
9400
|
+
console.log();
|
|
9401
|
+
}
|
|
9402
|
+
}
|
|
9403
|
+
|
|
9404
|
+
// src/commands/github/printCommitsReport.ts
|
|
9405
|
+
function printCommitsReport(report) {
|
|
9406
|
+
const { org, since, totalRepos, repos: repos2, committers, repoAuthors } = report;
|
|
9407
|
+
const scope = repos2.length < totalRepos ? ` (top ${repos2.length} of ${totalRepos} repos)` : "";
|
|
9408
|
+
console.log(`Top repos by commits in ${org} since ${since}${scope}:
|
|
9409
|
+
`);
|
|
9410
|
+
printCountTable(
|
|
9411
|
+
"Repo",
|
|
9412
|
+
repos2.map((r) => ({ label: r.name, count: r.commitCount }))
|
|
9413
|
+
);
|
|
9414
|
+
console.log(`
|
|
9415
|
+
Top committers in ${org} since ${since}${scope}:
|
|
9416
|
+
`);
|
|
9417
|
+
printCountTable(
|
|
9418
|
+
"Committer",
|
|
9419
|
+
committers.map((c) => ({ label: c.author, count: c.commitCount }))
|
|
9420
|
+
);
|
|
9421
|
+
console.log("\nCommits by author per repo:\n");
|
|
9422
|
+
printRepoAuthorBreakdown(repoAuthors);
|
|
9423
|
+
}
|
|
9424
|
+
|
|
9425
|
+
// src/commands/github/commits.ts
|
|
9426
|
+
function commits(org, options2) {
|
|
9427
|
+
const since = options2.since ? `${options2.since}T00:00:00Z` : new Date(Date.now() - 30 * 24 * 60 * 60 * 1e3).toISOString();
|
|
9428
|
+
const sinceDate = since.slice(0, 10);
|
|
9429
|
+
const allRepos = fetchOrgRepoCommitCounts(org, since).filter((repo) => repo.commitCount > 0).sort((a, b) => b.commitCount - a.commitCount);
|
|
9430
|
+
const repos2 = options2.top ? allRepos.slice(0, options2.top) : allRepos;
|
|
9431
|
+
const repoAuthors = repos2.map((repo) => ({
|
|
9432
|
+
name: repo.name,
|
|
9433
|
+
authors: fetchRepoCommitAuthors(org, repo.name, since)
|
|
9434
|
+
}));
|
|
9435
|
+
const report = {
|
|
9436
|
+
org,
|
|
9437
|
+
since: sinceDate,
|
|
9438
|
+
totalRepos: allRepos.length,
|
|
9439
|
+
repos: repos2,
|
|
9440
|
+
committers: aggregateCommitters(repoAuthors.map((r) => r.authors)),
|
|
9441
|
+
repoAuthors
|
|
9442
|
+
};
|
|
9443
|
+
if (options2.json) {
|
|
9444
|
+
console.log(JSON.stringify(report, null, 2));
|
|
9445
|
+
} else if (repos2.length === 0) {
|
|
9446
|
+
console.log(`No commits found in ${org} since ${sinceDate}.`);
|
|
9447
|
+
} else {
|
|
9448
|
+
printCommitsReport(report);
|
|
9449
|
+
}
|
|
9450
|
+
}
|
|
9451
|
+
|
|
9452
|
+
// src/commands/github/parseSinceDate.ts
|
|
9453
|
+
import { InvalidArgumentError } from "commander";
|
|
9454
|
+
function parseSinceDate(value) {
|
|
9455
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) {
|
|
9456
|
+
throw new InvalidArgumentError("Expected a date in YYYY-MM-DD format.");
|
|
9457
|
+
}
|
|
9458
|
+
const date = /* @__PURE__ */ new Date(`${value}T00:00:00Z`);
|
|
9459
|
+
if (Number.isNaN(date.getTime()) || date.toISOString().slice(0, 10) !== value) {
|
|
9460
|
+
throw new InvalidArgumentError(`Not a valid calendar date: ${value}.`);
|
|
9461
|
+
}
|
|
9462
|
+
return value;
|
|
9463
|
+
}
|
|
9464
|
+
|
|
9465
|
+
// src/commands/github/parseTopCount.ts
|
|
9466
|
+
import { InvalidArgumentError as InvalidArgumentError2 } from "commander";
|
|
9467
|
+
function parseTopCount(value) {
|
|
9468
|
+
if (!/^\d+$/.test(value) || Number.parseInt(value, 10) < 1) {
|
|
9469
|
+
throw new InvalidArgumentError2("Expected a positive integer.");
|
|
9470
|
+
}
|
|
9471
|
+
return Number.parseInt(value, 10);
|
|
9472
|
+
}
|
|
9473
|
+
|
|
9474
|
+
// src/commands/registerGithub.ts
|
|
9475
|
+
function registerGithub(program2) {
|
|
9476
|
+
const githubCommand = program2.command("github").description("GitHub organisation utilities");
|
|
9477
|
+
githubCommand.command("commits <org>").description("Report commit activity across an organisation").option(
|
|
9478
|
+
"--since <date>",
|
|
9479
|
+
"start of the window as YYYY-MM-DD (default: 30 days ago)",
|
|
9480
|
+
parseSinceDate
|
|
9481
|
+
).option(
|
|
9482
|
+
"--top <n>",
|
|
9483
|
+
"only report the top <n> repos by commit count",
|
|
9484
|
+
parseTopCount
|
|
9485
|
+
).option("--json", "Output as JSON").action(commits);
|
|
9486
|
+
}
|
|
9487
|
+
|
|
9234
9488
|
// src/commands/handover/archive.ts
|
|
9235
9489
|
import { existsSync as existsSync30, mkdirSync as mkdirSync6, renameSync as renameSync2 } from "fs";
|
|
9236
|
-
import { join as
|
|
9490
|
+
import { join as join29 } from "path";
|
|
9237
9491
|
|
|
9238
9492
|
// src/commands/handover/formatArchiveTimestamp.ts
|
|
9239
9493
|
function formatArchiveTimestamp(date = /* @__PURE__ */ new Date()) {
|
|
@@ -9248,9 +9502,9 @@ function formatArchiveTimestamp(date = /* @__PURE__ */ new Date()) {
|
|
|
9248
9502
|
}
|
|
9249
9503
|
|
|
9250
9504
|
// src/commands/handover/getHandoverArchiveDir.ts
|
|
9251
|
-
import { join as
|
|
9505
|
+
import { join as join28 } from "path";
|
|
9252
9506
|
function getHandoverArchiveDir(cwd = process.cwd()) {
|
|
9253
|
-
return
|
|
9507
|
+
return join28(cwd, ".assist", "handovers", "archive");
|
|
9254
9508
|
}
|
|
9255
9509
|
|
|
9256
9510
|
// src/commands/handover/archive.ts
|
|
@@ -9260,11 +9514,11 @@ function buildArchiveFilename(timestamp, suffix) {
|
|
|
9260
9514
|
return `${base}.md`;
|
|
9261
9515
|
}
|
|
9262
9516
|
function resolveCollisionPath(archiveDir, timestamp, suffix) {
|
|
9263
|
-
const initial =
|
|
9517
|
+
const initial = join29(archiveDir, buildArchiveFilename(timestamp, suffix));
|
|
9264
9518
|
if (!existsSync30(initial)) return initial;
|
|
9265
9519
|
for (let i = 1; i <= MAX_COLLISION_SUFFIX; i++) {
|
|
9266
9520
|
const collisionSuffix = suffix ? `${suffix}-${i}` : `${i}`;
|
|
9267
|
-
const candidate =
|
|
9521
|
+
const candidate = join29(
|
|
9268
9522
|
archiveDir,
|
|
9269
9523
|
buildArchiveFilename(timestamp, collisionSuffix)
|
|
9270
9524
|
);
|
|
@@ -9460,7 +9714,7 @@ function registerHandover(program2) {
|
|
|
9460
9714
|
}
|
|
9461
9715
|
|
|
9462
9716
|
// src/commands/jira/acceptanceCriteria.ts
|
|
9463
|
-
import
|
|
9717
|
+
import chalk108 from "chalk";
|
|
9464
9718
|
|
|
9465
9719
|
// src/commands/jira/adfToText.ts
|
|
9466
9720
|
function renderInline(node) {
|
|
@@ -9521,7 +9775,7 @@ function adfToText(doc) {
|
|
|
9521
9775
|
|
|
9522
9776
|
// src/commands/jira/fetchIssue.ts
|
|
9523
9777
|
import { execSync as execSync26 } from "child_process";
|
|
9524
|
-
import
|
|
9778
|
+
import chalk107 from "chalk";
|
|
9525
9779
|
function fetchIssue(issueKey, fields) {
|
|
9526
9780
|
let result;
|
|
9527
9781
|
try {
|
|
@@ -9534,15 +9788,15 @@ function fetchIssue(issueKey, fields) {
|
|
|
9534
9788
|
const stderr = error.stderr;
|
|
9535
9789
|
if (stderr.includes("unauthorized")) {
|
|
9536
9790
|
console.error(
|
|
9537
|
-
|
|
9791
|
+
chalk107.red("Jira authentication expired."),
|
|
9538
9792
|
"Run",
|
|
9539
|
-
|
|
9793
|
+
chalk107.cyan("assist jira auth"),
|
|
9540
9794
|
"to re-authenticate."
|
|
9541
9795
|
);
|
|
9542
9796
|
process.exit(1);
|
|
9543
9797
|
}
|
|
9544
9798
|
}
|
|
9545
|
-
console.error(
|
|
9799
|
+
console.error(chalk107.red(`Failed to fetch ${issueKey}.`));
|
|
9546
9800
|
process.exit(1);
|
|
9547
9801
|
}
|
|
9548
9802
|
return JSON.parse(result);
|
|
@@ -9556,7 +9810,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
9556
9810
|
const parsed = fetchIssue(issueKey, field);
|
|
9557
9811
|
const acValue = parsed?.fields?.[field];
|
|
9558
9812
|
if (!acValue) {
|
|
9559
|
-
console.log(
|
|
9813
|
+
console.log(chalk108.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
9560
9814
|
return;
|
|
9561
9815
|
}
|
|
9562
9816
|
if (typeof acValue === "string") {
|
|
@@ -9574,14 +9828,14 @@ function acceptanceCriteria(issueKey) {
|
|
|
9574
9828
|
import { execSync as execSync27 } from "child_process";
|
|
9575
9829
|
|
|
9576
9830
|
// src/shared/loadJson.ts
|
|
9577
|
-
import { existsSync as existsSync32, mkdirSync as mkdirSync7, readFileSync as readFileSync26, writeFileSync as
|
|
9831
|
+
import { existsSync as existsSync32, mkdirSync as mkdirSync7, readFileSync as readFileSync26, writeFileSync as writeFileSync19 } from "fs";
|
|
9578
9832
|
import { homedir as homedir8 } from "os";
|
|
9579
|
-
import { join as
|
|
9833
|
+
import { join as join30 } from "path";
|
|
9580
9834
|
function getStoreDir() {
|
|
9581
|
-
return
|
|
9835
|
+
return join30(homedir8(), ".assist");
|
|
9582
9836
|
}
|
|
9583
9837
|
function getStorePath(filename) {
|
|
9584
|
-
return
|
|
9838
|
+
return join30(getStoreDir(), filename);
|
|
9585
9839
|
}
|
|
9586
9840
|
function loadJson(filename) {
|
|
9587
9841
|
const path52 = getStorePath(filename);
|
|
@@ -9599,7 +9853,7 @@ function saveJson(filename, data) {
|
|
|
9599
9853
|
if (!existsSync32(dir)) {
|
|
9600
9854
|
mkdirSync7(dir, { recursive: true });
|
|
9601
9855
|
}
|
|
9602
|
-
|
|
9856
|
+
writeFileSync19(getStorePath(filename), JSON.stringify(data, null, 2));
|
|
9603
9857
|
}
|
|
9604
9858
|
|
|
9605
9859
|
// src/shared/promptInput.ts
|
|
@@ -9651,14 +9905,14 @@ async function jiraAuth() {
|
|
|
9651
9905
|
}
|
|
9652
9906
|
|
|
9653
9907
|
// src/commands/jira/viewIssue.ts
|
|
9654
|
-
import
|
|
9908
|
+
import chalk109 from "chalk";
|
|
9655
9909
|
function viewIssue(issueKey) {
|
|
9656
9910
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
9657
9911
|
const fields = parsed?.fields;
|
|
9658
9912
|
const summary = fields?.summary;
|
|
9659
9913
|
const description = fields?.description;
|
|
9660
9914
|
if (summary) {
|
|
9661
|
-
console.log(
|
|
9915
|
+
console.log(chalk109.bold(summary));
|
|
9662
9916
|
}
|
|
9663
9917
|
if (description) {
|
|
9664
9918
|
if (summary) console.log();
|
|
@@ -9672,7 +9926,7 @@ function viewIssue(issueKey) {
|
|
|
9672
9926
|
}
|
|
9673
9927
|
if (!summary && !description) {
|
|
9674
9928
|
console.log(
|
|
9675
|
-
|
|
9929
|
+
chalk109.yellow(`No summary or description found on ${issueKey}.`)
|
|
9676
9930
|
);
|
|
9677
9931
|
}
|
|
9678
9932
|
}
|
|
@@ -9687,13 +9941,13 @@ function registerJira(program2) {
|
|
|
9687
9941
|
|
|
9688
9942
|
// src/commands/reviewComments.ts
|
|
9689
9943
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
9690
|
-
import
|
|
9944
|
+
import chalk110 from "chalk";
|
|
9691
9945
|
async function reviewComments(number) {
|
|
9692
9946
|
if (number) {
|
|
9693
9947
|
try {
|
|
9694
9948
|
execFileSync5("gh", ["pr", "checkout", number], { stdio: "inherit" });
|
|
9695
9949
|
} catch {
|
|
9696
|
-
console.error(
|
|
9950
|
+
console.error(chalk110.red(`gh pr checkout ${number} failed; aborting.`));
|
|
9697
9951
|
process.exit(1);
|
|
9698
9952
|
}
|
|
9699
9953
|
}
|
|
@@ -9726,15 +9980,15 @@ function registerList(program2) {
|
|
|
9726
9980
|
// src/commands/mermaid/index.ts
|
|
9727
9981
|
import { mkdirSync as mkdirSync8, readdirSync as readdirSync5 } from "fs";
|
|
9728
9982
|
import { resolve as resolve10 } from "path";
|
|
9729
|
-
import
|
|
9983
|
+
import chalk113 from "chalk";
|
|
9730
9984
|
|
|
9731
9985
|
// src/commands/mermaid/exportFile.ts
|
|
9732
|
-
import { readFileSync as readFileSync27, writeFileSync as
|
|
9986
|
+
import { readFileSync as readFileSync27, writeFileSync as writeFileSync20 } from "fs";
|
|
9733
9987
|
import { basename as basename7, extname, resolve as resolve9 } from "path";
|
|
9734
|
-
import
|
|
9988
|
+
import chalk112 from "chalk";
|
|
9735
9989
|
|
|
9736
9990
|
// src/commands/mermaid/renderBlock.ts
|
|
9737
|
-
import
|
|
9991
|
+
import chalk111 from "chalk";
|
|
9738
9992
|
async function renderBlock(krokiUrl, source) {
|
|
9739
9993
|
const response = await fetch(`${krokiUrl}/mermaid/svg`, {
|
|
9740
9994
|
method: "POST",
|
|
@@ -9743,7 +9997,7 @@ async function renderBlock(krokiUrl, source) {
|
|
|
9743
9997
|
});
|
|
9744
9998
|
if (!response.ok) {
|
|
9745
9999
|
console.error(
|
|
9746
|
-
|
|
10000
|
+
chalk111.red(
|
|
9747
10001
|
`Kroki request failed: ${response.status} ${response.statusText}`
|
|
9748
10002
|
)
|
|
9749
10003
|
);
|
|
@@ -9761,27 +10015,27 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
9761
10015
|
if (onlyIndex !== void 0) {
|
|
9762
10016
|
if (onlyIndex < 1 || onlyIndex > blocks.length) {
|
|
9763
10017
|
console.error(
|
|
9764
|
-
|
|
10018
|
+
chalk112.red(
|
|
9765
10019
|
`${file}: --index ${onlyIndex} out of range (file has ${blocks.length} diagram(s))`
|
|
9766
10020
|
)
|
|
9767
10021
|
);
|
|
9768
10022
|
process.exit(1);
|
|
9769
10023
|
}
|
|
9770
10024
|
console.log(
|
|
9771
|
-
|
|
10025
|
+
chalk112.gray(
|
|
9772
10026
|
`${file} \u2014 rendering diagram ${onlyIndex} of ${blocks.length}`
|
|
9773
10027
|
)
|
|
9774
10028
|
);
|
|
9775
10029
|
} else {
|
|
9776
|
-
console.log(
|
|
10030
|
+
console.log(chalk112.gray(`${file} \u2014 ${blocks.length} diagram(s)`));
|
|
9777
10031
|
}
|
|
9778
10032
|
for (const [i, source] of blocks.entries()) {
|
|
9779
10033
|
const idx = i + 1;
|
|
9780
10034
|
if (onlyIndex !== void 0 && idx !== onlyIndex) continue;
|
|
9781
10035
|
const outPath = resolve9(outDir, `${stem}-${idx}.svg`);
|
|
9782
10036
|
const svg = await renderBlock(krokiUrl, source);
|
|
9783
|
-
|
|
9784
|
-
console.log(
|
|
10037
|
+
writeFileSync20(outPath, svg, "utf8");
|
|
10038
|
+
console.log(chalk112.green(` \u2192 ${outPath}`));
|
|
9785
10039
|
}
|
|
9786
10040
|
}
|
|
9787
10041
|
function extractMermaidBlocks(markdown) {
|
|
@@ -9797,18 +10051,18 @@ async function mermaidExport(file, options2 = {}) {
|
|
|
9797
10051
|
if (options2.index !== void 0) {
|
|
9798
10052
|
if (!Number.isInteger(options2.index) || options2.index < 1) {
|
|
9799
10053
|
console.error(
|
|
9800
|
-
|
|
10054
|
+
chalk113.red(`--index must be a positive integer (got ${options2.index})`)
|
|
9801
10055
|
);
|
|
9802
10056
|
process.exit(1);
|
|
9803
10057
|
}
|
|
9804
10058
|
if (!file) {
|
|
9805
|
-
console.error(
|
|
10059
|
+
console.error(chalk113.red("--index requires a file argument"));
|
|
9806
10060
|
process.exit(1);
|
|
9807
10061
|
}
|
|
9808
10062
|
}
|
|
9809
10063
|
const files = file ? [file] : readdirSync5(process.cwd()).filter((name) => name.toLowerCase().endsWith(".md")).sort();
|
|
9810
10064
|
if (files.length === 0) {
|
|
9811
|
-
console.log(
|
|
10065
|
+
console.log(chalk113.gray("No markdown files found in current directory."));
|
|
9812
10066
|
return;
|
|
9813
10067
|
}
|
|
9814
10068
|
for (const f of files) {
|
|
@@ -9831,7 +10085,7 @@ function registerMermaid(program2) {
|
|
|
9831
10085
|
}
|
|
9832
10086
|
|
|
9833
10087
|
// src/commands/news/add/index.ts
|
|
9834
|
-
import
|
|
10088
|
+
import chalk114 from "chalk";
|
|
9835
10089
|
import enquirer8 from "enquirer";
|
|
9836
10090
|
async function add2(url) {
|
|
9837
10091
|
if (!url) {
|
|
@@ -9854,17 +10108,17 @@ async function add2(url) {
|
|
|
9854
10108
|
const news = config.news ?? {};
|
|
9855
10109
|
const feeds = news.feeds ?? [];
|
|
9856
10110
|
if (feeds.includes(url)) {
|
|
9857
|
-
console.log(
|
|
10111
|
+
console.log(chalk114.yellow("Feed already exists in config"));
|
|
9858
10112
|
return;
|
|
9859
10113
|
}
|
|
9860
10114
|
feeds.push(url);
|
|
9861
10115
|
config.news = { ...news, feeds };
|
|
9862
10116
|
saveGlobalConfig(config);
|
|
9863
|
-
console.log(
|
|
10117
|
+
console.log(chalk114.green(`Added feed: ${url}`));
|
|
9864
10118
|
}
|
|
9865
10119
|
|
|
9866
10120
|
// src/commands/news/web/handleRequest.ts
|
|
9867
|
-
import
|
|
10121
|
+
import chalk115 from "chalk";
|
|
9868
10122
|
|
|
9869
10123
|
// src/commands/news/web/shared.ts
|
|
9870
10124
|
import { decodeHTML } from "entities";
|
|
@@ -10000,17 +10254,17 @@ function prefetch() {
|
|
|
10000
10254
|
const config = loadConfig();
|
|
10001
10255
|
const total = config.news.feeds.length;
|
|
10002
10256
|
if (total === 0) return;
|
|
10003
|
-
process.stdout.write(
|
|
10257
|
+
process.stdout.write(chalk115.dim(`Fetching ${total} feed(s)\u2026 `));
|
|
10004
10258
|
prefetchPromise = fetchFeeds(config.news.feeds, (done2, t) => {
|
|
10005
10259
|
const width = 20;
|
|
10006
10260
|
const filled = Math.round(done2 / t * width);
|
|
10007
10261
|
const bar = `${"\u2588".repeat(filled)}${"\u2591".repeat(width - filled)}`;
|
|
10008
10262
|
process.stdout.write(
|
|
10009
|
-
`\r${
|
|
10263
|
+
`\r${chalk115.dim(`Fetching feeds ${bar} ${done2}/${t}`)}`
|
|
10010
10264
|
);
|
|
10011
10265
|
}).then((items2) => {
|
|
10012
10266
|
process.stdout.write(
|
|
10013
|
-
`\r${
|
|
10267
|
+
`\r${chalk115.green(`Fetched ${items2.length} items from ${total} feed(s)`)}
|
|
10014
10268
|
`
|
|
10015
10269
|
);
|
|
10016
10270
|
cachedItems = items2;
|
|
@@ -10055,7 +10309,7 @@ function registerNews(program2) {
|
|
|
10055
10309
|
}
|
|
10056
10310
|
|
|
10057
10311
|
// src/commands/prompts/printPromptsTable.ts
|
|
10058
|
-
import
|
|
10312
|
+
import chalk116 from "chalk";
|
|
10059
10313
|
function truncate(str, max) {
|
|
10060
10314
|
if (str.length <= max) return str;
|
|
10061
10315
|
return `${str.slice(0, max - 1)}\u2026`;
|
|
@@ -10073,14 +10327,14 @@ function printPromptsTable(rows) {
|
|
|
10073
10327
|
"Command".padEnd(commandWidth),
|
|
10074
10328
|
"Repos"
|
|
10075
10329
|
].join(" ");
|
|
10076
|
-
console.log(
|
|
10077
|
-
console.log(
|
|
10330
|
+
console.log(chalk116.dim(header));
|
|
10331
|
+
console.log(chalk116.dim("-".repeat(header.length)));
|
|
10078
10332
|
for (const row of rows) {
|
|
10079
10333
|
const count6 = String(row.count).padStart(countWidth);
|
|
10080
10334
|
const tool = row.tool.padEnd(toolWidth);
|
|
10081
10335
|
const command = truncate(row.command, 60).padEnd(commandWidth);
|
|
10082
10336
|
console.log(
|
|
10083
|
-
`${
|
|
10337
|
+
`${chalk116.yellow(count6)} ${tool} ${command} ${chalk116.dim(row.repos)}`
|
|
10084
10338
|
);
|
|
10085
10339
|
}
|
|
10086
10340
|
}
|
|
@@ -10108,33 +10362,6 @@ function registerPrompts(program2) {
|
|
|
10108
10362
|
program2.command("prompts").description("Show top denied tool calls by frequency").action(prompts2);
|
|
10109
10363
|
}
|
|
10110
10364
|
|
|
10111
|
-
// src/commands/prs/runGhGraphql.ts
|
|
10112
|
-
import { spawnSync as spawnSync2 } from "child_process";
|
|
10113
|
-
import { unlinkSync as unlinkSync6, writeFileSync as writeFileSync20 } from "fs";
|
|
10114
|
-
import { tmpdir as tmpdir4 } from "os";
|
|
10115
|
-
import { join as join30 } from "path";
|
|
10116
|
-
function buildArgs2(queryFile, vars) {
|
|
10117
|
-
const args = ["api", "graphql", "-F", `query=@${queryFile}`];
|
|
10118
|
-
for (const [key, value] of Object.entries(vars)) {
|
|
10119
|
-
const flag = typeof value === "number" ? "-F" : "-f";
|
|
10120
|
-
args.push(flag, `${key}=${value}`);
|
|
10121
|
-
}
|
|
10122
|
-
return args;
|
|
10123
|
-
}
|
|
10124
|
-
function runGhGraphql(mutation, vars) {
|
|
10125
|
-
const queryFile = join30(tmpdir4(), `gh-query-${Date.now()}.graphql`);
|
|
10126
|
-
writeFileSync20(queryFile, mutation);
|
|
10127
|
-
try {
|
|
10128
|
-
const result = spawnSync2("gh", buildArgs2(queryFile, vars), {
|
|
10129
|
-
encoding: "utf-8"
|
|
10130
|
-
});
|
|
10131
|
-
if (result.status !== 0) throw new Error(result.stderr || result.stdout);
|
|
10132
|
-
return result.stdout;
|
|
10133
|
-
} finally {
|
|
10134
|
-
unlinkSync6(queryFile);
|
|
10135
|
-
}
|
|
10136
|
-
}
|
|
10137
|
-
|
|
10138
10365
|
// src/commands/prs/shared.ts
|
|
10139
10366
|
import { execSync as execSync29 } from "child_process";
|
|
10140
10367
|
|
|
@@ -10574,20 +10801,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
10574
10801
|
}
|
|
10575
10802
|
|
|
10576
10803
|
// src/commands/prs/listComments/printComments.ts
|
|
10577
|
-
import
|
|
10804
|
+
import chalk117 from "chalk";
|
|
10578
10805
|
function formatForHuman(comment3) {
|
|
10579
10806
|
if (comment3.type === "review") {
|
|
10580
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
10807
|
+
const stateColor = comment3.state === "APPROVED" ? chalk117.green : comment3.state === "CHANGES_REQUESTED" ? chalk117.red : chalk117.yellow;
|
|
10581
10808
|
return [
|
|
10582
|
-
`${
|
|
10809
|
+
`${chalk117.cyan("Review")} by ${chalk117.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
10583
10810
|
comment3.body,
|
|
10584
10811
|
""
|
|
10585
10812
|
].join("\n");
|
|
10586
10813
|
}
|
|
10587
10814
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
10588
10815
|
return [
|
|
10589
|
-
`${
|
|
10590
|
-
|
|
10816
|
+
`${chalk117.cyan("Line comment")} by ${chalk117.bold(comment3.user)} on ${chalk117.dim(`${comment3.path}${location}`)}`,
|
|
10817
|
+
chalk117.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
10591
10818
|
comment3.body,
|
|
10592
10819
|
""
|
|
10593
10820
|
].join("\n");
|
|
@@ -10677,13 +10904,13 @@ import { execSync as execSync35 } from "child_process";
|
|
|
10677
10904
|
import enquirer9 from "enquirer";
|
|
10678
10905
|
|
|
10679
10906
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
10680
|
-
import
|
|
10907
|
+
import chalk118 from "chalk";
|
|
10681
10908
|
var STATUS_MAP = {
|
|
10682
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
10683
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
10909
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk118.magenta("merged"), date: pr.mergedAt } : null,
|
|
10910
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk118.red("closed"), date: pr.closedAt } : null
|
|
10684
10911
|
};
|
|
10685
10912
|
function defaultStatus(pr) {
|
|
10686
|
-
return { label:
|
|
10913
|
+
return { label: chalk118.green("opened"), date: pr.createdAt };
|
|
10687
10914
|
}
|
|
10688
10915
|
function getStatus2(pr) {
|
|
10689
10916
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -10692,11 +10919,11 @@ function formatDate(dateStr) {
|
|
|
10692
10919
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
10693
10920
|
}
|
|
10694
10921
|
function formatPrHeader(pr, status2) {
|
|
10695
|
-
return `${
|
|
10922
|
+
return `${chalk118.cyan(`#${pr.number}`)} ${pr.title} ${chalk118.dim(`(${pr.author.login},`)} ${status2.label} ${chalk118.dim(`${formatDate(status2.date)})`)}`;
|
|
10696
10923
|
}
|
|
10697
10924
|
function logPrDetails(pr) {
|
|
10698
10925
|
console.log(
|
|
10699
|
-
|
|
10926
|
+
chalk118.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
10700
10927
|
);
|
|
10701
10928
|
console.log();
|
|
10702
10929
|
}
|
|
@@ -10884,10 +11111,10 @@ function registerPrs(program2) {
|
|
|
10884
11111
|
}
|
|
10885
11112
|
|
|
10886
11113
|
// src/commands/ravendb/ravendbAuth.ts
|
|
10887
|
-
import
|
|
11114
|
+
import chalk124 from "chalk";
|
|
10888
11115
|
|
|
10889
11116
|
// src/shared/createConnectionAuth.ts
|
|
10890
|
-
import
|
|
11117
|
+
import chalk119 from "chalk";
|
|
10891
11118
|
function listConnections(connections, format2) {
|
|
10892
11119
|
if (connections.length === 0) {
|
|
10893
11120
|
console.log("No connections configured.");
|
|
@@ -10900,7 +11127,7 @@ function listConnections(connections, format2) {
|
|
|
10900
11127
|
function removeConnection(connections, name, save) {
|
|
10901
11128
|
const filtered = connections.filter((c) => c.name !== name);
|
|
10902
11129
|
if (filtered.length === connections.length) {
|
|
10903
|
-
console.error(
|
|
11130
|
+
console.error(chalk119.red(`Connection "${name}" not found.`));
|
|
10904
11131
|
process.exit(1);
|
|
10905
11132
|
}
|
|
10906
11133
|
save(filtered);
|
|
@@ -10946,15 +11173,15 @@ function saveConnections(connections) {
|
|
|
10946
11173
|
}
|
|
10947
11174
|
|
|
10948
11175
|
// src/commands/ravendb/promptConnection.ts
|
|
10949
|
-
import
|
|
11176
|
+
import chalk122 from "chalk";
|
|
10950
11177
|
|
|
10951
11178
|
// src/commands/ravendb/selectOpSecret.ts
|
|
10952
|
-
import
|
|
11179
|
+
import chalk121 from "chalk";
|
|
10953
11180
|
import Enquirer2 from "enquirer";
|
|
10954
11181
|
|
|
10955
11182
|
// src/commands/ravendb/searchItems.ts
|
|
10956
11183
|
import { execSync as execSync37 } from "child_process";
|
|
10957
|
-
import
|
|
11184
|
+
import chalk120 from "chalk";
|
|
10958
11185
|
function opExec(args) {
|
|
10959
11186
|
return execSync37(`op ${args}`, {
|
|
10960
11187
|
encoding: "utf-8",
|
|
@@ -10967,7 +11194,7 @@ function searchItems(search2) {
|
|
|
10967
11194
|
items2 = JSON.parse(opExec("item list --format=json"));
|
|
10968
11195
|
} catch {
|
|
10969
11196
|
console.error(
|
|
10970
|
-
|
|
11197
|
+
chalk120.red(
|
|
10971
11198
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
10972
11199
|
)
|
|
10973
11200
|
);
|
|
@@ -10981,7 +11208,7 @@ function getItemFields(itemId) {
|
|
|
10981
11208
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
10982
11209
|
return item.fields.filter((f) => f.reference && f.label);
|
|
10983
11210
|
} catch {
|
|
10984
|
-
console.error(
|
|
11211
|
+
console.error(chalk120.red("Failed to get item details from 1Password."));
|
|
10985
11212
|
process.exit(1);
|
|
10986
11213
|
}
|
|
10987
11214
|
}
|
|
@@ -11000,7 +11227,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
11000
11227
|
}).run();
|
|
11001
11228
|
const items2 = searchItems(search2);
|
|
11002
11229
|
if (items2.length === 0) {
|
|
11003
|
-
console.error(
|
|
11230
|
+
console.error(chalk121.red(`No items found matching "${search2}".`));
|
|
11004
11231
|
process.exit(1);
|
|
11005
11232
|
}
|
|
11006
11233
|
const itemId = await selectOne(
|
|
@@ -11009,7 +11236,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
11009
11236
|
);
|
|
11010
11237
|
const fields = getItemFields(itemId);
|
|
11011
11238
|
if (fields.length === 0) {
|
|
11012
|
-
console.error(
|
|
11239
|
+
console.error(chalk121.red("No fields with references found on this item."));
|
|
11013
11240
|
process.exit(1);
|
|
11014
11241
|
}
|
|
11015
11242
|
const ref = await selectOne(
|
|
@@ -11023,7 +11250,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
11023
11250
|
async function promptConnection(existingNames) {
|
|
11024
11251
|
const name = await promptInput("name", "Connection name:");
|
|
11025
11252
|
if (existingNames.includes(name)) {
|
|
11026
|
-
console.error(
|
|
11253
|
+
console.error(chalk122.red(`Connection "${name}" already exists.`));
|
|
11027
11254
|
process.exit(1);
|
|
11028
11255
|
}
|
|
11029
11256
|
const url = await promptInput(
|
|
@@ -11032,22 +11259,22 @@ async function promptConnection(existingNames) {
|
|
|
11032
11259
|
);
|
|
11033
11260
|
const database = await promptInput("database", "Database name:");
|
|
11034
11261
|
if (!name || !url || !database) {
|
|
11035
|
-
console.error(
|
|
11262
|
+
console.error(chalk122.red("All fields are required."));
|
|
11036
11263
|
process.exit(1);
|
|
11037
11264
|
}
|
|
11038
11265
|
const apiKeyRef = await selectOpSecret();
|
|
11039
|
-
console.log(
|
|
11266
|
+
console.log(chalk122.dim(`Using: ${apiKeyRef}`));
|
|
11040
11267
|
return { name, url, database, apiKeyRef };
|
|
11041
11268
|
}
|
|
11042
11269
|
|
|
11043
11270
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
11044
|
-
import
|
|
11271
|
+
import chalk123 from "chalk";
|
|
11045
11272
|
function ravendbSetConnection(name) {
|
|
11046
11273
|
const raw = loadGlobalConfigRaw();
|
|
11047
11274
|
const ravendb = raw.ravendb ?? {};
|
|
11048
11275
|
const connections = ravendb.connections ?? [];
|
|
11049
11276
|
if (!connections.some((c) => c.name === name)) {
|
|
11050
|
-
console.error(
|
|
11277
|
+
console.error(chalk123.red(`Connection "${name}" not found.`));
|
|
11051
11278
|
console.error(
|
|
11052
11279
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
11053
11280
|
);
|
|
@@ -11063,16 +11290,16 @@ function ravendbSetConnection(name) {
|
|
|
11063
11290
|
var ravendbAuth = createConnectionAuth({
|
|
11064
11291
|
load: loadConnections,
|
|
11065
11292
|
save: saveConnections,
|
|
11066
|
-
format: (c) => `${
|
|
11293
|
+
format: (c) => `${chalk124.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
11067
11294
|
promptNew: promptConnection,
|
|
11068
11295
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
11069
11296
|
});
|
|
11070
11297
|
|
|
11071
11298
|
// src/commands/ravendb/ravendbCollections.ts
|
|
11072
|
-
import
|
|
11299
|
+
import chalk128 from "chalk";
|
|
11073
11300
|
|
|
11074
11301
|
// src/commands/ravendb/ravenFetch.ts
|
|
11075
|
-
import
|
|
11302
|
+
import chalk126 from "chalk";
|
|
11076
11303
|
|
|
11077
11304
|
// src/commands/ravendb/getAccessToken.ts
|
|
11078
11305
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -11109,10 +11336,10 @@ ${errorText}`
|
|
|
11109
11336
|
|
|
11110
11337
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
11111
11338
|
import { execSync as execSync38 } from "child_process";
|
|
11112
|
-
import
|
|
11339
|
+
import chalk125 from "chalk";
|
|
11113
11340
|
function resolveOpSecret(reference) {
|
|
11114
11341
|
if (!reference.startsWith("op://")) {
|
|
11115
|
-
console.error(
|
|
11342
|
+
console.error(chalk125.red(`Invalid secret reference: must start with op://`));
|
|
11116
11343
|
process.exit(1);
|
|
11117
11344
|
}
|
|
11118
11345
|
try {
|
|
@@ -11122,7 +11349,7 @@ function resolveOpSecret(reference) {
|
|
|
11122
11349
|
}).trim();
|
|
11123
11350
|
} catch {
|
|
11124
11351
|
console.error(
|
|
11125
|
-
|
|
11352
|
+
chalk125.red(
|
|
11126
11353
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
11127
11354
|
)
|
|
11128
11355
|
);
|
|
@@ -11149,7 +11376,7 @@ async function ravenFetch(connection, path52) {
|
|
|
11149
11376
|
if (!response.ok) {
|
|
11150
11377
|
const body = await response.text();
|
|
11151
11378
|
console.error(
|
|
11152
|
-
|
|
11379
|
+
chalk126.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
11153
11380
|
);
|
|
11154
11381
|
console.error(body.substring(0, 500));
|
|
11155
11382
|
process.exit(1);
|
|
@@ -11158,7 +11385,7 @@ async function ravenFetch(connection, path52) {
|
|
|
11158
11385
|
}
|
|
11159
11386
|
|
|
11160
11387
|
// src/commands/ravendb/resolveConnection.ts
|
|
11161
|
-
import
|
|
11388
|
+
import chalk127 from "chalk";
|
|
11162
11389
|
function loadRavendb() {
|
|
11163
11390
|
const raw = loadGlobalConfigRaw();
|
|
11164
11391
|
const ravendb = raw.ravendb;
|
|
@@ -11172,7 +11399,7 @@ function resolveConnection(name) {
|
|
|
11172
11399
|
const connectionName = name ?? defaultConnection;
|
|
11173
11400
|
if (!connectionName) {
|
|
11174
11401
|
console.error(
|
|
11175
|
-
|
|
11402
|
+
chalk127.red(
|
|
11176
11403
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
11177
11404
|
)
|
|
11178
11405
|
);
|
|
@@ -11180,7 +11407,7 @@ function resolveConnection(name) {
|
|
|
11180
11407
|
}
|
|
11181
11408
|
const connection = connections.find((c) => c.name === connectionName);
|
|
11182
11409
|
if (!connection) {
|
|
11183
|
-
console.error(
|
|
11410
|
+
console.error(chalk127.red(`Connection "${connectionName}" not found.`));
|
|
11184
11411
|
console.error(
|
|
11185
11412
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
11186
11413
|
);
|
|
@@ -11211,15 +11438,15 @@ async function ravendbCollections(connectionName) {
|
|
|
11211
11438
|
return;
|
|
11212
11439
|
}
|
|
11213
11440
|
for (const c of collections) {
|
|
11214
|
-
console.log(`${
|
|
11441
|
+
console.log(`${chalk128.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
11215
11442
|
}
|
|
11216
11443
|
}
|
|
11217
11444
|
|
|
11218
11445
|
// src/commands/ravendb/ravendbQuery.ts
|
|
11219
|
-
import
|
|
11446
|
+
import chalk130 from "chalk";
|
|
11220
11447
|
|
|
11221
11448
|
// src/commands/ravendb/fetchAllPages.ts
|
|
11222
|
-
import
|
|
11449
|
+
import chalk129 from "chalk";
|
|
11223
11450
|
|
|
11224
11451
|
// src/commands/ravendb/buildQueryPath.ts
|
|
11225
11452
|
function buildQueryPath(opts) {
|
|
@@ -11257,7 +11484,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
11257
11484
|
allResults.push(...results);
|
|
11258
11485
|
start3 += results.length;
|
|
11259
11486
|
process.stderr.write(
|
|
11260
|
-
`\r${
|
|
11487
|
+
`\r${chalk129.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
11261
11488
|
);
|
|
11262
11489
|
if (start3 >= totalResults) break;
|
|
11263
11490
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -11272,7 +11499,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
11272
11499
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
11273
11500
|
const resolved = resolveArgs(connectionName, collection);
|
|
11274
11501
|
if (!resolved.collection && !options2.query) {
|
|
11275
|
-
console.error(
|
|
11502
|
+
console.error(chalk130.red("Provide a collection name or --query filter."));
|
|
11276
11503
|
process.exit(1);
|
|
11277
11504
|
}
|
|
11278
11505
|
const { collection: col } = resolved;
|
|
@@ -11310,7 +11537,7 @@ import { spawn as spawn5 } from "child_process";
|
|
|
11310
11537
|
import * as path29 from "path";
|
|
11311
11538
|
|
|
11312
11539
|
// src/commands/refactor/logViolations.ts
|
|
11313
|
-
import
|
|
11540
|
+
import chalk131 from "chalk";
|
|
11314
11541
|
var DEFAULT_MAX_LINES = 100;
|
|
11315
11542
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
11316
11543
|
if (violations.length === 0) {
|
|
@@ -11319,43 +11546,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
11319
11546
|
}
|
|
11320
11547
|
return;
|
|
11321
11548
|
}
|
|
11322
|
-
console.error(
|
|
11549
|
+
console.error(chalk131.red(`
|
|
11323
11550
|
Refactor check failed:
|
|
11324
11551
|
`));
|
|
11325
|
-
console.error(
|
|
11552
|
+
console.error(chalk131.red(` The following files exceed ${maxLines} lines:
|
|
11326
11553
|
`));
|
|
11327
11554
|
for (const violation of violations) {
|
|
11328
|
-
console.error(
|
|
11555
|
+
console.error(chalk131.red(` ${violation.file} (${violation.lines} lines)`));
|
|
11329
11556
|
}
|
|
11330
11557
|
console.error(
|
|
11331
|
-
|
|
11558
|
+
chalk131.yellow(
|
|
11332
11559
|
`
|
|
11333
11560
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
11334
11561
|
way to refactor it, ignore it with:
|
|
11335
11562
|
`
|
|
11336
11563
|
)
|
|
11337
11564
|
);
|
|
11338
|
-
console.error(
|
|
11565
|
+
console.error(chalk131.gray(` assist refactor ignore <file>
|
|
11339
11566
|
`));
|
|
11340
11567
|
if (process.env.CLAUDECODE) {
|
|
11341
|
-
console.error(
|
|
11568
|
+
console.error(chalk131.cyan(`
|
|
11342
11569
|
## Extracting Code to New Files
|
|
11343
11570
|
`));
|
|
11344
11571
|
console.error(
|
|
11345
|
-
|
|
11572
|
+
chalk131.cyan(
|
|
11346
11573
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
11347
11574
|
`
|
|
11348
11575
|
)
|
|
11349
11576
|
);
|
|
11350
11577
|
console.error(
|
|
11351
|
-
|
|
11578
|
+
chalk131.cyan(
|
|
11352
11579
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
11353
11580
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
11354
11581
|
`
|
|
11355
11582
|
)
|
|
11356
11583
|
);
|
|
11357
11584
|
console.error(
|
|
11358
|
-
|
|
11585
|
+
chalk131.cyan(
|
|
11359
11586
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
11360
11587
|
domains, move it to a common/shared folder.
|
|
11361
11588
|
`
|
|
@@ -11511,7 +11738,7 @@ async function check(pattern2, options2) {
|
|
|
11511
11738
|
|
|
11512
11739
|
// src/commands/refactor/extract/index.ts
|
|
11513
11740
|
import path36 from "path";
|
|
11514
|
-
import
|
|
11741
|
+
import chalk134 from "chalk";
|
|
11515
11742
|
|
|
11516
11743
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
11517
11744
|
import { SyntaxKind as SyntaxKind4 } from "ts-morph";
|
|
@@ -12086,23 +12313,23 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
12086
12313
|
|
|
12087
12314
|
// src/commands/refactor/extract/displayPlan.ts
|
|
12088
12315
|
import path33 from "path";
|
|
12089
|
-
import
|
|
12316
|
+
import chalk132 from "chalk";
|
|
12090
12317
|
function section(title) {
|
|
12091
12318
|
return `
|
|
12092
|
-
${
|
|
12319
|
+
${chalk132.cyan(title)}`;
|
|
12093
12320
|
}
|
|
12094
12321
|
function displayImporters(plan2, cwd) {
|
|
12095
12322
|
if (plan2.importersToUpdate.length === 0) return;
|
|
12096
12323
|
console.log(section("Update importers:"));
|
|
12097
12324
|
for (const imp of plan2.importersToUpdate) {
|
|
12098
12325
|
const rel = path33.relative(cwd, imp.file.getFilePath());
|
|
12099
|
-
console.log(` ${
|
|
12326
|
+
console.log(` ${chalk132.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
12100
12327
|
}
|
|
12101
12328
|
}
|
|
12102
12329
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
12103
|
-
console.log(
|
|
12330
|
+
console.log(chalk132.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
12104
12331
|
`));
|
|
12105
|
-
console.log(` ${
|
|
12332
|
+
console.log(` ${chalk132.cyan("Functions to move:")}`);
|
|
12106
12333
|
for (const name of plan2.extractedNames) {
|
|
12107
12334
|
console.log(` ${name}`);
|
|
12108
12335
|
}
|
|
@@ -12136,7 +12363,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
12136
12363
|
|
|
12137
12364
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
12138
12365
|
import path35 from "path";
|
|
12139
|
-
import
|
|
12366
|
+
import chalk133 from "chalk";
|
|
12140
12367
|
import { Project as Project3 } from "ts-morph";
|
|
12141
12368
|
|
|
12142
12369
|
// src/commands/refactor/extract/findTsConfig.ts
|
|
@@ -12196,7 +12423,7 @@ function loadProjectFile(file) {
|
|
|
12196
12423
|
});
|
|
12197
12424
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
12198
12425
|
if (!sourceFile) {
|
|
12199
|
-
console.log(
|
|
12426
|
+
console.log(chalk133.red(`File not found in project: ${file}`));
|
|
12200
12427
|
process.exit(1);
|
|
12201
12428
|
}
|
|
12202
12429
|
return { project, sourceFile };
|
|
@@ -12219,19 +12446,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
12219
12446
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
12220
12447
|
if (options2.apply) {
|
|
12221
12448
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
12222
|
-
console.log(
|
|
12449
|
+
console.log(chalk134.green("\nExtraction complete"));
|
|
12223
12450
|
} else {
|
|
12224
|
-
console.log(
|
|
12451
|
+
console.log(chalk134.dim("\nDry run. Use --apply to execute."));
|
|
12225
12452
|
}
|
|
12226
12453
|
}
|
|
12227
12454
|
|
|
12228
12455
|
// src/commands/refactor/ignore.ts
|
|
12229
12456
|
import fs21 from "fs";
|
|
12230
|
-
import
|
|
12457
|
+
import chalk135 from "chalk";
|
|
12231
12458
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
12232
12459
|
function ignore(file) {
|
|
12233
12460
|
if (!fs21.existsSync(file)) {
|
|
12234
|
-
console.error(
|
|
12461
|
+
console.error(chalk135.red(`Error: File does not exist: ${file}`));
|
|
12235
12462
|
process.exit(1);
|
|
12236
12463
|
}
|
|
12237
12464
|
const content = fs21.readFileSync(file, "utf-8");
|
|
@@ -12247,7 +12474,7 @@ function ignore(file) {
|
|
|
12247
12474
|
fs21.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
12248
12475
|
}
|
|
12249
12476
|
console.log(
|
|
12250
|
-
|
|
12477
|
+
chalk135.green(
|
|
12251
12478
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
12252
12479
|
)
|
|
12253
12480
|
);
|
|
@@ -12255,25 +12482,25 @@ function ignore(file) {
|
|
|
12255
12482
|
|
|
12256
12483
|
// src/commands/refactor/rename/index.ts
|
|
12257
12484
|
import path37 from "path";
|
|
12258
|
-
import
|
|
12485
|
+
import chalk136 from "chalk";
|
|
12259
12486
|
async function rename(source, destination, options2 = {}) {
|
|
12260
12487
|
const destPath = path37.resolve(destination);
|
|
12261
12488
|
const cwd = process.cwd();
|
|
12262
12489
|
const relSource = path37.relative(cwd, path37.resolve(source));
|
|
12263
12490
|
const relDest = path37.relative(cwd, destPath);
|
|
12264
12491
|
const { project, sourceFile } = loadProjectFile(source);
|
|
12265
|
-
console.log(
|
|
12492
|
+
console.log(chalk136.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
12266
12493
|
if (options2.apply) {
|
|
12267
12494
|
sourceFile.move(destPath);
|
|
12268
12495
|
await project.save();
|
|
12269
|
-
console.log(
|
|
12496
|
+
console.log(chalk136.green("Done"));
|
|
12270
12497
|
} else {
|
|
12271
|
-
console.log(
|
|
12498
|
+
console.log(chalk136.dim("Dry run. Use --apply to execute."));
|
|
12272
12499
|
}
|
|
12273
12500
|
}
|
|
12274
12501
|
|
|
12275
12502
|
// src/commands/refactor/renameSymbol/index.ts
|
|
12276
|
-
import
|
|
12503
|
+
import chalk137 from "chalk";
|
|
12277
12504
|
|
|
12278
12505
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
12279
12506
|
import { SyntaxKind as SyntaxKind14 } from "ts-morph";
|
|
@@ -12319,33 +12546,33 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
12319
12546
|
const { project, sourceFile } = loadProjectFile(file);
|
|
12320
12547
|
const symbol = findSymbol(sourceFile, oldName);
|
|
12321
12548
|
if (!symbol) {
|
|
12322
|
-
console.log(
|
|
12549
|
+
console.log(chalk137.red(`Symbol "${oldName}" not found in ${file}`));
|
|
12323
12550
|
process.exit(1);
|
|
12324
12551
|
}
|
|
12325
12552
|
const grouped = groupReferences(symbol, cwd);
|
|
12326
12553
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
12327
12554
|
console.log(
|
|
12328
|
-
|
|
12555
|
+
chalk137.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
12329
12556
|
`)
|
|
12330
12557
|
);
|
|
12331
12558
|
for (const [refFile, lines] of grouped) {
|
|
12332
12559
|
console.log(
|
|
12333
|
-
` ${
|
|
12560
|
+
` ${chalk137.dim(refFile)}: lines ${chalk137.cyan(lines.join(", "))}`
|
|
12334
12561
|
);
|
|
12335
12562
|
}
|
|
12336
12563
|
if (options2.apply) {
|
|
12337
12564
|
symbol.rename(newName);
|
|
12338
12565
|
await project.save();
|
|
12339
|
-
console.log(
|
|
12566
|
+
console.log(chalk137.green(`
|
|
12340
12567
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
12341
12568
|
} else {
|
|
12342
|
-
console.log(
|
|
12569
|
+
console.log(chalk137.dim("\nDry run. Use --apply to execute."));
|
|
12343
12570
|
}
|
|
12344
12571
|
}
|
|
12345
12572
|
|
|
12346
12573
|
// src/commands/refactor/restructure/index.ts
|
|
12347
12574
|
import path47 from "path";
|
|
12348
|
-
import
|
|
12575
|
+
import chalk140 from "chalk";
|
|
12349
12576
|
|
|
12350
12577
|
// src/commands/refactor/restructure/buildImportGraph/index.ts
|
|
12351
12578
|
import path39 from "path";
|
|
@@ -12588,50 +12815,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
12588
12815
|
|
|
12589
12816
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
12590
12817
|
import path43 from "path";
|
|
12591
|
-
import
|
|
12818
|
+
import chalk138 from "chalk";
|
|
12592
12819
|
function relPath(filePath) {
|
|
12593
12820
|
return path43.relative(process.cwd(), filePath);
|
|
12594
12821
|
}
|
|
12595
12822
|
function displayMoves(plan2) {
|
|
12596
12823
|
if (plan2.moves.length === 0) return;
|
|
12597
|
-
console.log(
|
|
12824
|
+
console.log(chalk138.bold("\nFile moves:"));
|
|
12598
12825
|
for (const move of plan2.moves) {
|
|
12599
12826
|
console.log(
|
|
12600
|
-
` ${
|
|
12827
|
+
` ${chalk138.red(relPath(move.from))} \u2192 ${chalk138.green(relPath(move.to))}`
|
|
12601
12828
|
);
|
|
12602
|
-
console.log(
|
|
12829
|
+
console.log(chalk138.dim(` ${move.reason}`));
|
|
12603
12830
|
}
|
|
12604
12831
|
}
|
|
12605
12832
|
function displayRewrites(rewrites) {
|
|
12606
12833
|
if (rewrites.length === 0) return;
|
|
12607
12834
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
12608
|
-
console.log(
|
|
12835
|
+
console.log(chalk138.bold(`
|
|
12609
12836
|
Import rewrites (${affectedFiles.size} files):`));
|
|
12610
12837
|
for (const file of affectedFiles) {
|
|
12611
|
-
console.log(` ${
|
|
12838
|
+
console.log(` ${chalk138.cyan(relPath(file))}:`);
|
|
12612
12839
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
12613
12840
|
(r) => r.file === file
|
|
12614
12841
|
)) {
|
|
12615
12842
|
console.log(
|
|
12616
|
-
` ${
|
|
12843
|
+
` ${chalk138.red(`"${oldSpecifier}"`)} \u2192 ${chalk138.green(`"${newSpecifier}"`)}`
|
|
12617
12844
|
);
|
|
12618
12845
|
}
|
|
12619
12846
|
}
|
|
12620
12847
|
}
|
|
12621
12848
|
function displayPlan2(plan2) {
|
|
12622
12849
|
if (plan2.warnings.length > 0) {
|
|
12623
|
-
console.log(
|
|
12624
|
-
for (const w of plan2.warnings) console.log(
|
|
12850
|
+
console.log(chalk138.yellow("\nWarnings:"));
|
|
12851
|
+
for (const w of plan2.warnings) console.log(chalk138.yellow(` ${w}`));
|
|
12625
12852
|
}
|
|
12626
12853
|
if (plan2.newDirectories.length > 0) {
|
|
12627
|
-
console.log(
|
|
12854
|
+
console.log(chalk138.bold("\nNew directories:"));
|
|
12628
12855
|
for (const dir of plan2.newDirectories)
|
|
12629
|
-
console.log(
|
|
12856
|
+
console.log(chalk138.green(` ${dir}/`));
|
|
12630
12857
|
}
|
|
12631
12858
|
displayMoves(plan2);
|
|
12632
12859
|
displayRewrites(plan2.rewrites);
|
|
12633
12860
|
console.log(
|
|
12634
|
-
|
|
12861
|
+
chalk138.dim(
|
|
12635
12862
|
`
|
|
12636
12863
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
12637
12864
|
)
|
|
@@ -12641,18 +12868,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
12641
12868
|
// src/commands/refactor/restructure/executePlan.ts
|
|
12642
12869
|
import fs23 from "fs";
|
|
12643
12870
|
import path44 from "path";
|
|
12644
|
-
import
|
|
12871
|
+
import chalk139 from "chalk";
|
|
12645
12872
|
function executePlan(plan2) {
|
|
12646
12873
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
12647
12874
|
for (const [file, content] of updatedContents) {
|
|
12648
12875
|
fs23.writeFileSync(file, content, "utf-8");
|
|
12649
12876
|
console.log(
|
|
12650
|
-
|
|
12877
|
+
chalk139.cyan(` Rewrote imports in ${path44.relative(process.cwd(), file)}`)
|
|
12651
12878
|
);
|
|
12652
12879
|
}
|
|
12653
12880
|
for (const dir of plan2.newDirectories) {
|
|
12654
12881
|
fs23.mkdirSync(dir, { recursive: true });
|
|
12655
|
-
console.log(
|
|
12882
|
+
console.log(chalk139.green(` Created ${path44.relative(process.cwd(), dir)}/`));
|
|
12656
12883
|
}
|
|
12657
12884
|
for (const move of plan2.moves) {
|
|
12658
12885
|
const targetDir = path44.dirname(move.to);
|
|
@@ -12661,7 +12888,7 @@ function executePlan(plan2) {
|
|
|
12661
12888
|
}
|
|
12662
12889
|
fs23.renameSync(move.from, move.to);
|
|
12663
12890
|
console.log(
|
|
12664
|
-
|
|
12891
|
+
chalk139.white(
|
|
12665
12892
|
` Moved ${path44.relative(process.cwd(), move.from)} \u2192 ${path44.relative(process.cwd(), move.to)}`
|
|
12666
12893
|
)
|
|
12667
12894
|
);
|
|
@@ -12676,7 +12903,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
12676
12903
|
if (entries.length === 0) {
|
|
12677
12904
|
fs23.rmdirSync(dir);
|
|
12678
12905
|
console.log(
|
|
12679
|
-
|
|
12906
|
+
chalk139.dim(
|
|
12680
12907
|
` Removed empty directory ${path44.relative(process.cwd(), dir)}`
|
|
12681
12908
|
)
|
|
12682
12909
|
);
|
|
@@ -12809,22 +13036,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
12809
13036
|
const targetPattern = pattern2 ?? "src";
|
|
12810
13037
|
const files = findSourceFiles2(targetPattern);
|
|
12811
13038
|
if (files.length === 0) {
|
|
12812
|
-
console.log(
|
|
13039
|
+
console.log(chalk140.yellow("No files found matching pattern"));
|
|
12813
13040
|
return;
|
|
12814
13041
|
}
|
|
12815
13042
|
const tsConfigPath = path47.resolve("tsconfig.json");
|
|
12816
13043
|
const plan2 = buildPlan3(files, tsConfigPath);
|
|
12817
13044
|
if (plan2.moves.length === 0) {
|
|
12818
|
-
console.log(
|
|
13045
|
+
console.log(chalk140.green("No restructuring needed"));
|
|
12819
13046
|
return;
|
|
12820
13047
|
}
|
|
12821
13048
|
displayPlan2(plan2);
|
|
12822
13049
|
if (options2.apply) {
|
|
12823
|
-
console.log(
|
|
13050
|
+
console.log(chalk140.bold("\nApplying changes..."));
|
|
12824
13051
|
executePlan(plan2);
|
|
12825
|
-
console.log(
|
|
13052
|
+
console.log(chalk140.green("\nRestructuring complete"));
|
|
12826
13053
|
} else {
|
|
12827
|
-
console.log(
|
|
13054
|
+
console.log(chalk140.dim("\nDry run. Use --apply to execute."));
|
|
12828
13055
|
}
|
|
12829
13056
|
}
|
|
12830
13057
|
|
|
@@ -13300,18 +13527,18 @@ async function postAndMaybeSubmit(lineBound, markdown, options2) {
|
|
|
13300
13527
|
}
|
|
13301
13528
|
|
|
13302
13529
|
// src/commands/review/warnUnlocated.ts
|
|
13303
|
-
import
|
|
13530
|
+
import chalk141 from "chalk";
|
|
13304
13531
|
function warnUnlocated(unlocated) {
|
|
13305
13532
|
if (unlocated.length === 0) return;
|
|
13306
13533
|
console.warn(
|
|
13307
|
-
|
|
13534
|
+
chalk141.yellow(
|
|
13308
13535
|
`Skipped ${unlocated.length} finding(s) without a parseable file:line:`
|
|
13309
13536
|
)
|
|
13310
13537
|
);
|
|
13311
13538
|
for (const finding of unlocated) {
|
|
13312
|
-
const where = finding.location ||
|
|
13539
|
+
const where = finding.location || chalk141.dim("missing");
|
|
13313
13540
|
console.warn(
|
|
13314
|
-
` ${
|
|
13541
|
+
` ${chalk141.yellow("\xB7")} ${finding.title} ${chalk141.dim(`(${where})`)}`
|
|
13315
13542
|
);
|
|
13316
13543
|
}
|
|
13317
13544
|
}
|
|
@@ -14482,7 +14709,7 @@ function registerReview(program2) {
|
|
|
14482
14709
|
}
|
|
14483
14710
|
|
|
14484
14711
|
// src/commands/seq/seqAuth.ts
|
|
14485
|
-
import
|
|
14712
|
+
import chalk143 from "chalk";
|
|
14486
14713
|
|
|
14487
14714
|
// src/commands/seq/loadConnections.ts
|
|
14488
14715
|
function loadConnections2() {
|
|
@@ -14511,10 +14738,10 @@ function setDefaultConnection(name) {
|
|
|
14511
14738
|
}
|
|
14512
14739
|
|
|
14513
14740
|
// src/shared/assertUniqueName.ts
|
|
14514
|
-
import
|
|
14741
|
+
import chalk142 from "chalk";
|
|
14515
14742
|
function assertUniqueName(existingNames, name) {
|
|
14516
14743
|
if (existingNames.includes(name)) {
|
|
14517
|
-
console.error(
|
|
14744
|
+
console.error(chalk142.red(`Connection "${name}" already exists.`));
|
|
14518
14745
|
process.exit(1);
|
|
14519
14746
|
}
|
|
14520
14747
|
}
|
|
@@ -14532,16 +14759,16 @@ async function promptConnection2(existingNames) {
|
|
|
14532
14759
|
var seqAuth = createConnectionAuth({
|
|
14533
14760
|
load: loadConnections2,
|
|
14534
14761
|
save: saveConnections2,
|
|
14535
|
-
format: (c) => `${
|
|
14762
|
+
format: (c) => `${chalk143.bold(c.name)} ${c.url}`,
|
|
14536
14763
|
promptNew: promptConnection2,
|
|
14537
14764
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
14538
14765
|
});
|
|
14539
14766
|
|
|
14540
14767
|
// src/commands/seq/seqQuery.ts
|
|
14541
|
-
import
|
|
14768
|
+
import chalk147 from "chalk";
|
|
14542
14769
|
|
|
14543
14770
|
// src/commands/seq/fetchSeq.ts
|
|
14544
|
-
import
|
|
14771
|
+
import chalk144 from "chalk";
|
|
14545
14772
|
async function fetchSeq(conn, path52, params) {
|
|
14546
14773
|
const url = `${conn.url}${path52}?${params}`;
|
|
14547
14774
|
const response = await fetch(url, {
|
|
@@ -14552,7 +14779,7 @@ async function fetchSeq(conn, path52, params) {
|
|
|
14552
14779
|
});
|
|
14553
14780
|
if (!response.ok) {
|
|
14554
14781
|
const body = await response.text();
|
|
14555
|
-
console.error(
|
|
14782
|
+
console.error(chalk144.red(`Seq returned ${response.status}: ${body}`));
|
|
14556
14783
|
process.exit(1);
|
|
14557
14784
|
}
|
|
14558
14785
|
return response;
|
|
@@ -14607,23 +14834,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
14607
14834
|
}
|
|
14608
14835
|
|
|
14609
14836
|
// src/commands/seq/formatEvent.ts
|
|
14610
|
-
import
|
|
14837
|
+
import chalk145 from "chalk";
|
|
14611
14838
|
function levelColor(level) {
|
|
14612
14839
|
switch (level) {
|
|
14613
14840
|
case "Fatal":
|
|
14614
|
-
return
|
|
14841
|
+
return chalk145.bgRed.white;
|
|
14615
14842
|
case "Error":
|
|
14616
|
-
return
|
|
14843
|
+
return chalk145.red;
|
|
14617
14844
|
case "Warning":
|
|
14618
|
-
return
|
|
14845
|
+
return chalk145.yellow;
|
|
14619
14846
|
case "Information":
|
|
14620
|
-
return
|
|
14847
|
+
return chalk145.cyan;
|
|
14621
14848
|
case "Debug":
|
|
14622
|
-
return
|
|
14849
|
+
return chalk145.gray;
|
|
14623
14850
|
case "Verbose":
|
|
14624
|
-
return
|
|
14851
|
+
return chalk145.dim;
|
|
14625
14852
|
default:
|
|
14626
|
-
return
|
|
14853
|
+
return chalk145.white;
|
|
14627
14854
|
}
|
|
14628
14855
|
}
|
|
14629
14856
|
function levelAbbrev(level) {
|
|
@@ -14664,12 +14891,12 @@ function formatTimestamp(iso) {
|
|
|
14664
14891
|
function formatEvent(event) {
|
|
14665
14892
|
const color = levelColor(event.Level);
|
|
14666
14893
|
const abbrev = levelAbbrev(event.Level);
|
|
14667
|
-
const ts8 =
|
|
14894
|
+
const ts8 = chalk145.dim(formatTimestamp(event.Timestamp));
|
|
14668
14895
|
const msg = renderMessage(event);
|
|
14669
14896
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
14670
14897
|
if (event.Exception) {
|
|
14671
14898
|
for (const line of event.Exception.split("\n")) {
|
|
14672
|
-
lines.push(
|
|
14899
|
+
lines.push(chalk145.red(` ${line}`));
|
|
14673
14900
|
}
|
|
14674
14901
|
}
|
|
14675
14902
|
return lines.join("\n");
|
|
@@ -14702,11 +14929,11 @@ function rejectTimestampFilter(filter) {
|
|
|
14702
14929
|
}
|
|
14703
14930
|
|
|
14704
14931
|
// src/shared/resolveNamedConnection.ts
|
|
14705
|
-
import
|
|
14932
|
+
import chalk146 from "chalk";
|
|
14706
14933
|
function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
|
|
14707
14934
|
if (connections.length === 0) {
|
|
14708
14935
|
console.error(
|
|
14709
|
-
|
|
14936
|
+
chalk146.red(
|
|
14710
14937
|
`No ${kind} connections configured. Run '${authCommand}' first.`
|
|
14711
14938
|
)
|
|
14712
14939
|
);
|
|
@@ -14715,7 +14942,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
|
|
|
14715
14942
|
const target = requested ?? defaultName ?? connections[0].name;
|
|
14716
14943
|
const connection = connections.find((c) => c.name === target);
|
|
14717
14944
|
if (!connection) {
|
|
14718
|
-
console.error(
|
|
14945
|
+
console.error(chalk146.red(`${kind} connection "${target}" not found.`));
|
|
14719
14946
|
process.exit(1);
|
|
14720
14947
|
}
|
|
14721
14948
|
return connection;
|
|
@@ -14744,7 +14971,7 @@ async function seqQuery(filter, options2) {
|
|
|
14744
14971
|
new URLSearchParams({ filter, count: String(count6) })
|
|
14745
14972
|
);
|
|
14746
14973
|
if (events.length === 0) {
|
|
14747
|
-
console.log(
|
|
14974
|
+
console.log(chalk147.yellow("No events found."));
|
|
14748
14975
|
return;
|
|
14749
14976
|
}
|
|
14750
14977
|
if (options2.json) {
|
|
@@ -14755,11 +14982,11 @@ async function seqQuery(filter, options2) {
|
|
|
14755
14982
|
for (const event of chronological) {
|
|
14756
14983
|
console.log(formatEvent(event));
|
|
14757
14984
|
}
|
|
14758
|
-
console.log(
|
|
14985
|
+
console.log(chalk147.dim(`
|
|
14759
14986
|
${events.length} events`));
|
|
14760
14987
|
if (events.length >= count6) {
|
|
14761
14988
|
console.log(
|
|
14762
|
-
|
|
14989
|
+
chalk147.yellow(
|
|
14763
14990
|
`Results limited to ${count6}. Use --count to retrieve more.`
|
|
14764
14991
|
)
|
|
14765
14992
|
);
|
|
@@ -14767,10 +14994,10 @@ ${events.length} events`));
|
|
|
14767
14994
|
}
|
|
14768
14995
|
|
|
14769
14996
|
// src/shared/setNamedDefaultConnection.ts
|
|
14770
|
-
import
|
|
14997
|
+
import chalk148 from "chalk";
|
|
14771
14998
|
function setNamedDefaultConnection(connections, name, setDefault, kind) {
|
|
14772
14999
|
if (!connections.find((c) => c.name === name)) {
|
|
14773
|
-
console.error(
|
|
15000
|
+
console.error(chalk148.red(`Connection "${name}" not found.`));
|
|
14774
15001
|
process.exit(1);
|
|
14775
15002
|
}
|
|
14776
15003
|
setDefault(name);
|
|
@@ -14814,7 +15041,7 @@ function registerSignal(program2) {
|
|
|
14814
15041
|
}
|
|
14815
15042
|
|
|
14816
15043
|
// src/commands/sql/sqlAuth.ts
|
|
14817
|
-
import
|
|
15044
|
+
import chalk150 from "chalk";
|
|
14818
15045
|
|
|
14819
15046
|
// src/commands/sql/loadConnections.ts
|
|
14820
15047
|
function loadConnections3() {
|
|
@@ -14843,7 +15070,7 @@ function setDefaultConnection2(name) {
|
|
|
14843
15070
|
}
|
|
14844
15071
|
|
|
14845
15072
|
// src/commands/sql/promptConnection.ts
|
|
14846
|
-
import
|
|
15073
|
+
import chalk149 from "chalk";
|
|
14847
15074
|
async function promptConnection3(existingNames) {
|
|
14848
15075
|
const name = await promptInput("name", "Connection name:", "default");
|
|
14849
15076
|
assertUniqueName(existingNames, name);
|
|
@@ -14851,7 +15078,7 @@ async function promptConnection3(existingNames) {
|
|
|
14851
15078
|
const portStr = await promptInput("port", "Port:", "1433");
|
|
14852
15079
|
const port = Number.parseInt(portStr, 10);
|
|
14853
15080
|
if (!Number.isFinite(port)) {
|
|
14854
|
-
console.error(
|
|
15081
|
+
console.error(chalk149.red(`Invalid port "${portStr}".`));
|
|
14855
15082
|
process.exit(1);
|
|
14856
15083
|
}
|
|
14857
15084
|
const user = await promptInput("user", "User:");
|
|
@@ -14864,13 +15091,13 @@ async function promptConnection3(existingNames) {
|
|
|
14864
15091
|
var sqlAuth = createConnectionAuth({
|
|
14865
15092
|
load: loadConnections3,
|
|
14866
15093
|
save: saveConnections3,
|
|
14867
|
-
format: (c) => `${
|
|
15094
|
+
format: (c) => `${chalk150.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
|
|
14868
15095
|
promptNew: promptConnection3,
|
|
14869
15096
|
onFirst: (c) => setDefaultConnection2(c.name)
|
|
14870
15097
|
});
|
|
14871
15098
|
|
|
14872
15099
|
// src/commands/sql/printTable.ts
|
|
14873
|
-
import
|
|
15100
|
+
import chalk151 from "chalk";
|
|
14874
15101
|
function formatCell(value) {
|
|
14875
15102
|
if (value === null || value === void 0) return "";
|
|
14876
15103
|
if (value instanceof Date) return value.toISOString();
|
|
@@ -14879,7 +15106,7 @@ function formatCell(value) {
|
|
|
14879
15106
|
}
|
|
14880
15107
|
function printTable(rows) {
|
|
14881
15108
|
if (rows.length === 0) {
|
|
14882
|
-
console.log(
|
|
15109
|
+
console.log(chalk151.yellow("(no rows)"));
|
|
14883
15110
|
return;
|
|
14884
15111
|
}
|
|
14885
15112
|
const columns = Object.keys(rows[0]);
|
|
@@ -14887,13 +15114,13 @@ function printTable(rows) {
|
|
|
14887
15114
|
(col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
|
|
14888
15115
|
);
|
|
14889
15116
|
const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
|
|
14890
|
-
console.log(
|
|
14891
|
-
console.log(
|
|
15117
|
+
console.log(chalk151.dim(header));
|
|
15118
|
+
console.log(chalk151.dim("-".repeat(header.length)));
|
|
14892
15119
|
for (const row of rows) {
|
|
14893
15120
|
const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
|
|
14894
15121
|
console.log(line);
|
|
14895
15122
|
}
|
|
14896
|
-
console.log(
|
|
15123
|
+
console.log(chalk151.dim(`
|
|
14897
15124
|
${rows.length} row${rows.length === 1 ? "" : "s"}`));
|
|
14898
15125
|
}
|
|
14899
15126
|
|
|
@@ -14953,7 +15180,7 @@ async function sqlColumns(table, connectionName) {
|
|
|
14953
15180
|
}
|
|
14954
15181
|
|
|
14955
15182
|
// src/commands/sql/sqlMutate.ts
|
|
14956
|
-
import
|
|
15183
|
+
import chalk152 from "chalk";
|
|
14957
15184
|
|
|
14958
15185
|
// src/commands/sql/isMutation.ts
|
|
14959
15186
|
var MUTATION_KEYWORDS = [
|
|
@@ -14987,7 +15214,7 @@ function isMutation(sql4) {
|
|
|
14987
15214
|
async function sqlMutate(query, connectionName) {
|
|
14988
15215
|
if (!isMutation(query)) {
|
|
14989
15216
|
console.error(
|
|
14990
|
-
|
|
15217
|
+
chalk152.red(
|
|
14991
15218
|
"assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
|
|
14992
15219
|
)
|
|
14993
15220
|
);
|
|
@@ -14997,18 +15224,18 @@ async function sqlMutate(query, connectionName) {
|
|
|
14997
15224
|
const pool = await sqlConnect(conn);
|
|
14998
15225
|
try {
|
|
14999
15226
|
const result = await pool.request().query(query);
|
|
15000
|
-
console.log(
|
|
15227
|
+
console.log(chalk152.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
|
|
15001
15228
|
} finally {
|
|
15002
15229
|
await pool.close();
|
|
15003
15230
|
}
|
|
15004
15231
|
}
|
|
15005
15232
|
|
|
15006
15233
|
// src/commands/sql/sqlQuery.ts
|
|
15007
|
-
import
|
|
15234
|
+
import chalk153 from "chalk";
|
|
15008
15235
|
async function sqlQuery(query, connectionName) {
|
|
15009
15236
|
if (isMutation(query)) {
|
|
15010
15237
|
console.error(
|
|
15011
|
-
|
|
15238
|
+
chalk153.red(
|
|
15012
15239
|
"assist sql query refuses mutating statements. Use `assist sql mutate` instead."
|
|
15013
15240
|
)
|
|
15014
15241
|
);
|
|
@@ -15023,7 +15250,7 @@ async function sqlQuery(query, connectionName) {
|
|
|
15023
15250
|
printTable(rows);
|
|
15024
15251
|
} else {
|
|
15025
15252
|
console.log(
|
|
15026
|
-
|
|
15253
|
+
chalk153.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
|
|
15027
15254
|
);
|
|
15028
15255
|
}
|
|
15029
15256
|
} finally {
|
|
@@ -15603,14 +15830,14 @@ import {
|
|
|
15603
15830
|
import { dirname as dirname22, join as join40 } from "path";
|
|
15604
15831
|
|
|
15605
15832
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
15606
|
-
import
|
|
15833
|
+
import chalk154 from "chalk";
|
|
15607
15834
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
15608
15835
|
function validateStagedContent(filename, content) {
|
|
15609
15836
|
const firstLine = content.split("\n")[0];
|
|
15610
15837
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
15611
15838
|
if (!match) {
|
|
15612
15839
|
console.error(
|
|
15613
|
-
|
|
15840
|
+
chalk154.red(
|
|
15614
15841
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
15615
15842
|
)
|
|
15616
15843
|
);
|
|
@@ -15619,7 +15846,7 @@ function validateStagedContent(filename, content) {
|
|
|
15619
15846
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
15620
15847
|
if (!contentAfterLink) {
|
|
15621
15848
|
console.error(
|
|
15622
|
-
|
|
15849
|
+
chalk154.red(
|
|
15623
15850
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
15624
15851
|
)
|
|
15625
15852
|
);
|
|
@@ -16015,7 +16242,7 @@ function registerVoice(program2) {
|
|
|
16015
16242
|
|
|
16016
16243
|
// src/commands/roam/auth.ts
|
|
16017
16244
|
import { randomBytes } from "crypto";
|
|
16018
|
-
import
|
|
16245
|
+
import chalk155 from "chalk";
|
|
16019
16246
|
|
|
16020
16247
|
// src/lib/openBrowser.ts
|
|
16021
16248
|
import { execSync as execSync45 } from "child_process";
|
|
@@ -16190,13 +16417,13 @@ async function auth() {
|
|
|
16190
16417
|
saveGlobalConfig(config);
|
|
16191
16418
|
const state = randomBytes(16).toString("hex");
|
|
16192
16419
|
console.log(
|
|
16193
|
-
|
|
16420
|
+
chalk155.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
16194
16421
|
);
|
|
16195
|
-
console.log(
|
|
16196
|
-
console.log(
|
|
16197
|
-
console.log(
|
|
16422
|
+
console.log(chalk155.white("http://localhost:14523/callback\n"));
|
|
16423
|
+
console.log(chalk155.blue("Opening browser for authorization..."));
|
|
16424
|
+
console.log(chalk155.dim("Waiting for authorization callback..."));
|
|
16198
16425
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
16199
|
-
console.log(
|
|
16426
|
+
console.log(chalk155.dim("Exchanging code for tokens..."));
|
|
16200
16427
|
const tokens = await exchangeToken({
|
|
16201
16428
|
code,
|
|
16202
16429
|
clientId,
|
|
@@ -16212,7 +16439,7 @@ async function auth() {
|
|
|
16212
16439
|
};
|
|
16213
16440
|
saveGlobalConfig(config);
|
|
16214
16441
|
console.log(
|
|
16215
|
-
|
|
16442
|
+
chalk155.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
16216
16443
|
);
|
|
16217
16444
|
}
|
|
16218
16445
|
|
|
@@ -16635,7 +16862,7 @@ import { execSync as execSync47 } from "child_process";
|
|
|
16635
16862
|
import { existsSync as existsSync49, mkdirSync as mkdirSync17, unlinkSync as unlinkSync15, writeFileSync as writeFileSync30 } from "fs";
|
|
16636
16863
|
import { tmpdir as tmpdir7 } from "os";
|
|
16637
16864
|
import { join as join51, resolve as resolve13 } from "path";
|
|
16638
|
-
import
|
|
16865
|
+
import chalk156 from "chalk";
|
|
16639
16866
|
|
|
16640
16867
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
16641
16868
|
var captureWindowPs1 = `
|
|
@@ -16786,20 +17013,20 @@ function screenshot(processName) {
|
|
|
16786
17013
|
const config = loadConfig();
|
|
16787
17014
|
const outputDir = resolve13(config.screenshot.outputDir);
|
|
16788
17015
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
16789
|
-
console.log(
|
|
17016
|
+
console.log(chalk156.gray(`Capturing window for process "${processName}" ...`));
|
|
16790
17017
|
try {
|
|
16791
17018
|
runPowerShellScript(processName, outputPath);
|
|
16792
|
-
console.log(
|
|
17019
|
+
console.log(chalk156.green(`Screenshot saved: ${outputPath}`));
|
|
16793
17020
|
} catch (error) {
|
|
16794
17021
|
const msg = error instanceof Error ? error.message : String(error);
|
|
16795
|
-
console.error(
|
|
17022
|
+
console.error(chalk156.red(`Failed to capture screenshot: ${msg}`));
|
|
16796
17023
|
process.exit(1);
|
|
16797
17024
|
}
|
|
16798
17025
|
}
|
|
16799
17026
|
|
|
16800
17027
|
// src/commands/sessions/summarise/index.ts
|
|
16801
17028
|
import * as fs28 from "fs";
|
|
16802
|
-
import
|
|
17029
|
+
import chalk157 from "chalk";
|
|
16803
17030
|
|
|
16804
17031
|
// src/commands/sessions/summarise/shared.ts
|
|
16805
17032
|
import * as fs26 from "fs";
|
|
@@ -16926,22 +17153,22 @@ ${firstMessage}`);
|
|
|
16926
17153
|
async function summarise4(options2) {
|
|
16927
17154
|
const files = await discoverSessionJsonlPaths();
|
|
16928
17155
|
if (files.length === 0) {
|
|
16929
|
-
console.log(
|
|
17156
|
+
console.log(chalk157.yellow("No sessions found."));
|
|
16930
17157
|
return;
|
|
16931
17158
|
}
|
|
16932
17159
|
const toProcess = selectCandidates(files, options2);
|
|
16933
17160
|
if (toProcess.length === 0) {
|
|
16934
|
-
console.log(
|
|
17161
|
+
console.log(chalk157.green("All sessions already summarised."));
|
|
16935
17162
|
return;
|
|
16936
17163
|
}
|
|
16937
17164
|
console.log(
|
|
16938
|
-
|
|
17165
|
+
chalk157.cyan(
|
|
16939
17166
|
`Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
|
|
16940
17167
|
)
|
|
16941
17168
|
);
|
|
16942
17169
|
const { succeeded, failed: failed2 } = processSessions(toProcess);
|
|
16943
17170
|
console.log(
|
|
16944
|
-
|
|
17171
|
+
chalk157.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk157.yellow(`, ${failed2} skipped`) : "")
|
|
16945
17172
|
);
|
|
16946
17173
|
}
|
|
16947
17174
|
function selectCandidates(files, options2) {
|
|
@@ -16961,16 +17188,16 @@ function processSessions(files) {
|
|
|
16961
17188
|
let failed2 = 0;
|
|
16962
17189
|
for (let i = 0; i < files.length; i++) {
|
|
16963
17190
|
const file = files[i];
|
|
16964
|
-
process.stdout.write(
|
|
17191
|
+
process.stdout.write(chalk157.dim(` [${i + 1}/${files.length}] `));
|
|
16965
17192
|
const summary = summariseSession(file);
|
|
16966
17193
|
if (summary) {
|
|
16967
17194
|
writeSummary(file, summary);
|
|
16968
17195
|
succeeded++;
|
|
16969
|
-
process.stdout.write(`${
|
|
17196
|
+
process.stdout.write(`${chalk157.green("\u2713")} ${summary}
|
|
16970
17197
|
`);
|
|
16971
17198
|
} else {
|
|
16972
17199
|
failed2++;
|
|
16973
|
-
process.stdout.write(` ${
|
|
17200
|
+
process.stdout.write(` ${chalk157.yellow("skip")}
|
|
16974
17201
|
`);
|
|
16975
17202
|
}
|
|
16976
17203
|
}
|
|
@@ -16985,10 +17212,10 @@ function registerSessions(program2) {
|
|
|
16985
17212
|
}
|
|
16986
17213
|
|
|
16987
17214
|
// src/commands/statusLine.ts
|
|
16988
|
-
import
|
|
17215
|
+
import chalk159 from "chalk";
|
|
16989
17216
|
|
|
16990
17217
|
// src/commands/buildLimitsSegment.ts
|
|
16991
|
-
import
|
|
17218
|
+
import chalk158 from "chalk";
|
|
16992
17219
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
16993
17220
|
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
16994
17221
|
function formatTimeLeft(resetsAt) {
|
|
@@ -17011,10 +17238,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
|
|
|
17011
17238
|
function colorizeRateLimit(pct, resetsAt, windowSeconds) {
|
|
17012
17239
|
const label2 = `${Math.round(pct)}%`;
|
|
17013
17240
|
const projected = projectUsage(pct, resetsAt, windowSeconds);
|
|
17014
|
-
if (projected == null) return
|
|
17015
|
-
if (projected > 100) return
|
|
17016
|
-
if (projected > 75) return
|
|
17017
|
-
return
|
|
17241
|
+
if (projected == null) return chalk158.green(label2);
|
|
17242
|
+
if (projected > 100) return chalk158.red(label2);
|
|
17243
|
+
if (projected > 75) return chalk158.yellow(label2);
|
|
17244
|
+
return chalk158.green(label2);
|
|
17018
17245
|
}
|
|
17019
17246
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
|
|
17020
17247
|
const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
|
|
@@ -17040,14 +17267,14 @@ function buildLimitsSegment(rateLimits) {
|
|
|
17040
17267
|
}
|
|
17041
17268
|
|
|
17042
17269
|
// src/commands/statusLine.ts
|
|
17043
|
-
|
|
17270
|
+
chalk159.level = 3;
|
|
17044
17271
|
function formatNumber(num) {
|
|
17045
17272
|
return num.toLocaleString("en-US");
|
|
17046
17273
|
}
|
|
17047
17274
|
function colorizePercent(pct) {
|
|
17048
17275
|
const label2 = `${Math.round(pct)}%`;
|
|
17049
|
-
if (pct > 80) return
|
|
17050
|
-
if (pct > 40) return
|
|
17276
|
+
if (pct > 80) return chalk159.red(label2);
|
|
17277
|
+
if (pct > 40) return chalk159.yellow(label2);
|
|
17051
17278
|
return label2;
|
|
17052
17279
|
}
|
|
17053
17280
|
async function statusLine() {
|
|
@@ -17070,7 +17297,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
17070
17297
|
// src/commands/sync/syncClaudeMd.ts
|
|
17071
17298
|
import * as fs29 from "fs";
|
|
17072
17299
|
import * as path48 from "path";
|
|
17073
|
-
import
|
|
17300
|
+
import chalk160 from "chalk";
|
|
17074
17301
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
17075
17302
|
const source = path48.join(claudeDir, "CLAUDE.md");
|
|
17076
17303
|
const target = path48.join(targetBase, "CLAUDE.md");
|
|
@@ -17079,12 +17306,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
17079
17306
|
const targetContent = fs29.readFileSync(target, "utf-8");
|
|
17080
17307
|
if (sourceContent !== targetContent) {
|
|
17081
17308
|
console.log(
|
|
17082
|
-
|
|
17309
|
+
chalk160.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
17083
17310
|
);
|
|
17084
17311
|
console.log();
|
|
17085
17312
|
printDiff(targetContent, sourceContent);
|
|
17086
17313
|
const confirm = options2?.yes || await promptConfirm(
|
|
17087
|
-
|
|
17314
|
+
chalk160.red("Overwrite existing CLAUDE.md?"),
|
|
17088
17315
|
false
|
|
17089
17316
|
);
|
|
17090
17317
|
if (!confirm) {
|
|
@@ -17100,7 +17327,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
17100
17327
|
// src/commands/sync/syncSettings.ts
|
|
17101
17328
|
import * as fs30 from "fs";
|
|
17102
17329
|
import * as path49 from "path";
|
|
17103
|
-
import
|
|
17330
|
+
import chalk161 from "chalk";
|
|
17104
17331
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
17105
17332
|
const source = path49.join(claudeDir, "settings.json");
|
|
17106
17333
|
const target = path49.join(targetBase, "settings.json");
|
|
@@ -17116,14 +17343,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
17116
17343
|
if (mergedContent !== normalizedTarget) {
|
|
17117
17344
|
if (!options2?.yes) {
|
|
17118
17345
|
console.log(
|
|
17119
|
-
|
|
17346
|
+
chalk161.yellow(
|
|
17120
17347
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
17121
17348
|
)
|
|
17122
17349
|
);
|
|
17123
17350
|
console.log();
|
|
17124
17351
|
printDiff(targetContent, mergedContent);
|
|
17125
17352
|
const confirm = await promptConfirm(
|
|
17126
|
-
|
|
17353
|
+
chalk161.red("Overwrite existing settings.json?"),
|
|
17127
17354
|
false
|
|
17128
17355
|
);
|
|
17129
17356
|
if (!confirm) {
|
|
@@ -17223,6 +17450,7 @@ program.command("coverage").description("Print global statement coverage percent
|
|
|
17223
17450
|
program.command("screenshot").description("Capture a screenshot of a running application window").argument("<process>", "Name of the running process (e.g. notepad, code)").action(screenshot);
|
|
17224
17451
|
registerActivity(program);
|
|
17225
17452
|
registerCliHook(program);
|
|
17453
|
+
registerGithub(program);
|
|
17226
17454
|
registerHandover(program);
|
|
17227
17455
|
registerJira(program);
|
|
17228
17456
|
registerMermaid(program);
|