@staff0rd/assist 0.351.0 → 0.352.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/commands/sessions/web/bundle.js +1 -1
- package/dist/index.js +805 -710
- 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.352.1",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -1788,7 +1788,7 @@ function isYamlFile(filePath) {
|
|
|
1788
1788
|
function collectComments(sourceFile) {
|
|
1789
1789
|
const seen = /* @__PURE__ */ new Set();
|
|
1790
1790
|
const comments3 = [];
|
|
1791
|
-
const
|
|
1791
|
+
const collect5 = (node) => {
|
|
1792
1792
|
for (const range of [
|
|
1793
1793
|
...node.getLeadingCommentRanges(),
|
|
1794
1794
|
...node.getTrailingCommentRanges()
|
|
@@ -1799,8 +1799,8 @@ function collectComments(sourceFile) {
|
|
|
1799
1799
|
comments3.push({ pos, text: range.getText() });
|
|
1800
1800
|
}
|
|
1801
1801
|
};
|
|
1802
|
-
|
|
1803
|
-
sourceFile.forEachDescendant(
|
|
1802
|
+
collect5(sourceFile);
|
|
1803
|
+
sourceFile.forEachDescendant(collect5);
|
|
1804
1804
|
return comments3;
|
|
1805
1805
|
}
|
|
1806
1806
|
|
|
@@ -2887,13 +2887,13 @@ async function activity(options2) {
|
|
|
2887
2887
|
const activeDays = data.filter((d) => d.count > 0).length;
|
|
2888
2888
|
console.log(`${total} commits across ${activeDays} active days.`);
|
|
2889
2889
|
const weekly = /* @__PURE__ */ new Map();
|
|
2890
|
-
for (const { date, count:
|
|
2890
|
+
for (const { date, count: count8 } of data) {
|
|
2891
2891
|
const d = new Date(date);
|
|
2892
2892
|
d.setDate(d.getDate() - d.getDay());
|
|
2893
2893
|
const weekStart = d.toISOString().slice(0, 10);
|
|
2894
|
-
weekly.set(weekStart, (weekly.get(weekStart) ?? 0) +
|
|
2894
|
+
weekly.set(weekStart, (weekly.get(weekStart) ?? 0) + count8);
|
|
2895
2895
|
}
|
|
2896
|
-
const weeklyData = [...weekly.entries()].map(([date,
|
|
2896
|
+
const weeklyData = [...weekly.entries()].map(([date, count8]) => ({ date, count: count8 })).sort((a, b) => a.date.localeCompare(b.date));
|
|
2897
2897
|
const until = data[data.length - 1].date;
|
|
2898
2898
|
activityChart(weeklyData, { since, until });
|
|
2899
2899
|
}
|
|
@@ -4605,8 +4605,11 @@ function firstRemoteUrl(cwd) {
|
|
|
4605
4605
|
}
|
|
4606
4606
|
return null;
|
|
4607
4607
|
}
|
|
4608
|
+
function getRemoteOriginUrl(cwd) {
|
|
4609
|
+
return tryGit(cwd, ["remote", "get-url", "origin"]) ?? firstRemoteUrl(cwd);
|
|
4610
|
+
}
|
|
4608
4611
|
function getCurrentOrigin(cwd) {
|
|
4609
|
-
const url =
|
|
4612
|
+
const url = getRemoteOriginUrl(cwd);
|
|
4610
4613
|
if (url) return normalizeOrigin(url);
|
|
4611
4614
|
const root = tryGit(cwd, ["rev-parse", "--show-toplevel"]);
|
|
4612
4615
|
return `local:${root ?? cwd}`;
|
|
@@ -7645,7 +7648,7 @@ function registerImportCommand(cmd) {
|
|
|
7645
7648
|
}
|
|
7646
7649
|
|
|
7647
7650
|
// src/commands/backlog/add/index.ts
|
|
7648
|
-
import
|
|
7651
|
+
import chalk67 from "chalk";
|
|
7649
7652
|
|
|
7650
7653
|
// src/commands/backlog/insertPhaseAt.ts
|
|
7651
7654
|
import { count as count2, eq as eq19 } from "drizzle-orm";
|
|
@@ -7689,6 +7692,19 @@ async function insertSubtask(orm, itemId, title, description) {
|
|
|
7689
7692
|
});
|
|
7690
7693
|
}
|
|
7691
7694
|
|
|
7695
|
+
// src/commands/backlog/ensureRemoteOrigin.ts
|
|
7696
|
+
import chalk66 from "chalk";
|
|
7697
|
+
function ensureRemoteOrigin() {
|
|
7698
|
+
if (getRemoteOriginUrl(getBacklogDir())) return true;
|
|
7699
|
+
console.log(
|
|
7700
|
+
chalk66.red(
|
|
7701
|
+
"Backlog requires a git remote so items get a stable origin.\nAdd one with: git remote add origin <url>"
|
|
7702
|
+
)
|
|
7703
|
+
);
|
|
7704
|
+
process.exitCode = 1;
|
|
7705
|
+
return false;
|
|
7706
|
+
}
|
|
7707
|
+
|
|
7692
7708
|
// src/commands/backlog/add/shared.ts
|
|
7693
7709
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
7694
7710
|
import { mkdtempSync, readFileSync as readFileSync19, unlinkSync as unlinkSync6, writeFileSync as writeFileSync19 } from "fs";
|
|
@@ -7761,6 +7777,7 @@ async function promptAcceptanceCriteria() {
|
|
|
7761
7777
|
|
|
7762
7778
|
// src/commands/backlog/add/index.ts
|
|
7763
7779
|
async function add(options2) {
|
|
7780
|
+
if (!ensureRemoteOrigin()) return;
|
|
7764
7781
|
const type = options2.type ?? await promptType();
|
|
7765
7782
|
const name = options2.name ?? await promptName();
|
|
7766
7783
|
const description = options2.desc?.replaceAll(String.raw`\n`, "\n") ?? await promptDescription();
|
|
@@ -7784,14 +7801,14 @@ async function add(options2) {
|
|
|
7784
7801
|
for (const subtask of loadConfig().subtasks ?? []) {
|
|
7785
7802
|
await insertSubtask(orm, id2, subtask.title, subtask.description);
|
|
7786
7803
|
}
|
|
7787
|
-
console.log(
|
|
7804
|
+
console.log(chalk67.green(`Added item #${id2}: ${name}`));
|
|
7788
7805
|
}
|
|
7789
7806
|
|
|
7790
7807
|
// src/commands/backlog/addPhase.ts
|
|
7791
|
-
import
|
|
7808
|
+
import chalk69 from "chalk";
|
|
7792
7809
|
|
|
7793
7810
|
// src/commands/backlog/resolveInsertPosition.ts
|
|
7794
|
-
import
|
|
7811
|
+
import chalk68 from "chalk";
|
|
7795
7812
|
import { count as count3, eq as eq20 } from "drizzle-orm";
|
|
7796
7813
|
async function resolveInsertPosition(orm, itemId, position) {
|
|
7797
7814
|
const [row] = await orm.select({ cnt: count3() }).from(planPhases).where(eq20(planPhases.itemId, itemId));
|
|
@@ -7800,7 +7817,7 @@ async function resolveInsertPosition(orm, itemId, position) {
|
|
|
7800
7817
|
const pos = Number.parseInt(position, 10);
|
|
7801
7818
|
if (pos < 1 || pos > phaseCount + 1) {
|
|
7802
7819
|
console.log(
|
|
7803
|
-
|
|
7820
|
+
chalk68.red(
|
|
7804
7821
|
`Position ${pos} is out of range. Must be between 1 and ${phaseCount + 1}.`
|
|
7805
7822
|
)
|
|
7806
7823
|
);
|
|
@@ -7817,11 +7834,12 @@ function serializeManualChecks(manualCheck) {
|
|
|
7817
7834
|
|
|
7818
7835
|
// src/commands/backlog/addPhase.ts
|
|
7819
7836
|
async function addPhase(id2, name, options2) {
|
|
7837
|
+
if (!ensureRemoteOrigin()) return;
|
|
7820
7838
|
const found = await findOneItem(id2);
|
|
7821
7839
|
if (!found) return;
|
|
7822
7840
|
const tasks = options2.task ?? [];
|
|
7823
7841
|
if (tasks.length === 0) {
|
|
7824
|
-
console.log(
|
|
7842
|
+
console.log(chalk69.red("At least one --task is required."));
|
|
7825
7843
|
process.exitCode = 1;
|
|
7826
7844
|
return;
|
|
7827
7845
|
}
|
|
@@ -7840,14 +7858,14 @@ async function addPhase(id2, name, options2) {
|
|
|
7840
7858
|
);
|
|
7841
7859
|
const verb = options2.position !== void 0 ? "Inserted" : "Added";
|
|
7842
7860
|
console.log(
|
|
7843
|
-
|
|
7861
|
+
chalk69.green(
|
|
7844
7862
|
`${verb} phase ${phaseIdx + 1} "${name}" to item #${itemId} with ${tasks.length} task(s).`
|
|
7845
7863
|
)
|
|
7846
7864
|
);
|
|
7847
7865
|
}
|
|
7848
7866
|
|
|
7849
7867
|
// src/commands/backlog/list/index.ts
|
|
7850
|
-
import
|
|
7868
|
+
import chalk70 from "chalk";
|
|
7851
7869
|
function filterItems(items2, options2) {
|
|
7852
7870
|
if (options2.status) return items2.filter((i) => i.status === options2.status);
|
|
7853
7871
|
if (!options2.all)
|
|
@@ -7858,7 +7876,7 @@ async function list2(options2) {
|
|
|
7858
7876
|
const allItems = await loadBacklog(options2.allRepos);
|
|
7859
7877
|
const items2 = filterItems(allItems, options2);
|
|
7860
7878
|
if (items2.length === 0) {
|
|
7861
|
-
console.log(
|
|
7879
|
+
console.log(chalk70.dim("Backlog is empty."));
|
|
7862
7880
|
return;
|
|
7863
7881
|
}
|
|
7864
7882
|
const labels = originDisplayLabels(
|
|
@@ -7867,9 +7885,9 @@ async function list2(options2) {
|
|
|
7867
7885
|
const repoNameOf = (item) => item.origin ? labels.get(item.origin) ?? "" : "";
|
|
7868
7886
|
const prefixWidth = options2.allRepos ? Math.max(0, ...items2.map((i) => repoNameOf(i).length)) : 0;
|
|
7869
7887
|
for (const item of items2) {
|
|
7870
|
-
const repoPrefix = options2.allRepos ? `${
|
|
7888
|
+
const repoPrefix = options2.allRepos ? `${chalk70.dim(repoNameOf(item).padEnd(prefixWidth))} ` : "";
|
|
7871
7889
|
console.log(
|
|
7872
|
-
`${repoPrefix}${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
7890
|
+
`${repoPrefix}${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk70.dim(`#${item.id}`)} ${starMarker(item)}${item.name}${phaseLabel(item)}${dependencyLabel(item, allItems)}`
|
|
7873
7891
|
);
|
|
7874
7892
|
if (options2.verbose) {
|
|
7875
7893
|
printVerboseDetails(item);
|
|
@@ -7895,7 +7913,7 @@ function registerItemCommands(cmd) {
|
|
|
7895
7913
|
}
|
|
7896
7914
|
|
|
7897
7915
|
// src/commands/backlog/link.ts
|
|
7898
|
-
import
|
|
7916
|
+
import chalk72 from "chalk";
|
|
7899
7917
|
|
|
7900
7918
|
// src/commands/backlog/hasCycle.ts
|
|
7901
7919
|
function hasCycle(adjacency, fromId, toId) {
|
|
@@ -7927,14 +7945,14 @@ async function loadDependencyGraph(orm) {
|
|
|
7927
7945
|
}
|
|
7928
7946
|
|
|
7929
7947
|
// src/commands/backlog/validateLinkTarget.ts
|
|
7930
|
-
import
|
|
7948
|
+
import chalk71 from "chalk";
|
|
7931
7949
|
function validateLinkTarget(fromItem, fromNum, toNum, linkType) {
|
|
7932
7950
|
const duplicate = (fromItem.links ?? []).some(
|
|
7933
7951
|
(l) => l.targetId === toNum && l.type === linkType
|
|
7934
7952
|
);
|
|
7935
7953
|
if (duplicate) {
|
|
7936
7954
|
console.log(
|
|
7937
|
-
|
|
7955
|
+
chalk71.yellow(`Link already exists: #${fromNum} ${linkType} #${toNum}`)
|
|
7938
7956
|
);
|
|
7939
7957
|
return false;
|
|
7940
7958
|
}
|
|
@@ -7943,7 +7961,7 @@ function validateLinkTarget(fromItem, fromNum, toNum, linkType) {
|
|
|
7943
7961
|
|
|
7944
7962
|
// src/commands/backlog/link.ts
|
|
7945
7963
|
function fail2(message) {
|
|
7946
|
-
console.log(
|
|
7964
|
+
console.log(chalk72.red(message));
|
|
7947
7965
|
return void 0;
|
|
7948
7966
|
}
|
|
7949
7967
|
function parseLinkType(type) {
|
|
@@ -7973,12 +7991,12 @@ async function link(fromId, toId, opts) {
|
|
|
7973
7991
|
if (await createsCycle(orm, linkType, fromNum, toNum)) return;
|
|
7974
7992
|
await orm.insert(links).values({ itemId: fromNum, type: linkType, targetId: toNum });
|
|
7975
7993
|
console.log(
|
|
7976
|
-
|
|
7994
|
+
chalk72.green(`Linked #${fromNum} ${linkType} #${toNum} (${toItem.name})`)
|
|
7977
7995
|
);
|
|
7978
7996
|
}
|
|
7979
7997
|
|
|
7980
7998
|
// src/commands/backlog/unlink.ts
|
|
7981
|
-
import
|
|
7999
|
+
import chalk73 from "chalk";
|
|
7982
8000
|
import { and as and7, eq as eq22 } from "drizzle-orm";
|
|
7983
8001
|
async function unlink(fromId, toId) {
|
|
7984
8002
|
const fromNum = Number.parseInt(fromId, 10);
|
|
@@ -7986,19 +8004,19 @@ async function unlink(fromId, toId) {
|
|
|
7986
8004
|
const { orm } = await getReady();
|
|
7987
8005
|
const fromItem = await loadItem(orm, fromNum);
|
|
7988
8006
|
if (!fromItem) {
|
|
7989
|
-
console.log(
|
|
8007
|
+
console.log(chalk73.red(`Item #${fromId} not found.`));
|
|
7990
8008
|
return;
|
|
7991
8009
|
}
|
|
7992
8010
|
if (!fromItem.links || fromItem.links.length === 0) {
|
|
7993
|
-
console.log(
|
|
8011
|
+
console.log(chalk73.yellow(`No links found on item #${fromId}.`));
|
|
7994
8012
|
return;
|
|
7995
8013
|
}
|
|
7996
8014
|
if (!fromItem.links.some((l) => l.targetId === toNum)) {
|
|
7997
|
-
console.log(
|
|
8015
|
+
console.log(chalk73.yellow(`No link from #${fromId} to #${toId} found.`));
|
|
7998
8016
|
return;
|
|
7999
8017
|
}
|
|
8000
8018
|
await orm.delete(links).where(and7(eq22(links.itemId, fromNum), eq22(links.targetId, toNum)));
|
|
8001
|
-
console.log(
|
|
8019
|
+
console.log(chalk73.green(`Removed link from #${fromId} to #${toId}.`));
|
|
8002
8020
|
}
|
|
8003
8021
|
|
|
8004
8022
|
// src/commands/backlog/registerLinkCommands.ts
|
|
@@ -8012,17 +8030,17 @@ function registerLinkCommands(cmd) {
|
|
|
8012
8030
|
}
|
|
8013
8031
|
|
|
8014
8032
|
// src/commands/backlog/move-repo/index.ts
|
|
8015
|
-
import
|
|
8033
|
+
import chalk75 from "chalk";
|
|
8016
8034
|
import { eq as eq24 } from "drizzle-orm";
|
|
8017
8035
|
|
|
8018
8036
|
// src/commands/backlog/move-repo/confirmMove.ts
|
|
8019
|
-
import
|
|
8037
|
+
import chalk74 from "chalk";
|
|
8020
8038
|
function pluralItems(n) {
|
|
8021
8039
|
return `${n} item${n === 1 ? "" : "s"}`;
|
|
8022
8040
|
}
|
|
8023
8041
|
async function confirmMove(cnt, oldOrigin, newOrigin) {
|
|
8024
8042
|
console.log(
|
|
8025
|
-
`${pluralItems(cnt)}: ${
|
|
8043
|
+
`${pluralItems(cnt)}: ${chalk74.cyan(oldOrigin)} \u2192 ${chalk74.cyan(newOrigin)}`
|
|
8026
8044
|
);
|
|
8027
8045
|
return promptConfirm(`Retag ${pluralItems(cnt)}?`);
|
|
8028
8046
|
}
|
|
@@ -8054,7 +8072,7 @@ Pass the full origin.`
|
|
|
8054
8072
|
|
|
8055
8073
|
// src/commands/backlog/move-repo/index.ts
|
|
8056
8074
|
function fail3(message) {
|
|
8057
|
-
console.log(
|
|
8075
|
+
console.log(chalk75.red(message));
|
|
8058
8076
|
process.exitCode = 1;
|
|
8059
8077
|
}
|
|
8060
8078
|
async function moveRepo(oldOriginRaw, newOriginRaw, options2 = {}) {
|
|
@@ -8070,12 +8088,12 @@ async function moveRepo(oldOriginRaw, newOriginRaw, options2 = {}) {
|
|
|
8070
8088
|
}
|
|
8071
8089
|
const cnt = await countByOrigin(orm, oldOrigin);
|
|
8072
8090
|
if (!options2.yes && !await confirmMove(cnt, oldOrigin, newOrigin)) {
|
|
8073
|
-
console.log(
|
|
8091
|
+
console.log(chalk75.yellow("Move cancelled; no changes made."));
|
|
8074
8092
|
return;
|
|
8075
8093
|
}
|
|
8076
8094
|
await orm.update(items).set({ origin: newOrigin }).where(eq24(items.origin, oldOrigin));
|
|
8077
8095
|
console.log(
|
|
8078
|
-
|
|
8096
|
+
chalk75.green(
|
|
8079
8097
|
`Moved ${pluralItems(cnt)} from "${oldOrigin}" to "${newOrigin}".`
|
|
8080
8098
|
)
|
|
8081
8099
|
);
|
|
@@ -8104,14 +8122,14 @@ function registerPlanCommands(cmd) {
|
|
|
8104
8122
|
}
|
|
8105
8123
|
|
|
8106
8124
|
// src/commands/backlog/refine.ts
|
|
8107
|
-
import
|
|
8125
|
+
import chalk78 from "chalk";
|
|
8108
8126
|
import enquirer7 from "enquirer";
|
|
8109
8127
|
|
|
8110
8128
|
// src/commands/backlog/launchMode.ts
|
|
8111
8129
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
8112
8130
|
|
|
8113
8131
|
// src/commands/backlog/handleLaunchSignal.ts
|
|
8114
|
-
import
|
|
8132
|
+
import chalk77 from "chalk";
|
|
8115
8133
|
|
|
8116
8134
|
// src/commands/backlog/surfaceCreatedItem.ts
|
|
8117
8135
|
async function surfaceCreatedItem(slashCommand, id2) {
|
|
@@ -8129,31 +8147,31 @@ async function surfaceCreatedItem(slashCommand, id2) {
|
|
|
8129
8147
|
}
|
|
8130
8148
|
|
|
8131
8149
|
// src/commands/backlog/tryRunById.ts
|
|
8132
|
-
import
|
|
8150
|
+
import chalk76 from "chalk";
|
|
8133
8151
|
async function tryRunById(id2, options2) {
|
|
8134
8152
|
const numericId = Number.parseInt(id2, 10);
|
|
8135
8153
|
const { orm } = await getReady();
|
|
8136
8154
|
const item = Number.isNaN(numericId) ? void 0 : await loadItem(orm, numericId);
|
|
8137
8155
|
if (!item) {
|
|
8138
|
-
console.log(
|
|
8156
|
+
console.log(chalk76.red(`Item #${id2} not found.`));
|
|
8139
8157
|
return false;
|
|
8140
8158
|
}
|
|
8141
8159
|
if (item.status === "done") {
|
|
8142
|
-
console.log(
|
|
8160
|
+
console.log(chalk76.red(`Item #${id2} is already done.`));
|
|
8143
8161
|
return false;
|
|
8144
8162
|
}
|
|
8145
8163
|
if (item.status === "wontdo") {
|
|
8146
|
-
console.log(
|
|
8164
|
+
console.log(chalk76.red(`Item #${id2} is marked won't do.`));
|
|
8147
8165
|
return false;
|
|
8148
8166
|
}
|
|
8149
8167
|
const hasDeps = (item.links ?? []).some((l) => l.type === "depends-on");
|
|
8150
8168
|
if (hasDeps && isBlocked(item, await loadItemSummaries(orm, getOrigin()))) {
|
|
8151
8169
|
console.log(
|
|
8152
|
-
|
|
8170
|
+
chalk76.red(`Item #${id2} is blocked by unresolved dependencies.`)
|
|
8153
8171
|
);
|
|
8154
8172
|
return false;
|
|
8155
8173
|
}
|
|
8156
|
-
console.log(
|
|
8174
|
+
console.log(chalk76.bold(`
|
|
8157
8175
|
Running backlog item #${id2}...
|
|
8158
8176
|
`));
|
|
8159
8177
|
await run2(id2, options2);
|
|
@@ -8171,7 +8189,7 @@ async function handleLaunchSignal(slashCommand, once) {
|
|
|
8171
8189
|
if (typeof signal.id === "string" && signal.id) {
|
|
8172
8190
|
if (await tryRunById(signal.id, { allowEdits: true })) return;
|
|
8173
8191
|
}
|
|
8174
|
-
console.log(
|
|
8192
|
+
console.log(chalk77.bold("\nChaining into assist next...\n"));
|
|
8175
8193
|
await next({ allowEdits: true, once });
|
|
8176
8194
|
}
|
|
8177
8195
|
}
|
|
@@ -8211,12 +8229,12 @@ async function pickItemForRefine() {
|
|
|
8211
8229
|
(i) => i.status === "todo" || i.status === "in-progress"
|
|
8212
8230
|
);
|
|
8213
8231
|
if (active.length === 0) {
|
|
8214
|
-
console.log(
|
|
8232
|
+
console.log(chalk78.yellow("No active backlog items to refine."));
|
|
8215
8233
|
return void 0;
|
|
8216
8234
|
}
|
|
8217
8235
|
if (active.length === 1) {
|
|
8218
8236
|
const item = active[0];
|
|
8219
|
-
console.log(
|
|
8237
|
+
console.log(chalk78.bold(`Auto-selecting item #${item.id}: ${item.name}`));
|
|
8220
8238
|
return String(item.id);
|
|
8221
8239
|
}
|
|
8222
8240
|
const { selected } = await exitOnCancel(
|
|
@@ -8251,7 +8269,7 @@ function registerRefineCommand(cmd) {
|
|
|
8251
8269
|
}
|
|
8252
8270
|
|
|
8253
8271
|
// src/commands/backlog/rewindPhase.ts
|
|
8254
|
-
import
|
|
8272
|
+
import chalk79 from "chalk";
|
|
8255
8273
|
function validateRewind2(item, plan2, phaseNumber) {
|
|
8256
8274
|
if (phaseNumber < 1 || phaseNumber > plan2.length) {
|
|
8257
8275
|
return `Phase ${phaseNumber} does not exist. Valid range: 1\u2013${plan2.length}.`;
|
|
@@ -8268,13 +8286,13 @@ async function rewindPhase(id2, phase, opts) {
|
|
|
8268
8286
|
const { orm } = await getReady();
|
|
8269
8287
|
const item = await loadItem(orm, Number.parseInt(id2, 10));
|
|
8270
8288
|
if (!item) {
|
|
8271
|
-
console.log(
|
|
8289
|
+
console.log(chalk79.red(`Item #${id2} not found.`));
|
|
8272
8290
|
return;
|
|
8273
8291
|
}
|
|
8274
8292
|
const plan2 = resolveRewindPlan(item);
|
|
8275
8293
|
const error = validateRewind2(item, plan2, phaseNumber);
|
|
8276
8294
|
if (error) {
|
|
8277
|
-
console.log(
|
|
8295
|
+
console.log(chalk79.red(error));
|
|
8278
8296
|
process.exitCode = 1;
|
|
8279
8297
|
return;
|
|
8280
8298
|
}
|
|
@@ -8292,7 +8310,7 @@ async function rewindPhase(id2, phase, opts) {
|
|
|
8292
8310
|
targetPhase: phaseIndex
|
|
8293
8311
|
});
|
|
8294
8312
|
console.log(
|
|
8295
|
-
|
|
8313
|
+
chalk79.green(`Rewound item #${id2} to phase ${phaseNumber} (${phaseName}).`)
|
|
8296
8314
|
);
|
|
8297
8315
|
}
|
|
8298
8316
|
|
|
@@ -8318,22 +8336,22 @@ function registerRunCommand(cmd) {
|
|
|
8318
8336
|
}
|
|
8319
8337
|
|
|
8320
8338
|
// src/commands/backlog/search/index.ts
|
|
8321
|
-
import
|
|
8339
|
+
import chalk80 from "chalk";
|
|
8322
8340
|
async function search(query) {
|
|
8323
8341
|
const items2 = await searchBacklog(query);
|
|
8324
8342
|
if (items2.length === 0) {
|
|
8325
|
-
console.log(
|
|
8343
|
+
console.log(chalk80.dim(`No items matching "${query}".`));
|
|
8326
8344
|
return;
|
|
8327
8345
|
}
|
|
8328
8346
|
console.log(
|
|
8329
|
-
|
|
8347
|
+
chalk80.dim(
|
|
8330
8348
|
`${items2.length} item${items2.length === 1 ? "" : "s"} matching "${query}":
|
|
8331
8349
|
`
|
|
8332
8350
|
)
|
|
8333
8351
|
);
|
|
8334
8352
|
for (const item of items2) {
|
|
8335
8353
|
console.log(
|
|
8336
|
-
`${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
8354
|
+
`${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk80.dim(`#${item.id}`)} ${item.name}`
|
|
8337
8355
|
);
|
|
8338
8356
|
}
|
|
8339
8357
|
}
|
|
@@ -8344,16 +8362,16 @@ function registerSearchCommand(cmd) {
|
|
|
8344
8362
|
}
|
|
8345
8363
|
|
|
8346
8364
|
// src/commands/backlog/delete/index.ts
|
|
8347
|
-
import
|
|
8365
|
+
import chalk81 from "chalk";
|
|
8348
8366
|
async function del(id2) {
|
|
8349
8367
|
const name = await removeItem(id2);
|
|
8350
8368
|
if (name) {
|
|
8351
|
-
console.log(
|
|
8369
|
+
console.log(chalk81.green(`Deleted item #${id2}: ${name}`));
|
|
8352
8370
|
}
|
|
8353
8371
|
}
|
|
8354
8372
|
|
|
8355
8373
|
// src/commands/backlog/done/index.ts
|
|
8356
|
-
import
|
|
8374
|
+
import chalk82 from "chalk";
|
|
8357
8375
|
async function done(id2, summary) {
|
|
8358
8376
|
const found = await findOneItem(id2);
|
|
8359
8377
|
if (!found) return;
|
|
@@ -8367,12 +8385,12 @@ async function done(id2, summary) {
|
|
|
8367
8385
|
const pending = item.plan.slice(completedCount);
|
|
8368
8386
|
if (pending.length > 0) {
|
|
8369
8387
|
console.log(
|
|
8370
|
-
|
|
8388
|
+
chalk82.red(
|
|
8371
8389
|
`Cannot complete item #${id2}: ${pending.length} pending phase(s):`
|
|
8372
8390
|
)
|
|
8373
8391
|
);
|
|
8374
8392
|
for (const phase of pending) {
|
|
8375
|
-
console.log(
|
|
8393
|
+
console.log(chalk82.yellow(` - ${phase.name}`));
|
|
8376
8394
|
}
|
|
8377
8395
|
process.exitCode = 1;
|
|
8378
8396
|
return;
|
|
@@ -8383,11 +8401,11 @@ async function done(id2, summary) {
|
|
|
8383
8401
|
const phase = item.currentPhase ?? 1;
|
|
8384
8402
|
await appendComment(orm, item.id, summary, { phase, type: "summary" });
|
|
8385
8403
|
}
|
|
8386
|
-
console.log(
|
|
8404
|
+
console.log(chalk82.green(`Completed item #${id2}: ${item.name}`));
|
|
8387
8405
|
}
|
|
8388
8406
|
|
|
8389
8407
|
// src/commands/backlog/set-status/index.ts
|
|
8390
|
-
import
|
|
8408
|
+
import chalk83 from "chalk";
|
|
8391
8409
|
var allowedStatuses = [
|
|
8392
8410
|
"todo",
|
|
8393
8411
|
"in-progress",
|
|
@@ -8397,7 +8415,7 @@ var allowedStatuses = [
|
|
|
8397
8415
|
async function setStatusCommand(id2, status2) {
|
|
8398
8416
|
if (!allowedStatuses.includes(status2)) {
|
|
8399
8417
|
console.log(
|
|
8400
|
-
|
|
8418
|
+
chalk83.red(
|
|
8401
8419
|
`Invalid status "${status2}". Must be one of: ${allowedStatuses.join(", ")}.`
|
|
8402
8420
|
)
|
|
8403
8421
|
);
|
|
@@ -8406,19 +8424,19 @@ async function setStatusCommand(id2, status2) {
|
|
|
8406
8424
|
}
|
|
8407
8425
|
const name = await setStatus(id2, status2);
|
|
8408
8426
|
if (name) {
|
|
8409
|
-
console.log(
|
|
8427
|
+
console.log(chalk83.green(`Set item #${id2} to ${status2}: ${name}`));
|
|
8410
8428
|
}
|
|
8411
8429
|
}
|
|
8412
8430
|
|
|
8413
8431
|
// src/commands/backlog/star/index.ts
|
|
8414
|
-
import
|
|
8432
|
+
import chalk85 from "chalk";
|
|
8415
8433
|
|
|
8416
8434
|
// src/commands/backlog/setStarred.ts
|
|
8417
|
-
import
|
|
8435
|
+
import chalk84 from "chalk";
|
|
8418
8436
|
async function setStarred(id2, starred) {
|
|
8419
8437
|
const { orm } = await getReady();
|
|
8420
8438
|
const name = await updateStarred(orm, Number.parseInt(id2, 10), starred);
|
|
8421
|
-
if (name === void 0) console.log(
|
|
8439
|
+
if (name === void 0) console.log(chalk84.red(`Item #${id2} not found.`));
|
|
8422
8440
|
return name;
|
|
8423
8441
|
}
|
|
8424
8442
|
|
|
@@ -8426,45 +8444,45 @@ async function setStarred(id2, starred) {
|
|
|
8426
8444
|
async function star(id2) {
|
|
8427
8445
|
const name = await setStarred(id2, true);
|
|
8428
8446
|
if (name) {
|
|
8429
|
-
console.log(
|
|
8447
|
+
console.log(chalk85.green(`Starred item #${id2}: ${name}`));
|
|
8430
8448
|
}
|
|
8431
8449
|
}
|
|
8432
8450
|
|
|
8433
8451
|
// src/commands/backlog/start/index.ts
|
|
8434
|
-
import
|
|
8452
|
+
import chalk86 from "chalk";
|
|
8435
8453
|
async function start(id2) {
|
|
8436
8454
|
const name = await setStatus(id2, "in-progress");
|
|
8437
8455
|
if (name) {
|
|
8438
|
-
console.log(
|
|
8456
|
+
console.log(chalk86.green(`Started item #${id2}: ${name}`));
|
|
8439
8457
|
}
|
|
8440
8458
|
}
|
|
8441
8459
|
|
|
8442
8460
|
// src/commands/backlog/stop/index.ts
|
|
8443
|
-
import
|
|
8461
|
+
import chalk87 from "chalk";
|
|
8444
8462
|
import { and as and8, eq as eq25 } from "drizzle-orm";
|
|
8445
8463
|
async function stop() {
|
|
8446
8464
|
const { orm } = await getReady();
|
|
8447
8465
|
const stopped = await orm.update(items).set({ status: "todo", currentPhase: 1 }).where(and8(eq25(items.status, "in-progress"), eq25(items.origin, getOrigin()))).returning({ id: items.id, name: items.name });
|
|
8448
8466
|
if (stopped.length === 0) {
|
|
8449
|
-
console.log(
|
|
8467
|
+
console.log(chalk87.yellow("No in-progress items to stop."));
|
|
8450
8468
|
return;
|
|
8451
8469
|
}
|
|
8452
8470
|
for (const item of stopped) {
|
|
8453
|
-
console.log(
|
|
8471
|
+
console.log(chalk87.yellow(`Stopped item #${item.id}: ${item.name}`));
|
|
8454
8472
|
}
|
|
8455
8473
|
}
|
|
8456
8474
|
|
|
8457
8475
|
// src/commands/backlog/unstar/index.ts
|
|
8458
|
-
import
|
|
8476
|
+
import chalk88 from "chalk";
|
|
8459
8477
|
async function unstar(id2) {
|
|
8460
8478
|
const name = await setStarred(id2, false);
|
|
8461
8479
|
if (name) {
|
|
8462
|
-
console.log(
|
|
8480
|
+
console.log(chalk88.green(`Unstarred item #${id2}: ${name}`));
|
|
8463
8481
|
}
|
|
8464
8482
|
}
|
|
8465
8483
|
|
|
8466
8484
|
// src/commands/backlog/wontdo/index.ts
|
|
8467
|
-
import
|
|
8485
|
+
import chalk89 from "chalk";
|
|
8468
8486
|
async function wontdo(id2, reason) {
|
|
8469
8487
|
const found = await findOneItem(id2);
|
|
8470
8488
|
if (!found) return;
|
|
@@ -8474,7 +8492,7 @@ async function wontdo(id2, reason) {
|
|
|
8474
8492
|
const phase = item.currentPhase ?? 1;
|
|
8475
8493
|
await appendComment(orm, item.id, reason, { phase, type: "summary" });
|
|
8476
8494
|
}
|
|
8477
|
-
console.log(
|
|
8495
|
+
console.log(chalk89.red(`Won't do item #${id2}: ${item.name}`));
|
|
8478
8496
|
}
|
|
8479
8497
|
|
|
8480
8498
|
// src/commands/backlog/registerStatusCommands.ts
|
|
@@ -8492,11 +8510,11 @@ function registerStatusCommands(cmd) {
|
|
|
8492
8510
|
}
|
|
8493
8511
|
|
|
8494
8512
|
// src/commands/backlog/addSubtask.ts
|
|
8495
|
-
import
|
|
8513
|
+
import chalk90 from "chalk";
|
|
8496
8514
|
async function addSubtask(id2, options2) {
|
|
8497
8515
|
const title = options2.title?.trim();
|
|
8498
8516
|
if (!title) {
|
|
8499
|
-
console.log(
|
|
8517
|
+
console.log(chalk90.red("A sub-task title is required (--title)."));
|
|
8500
8518
|
process.exitCode = 1;
|
|
8501
8519
|
return;
|
|
8502
8520
|
}
|
|
@@ -8507,16 +8525,16 @@ async function addSubtask(id2, options2) {
|
|
|
8507
8525
|
}
|
|
8508
8526
|
const { orm, item } = found;
|
|
8509
8527
|
await insertSubtask(orm, item.id, title, options2.desc);
|
|
8510
|
-
console.log(
|
|
8528
|
+
console.log(chalk90.green(`Added sub-task to item #${id2}: ${title}`));
|
|
8511
8529
|
}
|
|
8512
8530
|
|
|
8513
8531
|
// src/commands/backlog/subtaskStatus.ts
|
|
8514
|
-
import
|
|
8532
|
+
import chalk91 from "chalk";
|
|
8515
8533
|
var validStatuses2 = ["todo", "in-progress", "done"];
|
|
8516
8534
|
async function subtaskStatus(id2, index3, status2) {
|
|
8517
8535
|
if (!validStatuses2.includes(status2)) {
|
|
8518
8536
|
console.log(
|
|
8519
|
-
|
|
8537
|
+
chalk91.red(
|
|
8520
8538
|
`Invalid status "${status2}". Use one of: ${validStatuses2.join(", ")}.`
|
|
8521
8539
|
)
|
|
8522
8540
|
);
|
|
@@ -8533,7 +8551,7 @@ async function subtaskStatus(id2, index3, status2) {
|
|
|
8533
8551
|
const subtasks = item.subtasks ?? [];
|
|
8534
8552
|
if (Number.isNaN(position) || position < 1 || position > subtasks.length) {
|
|
8535
8553
|
console.log(
|
|
8536
|
-
|
|
8554
|
+
chalk91.red(
|
|
8537
8555
|
`Item #${id2} has no sub-task ${index3}${subtasks.length > 0 ? ` (1-${subtasks.length})` : ""}.`
|
|
8538
8556
|
)
|
|
8539
8557
|
);
|
|
@@ -8547,7 +8565,7 @@ async function subtaskStatus(id2, index3, status2) {
|
|
|
8547
8565
|
status2
|
|
8548
8566
|
);
|
|
8549
8567
|
console.log(
|
|
8550
|
-
|
|
8568
|
+
chalk91.green(
|
|
8551
8569
|
`Set sub-task ${position} of item #${id2} to ${status2}: ${title}`
|
|
8552
8570
|
)
|
|
8553
8571
|
);
|
|
@@ -8561,39 +8579,22 @@ function registerSubtaskCommands(cmd) {
|
|
|
8561
8579
|
).action(subtaskStatus);
|
|
8562
8580
|
}
|
|
8563
8581
|
|
|
8564
|
-
// src/commands/backlog/
|
|
8582
|
+
// src/commands/backlog/movePhase.ts
|
|
8565
8583
|
import chalk92 from "chalk";
|
|
8566
|
-
import {
|
|
8584
|
+
import { count as count6, eq as eq28 } from "drizzle-orm";
|
|
8567
8585
|
|
|
8568
|
-
// src/commands/backlog/
|
|
8569
|
-
import
|
|
8570
|
-
import { and as and9, count as count5, eq as eq26 } from "drizzle-orm";
|
|
8571
|
-
async function findPhase(id2, phase) {
|
|
8572
|
-
const found = await findOneItem(id2);
|
|
8573
|
-
if (!found) return void 0;
|
|
8574
|
-
const { orm, item } = found;
|
|
8575
|
-
const itemId = item.id;
|
|
8576
|
-
const phaseIdx = Number.parseInt(phase, 10) - 1;
|
|
8577
|
-
const [row] = await orm.select({ cnt: count5() }).from(planPhases).where(and9(eq26(planPhases.itemId, itemId), eq26(planPhases.idx, phaseIdx)));
|
|
8578
|
-
if (!row || row.cnt === 0) {
|
|
8579
|
-
console.log(
|
|
8580
|
-
chalk91.red(`Phase ${phaseIdx + 1} not found on item #${itemId}.`)
|
|
8581
|
-
);
|
|
8582
|
-
process.exitCode = 1;
|
|
8583
|
-
return void 0;
|
|
8584
|
-
}
|
|
8585
|
-
return { item, orm, itemId, phaseIdx };
|
|
8586
|
-
}
|
|
8586
|
+
// src/commands/backlog/reorderPhaseRows.ts
|
|
8587
|
+
import { and as and10, asc as asc7, eq as eq27 } from "drizzle-orm";
|
|
8587
8588
|
|
|
8588
8589
|
// src/commands/backlog/reindexPhases.ts
|
|
8589
|
-
import { and as
|
|
8590
|
+
import { and as and9, asc as asc6, count as count5, eq as eq26 } from "drizzle-orm";
|
|
8590
8591
|
async function reindexPhases(db, itemId) {
|
|
8591
|
-
const remaining = await db.select({ idx: planPhases.idx }).from(planPhases).where(
|
|
8592
|
+
const remaining = await db.select({ idx: planPhases.idx }).from(planPhases).where(eq26(planPhases.itemId, itemId)).orderBy(asc6(planPhases.idx));
|
|
8592
8593
|
for (let i = 0; i < remaining.length; i++) {
|
|
8593
8594
|
const oldIdx = remaining[i].idx;
|
|
8594
8595
|
if (oldIdx === i) continue;
|
|
8595
|
-
await db.update(planTasks).set({ phaseIdx: i }).where(
|
|
8596
|
-
await db.update(planPhases).set({ idx: i }).where(
|
|
8596
|
+
await db.update(planTasks).set({ phaseIdx: i }).where(and9(eq26(planTasks.itemId, itemId), eq26(planTasks.phaseIdx, oldIdx)));
|
|
8597
|
+
await db.update(planPhases).set({ idx: i }).where(and9(eq26(planPhases.itemId, itemId), eq26(planPhases.idx, oldIdx)));
|
|
8597
8598
|
}
|
|
8598
8599
|
}
|
|
8599
8600
|
async function adjustCurrentPhase(db, item, removedIdx) {
|
|
@@ -8601,36 +8602,130 @@ async function adjustCurrentPhase(db, item, removedIdx) {
|
|
|
8601
8602
|
if (currentPhase === void 0) return;
|
|
8602
8603
|
const currentIdx = currentPhase - 1;
|
|
8603
8604
|
if (removedIdx < currentIdx) {
|
|
8604
|
-
await db.update(items).set({ currentPhase: currentPhase - 1 }).where(
|
|
8605
|
+
await db.update(items).set({ currentPhase: currentPhase - 1 }).where(eq26(items.id, item.id));
|
|
8605
8606
|
return;
|
|
8606
8607
|
}
|
|
8607
8608
|
if (removedIdx !== currentIdx) return;
|
|
8608
|
-
const [row] = await db.select({ cnt:
|
|
8609
|
+
const [row] = await db.select({ cnt: count5() }).from(planPhases).where(eq26(planPhases.itemId, item.id));
|
|
8609
8610
|
const cnt = row?.cnt ?? 0;
|
|
8610
|
-
await db.update(items).set({ currentPhase: cnt === 0 ? null : Math.min(currentPhase, cnt) }).where(
|
|
8611
|
+
await db.update(items).set({ currentPhase: cnt === 0 ? null : Math.min(currentPhase, cnt) }).where(eq26(items.id, item.id));
|
|
8611
8612
|
}
|
|
8612
8613
|
|
|
8613
|
-
// src/commands/backlog/
|
|
8614
|
-
async function
|
|
8615
|
-
const found = await findPhase(id2, phase);
|
|
8616
|
-
if (!found) return;
|
|
8617
|
-
const { item, orm, itemId, phaseIdx } = found;
|
|
8614
|
+
// src/commands/backlog/reorderPhaseRows.ts
|
|
8615
|
+
async function reorderPhaseRows(orm, itemId, fromIdx, toIdx) {
|
|
8618
8616
|
await orm.transaction(async (tx) => {
|
|
8617
|
+
const [phaseRow] = await tx.select({ name: planPhases.name, manualChecks: planPhases.manualChecks }).from(planPhases).where(and10(eq27(planPhases.itemId, itemId), eq27(planPhases.idx, fromIdx)));
|
|
8618
|
+
const tasks = await tx.select({ idx: planTasks.idx, task: planTasks.task }).from(planTasks).where(and10(eq27(planTasks.itemId, itemId), eq27(planTasks.phaseIdx, fromIdx))).orderBy(asc7(planTasks.idx));
|
|
8619
8619
|
await tx.delete(planTasks).where(
|
|
8620
|
-
|
|
8620
|
+
and10(eq27(planTasks.itemId, itemId), eq27(planTasks.phaseIdx, fromIdx))
|
|
8621
8621
|
);
|
|
8622
|
-
await tx.delete(planPhases).where(
|
|
8622
|
+
await tx.delete(planPhases).where(and10(eq27(planPhases.itemId, itemId), eq27(planPhases.idx, fromIdx)));
|
|
8623
8623
|
await reindexPhases(tx, itemId);
|
|
8624
|
-
await
|
|
8624
|
+
await shiftPhasesUp(tx, itemId, toIdx);
|
|
8625
|
+
await tx.insert(planPhases).values({
|
|
8626
|
+
itemId,
|
|
8627
|
+
idx: toIdx,
|
|
8628
|
+
name: phaseRow.name,
|
|
8629
|
+
manualChecks: phaseRow.manualChecks
|
|
8630
|
+
});
|
|
8631
|
+
if (tasks.length) {
|
|
8632
|
+
await tx.insert(planTasks).values(
|
|
8633
|
+
tasks.map((t) => ({
|
|
8634
|
+
itemId,
|
|
8635
|
+
phaseIdx: toIdx,
|
|
8636
|
+
idx: t.idx,
|
|
8637
|
+
task: t.task
|
|
8638
|
+
}))
|
|
8639
|
+
);
|
|
8640
|
+
}
|
|
8625
8641
|
});
|
|
8626
|
-
console.log(
|
|
8627
|
-
chalk92.green(`Removed phase ${phaseIdx + 1} from item #${itemId}.`)
|
|
8628
|
-
);
|
|
8629
8642
|
}
|
|
8630
8643
|
|
|
8631
|
-
// src/commands/backlog/
|
|
8644
|
+
// src/commands/backlog/movePhase.ts
|
|
8645
|
+
function toIndex(value, phaseCount) {
|
|
8646
|
+
const pos = Number.parseInt(value, 10);
|
|
8647
|
+
if (Number.isNaN(pos) || pos < 1 || pos > phaseCount) {
|
|
8648
|
+
console.log(
|
|
8649
|
+
chalk92.red(
|
|
8650
|
+
`Position "${value}" is out of range. Must be between 1 and ${phaseCount}.`
|
|
8651
|
+
)
|
|
8652
|
+
);
|
|
8653
|
+
process.exitCode = 1;
|
|
8654
|
+
return void 0;
|
|
8655
|
+
}
|
|
8656
|
+
return pos - 1;
|
|
8657
|
+
}
|
|
8658
|
+
async function movePhase(id2, from, to) {
|
|
8659
|
+
const found = await findOneItem(id2);
|
|
8660
|
+
if (!found) return;
|
|
8661
|
+
const { orm, item } = found;
|
|
8662
|
+
const itemId = item.id;
|
|
8663
|
+
const [row] = await orm.select({ cnt: count6() }).from(planPhases).where(eq28(planPhases.itemId, itemId));
|
|
8664
|
+
const phaseCount = row?.cnt ?? 0;
|
|
8665
|
+
const fromIdx = toIndex(from, phaseCount);
|
|
8666
|
+
if (fromIdx === void 0) return;
|
|
8667
|
+
const toIdx = toIndex(to, phaseCount);
|
|
8668
|
+
if (toIdx === void 0) return;
|
|
8669
|
+
if (fromIdx !== toIdx) {
|
|
8670
|
+
await reorderPhaseRows(orm, itemId, fromIdx, toIdx);
|
|
8671
|
+
}
|
|
8672
|
+
console.log(chalk92.green(`Moved phase ${from} to position ${to}.`));
|
|
8673
|
+
}
|
|
8674
|
+
|
|
8675
|
+
// src/commands/backlog/updatePhase.ts
|
|
8632
8676
|
import chalk94 from "chalk";
|
|
8633
|
-
|
|
8677
|
+
|
|
8678
|
+
// src/commands/backlog/applyPhaseUpdate.ts
|
|
8679
|
+
import { and as and11, eq as eq29 } from "drizzle-orm";
|
|
8680
|
+
async function applyPhaseUpdate(orm, itemId, phaseIdx, fields) {
|
|
8681
|
+
await orm.transaction(async (tx) => {
|
|
8682
|
+
if (fields.name) {
|
|
8683
|
+
await tx.update(planPhases).set({ name: fields.name }).where(
|
|
8684
|
+
and11(eq29(planPhases.itemId, itemId), eq29(planPhases.idx, phaseIdx))
|
|
8685
|
+
);
|
|
8686
|
+
}
|
|
8687
|
+
if (fields.manualCheck) {
|
|
8688
|
+
await tx.update(planPhases).set({ manualChecks: JSON.stringify(fields.manualCheck) }).where(
|
|
8689
|
+
and11(eq29(planPhases.itemId, itemId), eq29(planPhases.idx, phaseIdx))
|
|
8690
|
+
);
|
|
8691
|
+
}
|
|
8692
|
+
if (fields.task) {
|
|
8693
|
+
await tx.delete(planTasks).where(
|
|
8694
|
+
and11(eq29(planTasks.itemId, itemId), eq29(planTasks.phaseIdx, phaseIdx))
|
|
8695
|
+
);
|
|
8696
|
+
if (fields.task.length) {
|
|
8697
|
+
await tx.insert(planTasks).values(
|
|
8698
|
+
fields.task.map((task, i) => ({
|
|
8699
|
+
itemId,
|
|
8700
|
+
phaseIdx,
|
|
8701
|
+
idx: i,
|
|
8702
|
+
task
|
|
8703
|
+
}))
|
|
8704
|
+
);
|
|
8705
|
+
}
|
|
8706
|
+
}
|
|
8707
|
+
});
|
|
8708
|
+
}
|
|
8709
|
+
|
|
8710
|
+
// src/commands/backlog/findPhase.ts
|
|
8711
|
+
import chalk93 from "chalk";
|
|
8712
|
+
import { and as and12, count as count7, eq as eq30 } from "drizzle-orm";
|
|
8713
|
+
async function findPhase(id2, phase) {
|
|
8714
|
+
const found = await findOneItem(id2);
|
|
8715
|
+
if (!found) return void 0;
|
|
8716
|
+
const { orm, item } = found;
|
|
8717
|
+
const itemId = item.id;
|
|
8718
|
+
const phaseIdx = Number.parseInt(phase, 10) - 1;
|
|
8719
|
+
const [row] = await orm.select({ cnt: count7() }).from(planPhases).where(and12(eq30(planPhases.itemId, itemId), eq30(planPhases.idx, phaseIdx)));
|
|
8720
|
+
if (!row || row.cnt === 0) {
|
|
8721
|
+
console.log(
|
|
8722
|
+
chalk93.red(`Phase ${phaseIdx + 1} not found on item #${itemId}.`)
|
|
8723
|
+
);
|
|
8724
|
+
process.exitCode = 1;
|
|
8725
|
+
return void 0;
|
|
8726
|
+
}
|
|
8727
|
+
return { item, orm, itemId, phaseIdx };
|
|
8728
|
+
}
|
|
8634
8729
|
|
|
8635
8730
|
// src/commands/backlog/update/parseListIndex.ts
|
|
8636
8731
|
function parseListIndex(raw, length, label2) {
|
|
@@ -8686,123 +8781,6 @@ function applyListMutations(current, options2, flags) {
|
|
|
8686
8781
|
return { ok: true, items: items2 };
|
|
8687
8782
|
}
|
|
8688
8783
|
|
|
8689
|
-
// src/commands/backlog/update/applyAcMutations.ts
|
|
8690
|
-
function hasAcMutations(options2) {
|
|
8691
|
-
return hasListMutations({
|
|
8692
|
-
add: options2.addAc,
|
|
8693
|
-
edit: options2.editAc,
|
|
8694
|
-
remove: options2.removeAc
|
|
8695
|
-
});
|
|
8696
|
-
}
|
|
8697
|
-
function applyAcMutations(current, options2) {
|
|
8698
|
-
const result = applyListMutations(
|
|
8699
|
-
current,
|
|
8700
|
-
{ add: options2.addAc, edit: options2.editAc, remove: options2.removeAc },
|
|
8701
|
-
{ add: "--add-ac", edit: "--edit-ac", remove: "--remove-ac" }
|
|
8702
|
-
);
|
|
8703
|
-
if (!result.ok) return result;
|
|
8704
|
-
return { ok: true, criteria: result.items };
|
|
8705
|
-
}
|
|
8706
|
-
|
|
8707
|
-
// src/commands/backlog/update/buildUpdateValues.ts
|
|
8708
|
-
import chalk93 from "chalk";
|
|
8709
|
-
function buildUpdateValues(options2) {
|
|
8710
|
-
const { name, desc: desc6, type, ac } = options2;
|
|
8711
|
-
if (!name && !desc6 && !type && !ac) {
|
|
8712
|
-
console.log(chalk93.red("Nothing to update. Provide at least one flag."));
|
|
8713
|
-
process.exitCode = 1;
|
|
8714
|
-
return void 0;
|
|
8715
|
-
}
|
|
8716
|
-
if (type && type !== "story" && type !== "bug") {
|
|
8717
|
-
console.log(chalk93.red('Invalid type. Must be "story" or "bug".'));
|
|
8718
|
-
process.exitCode = 1;
|
|
8719
|
-
return void 0;
|
|
8720
|
-
}
|
|
8721
|
-
const set = {};
|
|
8722
|
-
const fieldNames = [];
|
|
8723
|
-
if (name) {
|
|
8724
|
-
set.name = name;
|
|
8725
|
-
fieldNames.push("name");
|
|
8726
|
-
}
|
|
8727
|
-
if (desc6) {
|
|
8728
|
-
set.description = desc6;
|
|
8729
|
-
fieldNames.push("description");
|
|
8730
|
-
}
|
|
8731
|
-
if (type) {
|
|
8732
|
-
set.type = type;
|
|
8733
|
-
fieldNames.push("type");
|
|
8734
|
-
}
|
|
8735
|
-
if (ac) {
|
|
8736
|
-
set.acceptanceCriteria = JSON.stringify(ac);
|
|
8737
|
-
fieldNames.push("acceptance criteria");
|
|
8738
|
-
}
|
|
8739
|
-
return { set, fields: fieldNames.join(", ") };
|
|
8740
|
-
}
|
|
8741
|
-
|
|
8742
|
-
// src/commands/backlog/update/index.ts
|
|
8743
|
-
async function update(id2, options2) {
|
|
8744
|
-
const found = await findOneItem(id2);
|
|
8745
|
-
if (!found) return;
|
|
8746
|
-
let ac = options2.ac;
|
|
8747
|
-
if (hasAcMutations(options2)) {
|
|
8748
|
-
if (options2.ac) {
|
|
8749
|
-
console.log(
|
|
8750
|
-
chalk94.red("Cannot combine --ac with --add-ac/--edit-ac/--remove-ac.")
|
|
8751
|
-
);
|
|
8752
|
-
process.exitCode = 1;
|
|
8753
|
-
return;
|
|
8754
|
-
}
|
|
8755
|
-
const mutation = applyAcMutations(found.item.acceptanceCriteria, options2);
|
|
8756
|
-
if (!mutation.ok) {
|
|
8757
|
-
console.log(chalk94.red(mutation.error));
|
|
8758
|
-
process.exitCode = 1;
|
|
8759
|
-
return;
|
|
8760
|
-
}
|
|
8761
|
-
ac = mutation.criteria;
|
|
8762
|
-
}
|
|
8763
|
-
const built = buildUpdateValues({ ...options2, ac });
|
|
8764
|
-
if (!built) return;
|
|
8765
|
-
const { orm } = found;
|
|
8766
|
-
const itemId = found.item.id;
|
|
8767
|
-
await orm.update(items).set(built.set).where(eq29(items.id, itemId));
|
|
8768
|
-
console.log(chalk94.green(`Updated ${built.fields} on item #${itemId}.`));
|
|
8769
|
-
}
|
|
8770
|
-
|
|
8771
|
-
// src/commands/backlog/updatePhase.ts
|
|
8772
|
-
import chalk95 from "chalk";
|
|
8773
|
-
|
|
8774
|
-
// src/commands/backlog/applyPhaseUpdate.ts
|
|
8775
|
-
import { and as and12, eq as eq30 } from "drizzle-orm";
|
|
8776
|
-
async function applyPhaseUpdate(orm, itemId, phaseIdx, fields) {
|
|
8777
|
-
await orm.transaction(async (tx) => {
|
|
8778
|
-
if (fields.name) {
|
|
8779
|
-
await tx.update(planPhases).set({ name: fields.name }).where(
|
|
8780
|
-
and12(eq30(planPhases.itemId, itemId), eq30(planPhases.idx, phaseIdx))
|
|
8781
|
-
);
|
|
8782
|
-
}
|
|
8783
|
-
if (fields.manualCheck) {
|
|
8784
|
-
await tx.update(planPhases).set({ manualChecks: JSON.stringify(fields.manualCheck) }).where(
|
|
8785
|
-
and12(eq30(planPhases.itemId, itemId), eq30(planPhases.idx, phaseIdx))
|
|
8786
|
-
);
|
|
8787
|
-
}
|
|
8788
|
-
if (fields.task) {
|
|
8789
|
-
await tx.delete(planTasks).where(
|
|
8790
|
-
and12(eq30(planTasks.itemId, itemId), eq30(planTasks.phaseIdx, phaseIdx))
|
|
8791
|
-
);
|
|
8792
|
-
if (fields.task.length) {
|
|
8793
|
-
await tx.insert(planTasks).values(
|
|
8794
|
-
fields.task.map((task, i) => ({
|
|
8795
|
-
itemId,
|
|
8796
|
-
phaseIdx,
|
|
8797
|
-
idx: i,
|
|
8798
|
-
task
|
|
8799
|
-
}))
|
|
8800
|
-
);
|
|
8801
|
-
}
|
|
8802
|
-
}
|
|
8803
|
-
});
|
|
8804
|
-
}
|
|
8805
|
-
|
|
8806
8784
|
// src/commands/backlog/update/resolveListUpdate.ts
|
|
8807
8785
|
function resolveListUpdate(whole, current, mutations, wholeFlag, flags) {
|
|
8808
8786
|
if (!hasListMutations(mutations)) return { ok: true, items: whole };
|
|
@@ -8866,55 +8844,172 @@ function resolvePhaseFields(options2, current) {
|
|
|
8866
8844
|
return buildFields(options2.name, tasks, checks);
|
|
8867
8845
|
}
|
|
8868
8846
|
|
|
8869
|
-
// src/commands/backlog/updatePhase.ts
|
|
8870
|
-
async function updatePhase(id2, phase, options2) {
|
|
8871
|
-
const found = await findPhase(id2, phase);
|
|
8847
|
+
// src/commands/backlog/updatePhase.ts
|
|
8848
|
+
async function updatePhase(id2, phase, options2) {
|
|
8849
|
+
const found = await findPhase(id2, phase);
|
|
8850
|
+
if (!found) return;
|
|
8851
|
+
const { item, orm, itemId, phaseIdx } = found;
|
|
8852
|
+
const resolved = resolvePhaseFields(options2, item.plan?.[phaseIdx]);
|
|
8853
|
+
if (!resolved.ok) {
|
|
8854
|
+
console.log(chalk94.red(resolved.error));
|
|
8855
|
+
process.exitCode = 1;
|
|
8856
|
+
return;
|
|
8857
|
+
}
|
|
8858
|
+
const { name, task, manualCheck } = resolved.fields;
|
|
8859
|
+
await applyPhaseUpdate(orm, itemId, phaseIdx, { name, task, manualCheck });
|
|
8860
|
+
const fields = [
|
|
8861
|
+
name && "name",
|
|
8862
|
+
task && "tasks",
|
|
8863
|
+
manualCheck && "manual checks"
|
|
8864
|
+
].filter(Boolean).join(", ");
|
|
8865
|
+
console.log(
|
|
8866
|
+
chalk94.green(
|
|
8867
|
+
`Updated ${fields} on phase ${phaseIdx + 1} of item #${itemId}.`
|
|
8868
|
+
)
|
|
8869
|
+
);
|
|
8870
|
+
}
|
|
8871
|
+
|
|
8872
|
+
// src/commands/backlog/registerUpdatePhaseCommand.ts
|
|
8873
|
+
function collect(value, previous) {
|
|
8874
|
+
return [...previous, value];
|
|
8875
|
+
}
|
|
8876
|
+
function registerUpdatePhaseCommand(cmd) {
|
|
8877
|
+
cmd.command("update-phase <id> <phase>").description("Modify a plan phase on a backlog item").option("--name <name>", "New phase name").option("--task <task...>", "Replace tasks (repeatable)").option("--manual-check <check...>", "Replace manual checks (repeatable)").option("--add-task <text>", "Append one task (repeatable)", collect, []).option("--edit-task <n> <text...>", "Replace task n (1-based) in place").option("--remove-task <n>", "Remove task n (1-based)").option(
|
|
8878
|
+
"--add-check <text>",
|
|
8879
|
+
"Append one manual check (repeatable)",
|
|
8880
|
+
collect,
|
|
8881
|
+
[]
|
|
8882
|
+
).option(
|
|
8883
|
+
"--edit-check <n> <text...>",
|
|
8884
|
+
"Replace manual check n (1-based) in place"
|
|
8885
|
+
).option("--remove-check <n>", "Remove manual check n (1-based)").action(updatePhase);
|
|
8886
|
+
}
|
|
8887
|
+
|
|
8888
|
+
// src/commands/backlog/removePhase.ts
|
|
8889
|
+
import chalk95 from "chalk";
|
|
8890
|
+
import { and as and13, eq as eq31 } from "drizzle-orm";
|
|
8891
|
+
async function removePhase(id2, phase) {
|
|
8892
|
+
const found = await findPhase(id2, phase);
|
|
8893
|
+
if (!found) return;
|
|
8894
|
+
const { item, orm, itemId, phaseIdx } = found;
|
|
8895
|
+
await orm.transaction(async (tx) => {
|
|
8896
|
+
await tx.delete(planTasks).where(
|
|
8897
|
+
and13(eq31(planTasks.itemId, itemId), eq31(planTasks.phaseIdx, phaseIdx))
|
|
8898
|
+
);
|
|
8899
|
+
await tx.delete(planPhases).where(and13(eq31(planPhases.itemId, itemId), eq31(planPhases.idx, phaseIdx)));
|
|
8900
|
+
await reindexPhases(tx, itemId);
|
|
8901
|
+
await adjustCurrentPhase(tx, item, phaseIdx);
|
|
8902
|
+
});
|
|
8903
|
+
console.log(
|
|
8904
|
+
chalk95.green(`Removed phase ${phaseIdx + 1} from item #${itemId}.`)
|
|
8905
|
+
);
|
|
8906
|
+
}
|
|
8907
|
+
|
|
8908
|
+
// src/commands/backlog/update/index.ts
|
|
8909
|
+
import chalk97 from "chalk";
|
|
8910
|
+
import { eq as eq32 } from "drizzle-orm";
|
|
8911
|
+
|
|
8912
|
+
// src/commands/backlog/update/applyAcMutations.ts
|
|
8913
|
+
function hasAcMutations(options2) {
|
|
8914
|
+
return hasListMutations({
|
|
8915
|
+
add: options2.addAc,
|
|
8916
|
+
edit: options2.editAc,
|
|
8917
|
+
remove: options2.removeAc
|
|
8918
|
+
});
|
|
8919
|
+
}
|
|
8920
|
+
function applyAcMutations(current, options2) {
|
|
8921
|
+
const result = applyListMutations(
|
|
8922
|
+
current,
|
|
8923
|
+
{ add: options2.addAc, edit: options2.editAc, remove: options2.removeAc },
|
|
8924
|
+
{ add: "--add-ac", edit: "--edit-ac", remove: "--remove-ac" }
|
|
8925
|
+
);
|
|
8926
|
+
if (!result.ok) return result;
|
|
8927
|
+
return { ok: true, criteria: result.items };
|
|
8928
|
+
}
|
|
8929
|
+
|
|
8930
|
+
// src/commands/backlog/update/buildUpdateValues.ts
|
|
8931
|
+
import chalk96 from "chalk";
|
|
8932
|
+
function buildUpdateValues(options2) {
|
|
8933
|
+
const { name, desc: desc6, type, ac } = options2;
|
|
8934
|
+
if (!name && !desc6 && !type && !ac) {
|
|
8935
|
+
console.log(chalk96.red("Nothing to update. Provide at least one flag."));
|
|
8936
|
+
process.exitCode = 1;
|
|
8937
|
+
return void 0;
|
|
8938
|
+
}
|
|
8939
|
+
if (type && type !== "story" && type !== "bug") {
|
|
8940
|
+
console.log(chalk96.red('Invalid type. Must be "story" or "bug".'));
|
|
8941
|
+
process.exitCode = 1;
|
|
8942
|
+
return void 0;
|
|
8943
|
+
}
|
|
8944
|
+
const set = {};
|
|
8945
|
+
const fieldNames = [];
|
|
8946
|
+
if (name) {
|
|
8947
|
+
set.name = name;
|
|
8948
|
+
fieldNames.push("name");
|
|
8949
|
+
}
|
|
8950
|
+
if (desc6) {
|
|
8951
|
+
set.description = desc6;
|
|
8952
|
+
fieldNames.push("description");
|
|
8953
|
+
}
|
|
8954
|
+
if (type) {
|
|
8955
|
+
set.type = type;
|
|
8956
|
+
fieldNames.push("type");
|
|
8957
|
+
}
|
|
8958
|
+
if (ac) {
|
|
8959
|
+
set.acceptanceCriteria = JSON.stringify(ac);
|
|
8960
|
+
fieldNames.push("acceptance criteria");
|
|
8961
|
+
}
|
|
8962
|
+
return { set, fields: fieldNames.join(", ") };
|
|
8963
|
+
}
|
|
8964
|
+
|
|
8965
|
+
// src/commands/backlog/update/index.ts
|
|
8966
|
+
async function update(id2, options2) {
|
|
8967
|
+
const found = await findOneItem(id2);
|
|
8872
8968
|
if (!found) return;
|
|
8873
|
-
|
|
8874
|
-
|
|
8875
|
-
|
|
8876
|
-
|
|
8877
|
-
|
|
8878
|
-
|
|
8969
|
+
let ac = options2.ac;
|
|
8970
|
+
if (hasAcMutations(options2)) {
|
|
8971
|
+
if (options2.ac) {
|
|
8972
|
+
console.log(
|
|
8973
|
+
chalk97.red("Cannot combine --ac with --add-ac/--edit-ac/--remove-ac.")
|
|
8974
|
+
);
|
|
8975
|
+
process.exitCode = 1;
|
|
8976
|
+
return;
|
|
8977
|
+
}
|
|
8978
|
+
const mutation = applyAcMutations(found.item.acceptanceCriteria, options2);
|
|
8979
|
+
if (!mutation.ok) {
|
|
8980
|
+
console.log(chalk97.red(mutation.error));
|
|
8981
|
+
process.exitCode = 1;
|
|
8982
|
+
return;
|
|
8983
|
+
}
|
|
8984
|
+
ac = mutation.criteria;
|
|
8879
8985
|
}
|
|
8880
|
-
const {
|
|
8881
|
-
|
|
8882
|
-
const
|
|
8883
|
-
|
|
8884
|
-
|
|
8885
|
-
|
|
8886
|
-
].filter(Boolean).join(", ");
|
|
8887
|
-
console.log(
|
|
8888
|
-
chalk95.green(
|
|
8889
|
-
`Updated ${fields} on phase ${phaseIdx + 1} of item #${itemId}.`
|
|
8890
|
-
)
|
|
8891
|
-
);
|
|
8986
|
+
const built = buildUpdateValues({ ...options2, ac });
|
|
8987
|
+
if (!built) return;
|
|
8988
|
+
const { orm } = found;
|
|
8989
|
+
const itemId = found.item.id;
|
|
8990
|
+
await orm.update(items).set(built.set).where(eq32(items.id, itemId));
|
|
8991
|
+
console.log(chalk97.green(`Updated ${built.fields} on item #${itemId}.`));
|
|
8892
8992
|
}
|
|
8893
8993
|
|
|
8894
8994
|
// src/commands/backlog/registerUpdateCommands.ts
|
|
8895
|
-
function
|
|
8995
|
+
function collect2(value, previous) {
|
|
8896
8996
|
return [...previous, value];
|
|
8897
8997
|
}
|
|
8898
8998
|
function registerUpdateCommands(cmd) {
|
|
8899
8999
|
cmd.command("update-field <id>").description("Update fields on a backlog item").option("--name <name>", "New item name").option("--desc <description>", "New description").option("--type <type>", "New type (story or bug)").option("--ac <criterion...>", "Replace acceptance criteria (repeatable)").option(
|
|
8900
9000
|
"--add-ac <text>",
|
|
8901
9001
|
"Append one acceptance criterion (repeatable)",
|
|
8902
|
-
|
|
9002
|
+
collect2,
|
|
8903
9003
|
[]
|
|
8904
9004
|
).option(
|
|
8905
9005
|
"--edit-ac <n> <text...>",
|
|
8906
9006
|
"Replace acceptance criterion n (1-based) in place"
|
|
8907
9007
|
).option("--remove-ac <n>", "Remove acceptance criterion n (1-based)").action(update);
|
|
8908
|
-
cmd
|
|
8909
|
-
"--add-check <text>",
|
|
8910
|
-
"Append one manual check (repeatable)",
|
|
8911
|
-
collect,
|
|
8912
|
-
[]
|
|
8913
|
-
).option(
|
|
8914
|
-
"--edit-check <n> <text...>",
|
|
8915
|
-
"Replace manual check n (1-based) in place"
|
|
8916
|
-
).option("--remove-check <n>", "Remove manual check n (1-based)").action(updatePhase);
|
|
9008
|
+
registerUpdatePhaseCommand(cmd);
|
|
8917
9009
|
cmd.command("remove-phase <id> <phase>").description("Remove a plan phase from a backlog item").action(removePhase);
|
|
9010
|
+
cmd.command("move-phase <id> <from> <to>").description(
|
|
9011
|
+
"Reorder a plan phase from one 1-based position to another, moving its tasks with it"
|
|
9012
|
+
).action(movePhase);
|
|
8918
9013
|
}
|
|
8919
9014
|
|
|
8920
9015
|
// src/commands/registerBacklog.ts
|
|
@@ -9734,11 +9829,11 @@ function assertCliExists(cli) {
|
|
|
9734
9829
|
}
|
|
9735
9830
|
|
|
9736
9831
|
// src/commands/permitCliReads/colorize.ts
|
|
9737
|
-
import
|
|
9832
|
+
import chalk98 from "chalk";
|
|
9738
9833
|
function colorize(plainOutput) {
|
|
9739
9834
|
return plainOutput.split("\n").map((line) => {
|
|
9740
|
-
if (line.startsWith(" R ")) return
|
|
9741
|
-
if (line.startsWith(" W ")) return
|
|
9835
|
+
if (line.startsWith(" R ")) return chalk98.green(line);
|
|
9836
|
+
if (line.startsWith(" W ")) return chalk98.red(line);
|
|
9742
9837
|
return line;
|
|
9743
9838
|
}).join("\n");
|
|
9744
9839
|
}
|
|
@@ -10036,7 +10131,7 @@ async function permitCliReads(cli, options2 = { noCache: false }) {
|
|
|
10036
10131
|
}
|
|
10037
10132
|
|
|
10038
10133
|
// src/commands/deny/denyAdd.ts
|
|
10039
|
-
import
|
|
10134
|
+
import chalk99 from "chalk";
|
|
10040
10135
|
|
|
10041
10136
|
// src/commands/deny/loadDenyConfig.ts
|
|
10042
10137
|
function loadDenyConfig(global) {
|
|
@@ -10056,16 +10151,16 @@ function loadDenyConfig(global) {
|
|
|
10056
10151
|
function denyAdd(pattern2, message, options2) {
|
|
10057
10152
|
const { deny, saveDeny } = loadDenyConfig(options2.global);
|
|
10058
10153
|
if (deny.some((r) => r.pattern === pattern2)) {
|
|
10059
|
-
console.log(
|
|
10154
|
+
console.log(chalk99.yellow(`Deny rule already exists for: ${pattern2}`));
|
|
10060
10155
|
return;
|
|
10061
10156
|
}
|
|
10062
10157
|
deny.push({ pattern: pattern2, message });
|
|
10063
10158
|
saveDeny(deny);
|
|
10064
|
-
console.log(
|
|
10159
|
+
console.log(chalk99.green(`Added deny rule: ${pattern2} \u2192 ${message}`));
|
|
10065
10160
|
}
|
|
10066
10161
|
|
|
10067
10162
|
// src/commands/deny/denyList.ts
|
|
10068
|
-
import
|
|
10163
|
+
import chalk100 from "chalk";
|
|
10069
10164
|
function denyList() {
|
|
10070
10165
|
const globalRaw = loadGlobalConfigRaw();
|
|
10071
10166
|
const projectRaw = loadProjectConfig();
|
|
@@ -10076,7 +10171,7 @@ function denyList() {
|
|
|
10076
10171
|
projectDeny.length > 0 ? projectDeny : void 0
|
|
10077
10172
|
);
|
|
10078
10173
|
if (!merged || merged.length === 0) {
|
|
10079
|
-
console.log(
|
|
10174
|
+
console.log(chalk100.dim("No deny rules configured."));
|
|
10080
10175
|
return;
|
|
10081
10176
|
}
|
|
10082
10177
|
const projectPatterns = new Set(projectDeny.map((r) => r.pattern));
|
|
@@ -10084,23 +10179,23 @@ function denyList() {
|
|
|
10084
10179
|
for (const rule of merged) {
|
|
10085
10180
|
const inProject = projectPatterns.has(rule.pattern);
|
|
10086
10181
|
const inGlobal = globalPatterns.has(rule.pattern);
|
|
10087
|
-
const label2 = inProject && inGlobal ?
|
|
10088
|
-
console.log(`${
|
|
10182
|
+
const label2 = inProject && inGlobal ? chalk100.dim(" (project, overrides global)") : inGlobal ? chalk100.dim(" (global)") : "";
|
|
10183
|
+
console.log(`${chalk100.red(rule.pattern)} \u2192 ${rule.message}${label2}`);
|
|
10089
10184
|
}
|
|
10090
10185
|
}
|
|
10091
10186
|
|
|
10092
10187
|
// src/commands/deny/denyRemove.ts
|
|
10093
|
-
import
|
|
10188
|
+
import chalk101 from "chalk";
|
|
10094
10189
|
function denyRemove(pattern2, options2) {
|
|
10095
10190
|
const { deny, saveDeny } = loadDenyConfig(options2.global);
|
|
10096
10191
|
const index3 = deny.findIndex((r) => r.pattern === pattern2);
|
|
10097
10192
|
if (index3 === -1) {
|
|
10098
|
-
console.log(
|
|
10193
|
+
console.log(chalk101.yellow(`No deny rule found for: ${pattern2}`));
|
|
10099
10194
|
return;
|
|
10100
10195
|
}
|
|
10101
10196
|
deny.splice(index3, 1);
|
|
10102
10197
|
saveDeny(deny.length > 0 ? deny : void 0);
|
|
10103
|
-
console.log(
|
|
10198
|
+
console.log(chalk101.green(`Removed deny rule: ${pattern2}`));
|
|
10104
10199
|
}
|
|
10105
10200
|
|
|
10106
10201
|
// src/commands/registerDeny.ts
|
|
@@ -10130,7 +10225,7 @@ function registerCliHook(program2) {
|
|
|
10130
10225
|
|
|
10131
10226
|
// src/commands/codeComment/codeCommentConfirm.ts
|
|
10132
10227
|
import { existsSync as existsSync29, readFileSync as readFileSync24, unlinkSync as unlinkSync8, writeFileSync as writeFileSync22 } from "fs";
|
|
10133
|
-
import
|
|
10228
|
+
import chalk102 from "chalk";
|
|
10134
10229
|
|
|
10135
10230
|
// src/commands/codeComment/getRestrictedDir.ts
|
|
10136
10231
|
import { homedir as homedir13 } from "os";
|
|
@@ -10183,12 +10278,12 @@ function codeCommentConfirm(pin) {
|
|
|
10183
10278
|
sweepRestrictedDir();
|
|
10184
10279
|
const state = readPinState(pin);
|
|
10185
10280
|
if (!state) {
|
|
10186
|
-
console.error(
|
|
10281
|
+
console.error(chalk102.red(`No pending comment for pin: ${pin}`));
|
|
10187
10282
|
process.exitCode = 1;
|
|
10188
10283
|
return;
|
|
10189
10284
|
}
|
|
10190
10285
|
if (!existsSync29(state.file)) {
|
|
10191
|
-
console.error(
|
|
10286
|
+
console.error(chalk102.red(`Target file no longer exists: ${state.file}`));
|
|
10192
10287
|
process.exitCode = 1;
|
|
10193
10288
|
return;
|
|
10194
10289
|
}
|
|
@@ -10197,7 +10292,7 @@ function codeCommentConfirm(pin) {
|
|
|
10197
10292
|
const index3 = state.line - 1;
|
|
10198
10293
|
if (index3 > lines.length) {
|
|
10199
10294
|
console.error(
|
|
10200
|
-
|
|
10295
|
+
chalk102.red(
|
|
10201
10296
|
`Line ${state.line} is beyond the end of ${state.file} (${lines.length} lines).`
|
|
10202
10297
|
)
|
|
10203
10298
|
);
|
|
@@ -10211,14 +10306,14 @@ function codeCommentConfirm(pin) {
|
|
|
10211
10306
|
writeFileSync22(state.file, lines.join("\n"));
|
|
10212
10307
|
unlinkSync8(getPinStatePath(pin));
|
|
10213
10308
|
console.log(
|
|
10214
|
-
|
|
10309
|
+
chalk102.green(
|
|
10215
10310
|
`Inserted "${marker} ${state.text}" at ${state.file}:${state.line}`
|
|
10216
10311
|
)
|
|
10217
10312
|
);
|
|
10218
10313
|
}
|
|
10219
10314
|
|
|
10220
10315
|
// src/commands/codeComment/codeCommentSet.ts
|
|
10221
|
-
import
|
|
10316
|
+
import chalk103 from "chalk";
|
|
10222
10317
|
|
|
10223
10318
|
// src/commands/codeComment/validateCommentText.ts
|
|
10224
10319
|
var MAX_COMMENT_LENGTH = 50;
|
|
@@ -10269,27 +10364,27 @@ function generatePin() {
|
|
|
10269
10364
|
function codeCommentSet(file, line, text8) {
|
|
10270
10365
|
const lineNumber = Number.parseInt(line, 10);
|
|
10271
10366
|
if (!Number.isInteger(lineNumber) || lineNumber < 1) {
|
|
10272
|
-
console.error(
|
|
10367
|
+
console.error(chalk103.red(`Invalid line number: ${line}`));
|
|
10273
10368
|
process.exitCode = 1;
|
|
10274
10369
|
return;
|
|
10275
10370
|
}
|
|
10276
10371
|
const marker = isYamlFile(file) ? "#" : "//";
|
|
10277
10372
|
const validation = validateCommentText(text8, isYamlFile(file));
|
|
10278
10373
|
if (!validation.ok) {
|
|
10279
|
-
console.error(
|
|
10280
|
-
console.error(
|
|
10374
|
+
console.error(chalk103.red(`Refused: ${validation.reason}`));
|
|
10375
|
+
console.error(chalk103.red("No pin issued."));
|
|
10281
10376
|
process.exitCode = 1;
|
|
10282
10377
|
return;
|
|
10283
10378
|
}
|
|
10284
10379
|
console.error(
|
|
10285
|
-
|
|
10380
|
+
chalk103.yellow.bold(
|
|
10286
10381
|
"THIS IS YOUR LAST CHANCE TO RECONSIDER BEFORE INVOLVING A HUMAN.\nRequesting this pin pages a real person to approve a comment. DO NOT WASTE THEIR TIME.\nYou had BETTER BE RIGHT that this comment is genuinely necessary.\n\nComments are a last resort, not a habit. Almost every comment you reach for is a sign\nthe code should be clearer instead. Before a human is pulled in, ask whether a better\nname, a smaller function, or a test would make the comment redundant. ONLY if you are\ncertain this one line earns its keep should you proceed to the confirm step below."
|
|
10287
10382
|
)
|
|
10288
10383
|
);
|
|
10289
10384
|
const delivered = issuePin(file, lineNumber, validation.text);
|
|
10290
10385
|
if (!delivered) {
|
|
10291
10386
|
console.error(
|
|
10292
|
-
|
|
10387
|
+
chalk103.red(
|
|
10293
10388
|
"Could not deliver the confirmation pin via notification.\nThe comment cannot be confirmed until the notification channel works."
|
|
10294
10389
|
)
|
|
10295
10390
|
);
|
|
@@ -10299,7 +10394,7 @@ function codeCommentSet(file, line, text8) {
|
|
|
10299
10394
|
console.log(
|
|
10300
10395
|
`A confirmation pin was sent to your desktop notifications.
|
|
10301
10396
|
To insert "${marker} ${validation.text}" at ${file}:${lineNumber}, run:
|
|
10302
|
-
${
|
|
10397
|
+
${chalk103.cyan(" assist code-comment confirm <PIN>")}
|
|
10303
10398
|
using the pin from that notification.`
|
|
10304
10399
|
);
|
|
10305
10400
|
}
|
|
@@ -10319,15 +10414,15 @@ function registerCodeComment(parent) {
|
|
|
10319
10414
|
}
|
|
10320
10415
|
|
|
10321
10416
|
// src/commands/complexity/analyze.ts
|
|
10322
|
-
import
|
|
10417
|
+
import chalk112 from "chalk";
|
|
10323
10418
|
|
|
10324
10419
|
// src/commands/complexity/cyclomatic.ts
|
|
10325
|
-
import
|
|
10420
|
+
import chalk105 from "chalk";
|
|
10326
10421
|
|
|
10327
10422
|
// src/commands/complexity/shared/index.ts
|
|
10328
10423
|
import fs17 from "fs";
|
|
10329
10424
|
import path21 from "path";
|
|
10330
|
-
import
|
|
10425
|
+
import chalk104 from "chalk";
|
|
10331
10426
|
import ts5 from "typescript";
|
|
10332
10427
|
|
|
10333
10428
|
// src/commands/complexity/findSourceFiles.ts
|
|
@@ -10530,7 +10625,7 @@ function calculateHalstead(node) {
|
|
|
10530
10625
|
// src/commands/complexity/shared/countSloc.ts
|
|
10531
10626
|
function countSloc(content) {
|
|
10532
10627
|
let inMultiLineComment = false;
|
|
10533
|
-
let
|
|
10628
|
+
let count8 = 0;
|
|
10534
10629
|
for (const line of content.split("\n")) {
|
|
10535
10630
|
const trimmed = line.trim();
|
|
10536
10631
|
if (inMultiLineComment) {
|
|
@@ -10538,7 +10633,7 @@ function countSloc(content) {
|
|
|
10538
10633
|
inMultiLineComment = false;
|
|
10539
10634
|
const afterComment = trimmed.substring(trimmed.indexOf("*/") + 2);
|
|
10540
10635
|
if (afterComment.trim().length > 0) {
|
|
10541
|
-
|
|
10636
|
+
count8++;
|
|
10542
10637
|
}
|
|
10543
10638
|
}
|
|
10544
10639
|
continue;
|
|
@@ -10550,7 +10645,7 @@ function countSloc(content) {
|
|
|
10550
10645
|
if (trimmed.includes("*/")) {
|
|
10551
10646
|
const afterComment = trimmed.substring(trimmed.indexOf("*/") + 2);
|
|
10552
10647
|
if (afterComment.trim().length > 0) {
|
|
10553
|
-
|
|
10648
|
+
count8++;
|
|
10554
10649
|
}
|
|
10555
10650
|
} else {
|
|
10556
10651
|
inMultiLineComment = true;
|
|
@@ -10558,10 +10653,10 @@ function countSloc(content) {
|
|
|
10558
10653
|
continue;
|
|
10559
10654
|
}
|
|
10560
10655
|
if (trimmed.length > 0) {
|
|
10561
|
-
|
|
10656
|
+
count8++;
|
|
10562
10657
|
}
|
|
10563
10658
|
}
|
|
10564
|
-
return
|
|
10659
|
+
return count8;
|
|
10565
10660
|
}
|
|
10566
10661
|
|
|
10567
10662
|
// src/commands/complexity/shared/index.ts
|
|
@@ -10578,7 +10673,7 @@ function createSourceFromFile(filePath) {
|
|
|
10578
10673
|
function withSourceFiles(pattern2, callback, extraIgnore = []) {
|
|
10579
10674
|
const files = findSourceFiles2(pattern2, ".", extraIgnore);
|
|
10580
10675
|
if (files.length === 0) {
|
|
10581
|
-
console.log(
|
|
10676
|
+
console.log(chalk104.yellow("No files found matching pattern"));
|
|
10582
10677
|
return void 0;
|
|
10583
10678
|
}
|
|
10584
10679
|
return callback(files);
|
|
@@ -10611,11 +10706,11 @@ async function cyclomatic(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
10611
10706
|
results.sort((a, b) => b.complexity - a.complexity);
|
|
10612
10707
|
for (const { file, name, complexity } of results) {
|
|
10613
10708
|
const exceedsThreshold = options2.threshold !== void 0 && complexity > options2.threshold;
|
|
10614
|
-
const color = exceedsThreshold ?
|
|
10615
|
-
console.log(`${color(`${file}:${name}`)} \u2192 ${
|
|
10709
|
+
const color = exceedsThreshold ? chalk105.red : chalk105.white;
|
|
10710
|
+
console.log(`${color(`${file}:${name}`)} \u2192 ${chalk105.cyan(complexity)}`);
|
|
10616
10711
|
}
|
|
10617
10712
|
console.log(
|
|
10618
|
-
|
|
10713
|
+
chalk105.dim(
|
|
10619
10714
|
`
|
|
10620
10715
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
10621
10716
|
)
|
|
@@ -10627,7 +10722,7 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
10627
10722
|
}
|
|
10628
10723
|
|
|
10629
10724
|
// src/commands/complexity/halstead.ts
|
|
10630
|
-
import
|
|
10725
|
+
import chalk106 from "chalk";
|
|
10631
10726
|
async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
10632
10727
|
withSourceFiles(pattern2, (files) => {
|
|
10633
10728
|
const results = [];
|
|
@@ -10642,13 +10737,13 @@ async function halstead(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
10642
10737
|
results.sort((a, b) => b.metrics.effort - a.metrics.effort);
|
|
10643
10738
|
for (const { file, name, metrics } of results) {
|
|
10644
10739
|
const exceedsThreshold = options2.threshold !== void 0 && metrics.volume > options2.threshold;
|
|
10645
|
-
const color = exceedsThreshold ?
|
|
10740
|
+
const color = exceedsThreshold ? chalk106.red : chalk106.white;
|
|
10646
10741
|
console.log(
|
|
10647
|
-
`${color(`${file}:${name}`)} \u2192 volume: ${
|
|
10742
|
+
`${color(`${file}:${name}`)} \u2192 volume: ${chalk106.cyan(metrics.volume.toFixed(1))}, difficulty: ${chalk106.yellow(metrics.difficulty.toFixed(1))}, effort: ${chalk106.magenta(metrics.effort.toFixed(1))}`
|
|
10648
10743
|
);
|
|
10649
10744
|
}
|
|
10650
10745
|
console.log(
|
|
10651
|
-
|
|
10746
|
+
chalk106.dim(
|
|
10652
10747
|
`
|
|
10653
10748
|
Analyzed ${results.length} functions across ${files.length} files`
|
|
10654
10749
|
)
|
|
@@ -10660,27 +10755,27 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
10660
10755
|
}
|
|
10661
10756
|
|
|
10662
10757
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
10663
|
-
import
|
|
10758
|
+
import chalk109 from "chalk";
|
|
10664
10759
|
|
|
10665
10760
|
// src/commands/complexity/maintainability/formatResultLine.ts
|
|
10666
|
-
import
|
|
10761
|
+
import chalk107 from "chalk";
|
|
10667
10762
|
function formatResultLine(entry, failing) {
|
|
10668
10763
|
const { file, avgMaintainability, minMaintainability, override } = entry;
|
|
10669
|
-
const name = failing ?
|
|
10670
|
-
const suffix = override !== void 0 ?
|
|
10671
|
-
return `${name} \u2192 avg: ${
|
|
10764
|
+
const name = failing ? chalk107.red(file) : chalk107.white(file);
|
|
10765
|
+
const suffix = override !== void 0 ? chalk107.magenta(` (override: ${override})`) : "";
|
|
10766
|
+
return `${name} \u2192 avg: ${chalk107.cyan(avgMaintainability.toFixed(1))}, min: ${chalk107.yellow(minMaintainability.toFixed(1))}${suffix}`;
|
|
10672
10767
|
}
|
|
10673
10768
|
|
|
10674
10769
|
// src/commands/complexity/maintainability/printMaintainabilityFailure.ts
|
|
10675
|
-
import
|
|
10770
|
+
import chalk108 from "chalk";
|
|
10676
10771
|
function printMaintainabilityFailure(failingCount, threshold) {
|
|
10677
10772
|
const thresholdLabel = threshold !== void 0 ? ` ${threshold}` : "";
|
|
10678
10773
|
console.error(
|
|
10679
|
-
|
|
10774
|
+
chalk108.red(
|
|
10680
10775
|
`
|
|
10681
10776
|
Fail: ${failingCount} file(s) below threshold${thresholdLabel} (files marked "(override: N)" were judged against their own marker). Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
|
|
10682
10777
|
|
|
10683
|
-
\u26A0\uFE0F ${
|
|
10778
|
+
\u26A0\uFE0F ${chalk108.bold("Diagnose and fix one file at a time")} \u2014 do not investigate or fix multiple files in parallel.
|
|
10684
10779
|
|
|
10685
10780
|
The score is a property of the whole file, not your diff: any existing logic counts, so the fix is to shrink the file \u2014 not to revert or micro-optimize the lines you just changed. Identify the largest cohesive responsibility (often the biggest function, or a related group of functions) and move it to a new file with 'assist refactor extract'. Run 'assist complexity <file>' for per-function metrics only to locate that responsibility, not to tweak individual lines.`
|
|
10686
10781
|
)
|
|
@@ -10692,7 +10787,7 @@ function displayMaintainabilityResults(results, threshold) {
|
|
|
10692
10787
|
const gating = threshold !== void 0 || results.some((r) => r.override !== void 0);
|
|
10693
10788
|
if (!gating) {
|
|
10694
10789
|
for (const entry of results) console.log(formatResultLine(entry, false));
|
|
10695
|
-
console.log(
|
|
10790
|
+
console.log(chalk109.dim(`
|
|
10696
10791
|
Analyzed ${results.length} files`));
|
|
10697
10792
|
return;
|
|
10698
10793
|
}
|
|
@@ -10701,7 +10796,7 @@ Analyzed ${results.length} files`));
|
|
|
10701
10796
|
return limit !== void 0 && r.minMaintainability < limit;
|
|
10702
10797
|
});
|
|
10703
10798
|
if (failing.length === 0) {
|
|
10704
|
-
console.log(
|
|
10799
|
+
console.log(chalk109.green("All files pass maintainability threshold"));
|
|
10705
10800
|
} else {
|
|
10706
10801
|
for (const entry of failing) console.log(formatResultLine(entry, true));
|
|
10707
10802
|
}
|
|
@@ -10710,7 +10805,7 @@ Analyzed ${results.length} files`));
|
|
|
10710
10805
|
);
|
|
10711
10806
|
for (const entry of passingOverrides)
|
|
10712
10807
|
console.log(formatResultLine(entry, false));
|
|
10713
|
-
console.log(
|
|
10808
|
+
console.log(chalk109.dim(`
|
|
10714
10809
|
Analyzed ${results.length} files`));
|
|
10715
10810
|
if (failing.length > 0) {
|
|
10716
10811
|
printMaintainabilityFailure(failing.length, threshold);
|
|
@@ -10719,10 +10814,10 @@ Analyzed ${results.length} files`));
|
|
|
10719
10814
|
}
|
|
10720
10815
|
|
|
10721
10816
|
// src/commands/complexity/maintainability/printMaintainabilityFormula.ts
|
|
10722
|
-
import
|
|
10817
|
+
import chalk110 from "chalk";
|
|
10723
10818
|
var MI_FORMULA = "171 - 5.2*ln(HalsteadVolume) - 0.23*CyclomaticComplexity - 16.2*ln(SLOC), clamped 0-100";
|
|
10724
10819
|
function printMaintainabilityFormula() {
|
|
10725
|
-
console.log(
|
|
10820
|
+
console.log(chalk110.dim(MI_FORMULA));
|
|
10726
10821
|
}
|
|
10727
10822
|
|
|
10728
10823
|
// src/commands/complexity/maintainability/collectFileMetrics.ts
|
|
@@ -10798,7 +10893,7 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
10798
10893
|
|
|
10799
10894
|
// src/commands/complexity/sloc.ts
|
|
10800
10895
|
import fs19 from "fs";
|
|
10801
|
-
import
|
|
10896
|
+
import chalk111 from "chalk";
|
|
10802
10897
|
async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
10803
10898
|
withSourceFiles(pattern2, (files) => {
|
|
10804
10899
|
const results = [];
|
|
@@ -10814,12 +10909,12 @@ async function sloc(pattern2 = "**/*.ts", options2 = {}) {
|
|
|
10814
10909
|
results.sort((a, b) => b.lines - a.lines);
|
|
10815
10910
|
for (const { file, lines } of results) {
|
|
10816
10911
|
const exceedsThreshold = options2.threshold !== void 0 && lines > options2.threshold;
|
|
10817
|
-
const color = exceedsThreshold ?
|
|
10818
|
-
console.log(`${color(file)} \u2192 ${
|
|
10912
|
+
const color = exceedsThreshold ? chalk111.red : chalk111.white;
|
|
10913
|
+
console.log(`${color(file)} \u2192 ${chalk111.cyan(lines)} lines`);
|
|
10819
10914
|
}
|
|
10820
10915
|
const total = results.reduce((sum, r) => sum + r.lines, 0);
|
|
10821
10916
|
console.log(
|
|
10822
|
-
|
|
10917
|
+
chalk111.dim(`
|
|
10823
10918
|
Total: ${total} lines across ${files.length} files`)
|
|
10824
10919
|
);
|
|
10825
10920
|
if (hasViolation) {
|
|
@@ -10833,25 +10928,25 @@ async function analyze(pattern2) {
|
|
|
10833
10928
|
const searchPattern = pattern2.includes("*") || pattern2.includes("/") ? pattern2 : `**/${pattern2}`;
|
|
10834
10929
|
const files = findSourceFiles2(searchPattern);
|
|
10835
10930
|
if (files.length === 0) {
|
|
10836
|
-
console.log(
|
|
10931
|
+
console.log(chalk112.yellow("No files found matching pattern"));
|
|
10837
10932
|
return;
|
|
10838
10933
|
}
|
|
10839
10934
|
if (files.length === 1) {
|
|
10840
10935
|
const file = files[0];
|
|
10841
|
-
console.log(
|
|
10936
|
+
console.log(chalk112.bold.underline("SLOC"));
|
|
10842
10937
|
await sloc(file);
|
|
10843
10938
|
console.log();
|
|
10844
|
-
console.log(
|
|
10939
|
+
console.log(chalk112.bold.underline("Cyclomatic Complexity"));
|
|
10845
10940
|
await cyclomatic(file);
|
|
10846
10941
|
console.log();
|
|
10847
|
-
console.log(
|
|
10942
|
+
console.log(chalk112.bold.underline("Halstead Metrics"));
|
|
10848
10943
|
await halstead(file);
|
|
10849
10944
|
console.log();
|
|
10850
|
-
console.log(
|
|
10945
|
+
console.log(chalk112.bold.underline("Maintainability Index"));
|
|
10851
10946
|
await maintainability(file);
|
|
10852
10947
|
console.log();
|
|
10853
10948
|
console.log(
|
|
10854
|
-
|
|
10949
|
+
chalk112.dim(
|
|
10855
10950
|
"To improve the maintainability index, extract functions and logic out of this file into separate, smaller modules. Collapsing whitespace or removing comments is not the goal."
|
|
10856
10951
|
)
|
|
10857
10952
|
);
|
|
@@ -10885,7 +10980,7 @@ function registerComplexity(program2) {
|
|
|
10885
10980
|
}
|
|
10886
10981
|
|
|
10887
10982
|
// src/commands/config/index.ts
|
|
10888
|
-
import
|
|
10983
|
+
import chalk113 from "chalk";
|
|
10889
10984
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
10890
10985
|
|
|
10891
10986
|
// src/commands/config/setNestedValue.ts
|
|
@@ -10948,7 +11043,7 @@ function formatIssuePath(issue, key) {
|
|
|
10948
11043
|
function printValidationErrors(issues, key) {
|
|
10949
11044
|
for (const issue of issues) {
|
|
10950
11045
|
console.error(
|
|
10951
|
-
|
|
11046
|
+
chalk113.red(`${formatIssuePath(issue, key)}: ${issue.message}`)
|
|
10952
11047
|
);
|
|
10953
11048
|
}
|
|
10954
11049
|
}
|
|
@@ -10965,7 +11060,7 @@ var GLOBAL_ONLY_KEYS = ["sync.autoConfirm"];
|
|
|
10965
11060
|
function assertNotGlobalOnly(key, global) {
|
|
10966
11061
|
if (!global && GLOBAL_ONLY_KEYS.some((k) => key.startsWith(k))) {
|
|
10967
11062
|
console.error(
|
|
10968
|
-
|
|
11063
|
+
chalk113.red(
|
|
10969
11064
|
`"${key}" is a global-only key. Use --global to set it in ~/.assist.yml`
|
|
10970
11065
|
)
|
|
10971
11066
|
);
|
|
@@ -10988,7 +11083,7 @@ function configSet(key, value, options2 = {}) {
|
|
|
10988
11083
|
applyConfigSet(key, coerced, options2.global ?? false);
|
|
10989
11084
|
const target = options2.global ? "global" : "project";
|
|
10990
11085
|
console.log(
|
|
10991
|
-
|
|
11086
|
+
chalk113.green(`Set ${key} = ${JSON.stringify(coerced)} (${target})`)
|
|
10992
11087
|
);
|
|
10993
11088
|
}
|
|
10994
11089
|
function configList() {
|
|
@@ -10997,7 +11092,7 @@ function configList() {
|
|
|
10997
11092
|
}
|
|
10998
11093
|
|
|
10999
11094
|
// src/commands/config/configGet.ts
|
|
11000
|
-
import
|
|
11095
|
+
import chalk114 from "chalk";
|
|
11001
11096
|
|
|
11002
11097
|
// src/commands/config/getNestedValue.ts
|
|
11003
11098
|
function isTraversable(value) {
|
|
@@ -11029,7 +11124,7 @@ function requireNestedValue(config, key) {
|
|
|
11029
11124
|
return value;
|
|
11030
11125
|
}
|
|
11031
11126
|
function exitKeyNotSet(key) {
|
|
11032
|
-
console.error(
|
|
11127
|
+
console.error(chalk114.red(`Key "${key}" is not set`));
|
|
11033
11128
|
process.exit(1);
|
|
11034
11129
|
}
|
|
11035
11130
|
|
|
@@ -11043,7 +11138,7 @@ function registerConfig(program2) {
|
|
|
11043
11138
|
|
|
11044
11139
|
// src/commands/deploy/redirect.ts
|
|
11045
11140
|
import { existsSync as existsSync30, readFileSync as readFileSync25, writeFileSync as writeFileSync24 } from "fs";
|
|
11046
|
-
import
|
|
11141
|
+
import chalk115 from "chalk";
|
|
11047
11142
|
var TRAILING_SLASH_SCRIPT = ` <script>
|
|
11048
11143
|
if (!window.location.pathname.endsWith('/')) {
|
|
11049
11144
|
window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
|
|
@@ -11052,23 +11147,23 @@ var TRAILING_SLASH_SCRIPT = ` <script>
|
|
|
11052
11147
|
function redirect() {
|
|
11053
11148
|
const indexPath = "index.html";
|
|
11054
11149
|
if (!existsSync30(indexPath)) {
|
|
11055
|
-
console.log(
|
|
11150
|
+
console.log(chalk115.yellow("No index.html found"));
|
|
11056
11151
|
return;
|
|
11057
11152
|
}
|
|
11058
11153
|
const content = readFileSync25(indexPath, "utf8");
|
|
11059
11154
|
if (content.includes("window.location.pathname.endsWith('/')")) {
|
|
11060
|
-
console.log(
|
|
11155
|
+
console.log(chalk115.dim("Trailing slash script already present"));
|
|
11061
11156
|
return;
|
|
11062
11157
|
}
|
|
11063
11158
|
const headCloseIndex = content.indexOf("</head>");
|
|
11064
11159
|
if (headCloseIndex === -1) {
|
|
11065
|
-
console.log(
|
|
11160
|
+
console.log(chalk115.red("Could not find </head> tag in index.html"));
|
|
11066
11161
|
return;
|
|
11067
11162
|
}
|
|
11068
11163
|
const newContent = `${content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT}
|
|
11069
11164
|
${content.slice(headCloseIndex)}`;
|
|
11070
11165
|
writeFileSync24(indexPath, newContent);
|
|
11071
|
-
console.log(
|
|
11166
|
+
console.log(chalk115.green("Added trailing slash redirect to index.html"));
|
|
11072
11167
|
}
|
|
11073
11168
|
|
|
11074
11169
|
// src/commands/registerDeploy.ts
|
|
@@ -11095,7 +11190,7 @@ function loadBlogSkipDays(repoName) {
|
|
|
11095
11190
|
|
|
11096
11191
|
// src/commands/devlog/shared.ts
|
|
11097
11192
|
import { execSync as execSync26 } from "child_process";
|
|
11098
|
-
import
|
|
11193
|
+
import chalk116 from "chalk";
|
|
11099
11194
|
|
|
11100
11195
|
// src/shared/getRepoName.ts
|
|
11101
11196
|
import { existsSync as existsSync31, readFileSync as readFileSync26 } from "fs";
|
|
@@ -11204,13 +11299,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
|
|
|
11204
11299
|
}
|
|
11205
11300
|
function printCommitsWithFiles(commits2, ignore2, verbose) {
|
|
11206
11301
|
for (const commit2 of commits2) {
|
|
11207
|
-
console.log(` ${
|
|
11302
|
+
console.log(` ${chalk116.yellow(commit2.hash)} ${commit2.message}`);
|
|
11208
11303
|
if (verbose) {
|
|
11209
11304
|
const visibleFiles = commit2.files.filter(
|
|
11210
11305
|
(file) => !ignore2.some((p) => file.startsWith(p))
|
|
11211
11306
|
);
|
|
11212
11307
|
for (const file of visibleFiles) {
|
|
11213
|
-
console.log(` ${
|
|
11308
|
+
console.log(` ${chalk116.dim(file)}`);
|
|
11214
11309
|
}
|
|
11215
11310
|
}
|
|
11216
11311
|
}
|
|
@@ -11235,15 +11330,15 @@ function parseGitLogCommits(output, ignore2, afterDate) {
|
|
|
11235
11330
|
}
|
|
11236
11331
|
|
|
11237
11332
|
// src/commands/devlog/list/printDateHeader.ts
|
|
11238
|
-
import
|
|
11333
|
+
import chalk117 from "chalk";
|
|
11239
11334
|
function printDateHeader(date, isSkipped, entries) {
|
|
11240
11335
|
if (isSkipped) {
|
|
11241
|
-
console.log(`${
|
|
11336
|
+
console.log(`${chalk117.bold.blue(date)} ${chalk117.dim("skipped")}`);
|
|
11242
11337
|
} else if (entries && entries.length > 0) {
|
|
11243
|
-
const entryInfo = entries.map((e) => `${
|
|
11244
|
-
console.log(`${
|
|
11338
|
+
const entryInfo = entries.map((e) => `${chalk117.green(e.version)} ${e.title}`).join(" | ");
|
|
11339
|
+
console.log(`${chalk117.bold.blue(date)} ${entryInfo}`);
|
|
11245
11340
|
} else {
|
|
11246
|
-
console.log(`${
|
|
11341
|
+
console.log(`${chalk117.bold.blue(date)} ${chalk117.red("\u26A0 devlog missing")}`);
|
|
11247
11342
|
}
|
|
11248
11343
|
}
|
|
11249
11344
|
|
|
@@ -11347,24 +11442,24 @@ function bumpVersion(version2, type) {
|
|
|
11347
11442
|
|
|
11348
11443
|
// src/commands/devlog/next/displayNextEntry/index.ts
|
|
11349
11444
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
11350
|
-
import
|
|
11445
|
+
import chalk119 from "chalk";
|
|
11351
11446
|
|
|
11352
11447
|
// src/commands/devlog/next/displayNextEntry/displayVersion.ts
|
|
11353
|
-
import
|
|
11448
|
+
import chalk118 from "chalk";
|
|
11354
11449
|
function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
|
|
11355
11450
|
if (conventional && firstHash) {
|
|
11356
11451
|
const version2 = getVersionAtCommit(firstHash);
|
|
11357
11452
|
if (version2) {
|
|
11358
|
-
console.log(`${
|
|
11453
|
+
console.log(`${chalk118.bold("version:")} ${stripToMinor(version2)}`);
|
|
11359
11454
|
} else {
|
|
11360
|
-
console.log(`${
|
|
11455
|
+
console.log(`${chalk118.bold("version:")} ${chalk118.red("unknown")}`);
|
|
11361
11456
|
}
|
|
11362
11457
|
} else if (patchVersion && minorVersion) {
|
|
11363
11458
|
console.log(
|
|
11364
|
-
`${
|
|
11459
|
+
`${chalk118.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
|
|
11365
11460
|
);
|
|
11366
11461
|
} else {
|
|
11367
|
-
console.log(`${
|
|
11462
|
+
console.log(`${chalk118.bold("version:")} v0.1 (initial)`);
|
|
11368
11463
|
}
|
|
11369
11464
|
}
|
|
11370
11465
|
|
|
@@ -11412,16 +11507,16 @@ function noCommitsMessage(hasLastInfo) {
|
|
|
11412
11507
|
return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
|
|
11413
11508
|
}
|
|
11414
11509
|
function logName(repoName) {
|
|
11415
|
-
console.log(`${
|
|
11510
|
+
console.log(`${chalk119.bold("name:")} ${repoName}`);
|
|
11416
11511
|
}
|
|
11417
11512
|
function displayNextEntry(ctx, targetDate, commits2) {
|
|
11418
11513
|
logName(ctx.repoName);
|
|
11419
11514
|
printVersionInfo(ctx.config, ctx.lastInfo, commits2[0]?.hash);
|
|
11420
|
-
console.log(
|
|
11515
|
+
console.log(chalk119.bold.blue(targetDate));
|
|
11421
11516
|
printCommitsWithFiles(commits2, ctx.ignore, ctx.verbose);
|
|
11422
11517
|
}
|
|
11423
11518
|
function logNoCommits(lastInfo) {
|
|
11424
|
-
console.log(
|
|
11519
|
+
console.log(chalk119.dim(noCommitsMessage(!!lastInfo)));
|
|
11425
11520
|
}
|
|
11426
11521
|
|
|
11427
11522
|
// src/commands/devlog/next/index.ts
|
|
@@ -11462,11 +11557,11 @@ function next2(options2) {
|
|
|
11462
11557
|
import { execSync as execSync28 } from "child_process";
|
|
11463
11558
|
|
|
11464
11559
|
// src/commands/devlog/repos/printReposTable.ts
|
|
11465
|
-
import
|
|
11560
|
+
import chalk120 from "chalk";
|
|
11466
11561
|
function colorStatus(status2) {
|
|
11467
|
-
if (status2 === "missing") return
|
|
11468
|
-
if (status2 === "outdated") return
|
|
11469
|
-
return
|
|
11562
|
+
if (status2 === "missing") return chalk120.red(status2);
|
|
11563
|
+
if (status2 === "outdated") return chalk120.yellow(status2);
|
|
11564
|
+
return chalk120.green(status2);
|
|
11470
11565
|
}
|
|
11471
11566
|
function formatRow(row, nameWidth) {
|
|
11472
11567
|
const devlog = (row.lastDevlog ?? "-").padEnd(11);
|
|
@@ -11480,8 +11575,8 @@ function printReposTable(rows) {
|
|
|
11480
11575
|
"Last Devlog".padEnd(11),
|
|
11481
11576
|
"Status"
|
|
11482
11577
|
].join(" ");
|
|
11483
|
-
console.log(
|
|
11484
|
-
console.log(
|
|
11578
|
+
console.log(chalk120.dim(header));
|
|
11579
|
+
console.log(chalk120.dim("-".repeat(header.length)));
|
|
11485
11580
|
for (const row of rows) {
|
|
11486
11581
|
console.log(formatRow(row, nameWidth));
|
|
11487
11582
|
}
|
|
@@ -11539,14 +11634,14 @@ function repos(options2) {
|
|
|
11539
11634
|
// src/commands/devlog/skip.ts
|
|
11540
11635
|
import { writeFileSync as writeFileSync25 } from "fs";
|
|
11541
11636
|
import { join as join32 } from "path";
|
|
11542
|
-
import
|
|
11637
|
+
import chalk121 from "chalk";
|
|
11543
11638
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
11544
11639
|
function getBlogConfigPath() {
|
|
11545
11640
|
return join32(BLOG_REPO_ROOT, "assist.yml");
|
|
11546
11641
|
}
|
|
11547
11642
|
function skip(date) {
|
|
11548
11643
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
11549
|
-
console.log(
|
|
11644
|
+
console.log(chalk121.red("Invalid date format. Use YYYY-MM-DD"));
|
|
11550
11645
|
process.exit(1);
|
|
11551
11646
|
}
|
|
11552
11647
|
const repoName = getRepoName();
|
|
@@ -11557,7 +11652,7 @@ function skip(date) {
|
|
|
11557
11652
|
const skipDays = skip2[repoName] ?? [];
|
|
11558
11653
|
if (skipDays.includes(date)) {
|
|
11559
11654
|
console.log(
|
|
11560
|
-
|
|
11655
|
+
chalk121.yellow(`${date} is already in skip list for ${repoName}`)
|
|
11561
11656
|
);
|
|
11562
11657
|
return;
|
|
11563
11658
|
}
|
|
@@ -11567,20 +11662,20 @@ function skip(date) {
|
|
|
11567
11662
|
devlog.skip = skip2;
|
|
11568
11663
|
config.devlog = devlog;
|
|
11569
11664
|
writeFileSync25(configPath, stringifyYaml3(config, { lineWidth: 0 }));
|
|
11570
|
-
console.log(
|
|
11665
|
+
console.log(chalk121.green(`Added ${date} to skip list for ${repoName}`));
|
|
11571
11666
|
}
|
|
11572
11667
|
|
|
11573
11668
|
// src/commands/devlog/version.ts
|
|
11574
|
-
import
|
|
11669
|
+
import chalk122 from "chalk";
|
|
11575
11670
|
function version() {
|
|
11576
11671
|
const config = loadConfig();
|
|
11577
11672
|
const name = getRepoName();
|
|
11578
11673
|
const lastInfo = getLastVersionInfo(name, config);
|
|
11579
11674
|
const lastVersion = lastInfo?.version ?? null;
|
|
11580
11675
|
const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
|
|
11581
|
-
console.log(`${
|
|
11582
|
-
console.log(`${
|
|
11583
|
-
console.log(`${
|
|
11676
|
+
console.log(`${chalk122.bold("name:")} ${name}`);
|
|
11677
|
+
console.log(`${chalk122.bold("last:")} ${lastVersion ?? chalk122.dim("none")}`);
|
|
11678
|
+
console.log(`${chalk122.bold("next:")} ${nextVersion ?? chalk122.dim("none")}`);
|
|
11584
11679
|
}
|
|
11585
11680
|
|
|
11586
11681
|
// src/commands/registerDevlog.ts
|
|
@@ -11604,7 +11699,7 @@ function registerDevlog(program2) {
|
|
|
11604
11699
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
11605
11700
|
import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync4 } from "fs";
|
|
11606
11701
|
import { join as join33 } from "path";
|
|
11607
|
-
import
|
|
11702
|
+
import chalk123 from "chalk";
|
|
11608
11703
|
|
|
11609
11704
|
// src/shared/findRepoRoot.ts
|
|
11610
11705
|
import { existsSync as existsSync32 } from "fs";
|
|
@@ -11667,14 +11762,14 @@ function checkBuildLocks(startDir) {
|
|
|
11667
11762
|
const locked = findFirstLockedDll(startDir ?? getSearchRoot());
|
|
11668
11763
|
if (locked) {
|
|
11669
11764
|
console.error(
|
|
11670
|
-
|
|
11765
|
+
chalk123.red("Build output locked (is VS debugging?): ") + locked
|
|
11671
11766
|
);
|
|
11672
11767
|
process.exit(1);
|
|
11673
11768
|
}
|
|
11674
11769
|
}
|
|
11675
11770
|
async function checkBuildLocksCommand() {
|
|
11676
11771
|
checkBuildLocks();
|
|
11677
|
-
console.log(
|
|
11772
|
+
console.log(chalk123.green("No build locks detected"));
|
|
11678
11773
|
}
|
|
11679
11774
|
|
|
11680
11775
|
// src/commands/dotnet/buildTree.ts
|
|
@@ -11773,30 +11868,30 @@ function escapeRegex(s) {
|
|
|
11773
11868
|
}
|
|
11774
11869
|
|
|
11775
11870
|
// src/commands/dotnet/printTree.ts
|
|
11776
|
-
import
|
|
11871
|
+
import chalk124 from "chalk";
|
|
11777
11872
|
function printNodes(nodes, prefix2) {
|
|
11778
11873
|
for (let i = 0; i < nodes.length; i++) {
|
|
11779
11874
|
const isLast = i === nodes.length - 1;
|
|
11780
11875
|
const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
11781
11876
|
const childPrefix = isLast ? " " : "\u2502 ";
|
|
11782
11877
|
const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
|
|
11783
|
-
const label2 = isMissing ?
|
|
11878
|
+
const label2 = isMissing ? chalk124.red(nodes[i].relativePath) : nodes[i].relativePath;
|
|
11784
11879
|
console.log(`${prefix2}${connector}${label2}`);
|
|
11785
11880
|
printNodes(nodes[i].children, prefix2 + childPrefix);
|
|
11786
11881
|
}
|
|
11787
11882
|
}
|
|
11788
11883
|
function printTree(tree, totalCount, solutions) {
|
|
11789
|
-
console.log(
|
|
11790
|
-
console.log(
|
|
11884
|
+
console.log(chalk124.bold("\nProject Dependency Tree"));
|
|
11885
|
+
console.log(chalk124.cyan(tree.relativePath));
|
|
11791
11886
|
printNodes(tree.children, "");
|
|
11792
|
-
console.log(
|
|
11887
|
+
console.log(chalk124.dim(`
|
|
11793
11888
|
${totalCount} projects total (including root)`));
|
|
11794
|
-
console.log(
|
|
11889
|
+
console.log(chalk124.bold("\nSolution Membership"));
|
|
11795
11890
|
if (solutions.length === 0) {
|
|
11796
|
-
console.log(
|
|
11891
|
+
console.log(chalk124.yellow(" Not found in any .sln"));
|
|
11797
11892
|
} else {
|
|
11798
11893
|
for (const sln of solutions) {
|
|
11799
|
-
console.log(` ${
|
|
11894
|
+
console.log(` ${chalk124.green(sln)}`);
|
|
11800
11895
|
}
|
|
11801
11896
|
}
|
|
11802
11897
|
console.log();
|
|
@@ -11825,16 +11920,16 @@ function printJson(tree, totalCount, solutions) {
|
|
|
11825
11920
|
// src/commands/dotnet/resolveCsproj.ts
|
|
11826
11921
|
import { existsSync as existsSync33 } from "fs";
|
|
11827
11922
|
import path25 from "path";
|
|
11828
|
-
import
|
|
11923
|
+
import chalk125 from "chalk";
|
|
11829
11924
|
function resolveCsproj(csprojPath) {
|
|
11830
11925
|
const resolved = path25.resolve(csprojPath);
|
|
11831
11926
|
if (!existsSync33(resolved)) {
|
|
11832
|
-
console.error(
|
|
11927
|
+
console.error(chalk125.red(`File not found: ${resolved}`));
|
|
11833
11928
|
process.exit(1);
|
|
11834
11929
|
}
|
|
11835
11930
|
const repoRoot = findRepoRoot(path25.dirname(resolved));
|
|
11836
11931
|
if (!repoRoot) {
|
|
11837
|
-
console.error(
|
|
11932
|
+
console.error(chalk125.red("Could not find git repository root"));
|
|
11838
11933
|
process.exit(1);
|
|
11839
11934
|
}
|
|
11840
11935
|
return { resolved, repoRoot };
|
|
@@ -11884,12 +11979,12 @@ function getChangedCsFiles(scope) {
|
|
|
11884
11979
|
}
|
|
11885
11980
|
|
|
11886
11981
|
// src/commands/dotnet/inSln.ts
|
|
11887
|
-
import
|
|
11982
|
+
import chalk126 from "chalk";
|
|
11888
11983
|
async function inSln(csprojPath) {
|
|
11889
11984
|
const { resolved, repoRoot } = resolveCsproj(csprojPath);
|
|
11890
11985
|
const solutions = findContainingSolutions(resolved, repoRoot);
|
|
11891
11986
|
if (solutions.length === 0) {
|
|
11892
|
-
console.log(
|
|
11987
|
+
console.log(chalk126.yellow("Not found in any .sln file"));
|
|
11893
11988
|
process.exit(1);
|
|
11894
11989
|
}
|
|
11895
11990
|
for (const sln of solutions) {
|
|
@@ -11898,7 +11993,7 @@ async function inSln(csprojPath) {
|
|
|
11898
11993
|
}
|
|
11899
11994
|
|
|
11900
11995
|
// src/commands/dotnet/inspect.ts
|
|
11901
|
-
import
|
|
11996
|
+
import chalk132 from "chalk";
|
|
11902
11997
|
|
|
11903
11998
|
// src/shared/formatElapsed.ts
|
|
11904
11999
|
function formatElapsed(ms) {
|
|
@@ -11910,12 +12005,12 @@ function formatElapsed(ms) {
|
|
|
11910
12005
|
}
|
|
11911
12006
|
|
|
11912
12007
|
// src/commands/dotnet/displayIssues.ts
|
|
11913
|
-
import
|
|
12008
|
+
import chalk127 from "chalk";
|
|
11914
12009
|
var SEVERITY_COLOR = {
|
|
11915
|
-
ERROR:
|
|
11916
|
-
WARNING:
|
|
11917
|
-
SUGGESTION:
|
|
11918
|
-
HINT:
|
|
12010
|
+
ERROR: chalk127.red,
|
|
12011
|
+
WARNING: chalk127.yellow,
|
|
12012
|
+
SUGGESTION: chalk127.cyan,
|
|
12013
|
+
HINT: chalk127.dim
|
|
11919
12014
|
};
|
|
11920
12015
|
function groupByFile(issues) {
|
|
11921
12016
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -11931,15 +12026,15 @@ function groupByFile(issues) {
|
|
|
11931
12026
|
}
|
|
11932
12027
|
function displayIssues(issues) {
|
|
11933
12028
|
for (const [file, fileIssues] of groupByFile(issues)) {
|
|
11934
|
-
console.log(
|
|
12029
|
+
console.log(chalk127.bold(file));
|
|
11935
12030
|
for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
|
|
11936
|
-
const color = SEVERITY_COLOR[issue.severity] ??
|
|
12031
|
+
const color = SEVERITY_COLOR[issue.severity] ?? chalk127.white;
|
|
11937
12032
|
console.log(
|
|
11938
|
-
` ${
|
|
12033
|
+
` ${chalk127.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
|
|
11939
12034
|
);
|
|
11940
12035
|
}
|
|
11941
12036
|
}
|
|
11942
|
-
console.log(
|
|
12037
|
+
console.log(chalk127.dim(`
|
|
11943
12038
|
${issues.length} issue(s) found`));
|
|
11944
12039
|
}
|
|
11945
12040
|
|
|
@@ -11998,12 +12093,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
|
|
|
11998
12093
|
// src/commands/dotnet/resolveSolution.ts
|
|
11999
12094
|
import { existsSync as existsSync34 } from "fs";
|
|
12000
12095
|
import path26 from "path";
|
|
12001
|
-
import
|
|
12096
|
+
import chalk129 from "chalk";
|
|
12002
12097
|
|
|
12003
12098
|
// src/commands/dotnet/findSolution.ts
|
|
12004
12099
|
import { readdirSync as readdirSync6 } from "fs";
|
|
12005
12100
|
import { dirname as dirname20, join as join34 } from "path";
|
|
12006
|
-
import
|
|
12101
|
+
import chalk128 from "chalk";
|
|
12007
12102
|
function findSlnInDir(dir) {
|
|
12008
12103
|
try {
|
|
12009
12104
|
return readdirSync6(dir).filter((f) => f.endsWith(".sln")).map((f) => join34(dir, f));
|
|
@@ -12019,17 +12114,17 @@ function findSolution() {
|
|
|
12019
12114
|
const slnFiles = findSlnInDir(current);
|
|
12020
12115
|
if (slnFiles.length === 1) return slnFiles[0];
|
|
12021
12116
|
if (slnFiles.length > 1) {
|
|
12022
|
-
console.error(
|
|
12117
|
+
console.error(chalk128.red(`Multiple .sln files found in ${current}:`));
|
|
12023
12118
|
for (const f of slnFiles) console.error(` ${f}`);
|
|
12024
12119
|
console.error(
|
|
12025
|
-
|
|
12120
|
+
chalk128.yellow("Specify which one: assist dotnet inspect <sln>")
|
|
12026
12121
|
);
|
|
12027
12122
|
process.exit(1);
|
|
12028
12123
|
}
|
|
12029
12124
|
if (current === ceiling) break;
|
|
12030
12125
|
current = dirname20(current);
|
|
12031
12126
|
}
|
|
12032
|
-
console.error(
|
|
12127
|
+
console.error(chalk128.red("No .sln file found between cwd and repo root"));
|
|
12033
12128
|
process.exit(1);
|
|
12034
12129
|
}
|
|
12035
12130
|
|
|
@@ -12038,7 +12133,7 @@ function resolveSolution(sln) {
|
|
|
12038
12133
|
if (sln) {
|
|
12039
12134
|
const resolved = path26.resolve(sln);
|
|
12040
12135
|
if (!existsSync34(resolved)) {
|
|
12041
|
-
console.error(
|
|
12136
|
+
console.error(chalk129.red(`Solution file not found: ${resolved}`));
|
|
12042
12137
|
process.exit(1);
|
|
12043
12138
|
}
|
|
12044
12139
|
return resolved;
|
|
@@ -12080,14 +12175,14 @@ import { execSync as execSync30 } from "child_process";
|
|
|
12080
12175
|
import { existsSync as existsSync35, readFileSync as readFileSync30, unlinkSync as unlinkSync9 } from "fs";
|
|
12081
12176
|
import { tmpdir as tmpdir3 } from "os";
|
|
12082
12177
|
import path27 from "path";
|
|
12083
|
-
import
|
|
12178
|
+
import chalk130 from "chalk";
|
|
12084
12179
|
function assertJbInstalled() {
|
|
12085
12180
|
try {
|
|
12086
12181
|
execSync30("jb inspectcode --version", { stdio: "pipe" });
|
|
12087
12182
|
} catch {
|
|
12088
|
-
console.error(
|
|
12183
|
+
console.error(chalk130.red("jb is not installed. Install with:"));
|
|
12089
12184
|
console.error(
|
|
12090
|
-
|
|
12185
|
+
chalk130.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
|
|
12091
12186
|
);
|
|
12092
12187
|
process.exit(1);
|
|
12093
12188
|
}
|
|
@@ -12105,11 +12200,11 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
12105
12200
|
if (error && typeof error === "object" && "stderr" in error) {
|
|
12106
12201
|
process.stderr.write(error.stderr);
|
|
12107
12202
|
}
|
|
12108
|
-
console.error(
|
|
12203
|
+
console.error(chalk130.red("jb inspectcode failed"));
|
|
12109
12204
|
process.exit(1);
|
|
12110
12205
|
}
|
|
12111
12206
|
if (!existsSync35(reportPath)) {
|
|
12112
|
-
console.error(
|
|
12207
|
+
console.error(chalk130.red("Report file not generated"));
|
|
12113
12208
|
process.exit(1);
|
|
12114
12209
|
}
|
|
12115
12210
|
const xml = readFileSync30(reportPath, "utf8");
|
|
@@ -12119,7 +12214,7 @@ function runInspectCode(slnPath, include, swea) {
|
|
|
12119
12214
|
|
|
12120
12215
|
// src/commands/dotnet/runRoslynInspect.ts
|
|
12121
12216
|
import { execSync as execSync31 } from "child_process";
|
|
12122
|
-
import
|
|
12217
|
+
import chalk131 from "chalk";
|
|
12123
12218
|
function resolveMsbuildPath() {
|
|
12124
12219
|
const { run: run4 } = loadConfig();
|
|
12125
12220
|
const configs = resolveRunConfigs(run4, getConfigDir());
|
|
@@ -12131,9 +12226,9 @@ function assertMsbuildInstalled() {
|
|
|
12131
12226
|
try {
|
|
12132
12227
|
execSync31(`"${msbuild}" -version`, { stdio: "pipe" });
|
|
12133
12228
|
} catch {
|
|
12134
|
-
console.error(
|
|
12229
|
+
console.error(chalk131.red(`msbuild not found at: ${msbuild}`));
|
|
12135
12230
|
console.error(
|
|
12136
|
-
|
|
12231
|
+
chalk131.yellow(
|
|
12137
12232
|
"Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
|
|
12138
12233
|
)
|
|
12139
12234
|
);
|
|
@@ -12180,17 +12275,17 @@ function runEngine(resolved, changedFiles, options2) {
|
|
|
12180
12275
|
// src/commands/dotnet/inspect.ts
|
|
12181
12276
|
function logScope(changedFiles) {
|
|
12182
12277
|
if (changedFiles === null) {
|
|
12183
|
-
console.log(
|
|
12278
|
+
console.log(chalk132.dim("Inspecting full solution..."));
|
|
12184
12279
|
} else {
|
|
12185
12280
|
console.log(
|
|
12186
|
-
|
|
12281
|
+
chalk132.dim(`Inspecting ${changedFiles.length} changed file(s)...`)
|
|
12187
12282
|
);
|
|
12188
12283
|
}
|
|
12189
12284
|
}
|
|
12190
12285
|
function reportResults(issues, elapsed) {
|
|
12191
12286
|
if (issues.length > 0) displayIssues(issues);
|
|
12192
|
-
else console.log(
|
|
12193
|
-
console.log(
|
|
12287
|
+
else console.log(chalk132.green("No issues found"));
|
|
12288
|
+
console.log(chalk132.dim(`Completed in ${formatElapsed(elapsed)}`));
|
|
12194
12289
|
if (issues.length > 0) process.exit(1);
|
|
12195
12290
|
}
|
|
12196
12291
|
async function inspect(sln, options2) {
|
|
@@ -12201,7 +12296,7 @@ async function inspect(sln, options2) {
|
|
|
12201
12296
|
const scope = parseScope(options2.scope);
|
|
12202
12297
|
const changedFiles = getChangedCsFiles(scope);
|
|
12203
12298
|
if (changedFiles !== null && changedFiles.length === 0) {
|
|
12204
|
-
console.log(
|
|
12299
|
+
console.log(chalk132.green("No changed .cs files found"));
|
|
12205
12300
|
return;
|
|
12206
12301
|
}
|
|
12207
12302
|
logScope(changedFiles);
|
|
@@ -12526,25 +12621,25 @@ function fetchRepoCommitAuthors(org, repo, since) {
|
|
|
12526
12621
|
}
|
|
12527
12622
|
|
|
12528
12623
|
// src/commands/github/printCountTable.ts
|
|
12529
|
-
import
|
|
12624
|
+
import chalk133 from "chalk";
|
|
12530
12625
|
function printCountTable(labelHeader, rows) {
|
|
12531
12626
|
const labelWidth = Math.max(
|
|
12532
12627
|
labelHeader.length,
|
|
12533
12628
|
...rows.map((row) => row.label.length)
|
|
12534
12629
|
);
|
|
12535
12630
|
const header = `${labelHeader.padEnd(labelWidth)} Commits`;
|
|
12536
|
-
console.log(
|
|
12537
|
-
console.log(
|
|
12631
|
+
console.log(chalk133.dim(header));
|
|
12632
|
+
console.log(chalk133.dim("-".repeat(header.length)));
|
|
12538
12633
|
for (const row of rows) {
|
|
12539
12634
|
console.log(`${row.label.padEnd(labelWidth)} ${row.count}`);
|
|
12540
12635
|
}
|
|
12541
12636
|
}
|
|
12542
12637
|
|
|
12543
12638
|
// src/commands/github/printRepoAuthorBreakdown.ts
|
|
12544
|
-
import
|
|
12639
|
+
import chalk134 from "chalk";
|
|
12545
12640
|
function printRepoAuthorBreakdown(repos2) {
|
|
12546
12641
|
for (const repo of repos2) {
|
|
12547
|
-
console.log(
|
|
12642
|
+
console.log(chalk134.bold(repo.name));
|
|
12548
12643
|
const authorWidth = Math.max(
|
|
12549
12644
|
0,
|
|
12550
12645
|
...repo.authors.map((a) => a.author.length)
|
|
@@ -12641,9 +12736,9 @@ function registerGithub(program2) {
|
|
|
12641
12736
|
}
|
|
12642
12737
|
|
|
12643
12738
|
// src/commands/handover/countPendingHandovers.ts
|
|
12644
|
-
import { and as
|
|
12739
|
+
import { and as and14, eq as eq33, isNull, sql as sql5 } from "drizzle-orm";
|
|
12645
12740
|
async function countPendingHandovers(orm, origin) {
|
|
12646
|
-
const [row] = await orm.select({ count: sql5`count(*)::int` }).from(handovers).where(
|
|
12741
|
+
const [row] = await orm.select({ count: sql5`count(*)::int` }).from(handovers).where(and14(eq33(handovers.origin, origin), isNull(handovers.recalledAt)));
|
|
12647
12742
|
return row?.count ?? 0;
|
|
12648
12743
|
}
|
|
12649
12744
|
|
|
@@ -12758,9 +12853,9 @@ function resolveLoadOptions(options2) {
|
|
|
12758
12853
|
}
|
|
12759
12854
|
|
|
12760
12855
|
// src/commands/handover/load.ts
|
|
12761
|
-
function advisory(
|
|
12762
|
-
const noun =
|
|
12763
|
-
return `${
|
|
12856
|
+
function advisory(count8) {
|
|
12857
|
+
const noun = count8 === 1 ? "handover" : "handovers";
|
|
12858
|
+
return `${count8} unrecalled ${noun} for this repo. Run /recall to load.`;
|
|
12764
12859
|
}
|
|
12765
12860
|
function emit2(message) {
|
|
12766
12861
|
const json = JSON.stringify({
|
|
@@ -12777,19 +12872,19 @@ async function load2(options2 = {}) {
|
|
|
12777
12872
|
const origin = getCurrentOrigin(cwd);
|
|
12778
12873
|
const orm = options2.orm ?? await getDb();
|
|
12779
12874
|
await migrateDiskHandovers(orm, origin, cwd);
|
|
12780
|
-
const
|
|
12781
|
-
if (
|
|
12782
|
-
return emit2(advisory(
|
|
12875
|
+
const count8 = await countPendingHandovers(orm, origin);
|
|
12876
|
+
if (count8 === 0) return null;
|
|
12877
|
+
return emit2(advisory(count8));
|
|
12783
12878
|
}
|
|
12784
12879
|
|
|
12785
12880
|
// src/commands/handover/listPendingHandovers.ts
|
|
12786
|
-
import { and as
|
|
12881
|
+
import { and as and15, desc as desc4, eq as eq34, isNull as isNull2 } from "drizzle-orm";
|
|
12787
12882
|
async function listPendingHandovers(orm, origin) {
|
|
12788
12883
|
return orm.select({
|
|
12789
12884
|
id: handovers.id,
|
|
12790
12885
|
summary: handovers.summary,
|
|
12791
12886
|
createdAt: handovers.createdAt
|
|
12792
|
-
}).from(handovers).where(
|
|
12887
|
+
}).from(handovers).where(and15(eq34(handovers.origin, origin), isNull2(handovers.recalledAt))).orderBy(desc4(handovers.createdAt), desc4(handovers.id));
|
|
12793
12888
|
}
|
|
12794
12889
|
|
|
12795
12890
|
// src/commands/handover/printPendingHandovers.ts
|
|
@@ -12802,17 +12897,17 @@ async function printPendingHandovers() {
|
|
|
12802
12897
|
}
|
|
12803
12898
|
|
|
12804
12899
|
// src/commands/handover/recallHandover.ts
|
|
12805
|
-
import { and as
|
|
12900
|
+
import { and as and16, desc as desc5, eq as eq35, isNull as isNull3 } from "drizzle-orm";
|
|
12806
12901
|
async function recallHandover(orm, origin, id2) {
|
|
12807
12902
|
const [row] = await orm.select().from(handovers).where(
|
|
12808
|
-
|
|
12809
|
-
|
|
12903
|
+
and16(
|
|
12904
|
+
eq35(handovers.origin, origin),
|
|
12810
12905
|
isNull3(handovers.recalledAt),
|
|
12811
|
-
...id2 === void 0 ? [] : [
|
|
12906
|
+
...id2 === void 0 ? [] : [eq35(handovers.id, id2)]
|
|
12812
12907
|
)
|
|
12813
12908
|
).orderBy(desc5(handovers.createdAt), desc5(handovers.id)).limit(1);
|
|
12814
12909
|
if (!row) return void 0;
|
|
12815
|
-
await orm.update(handovers).set({ recalledAt: /* @__PURE__ */ new Date() }).where(
|
|
12910
|
+
await orm.update(handovers).set({ recalledAt: /* @__PURE__ */ new Date() }).where(eq35(handovers.id, row.id));
|
|
12816
12911
|
return row.content;
|
|
12817
12912
|
}
|
|
12818
12913
|
|
|
@@ -12862,7 +12957,7 @@ function registerHandover(program2) {
|
|
|
12862
12957
|
}
|
|
12863
12958
|
|
|
12864
12959
|
// src/commands/jira/acceptanceCriteria.ts
|
|
12865
|
-
import
|
|
12960
|
+
import chalk135 from "chalk";
|
|
12866
12961
|
|
|
12867
12962
|
// src/commands/jira/adfToText.ts
|
|
12868
12963
|
function renderInline(node) {
|
|
@@ -12929,7 +13024,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
12929
13024
|
const parsed = fetchIssue(issueKey, field);
|
|
12930
13025
|
const acValue = parsed?.fields?.[field];
|
|
12931
13026
|
if (!acValue) {
|
|
12932
|
-
console.log(
|
|
13027
|
+
console.log(chalk135.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
12933
13028
|
return;
|
|
12934
13029
|
}
|
|
12935
13030
|
if (typeof acValue === "string") {
|
|
@@ -13024,14 +13119,14 @@ async function jiraAuth() {
|
|
|
13024
13119
|
}
|
|
13025
13120
|
|
|
13026
13121
|
// src/commands/jira/viewIssue.ts
|
|
13027
|
-
import
|
|
13122
|
+
import chalk136 from "chalk";
|
|
13028
13123
|
function viewIssue(issueKey) {
|
|
13029
13124
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
13030
13125
|
const fields = parsed?.fields;
|
|
13031
13126
|
const summary = fields?.summary;
|
|
13032
13127
|
const description = fields?.description;
|
|
13033
13128
|
if (summary) {
|
|
13034
|
-
console.log(
|
|
13129
|
+
console.log(chalk136.bold(summary));
|
|
13035
13130
|
}
|
|
13036
13131
|
if (description) {
|
|
13037
13132
|
if (summary) console.log();
|
|
@@ -13045,7 +13140,7 @@ function viewIssue(issueKey) {
|
|
|
13045
13140
|
}
|
|
13046
13141
|
if (!summary && !description) {
|
|
13047
13142
|
console.log(
|
|
13048
|
-
|
|
13143
|
+
chalk136.yellow(`No summary or description found on ${issueKey}.`)
|
|
13049
13144
|
);
|
|
13050
13145
|
}
|
|
13051
13146
|
}
|
|
@@ -13061,13 +13156,13 @@ function registerJira(program2) {
|
|
|
13061
13156
|
// src/commands/reviewComments.ts
|
|
13062
13157
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
13063
13158
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
13064
|
-
import
|
|
13159
|
+
import chalk137 from "chalk";
|
|
13065
13160
|
async function reviewComments(number) {
|
|
13066
13161
|
if (number) {
|
|
13067
13162
|
try {
|
|
13068
13163
|
execFileSync5("gh", ["pr", "checkout", number], { stdio: "inherit" });
|
|
13069
13164
|
} catch {
|
|
13070
|
-
console.error(
|
|
13165
|
+
console.error(chalk137.red(`gh pr checkout ${number} failed; aborting.`));
|
|
13071
13166
|
process.exit(1);
|
|
13072
13167
|
}
|
|
13073
13168
|
}
|
|
@@ -13141,15 +13236,15 @@ function registerList(program2) {
|
|
|
13141
13236
|
// src/commands/mermaid/index.ts
|
|
13142
13237
|
import { mkdirSync as mkdirSync14, readdirSync as readdirSync8 } from "fs";
|
|
13143
13238
|
import { resolve as resolve11 } from "path";
|
|
13144
|
-
import
|
|
13239
|
+
import chalk140 from "chalk";
|
|
13145
13240
|
|
|
13146
13241
|
// src/commands/mermaid/exportFile.ts
|
|
13147
13242
|
import { readFileSync as readFileSync33, writeFileSync as writeFileSync28 } from "fs";
|
|
13148
13243
|
import { basename as basename8, extname, resolve as resolve10 } from "path";
|
|
13149
|
-
import
|
|
13244
|
+
import chalk139 from "chalk";
|
|
13150
13245
|
|
|
13151
13246
|
// src/commands/mermaid/renderBlock.ts
|
|
13152
|
-
import
|
|
13247
|
+
import chalk138 from "chalk";
|
|
13153
13248
|
async function renderBlock(krokiUrl, source) {
|
|
13154
13249
|
const response = await fetch(`${krokiUrl}/mermaid/svg`, {
|
|
13155
13250
|
method: "POST",
|
|
@@ -13158,7 +13253,7 @@ async function renderBlock(krokiUrl, source) {
|
|
|
13158
13253
|
});
|
|
13159
13254
|
if (!response.ok) {
|
|
13160
13255
|
console.error(
|
|
13161
|
-
|
|
13256
|
+
chalk138.red(
|
|
13162
13257
|
`Kroki request failed: ${response.status} ${response.statusText}`
|
|
13163
13258
|
)
|
|
13164
13259
|
);
|
|
@@ -13176,19 +13271,19 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
13176
13271
|
if (onlyIndex !== void 0) {
|
|
13177
13272
|
if (onlyIndex < 1 || onlyIndex > blocks.length) {
|
|
13178
13273
|
console.error(
|
|
13179
|
-
|
|
13274
|
+
chalk139.red(
|
|
13180
13275
|
`${file}: --index ${onlyIndex} out of range (file has ${blocks.length} diagram(s))`
|
|
13181
13276
|
)
|
|
13182
13277
|
);
|
|
13183
13278
|
process.exit(1);
|
|
13184
13279
|
}
|
|
13185
13280
|
console.log(
|
|
13186
|
-
|
|
13281
|
+
chalk139.gray(
|
|
13187
13282
|
`${file} \u2014 rendering diagram ${onlyIndex} of ${blocks.length}`
|
|
13188
13283
|
)
|
|
13189
13284
|
);
|
|
13190
13285
|
} else {
|
|
13191
|
-
console.log(
|
|
13286
|
+
console.log(chalk139.gray(`${file} \u2014 ${blocks.length} diagram(s)`));
|
|
13192
13287
|
}
|
|
13193
13288
|
for (const [i, source] of blocks.entries()) {
|
|
13194
13289
|
const idx = i + 1;
|
|
@@ -13196,7 +13291,7 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
13196
13291
|
const outPath = resolve10(outDir, `${stem}-${idx}.svg`);
|
|
13197
13292
|
const svg = await renderBlock(krokiUrl, source);
|
|
13198
13293
|
writeFileSync28(outPath, svg, "utf8");
|
|
13199
|
-
console.log(
|
|
13294
|
+
console.log(chalk139.green(` \u2192 ${outPath}`));
|
|
13200
13295
|
}
|
|
13201
13296
|
}
|
|
13202
13297
|
function extractMermaidBlocks(markdown) {
|
|
@@ -13212,18 +13307,18 @@ async function mermaidExport(file, options2 = {}) {
|
|
|
13212
13307
|
if (options2.index !== void 0) {
|
|
13213
13308
|
if (!Number.isInteger(options2.index) || options2.index < 1) {
|
|
13214
13309
|
console.error(
|
|
13215
|
-
|
|
13310
|
+
chalk140.red(`--index must be a positive integer (got ${options2.index})`)
|
|
13216
13311
|
);
|
|
13217
13312
|
process.exit(1);
|
|
13218
13313
|
}
|
|
13219
13314
|
if (!file) {
|
|
13220
|
-
console.error(
|
|
13315
|
+
console.error(chalk140.red("--index requires a file argument"));
|
|
13221
13316
|
process.exit(1);
|
|
13222
13317
|
}
|
|
13223
13318
|
}
|
|
13224
13319
|
const files = file ? [file] : readdirSync8(process.cwd()).filter((name) => name.toLowerCase().endsWith(".md")).sort();
|
|
13225
13320
|
if (files.length === 0) {
|
|
13226
|
-
console.log(
|
|
13321
|
+
console.log(chalk140.gray("No markdown files found in current directory."));
|
|
13227
13322
|
return;
|
|
13228
13323
|
}
|
|
13229
13324
|
for (const f of files) {
|
|
@@ -13249,7 +13344,7 @@ function registerMermaid(program2) {
|
|
|
13249
13344
|
import { mkdir as mkdir3 } from "fs/promises";
|
|
13250
13345
|
import { createServer as createServer2 } from "http";
|
|
13251
13346
|
import { dirname as dirname22 } from "path";
|
|
13252
|
-
import
|
|
13347
|
+
import chalk142 from "chalk";
|
|
13253
13348
|
|
|
13254
13349
|
// src/commands/netcap/corsHeaders.ts
|
|
13255
13350
|
var corsHeaders = {
|
|
@@ -13328,7 +13423,7 @@ function createNetcapHandler(options2) {
|
|
|
13328
13423
|
import { cp, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
13329
13424
|
import { networkInterfaces } from "os";
|
|
13330
13425
|
import { join as join41 } from "path";
|
|
13331
|
-
import
|
|
13426
|
+
import chalk141 from "chalk";
|
|
13332
13427
|
|
|
13333
13428
|
// src/commands/netcap/netcapExtensionDir.ts
|
|
13334
13429
|
import { dirname as dirname21, join as join40 } from "path";
|
|
@@ -13372,7 +13467,7 @@ async function prepareExtensionForLoad(port, filter = "") {
|
|
|
13372
13467
|
const host = lanIPv4();
|
|
13373
13468
|
if (!host) {
|
|
13374
13469
|
console.log(
|
|
13375
|
-
|
|
13470
|
+
chalk141.yellow("could not determine the WSL IP for the extension")
|
|
13376
13471
|
);
|
|
13377
13472
|
await configureBackground(source, "127.0.0.1", port, filter);
|
|
13378
13473
|
return source;
|
|
@@ -13383,7 +13478,7 @@ async function prepareExtensionForLoad(port, filter = "") {
|
|
|
13383
13478
|
return WSL_WINDOWS_PATH;
|
|
13384
13479
|
} catch {
|
|
13385
13480
|
console.log(
|
|
13386
|
-
|
|
13481
|
+
chalk141.yellow(`could not copy extension to ${WSL_WINDOWS_PATH}`)
|
|
13387
13482
|
);
|
|
13388
13483
|
return source;
|
|
13389
13484
|
}
|
|
@@ -13413,35 +13508,35 @@ async function netcap(options2) {
|
|
|
13413
13508
|
const filter = options2.filter ?? "";
|
|
13414
13509
|
await mkdir3(dirname22(outPath), { recursive: true });
|
|
13415
13510
|
const extensionPath = await prepareExtensionForLoad(port, filter);
|
|
13416
|
-
let
|
|
13511
|
+
let count8 = 0;
|
|
13417
13512
|
const handler = createNetcapHandler({
|
|
13418
13513
|
outPath,
|
|
13419
|
-
onPing: () => console.log(
|
|
13514
|
+
onPing: () => console.log(chalk142.dim("ping from extension")),
|
|
13420
13515
|
onCapture: (entry) => {
|
|
13421
|
-
|
|
13516
|
+
count8 += 1;
|
|
13422
13517
|
console.log(
|
|
13423
|
-
|
|
13424
|
-
|
|
13518
|
+
chalk142.green(`captured #${count8}`),
|
|
13519
|
+
chalk142.dim(`${entry.method ?? "?"} ${entry.url ?? "?"}`)
|
|
13425
13520
|
);
|
|
13426
13521
|
}
|
|
13427
13522
|
});
|
|
13428
13523
|
const server = createServer2(handler);
|
|
13429
13524
|
server.listen(port, () => {
|
|
13430
13525
|
console.log(
|
|
13431
|
-
|
|
13526
|
+
chalk142.bold(`netcap receiver listening on http://127.0.0.1:${port}`)
|
|
13432
13527
|
);
|
|
13433
|
-
console.log(
|
|
13528
|
+
console.log(chalk142.dim(`appending captures to ${outPath}`));
|
|
13434
13529
|
if (filter)
|
|
13435
|
-
console.log(
|
|
13436
|
-
console.log(
|
|
13437
|
-
console.log(
|
|
13530
|
+
console.log(chalk142.dim(`forwarding only URLs matching "${filter}"`));
|
|
13531
|
+
console.log(chalk142.dim(`load the unpacked extension from ${extensionPath}`));
|
|
13532
|
+
console.log(chalk142.dim("press Ctrl-C to stop"));
|
|
13438
13533
|
});
|
|
13439
13534
|
process.on("SIGINT", () => {
|
|
13440
13535
|
server.close();
|
|
13441
13536
|
console.log(
|
|
13442
|
-
|
|
13537
|
+
chalk142.bold(
|
|
13443
13538
|
`
|
|
13444
|
-
netcap stopped \u2014 captured ${
|
|
13539
|
+
netcap stopped \u2014 captured ${count8} ${count8 === 1 ? "entry" : "entries"} to ${outPath}`
|
|
13445
13540
|
)
|
|
13446
13541
|
);
|
|
13447
13542
|
process.exit(0);
|
|
@@ -13451,7 +13546,7 @@ netcap stopped \u2014 captured ${count7} ${count7 === 1 ? "entry" : "entries"} t
|
|
|
13451
13546
|
// src/commands/netcap/netcapExtract.ts
|
|
13452
13547
|
import { writeFileSync as writeFileSync29 } from "fs";
|
|
13453
13548
|
import { join as join44 } from "path";
|
|
13454
|
-
import
|
|
13549
|
+
import chalk143 from "chalk";
|
|
13455
13550
|
|
|
13456
13551
|
// src/commands/netcap/extractPostsFromCapture.ts
|
|
13457
13552
|
import { readFileSync as readFileSync34 } from "fs";
|
|
@@ -13899,8 +13994,8 @@ function netcapExtract(file) {
|
|
|
13899
13994
|
writeFileSync29(outFile, `${JSON.stringify(posts, null, 2)}
|
|
13900
13995
|
`);
|
|
13901
13996
|
console.log(
|
|
13902
|
-
|
|
13903
|
-
|
|
13997
|
+
chalk143.green(`extracted ${posts.length} posts`),
|
|
13998
|
+
chalk143.dim(`-> ${outFile}`)
|
|
13904
13999
|
);
|
|
13905
14000
|
}
|
|
13906
14001
|
|
|
@@ -13921,7 +14016,7 @@ function registerNetcap(program2) {
|
|
|
13921
14016
|
}
|
|
13922
14017
|
|
|
13923
14018
|
// src/commands/news/add/index.ts
|
|
13924
|
-
import
|
|
14019
|
+
import chalk144 from "chalk";
|
|
13925
14020
|
import enquirer8 from "enquirer";
|
|
13926
14021
|
async function add2(url) {
|
|
13927
14022
|
if (!url) {
|
|
@@ -13943,10 +14038,10 @@ async function add2(url) {
|
|
|
13943
14038
|
const { orm } = await getReady();
|
|
13944
14039
|
const added = await addFeed(orm, url);
|
|
13945
14040
|
if (!added) {
|
|
13946
|
-
console.log(
|
|
14041
|
+
console.log(chalk144.yellow("Feed already exists"));
|
|
13947
14042
|
return;
|
|
13948
14043
|
}
|
|
13949
|
-
console.log(
|
|
14044
|
+
console.log(chalk144.green(`Added feed: ${url}`));
|
|
13950
14045
|
}
|
|
13951
14046
|
|
|
13952
14047
|
// src/commands/registerNews.ts
|
|
@@ -13956,7 +14051,7 @@ function registerNews(program2) {
|
|
|
13956
14051
|
}
|
|
13957
14052
|
|
|
13958
14053
|
// src/commands/prompts/printPromptsTable.ts
|
|
13959
|
-
import
|
|
14054
|
+
import chalk145 from "chalk";
|
|
13960
14055
|
function truncate(str, max) {
|
|
13961
14056
|
if (str.length <= max) return str;
|
|
13962
14057
|
return `${str.slice(0, max - 1)}\u2026`;
|
|
@@ -13974,14 +14069,14 @@ function printPromptsTable(rows) {
|
|
|
13974
14069
|
"Command".padEnd(commandWidth),
|
|
13975
14070
|
"Repos"
|
|
13976
14071
|
].join(" ");
|
|
13977
|
-
console.log(
|
|
13978
|
-
console.log(
|
|
14072
|
+
console.log(chalk145.dim(header));
|
|
14073
|
+
console.log(chalk145.dim("-".repeat(header.length)));
|
|
13979
14074
|
for (const row of rows) {
|
|
13980
|
-
const
|
|
14075
|
+
const count8 = String(row.count).padStart(countWidth);
|
|
13981
14076
|
const tool = row.tool.padEnd(toolWidth);
|
|
13982
14077
|
const command = truncate(row.command, 60).padEnd(commandWidth);
|
|
13983
14078
|
console.log(
|
|
13984
|
-
`${
|
|
14079
|
+
`${chalk145.yellow(count8)} ${tool} ${command} ${chalk145.dim(row.repos)}`
|
|
13985
14080
|
);
|
|
13986
14081
|
}
|
|
13987
14082
|
}
|
|
@@ -14530,20 +14625,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
14530
14625
|
}
|
|
14531
14626
|
|
|
14532
14627
|
// src/commands/prs/listComments/printComments.ts
|
|
14533
|
-
import
|
|
14628
|
+
import chalk146 from "chalk";
|
|
14534
14629
|
function formatForHuman(comment3) {
|
|
14535
14630
|
if (comment3.type === "review") {
|
|
14536
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
14631
|
+
const stateColor = comment3.state === "APPROVED" ? chalk146.green : comment3.state === "CHANGES_REQUESTED" ? chalk146.red : chalk146.yellow;
|
|
14537
14632
|
return [
|
|
14538
|
-
`${
|
|
14633
|
+
`${chalk146.cyan("Review")} by ${chalk146.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
14539
14634
|
comment3.body,
|
|
14540
14635
|
""
|
|
14541
14636
|
].join("\n");
|
|
14542
14637
|
}
|
|
14543
14638
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
14544
14639
|
return [
|
|
14545
|
-
`${
|
|
14546
|
-
|
|
14640
|
+
`${chalk146.cyan("Line comment")} by ${chalk146.bold(comment3.user)} on ${chalk146.dim(`${comment3.path}${location}`)}`,
|
|
14641
|
+
chalk146.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
14547
14642
|
comment3.body,
|
|
14548
14643
|
""
|
|
14549
14644
|
].join("\n");
|
|
@@ -14633,13 +14728,13 @@ import { execSync as execSync40 } from "child_process";
|
|
|
14633
14728
|
import enquirer9 from "enquirer";
|
|
14634
14729
|
|
|
14635
14730
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
14636
|
-
import
|
|
14731
|
+
import chalk147 from "chalk";
|
|
14637
14732
|
var STATUS_MAP = {
|
|
14638
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
14639
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
14733
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk147.magenta("merged"), date: pr.mergedAt } : null,
|
|
14734
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk147.red("closed"), date: pr.closedAt } : null
|
|
14640
14735
|
};
|
|
14641
14736
|
function defaultStatus(pr) {
|
|
14642
|
-
return { label:
|
|
14737
|
+
return { label: chalk147.green("opened"), date: pr.createdAt };
|
|
14643
14738
|
}
|
|
14644
14739
|
function getStatus2(pr) {
|
|
14645
14740
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -14648,11 +14743,11 @@ function formatDate(dateStr) {
|
|
|
14648
14743
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
14649
14744
|
}
|
|
14650
14745
|
function formatPrHeader(pr, status2) {
|
|
14651
|
-
return `${
|
|
14746
|
+
return `${chalk147.cyan(`#${pr.number}`)} ${pr.title} ${chalk147.dim(`(${pr.author.login},`)} ${status2.label} ${chalk147.dim(`${formatDate(status2.date)})`)}`;
|
|
14652
14747
|
}
|
|
14653
14748
|
function logPrDetails(pr) {
|
|
14654
14749
|
console.log(
|
|
14655
|
-
|
|
14750
|
+
chalk147.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
14656
14751
|
);
|
|
14657
14752
|
console.log();
|
|
14658
14753
|
}
|
|
@@ -14708,8 +14803,8 @@ async function promptNavigation(currentPage, totalPages) {
|
|
|
14708
14803
|
});
|
|
14709
14804
|
return parseAction(action);
|
|
14710
14805
|
}
|
|
14711
|
-
function computeTotalPages(
|
|
14712
|
-
return Math.ceil(
|
|
14806
|
+
function computeTotalPages(count8) {
|
|
14807
|
+
return Math.ceil(count8 / PAGE_SIZE);
|
|
14713
14808
|
}
|
|
14714
14809
|
async function navigateAndDisplay(pullRequests, totalPages, currentPage) {
|
|
14715
14810
|
const delta = await promptNavigation(currentPage, totalPages);
|
|
@@ -14894,7 +14989,7 @@ function wontfix(commentId, reason) {
|
|
|
14894
14989
|
}
|
|
14895
14990
|
|
|
14896
14991
|
// src/commands/registerPrsEdit.ts
|
|
14897
|
-
function
|
|
14992
|
+
function collect3(value, previous) {
|
|
14898
14993
|
return previous.concat([value]);
|
|
14899
14994
|
}
|
|
14900
14995
|
function registerPrsEdit(prsCommand) {
|
|
@@ -14903,13 +14998,13 @@ function registerPrsEdit(prsCommand) {
|
|
|
14903
14998
|
).option("-t, --title <title>", "New title for the pull request").option("--what <what>", "Replace the ## What section").option("--why <why>", "Replace the ## Why section").option("--how <how>", "Replace the ## How section").option(
|
|
14904
14999
|
"--resolves <key>",
|
|
14905
15000
|
"Jira issue key resolved by this PR, appended to ## Why (repeatable)",
|
|
14906
|
-
|
|
15001
|
+
collect3,
|
|
14907
15002
|
[]
|
|
14908
15003
|
).action(edit);
|
|
14909
15004
|
}
|
|
14910
15005
|
|
|
14911
15006
|
// src/commands/registerPrsRaise.ts
|
|
14912
|
-
function
|
|
15007
|
+
function collect4(value, previous) {
|
|
14913
15008
|
return previous.concat([value]);
|
|
14914
15009
|
}
|
|
14915
15010
|
function registerPrsRaise(prsCommand) {
|
|
@@ -14918,20 +15013,20 @@ function registerPrsRaise(prsCommand) {
|
|
|
14918
15013
|
).option("-t, --title <title>", "Title for the pull request").option("--what <what>", "What the change does (## What section)").option("--why <why>", "Why the change is needed (## Why section)").option("--how <how>", "How the change works (optional ## How section)").option(
|
|
14919
15014
|
"--resolves <key>",
|
|
14920
15015
|
"Jira issue key resolved by this PR, appended to ## Why (repeatable)",
|
|
14921
|
-
|
|
15016
|
+
collect4,
|
|
14922
15017
|
[]
|
|
14923
15018
|
).option(
|
|
14924
15019
|
"--force",
|
|
14925
15020
|
"Overwrite the title and body of an existing pull request"
|
|
14926
|
-
).option("-B, --base <branch>", "Branch into which the pull request merges").option("-H, --head <branch>", "Branch that contains the commits").option("-d, --draft", "Mark the pull request as a draft").option("-w, --web", "Open the browser to create the pull request").option("-l, --label <label>", "Add a label (repeatable)",
|
|
15021
|
+
).option("-B, --base <branch>", "Branch into which the pull request merges").option("-H, --head <branch>", "Branch that contains the commits").option("-d, --draft", "Mark the pull request as a draft").option("-w, --web", "Open the browser to create the pull request").option("-l, --label <label>", "Add a label (repeatable)", collect4, []).option(
|
|
14927
15022
|
"-a, --assignee <login>",
|
|
14928
15023
|
"Assign a person by login (repeatable)",
|
|
14929
|
-
|
|
15024
|
+
collect4,
|
|
14930
15025
|
[]
|
|
14931
15026
|
).option(
|
|
14932
15027
|
"-r, --reviewer <handle>",
|
|
14933
15028
|
"Request a review (repeatable)",
|
|
14934
|
-
|
|
15029
|
+
collect4,
|
|
14935
15030
|
[]
|
|
14936
15031
|
).option("-m, --milestone <name>", "Add the pull request to a milestone").action(raise);
|
|
14937
15032
|
}
|
|
@@ -14959,10 +15054,10 @@ function registerPrs(program2) {
|
|
|
14959
15054
|
}
|
|
14960
15055
|
|
|
14961
15056
|
// src/commands/ravendb/ravendbAuth.ts
|
|
14962
|
-
import
|
|
15057
|
+
import chalk153 from "chalk";
|
|
14963
15058
|
|
|
14964
15059
|
// src/shared/createConnectionAuth.ts
|
|
14965
|
-
import
|
|
15060
|
+
import chalk148 from "chalk";
|
|
14966
15061
|
function listConnections(connections, format) {
|
|
14967
15062
|
if (connections.length === 0) {
|
|
14968
15063
|
console.log("No connections configured.");
|
|
@@ -14975,7 +15070,7 @@ function listConnections(connections, format) {
|
|
|
14975
15070
|
function removeConnection(connections, name, save) {
|
|
14976
15071
|
const filtered = connections.filter((c) => c.name !== name);
|
|
14977
15072
|
if (filtered.length === connections.length) {
|
|
14978
|
-
console.error(
|
|
15073
|
+
console.error(chalk148.red(`Connection "${name}" not found.`));
|
|
14979
15074
|
process.exit(1);
|
|
14980
15075
|
}
|
|
14981
15076
|
save(filtered);
|
|
@@ -15021,15 +15116,15 @@ function saveConnections(connections) {
|
|
|
15021
15116
|
}
|
|
15022
15117
|
|
|
15023
15118
|
// src/commands/ravendb/promptConnection.ts
|
|
15024
|
-
import
|
|
15119
|
+
import chalk151 from "chalk";
|
|
15025
15120
|
|
|
15026
15121
|
// src/commands/ravendb/selectOpSecret.ts
|
|
15027
|
-
import
|
|
15122
|
+
import chalk150 from "chalk";
|
|
15028
15123
|
import Enquirer2 from "enquirer";
|
|
15029
15124
|
|
|
15030
15125
|
// src/commands/ravendb/searchItems.ts
|
|
15031
15126
|
import { execSync as execSync43 } from "child_process";
|
|
15032
|
-
import
|
|
15127
|
+
import chalk149 from "chalk";
|
|
15033
15128
|
function opExec(args) {
|
|
15034
15129
|
return execSync43(`op ${args}`, {
|
|
15035
15130
|
encoding: "utf8",
|
|
@@ -15042,7 +15137,7 @@ function searchItems(search2) {
|
|
|
15042
15137
|
items2 = JSON.parse(opExec("item list --format=json"));
|
|
15043
15138
|
} catch {
|
|
15044
15139
|
console.error(
|
|
15045
|
-
|
|
15140
|
+
chalk149.red(
|
|
15046
15141
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
15047
15142
|
)
|
|
15048
15143
|
);
|
|
@@ -15056,7 +15151,7 @@ function getItemFields(itemId) {
|
|
|
15056
15151
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
15057
15152
|
return item.fields.filter((f) => f.reference && f.label);
|
|
15058
15153
|
} catch {
|
|
15059
|
-
console.error(
|
|
15154
|
+
console.error(chalk149.red("Failed to get item details from 1Password."));
|
|
15060
15155
|
process.exit(1);
|
|
15061
15156
|
}
|
|
15062
15157
|
}
|
|
@@ -15075,7 +15170,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
15075
15170
|
}).run();
|
|
15076
15171
|
const items2 = searchItems(search2);
|
|
15077
15172
|
if (items2.length === 0) {
|
|
15078
|
-
console.error(
|
|
15173
|
+
console.error(chalk150.red(`No items found matching "${search2}".`));
|
|
15079
15174
|
process.exit(1);
|
|
15080
15175
|
}
|
|
15081
15176
|
const itemId = await selectOne(
|
|
@@ -15084,7 +15179,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
15084
15179
|
);
|
|
15085
15180
|
const fields = getItemFields(itemId);
|
|
15086
15181
|
if (fields.length === 0) {
|
|
15087
|
-
console.error(
|
|
15182
|
+
console.error(chalk150.red("No fields with references found on this item."));
|
|
15088
15183
|
process.exit(1);
|
|
15089
15184
|
}
|
|
15090
15185
|
const ref = await selectOne(
|
|
@@ -15098,7 +15193,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
15098
15193
|
async function promptConnection(existingNames) {
|
|
15099
15194
|
const name = await promptInput("name", "Connection name:");
|
|
15100
15195
|
if (existingNames.includes(name)) {
|
|
15101
|
-
console.error(
|
|
15196
|
+
console.error(chalk151.red(`Connection "${name}" already exists.`));
|
|
15102
15197
|
process.exit(1);
|
|
15103
15198
|
}
|
|
15104
15199
|
const url = await promptInput(
|
|
@@ -15107,22 +15202,22 @@ async function promptConnection(existingNames) {
|
|
|
15107
15202
|
);
|
|
15108
15203
|
const database = await promptInput("database", "Database name:");
|
|
15109
15204
|
if (!name || !url || !database) {
|
|
15110
|
-
console.error(
|
|
15205
|
+
console.error(chalk151.red("All fields are required."));
|
|
15111
15206
|
process.exit(1);
|
|
15112
15207
|
}
|
|
15113
15208
|
const apiKeyRef = await selectOpSecret();
|
|
15114
|
-
console.log(
|
|
15209
|
+
console.log(chalk151.dim(`Using: ${apiKeyRef}`));
|
|
15115
15210
|
return { name, url, database, apiKeyRef };
|
|
15116
15211
|
}
|
|
15117
15212
|
|
|
15118
15213
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
15119
|
-
import
|
|
15214
|
+
import chalk152 from "chalk";
|
|
15120
15215
|
function ravendbSetConnection(name) {
|
|
15121
15216
|
const raw = loadGlobalConfigRaw();
|
|
15122
15217
|
const ravendb = raw.ravendb ?? {};
|
|
15123
15218
|
const connections = ravendb.connections ?? [];
|
|
15124
15219
|
if (!connections.some((c) => c.name === name)) {
|
|
15125
|
-
console.error(
|
|
15220
|
+
console.error(chalk152.red(`Connection "${name}" not found.`));
|
|
15126
15221
|
console.error(
|
|
15127
15222
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
15128
15223
|
);
|
|
@@ -15138,16 +15233,16 @@ function ravendbSetConnection(name) {
|
|
|
15138
15233
|
var ravendbAuth = createConnectionAuth({
|
|
15139
15234
|
load: loadConnections,
|
|
15140
15235
|
save: saveConnections,
|
|
15141
|
-
format: (c) => `${
|
|
15236
|
+
format: (c) => `${chalk153.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
15142
15237
|
promptNew: promptConnection,
|
|
15143
15238
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
15144
15239
|
});
|
|
15145
15240
|
|
|
15146
15241
|
// src/commands/ravendb/ravendbCollections.ts
|
|
15147
|
-
import
|
|
15242
|
+
import chalk157 from "chalk";
|
|
15148
15243
|
|
|
15149
15244
|
// src/commands/ravendb/ravenFetch.ts
|
|
15150
|
-
import
|
|
15245
|
+
import chalk155 from "chalk";
|
|
15151
15246
|
|
|
15152
15247
|
// src/commands/ravendb/getAccessToken.ts
|
|
15153
15248
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -15184,10 +15279,10 @@ ${errorText}`
|
|
|
15184
15279
|
|
|
15185
15280
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
15186
15281
|
import { execSync as execSync44 } from "child_process";
|
|
15187
|
-
import
|
|
15282
|
+
import chalk154 from "chalk";
|
|
15188
15283
|
function resolveOpSecret(reference) {
|
|
15189
15284
|
if (!reference.startsWith("op://")) {
|
|
15190
|
-
console.error(
|
|
15285
|
+
console.error(chalk154.red(`Invalid secret reference: must start with op://`));
|
|
15191
15286
|
process.exit(1);
|
|
15192
15287
|
}
|
|
15193
15288
|
try {
|
|
@@ -15197,7 +15292,7 @@ function resolveOpSecret(reference) {
|
|
|
15197
15292
|
}).trim();
|
|
15198
15293
|
} catch {
|
|
15199
15294
|
console.error(
|
|
15200
|
-
|
|
15295
|
+
chalk154.red(
|
|
15201
15296
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
15202
15297
|
)
|
|
15203
15298
|
);
|
|
@@ -15224,7 +15319,7 @@ async function ravenFetch(connection, path57) {
|
|
|
15224
15319
|
if (!response.ok) {
|
|
15225
15320
|
const body = await response.text();
|
|
15226
15321
|
console.error(
|
|
15227
|
-
|
|
15322
|
+
chalk155.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
15228
15323
|
);
|
|
15229
15324
|
console.error(body.substring(0, 500));
|
|
15230
15325
|
process.exit(1);
|
|
@@ -15233,7 +15328,7 @@ async function ravenFetch(connection, path57) {
|
|
|
15233
15328
|
}
|
|
15234
15329
|
|
|
15235
15330
|
// src/commands/ravendb/resolveConnection.ts
|
|
15236
|
-
import
|
|
15331
|
+
import chalk156 from "chalk";
|
|
15237
15332
|
function loadRavendb() {
|
|
15238
15333
|
const raw = loadGlobalConfigRaw();
|
|
15239
15334
|
const ravendb = raw.ravendb;
|
|
@@ -15247,7 +15342,7 @@ function resolveConnection(name) {
|
|
|
15247
15342
|
const connectionName = name ?? defaultConnection;
|
|
15248
15343
|
if (!connectionName) {
|
|
15249
15344
|
console.error(
|
|
15250
|
-
|
|
15345
|
+
chalk156.red(
|
|
15251
15346
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
15252
15347
|
)
|
|
15253
15348
|
);
|
|
@@ -15255,7 +15350,7 @@ function resolveConnection(name) {
|
|
|
15255
15350
|
}
|
|
15256
15351
|
const connection = connections.find((c) => c.name === connectionName);
|
|
15257
15352
|
if (!connection) {
|
|
15258
|
-
console.error(
|
|
15353
|
+
console.error(chalk156.red(`Connection "${connectionName}" not found.`));
|
|
15259
15354
|
console.error(
|
|
15260
15355
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
15261
15356
|
);
|
|
@@ -15286,15 +15381,15 @@ async function ravendbCollections(connectionName) {
|
|
|
15286
15381
|
return;
|
|
15287
15382
|
}
|
|
15288
15383
|
for (const c of collections) {
|
|
15289
|
-
console.log(`${
|
|
15384
|
+
console.log(`${chalk157.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
15290
15385
|
}
|
|
15291
15386
|
}
|
|
15292
15387
|
|
|
15293
15388
|
// src/commands/ravendb/ravendbQuery.ts
|
|
15294
|
-
import
|
|
15389
|
+
import chalk159 from "chalk";
|
|
15295
15390
|
|
|
15296
15391
|
// src/commands/ravendb/fetchAllPages.ts
|
|
15297
|
-
import
|
|
15392
|
+
import chalk158 from "chalk";
|
|
15298
15393
|
|
|
15299
15394
|
// src/commands/ravendb/buildQueryPath.ts
|
|
15300
15395
|
function buildQueryPath(opts) {
|
|
@@ -15332,7 +15427,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
15332
15427
|
allResults.push(...results);
|
|
15333
15428
|
start3 += results.length;
|
|
15334
15429
|
process.stderr.write(
|
|
15335
|
-
`\r${
|
|
15430
|
+
`\r${chalk158.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
15336
15431
|
);
|
|
15337
15432
|
if (start3 >= totalResults) break;
|
|
15338
15433
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -15347,7 +15442,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
15347
15442
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
15348
15443
|
const resolved = resolveArgs(connectionName, collection);
|
|
15349
15444
|
if (!resolved.collection && !options2.query) {
|
|
15350
|
-
console.error(
|
|
15445
|
+
console.error(chalk159.red("Provide a collection name or --query filter."));
|
|
15351
15446
|
process.exit(1);
|
|
15352
15447
|
}
|
|
15353
15448
|
const { collection: col } = resolved;
|
|
@@ -15385,7 +15480,7 @@ import { spawn as spawn5 } from "child_process";
|
|
|
15385
15480
|
import * as path28 from "path";
|
|
15386
15481
|
|
|
15387
15482
|
// src/commands/refactor/logViolations.ts
|
|
15388
|
-
import
|
|
15483
|
+
import chalk160 from "chalk";
|
|
15389
15484
|
var DEFAULT_MAX_LINES = 100;
|
|
15390
15485
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
15391
15486
|
if (violations.length === 0) {
|
|
@@ -15394,43 +15489,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
15394
15489
|
}
|
|
15395
15490
|
return;
|
|
15396
15491
|
}
|
|
15397
|
-
console.error(
|
|
15492
|
+
console.error(chalk160.red(`
|
|
15398
15493
|
Refactor check failed:
|
|
15399
15494
|
`));
|
|
15400
|
-
console.error(
|
|
15495
|
+
console.error(chalk160.red(` The following files exceed ${maxLines} lines:
|
|
15401
15496
|
`));
|
|
15402
15497
|
for (const violation of violations) {
|
|
15403
|
-
console.error(
|
|
15498
|
+
console.error(chalk160.red(` ${violation.file} (${violation.lines} lines)`));
|
|
15404
15499
|
}
|
|
15405
15500
|
console.error(
|
|
15406
|
-
|
|
15501
|
+
chalk160.yellow(
|
|
15407
15502
|
`
|
|
15408
15503
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
15409
15504
|
way to refactor it, ignore it with:
|
|
15410
15505
|
`
|
|
15411
15506
|
)
|
|
15412
15507
|
);
|
|
15413
|
-
console.error(
|
|
15508
|
+
console.error(chalk160.gray(` assist refactor ignore <file>
|
|
15414
15509
|
`));
|
|
15415
15510
|
if (process.env.CLAUDECODE) {
|
|
15416
|
-
console.error(
|
|
15511
|
+
console.error(chalk160.cyan(`
|
|
15417
15512
|
## Extracting Code to New Files
|
|
15418
15513
|
`));
|
|
15419
15514
|
console.error(
|
|
15420
|
-
|
|
15515
|
+
chalk160.cyan(
|
|
15421
15516
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
15422
15517
|
`
|
|
15423
15518
|
)
|
|
15424
15519
|
);
|
|
15425
15520
|
console.error(
|
|
15426
|
-
|
|
15521
|
+
chalk160.cyan(
|
|
15427
15522
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
15428
15523
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
15429
15524
|
`
|
|
15430
15525
|
)
|
|
15431
15526
|
);
|
|
15432
15527
|
console.error(
|
|
15433
|
-
|
|
15528
|
+
chalk160.cyan(
|
|
15434
15529
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
15435
15530
|
domains, move it to a common/shared folder.
|
|
15436
15531
|
`
|
|
@@ -15586,7 +15681,7 @@ async function check(pattern2, options2) {
|
|
|
15586
15681
|
|
|
15587
15682
|
// src/commands/refactor/extract/index.ts
|
|
15588
15683
|
import path35 from "path";
|
|
15589
|
-
import
|
|
15684
|
+
import chalk163 from "chalk";
|
|
15590
15685
|
|
|
15591
15686
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
15592
15687
|
import { SyntaxKind as SyntaxKind4 } from "ts-morph";
|
|
@@ -15597,16 +15692,16 @@ import {
|
|
|
15597
15692
|
} from "ts-morph";
|
|
15598
15693
|
var suppressionPattern = /^\s*(\/\/|\/\*)\s*oxlint-disable\b/;
|
|
15599
15694
|
function countLeadingSuppressions(sourceFile) {
|
|
15600
|
-
let
|
|
15695
|
+
let count8 = 0;
|
|
15601
15696
|
for (const stmt of sourceFile.getStatementsWithComments()) {
|
|
15602
15697
|
const kind = stmt.getKind();
|
|
15603
15698
|
if ((kind === SyntaxKind2.SingleLineCommentTrivia || kind === SyntaxKind2.MultiLineCommentTrivia) && suppressionPattern.test(stmt.getText())) {
|
|
15604
|
-
|
|
15699
|
+
count8++;
|
|
15605
15700
|
} else {
|
|
15606
15701
|
break;
|
|
15607
15702
|
}
|
|
15608
15703
|
}
|
|
15609
|
-
return
|
|
15704
|
+
return count8;
|
|
15610
15705
|
}
|
|
15611
15706
|
function addImportPreservingSuppressions(sourceFile, structure) {
|
|
15612
15707
|
if (sourceFile.getImportDeclarations().length > 0) {
|
|
@@ -16161,23 +16256,23 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
16161
16256
|
|
|
16162
16257
|
// src/commands/refactor/extract/displayPlan.ts
|
|
16163
16258
|
import path32 from "path";
|
|
16164
|
-
import
|
|
16259
|
+
import chalk161 from "chalk";
|
|
16165
16260
|
function section(title) {
|
|
16166
16261
|
return `
|
|
16167
|
-
${
|
|
16262
|
+
${chalk161.cyan(title)}`;
|
|
16168
16263
|
}
|
|
16169
16264
|
function displayImporters(plan2, cwd) {
|
|
16170
16265
|
if (plan2.importersToUpdate.length === 0) return;
|
|
16171
16266
|
console.log(section("Update importers:"));
|
|
16172
16267
|
for (const imp of plan2.importersToUpdate) {
|
|
16173
16268
|
const rel = path32.relative(cwd, imp.file.getFilePath());
|
|
16174
|
-
console.log(` ${
|
|
16269
|
+
console.log(` ${chalk161.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
16175
16270
|
}
|
|
16176
16271
|
}
|
|
16177
16272
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
16178
|
-
console.log(
|
|
16273
|
+
console.log(chalk161.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
16179
16274
|
`));
|
|
16180
|
-
console.log(` ${
|
|
16275
|
+
console.log(` ${chalk161.cyan("Functions to move:")}`);
|
|
16181
16276
|
for (const name of plan2.extractedNames) {
|
|
16182
16277
|
console.log(` ${name}`);
|
|
16183
16278
|
}
|
|
@@ -16211,7 +16306,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
16211
16306
|
|
|
16212
16307
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
16213
16308
|
import path34 from "path";
|
|
16214
|
-
import
|
|
16309
|
+
import chalk162 from "chalk";
|
|
16215
16310
|
import { Project as Project4 } from "ts-morph";
|
|
16216
16311
|
|
|
16217
16312
|
// src/commands/refactor/extract/findTsConfig.ts
|
|
@@ -16271,7 +16366,7 @@ function loadProjectFile(file) {
|
|
|
16271
16366
|
});
|
|
16272
16367
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
16273
16368
|
if (!sourceFile) {
|
|
16274
|
-
console.log(
|
|
16369
|
+
console.log(chalk162.red(`File not found in project: ${file}`));
|
|
16275
16370
|
process.exit(1);
|
|
16276
16371
|
}
|
|
16277
16372
|
return { project, sourceFile };
|
|
@@ -16294,19 +16389,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
16294
16389
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
16295
16390
|
if (options2.apply) {
|
|
16296
16391
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
16297
|
-
console.log(
|
|
16392
|
+
console.log(chalk163.green("\nExtraction complete"));
|
|
16298
16393
|
} else {
|
|
16299
|
-
console.log(
|
|
16394
|
+
console.log(chalk163.dim("\nDry run. Use --apply to execute."));
|
|
16300
16395
|
}
|
|
16301
16396
|
}
|
|
16302
16397
|
|
|
16303
16398
|
// src/commands/refactor/ignore.ts
|
|
16304
16399
|
import fs24 from "fs";
|
|
16305
|
-
import
|
|
16400
|
+
import chalk164 from "chalk";
|
|
16306
16401
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
16307
16402
|
function ignore(file) {
|
|
16308
16403
|
if (!fs24.existsSync(file)) {
|
|
16309
|
-
console.error(
|
|
16404
|
+
console.error(chalk164.red(`Error: File does not exist: ${file}`));
|
|
16310
16405
|
process.exit(1);
|
|
16311
16406
|
}
|
|
16312
16407
|
const content = fs24.readFileSync(file, "utf8");
|
|
@@ -16322,7 +16417,7 @@ function ignore(file) {
|
|
|
16322
16417
|
fs24.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
16323
16418
|
}
|
|
16324
16419
|
console.log(
|
|
16325
|
-
|
|
16420
|
+
chalk164.green(
|
|
16326
16421
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
16327
16422
|
)
|
|
16328
16423
|
);
|
|
@@ -16331,12 +16426,12 @@ function ignore(file) {
|
|
|
16331
16426
|
// src/commands/refactor/rename/index.ts
|
|
16332
16427
|
import fs27 from "fs";
|
|
16333
16428
|
import path40 from "path";
|
|
16334
|
-
import
|
|
16429
|
+
import chalk167 from "chalk";
|
|
16335
16430
|
|
|
16336
16431
|
// src/commands/refactor/rename/applyRename.ts
|
|
16337
16432
|
import fs26 from "fs";
|
|
16338
16433
|
import path37 from "path";
|
|
16339
|
-
import
|
|
16434
|
+
import chalk165 from "chalk";
|
|
16340
16435
|
|
|
16341
16436
|
// src/commands/refactor/restructure/computeRewrites/index.ts
|
|
16342
16437
|
import path36 from "path";
|
|
@@ -16441,13 +16536,13 @@ function applyRename(rewrites, sourcePath, destPath, cwd) {
|
|
|
16441
16536
|
const updatedContents = applyRewrites(rewrites);
|
|
16442
16537
|
for (const [file, content] of updatedContents) {
|
|
16443
16538
|
fs26.writeFileSync(file, content, "utf8");
|
|
16444
|
-
console.log(
|
|
16539
|
+
console.log(chalk165.cyan(` Updated imports in ${path37.relative(cwd, file)}`));
|
|
16445
16540
|
}
|
|
16446
16541
|
const destDir = path37.dirname(destPath);
|
|
16447
16542
|
if (!fs26.existsSync(destDir)) fs26.mkdirSync(destDir, { recursive: true });
|
|
16448
16543
|
fs26.renameSync(sourcePath, destPath);
|
|
16449
16544
|
console.log(
|
|
16450
|
-
|
|
16545
|
+
chalk165.white(
|
|
16451
16546
|
` Moved ${path37.relative(cwd, sourcePath)} \u2192 ${path37.relative(cwd, destPath)}`
|
|
16452
16547
|
)
|
|
16453
16548
|
);
|
|
@@ -16534,16 +16629,16 @@ function computeRenameRewrites(sourcePath, destPath) {
|
|
|
16534
16629
|
|
|
16535
16630
|
// src/commands/refactor/rename/printRenamePreview.ts
|
|
16536
16631
|
import path39 from "path";
|
|
16537
|
-
import
|
|
16632
|
+
import chalk166 from "chalk";
|
|
16538
16633
|
function printRenamePreview(rewrites, cwd) {
|
|
16539
16634
|
for (const rewrite of rewrites) {
|
|
16540
16635
|
console.log(
|
|
16541
|
-
|
|
16636
|
+
chalk166.dim(
|
|
16542
16637
|
` ${path39.relative(cwd, rewrite.file)}: ${rewrite.oldSpecifier} \u2192 ${rewrite.newSpecifier}`
|
|
16543
16638
|
)
|
|
16544
16639
|
);
|
|
16545
16640
|
}
|
|
16546
|
-
console.log(
|
|
16641
|
+
console.log(chalk166.dim("Dry run. Use --apply to execute."));
|
|
16547
16642
|
}
|
|
16548
16643
|
|
|
16549
16644
|
// src/commands/refactor/rename/index.ts
|
|
@@ -16554,20 +16649,20 @@ async function rename(source, destination, options2 = {}) {
|
|
|
16554
16649
|
const relSource = path40.relative(cwd, sourcePath);
|
|
16555
16650
|
const relDest = path40.relative(cwd, destPath);
|
|
16556
16651
|
if (!fs27.existsSync(sourcePath)) {
|
|
16557
|
-
console.log(
|
|
16652
|
+
console.log(chalk167.red(`File not found: ${source}`));
|
|
16558
16653
|
process.exit(1);
|
|
16559
16654
|
}
|
|
16560
16655
|
if (destPath !== sourcePath && fs27.existsSync(destPath)) {
|
|
16561
|
-
console.log(
|
|
16656
|
+
console.log(chalk167.red(`Destination already exists: ${destination}`));
|
|
16562
16657
|
process.exit(1);
|
|
16563
16658
|
}
|
|
16564
|
-
console.log(
|
|
16565
|
-
console.log(
|
|
16566
|
-
console.log(
|
|
16659
|
+
console.log(chalk167.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
16660
|
+
console.log(chalk167.dim("Loading project..."));
|
|
16661
|
+
console.log(chalk167.dim("Scanning imports across the project..."));
|
|
16567
16662
|
const rewrites = computeRenameRewrites(sourcePath, destPath);
|
|
16568
16663
|
const affectedFiles = new Set(rewrites.map((r) => r.file)).size;
|
|
16569
16664
|
console.log(
|
|
16570
|
-
|
|
16665
|
+
chalk167.dim(
|
|
16571
16666
|
`${rewrites.length} import path(s) to update across ${affectedFiles} file(s)`
|
|
16572
16667
|
)
|
|
16573
16668
|
);
|
|
@@ -16576,11 +16671,11 @@ async function rename(source, destination, options2 = {}) {
|
|
|
16576
16671
|
return;
|
|
16577
16672
|
}
|
|
16578
16673
|
applyRename(rewrites, sourcePath, destPath, cwd);
|
|
16579
|
-
console.log(
|
|
16674
|
+
console.log(chalk167.green("Done"));
|
|
16580
16675
|
}
|
|
16581
16676
|
|
|
16582
16677
|
// src/commands/refactor/renameSymbol/index.ts
|
|
16583
|
-
import
|
|
16678
|
+
import chalk168 from "chalk";
|
|
16584
16679
|
|
|
16585
16680
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
16586
16681
|
import { SyntaxKind as SyntaxKind14 } from "ts-morph";
|
|
@@ -16626,33 +16721,33 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
16626
16721
|
const { project, sourceFile } = loadProjectFile(file);
|
|
16627
16722
|
const symbol = findSymbol(sourceFile, oldName);
|
|
16628
16723
|
if (!symbol) {
|
|
16629
|
-
console.log(
|
|
16724
|
+
console.log(chalk168.red(`Symbol "${oldName}" not found in ${file}`));
|
|
16630
16725
|
process.exit(1);
|
|
16631
16726
|
}
|
|
16632
16727
|
const grouped = groupReferences(symbol, cwd);
|
|
16633
16728
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
16634
16729
|
console.log(
|
|
16635
|
-
|
|
16730
|
+
chalk168.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
16636
16731
|
`)
|
|
16637
16732
|
);
|
|
16638
16733
|
for (const [refFile, lines] of grouped) {
|
|
16639
16734
|
console.log(
|
|
16640
|
-
` ${
|
|
16735
|
+
` ${chalk168.dim(refFile)}: lines ${chalk168.cyan(lines.join(", "))}`
|
|
16641
16736
|
);
|
|
16642
16737
|
}
|
|
16643
16738
|
if (options2.apply) {
|
|
16644
16739
|
symbol.rename(newName);
|
|
16645
16740
|
await project.save();
|
|
16646
|
-
console.log(
|
|
16741
|
+
console.log(chalk168.green(`
|
|
16647
16742
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
16648
16743
|
} else {
|
|
16649
|
-
console.log(
|
|
16744
|
+
console.log(chalk168.dim("\nDry run. Use --apply to execute."));
|
|
16650
16745
|
}
|
|
16651
16746
|
}
|
|
16652
16747
|
|
|
16653
16748
|
// src/commands/refactor/restructure/index.ts
|
|
16654
16749
|
import path48 from "path";
|
|
16655
|
-
import
|
|
16750
|
+
import chalk171 from "chalk";
|
|
16656
16751
|
|
|
16657
16752
|
// src/commands/refactor/restructure/clusterDirectories.ts
|
|
16658
16753
|
import path42 from "path";
|
|
@@ -16731,50 +16826,50 @@ function clusterFiles(graph) {
|
|
|
16731
16826
|
|
|
16732
16827
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
16733
16828
|
import path44 from "path";
|
|
16734
|
-
import
|
|
16829
|
+
import chalk169 from "chalk";
|
|
16735
16830
|
function relPath(filePath) {
|
|
16736
16831
|
return path44.relative(process.cwd(), filePath);
|
|
16737
16832
|
}
|
|
16738
16833
|
function displayMoves(plan2) {
|
|
16739
16834
|
if (plan2.moves.length === 0) return;
|
|
16740
|
-
console.log(
|
|
16835
|
+
console.log(chalk169.bold("\nFile moves:"));
|
|
16741
16836
|
for (const move2 of plan2.moves) {
|
|
16742
16837
|
console.log(
|
|
16743
|
-
` ${
|
|
16838
|
+
` ${chalk169.red(relPath(move2.from))} \u2192 ${chalk169.green(relPath(move2.to))}`
|
|
16744
16839
|
);
|
|
16745
|
-
console.log(
|
|
16840
|
+
console.log(chalk169.dim(` ${move2.reason}`));
|
|
16746
16841
|
}
|
|
16747
16842
|
}
|
|
16748
16843
|
function displayRewrites(rewrites) {
|
|
16749
16844
|
if (rewrites.length === 0) return;
|
|
16750
16845
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
16751
|
-
console.log(
|
|
16846
|
+
console.log(chalk169.bold(`
|
|
16752
16847
|
Import rewrites (${affectedFiles.size} files):`));
|
|
16753
16848
|
for (const file of affectedFiles) {
|
|
16754
|
-
console.log(` ${
|
|
16849
|
+
console.log(` ${chalk169.cyan(relPath(file))}:`);
|
|
16755
16850
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
16756
16851
|
(r) => r.file === file
|
|
16757
16852
|
)) {
|
|
16758
16853
|
console.log(
|
|
16759
|
-
` ${
|
|
16854
|
+
` ${chalk169.red(`"${oldSpecifier}"`)} \u2192 ${chalk169.green(`"${newSpecifier}"`)}`
|
|
16760
16855
|
);
|
|
16761
16856
|
}
|
|
16762
16857
|
}
|
|
16763
16858
|
}
|
|
16764
16859
|
function displayPlan2(plan2) {
|
|
16765
16860
|
if (plan2.warnings.length > 0) {
|
|
16766
|
-
console.log(
|
|
16767
|
-
for (const w of plan2.warnings) console.log(
|
|
16861
|
+
console.log(chalk169.yellow("\nWarnings:"));
|
|
16862
|
+
for (const w of plan2.warnings) console.log(chalk169.yellow(` ${w}`));
|
|
16768
16863
|
}
|
|
16769
16864
|
if (plan2.newDirectories.length > 0) {
|
|
16770
|
-
console.log(
|
|
16865
|
+
console.log(chalk169.bold("\nNew directories:"));
|
|
16771
16866
|
for (const dir of plan2.newDirectories)
|
|
16772
|
-
console.log(
|
|
16867
|
+
console.log(chalk169.green(` ${dir}/`));
|
|
16773
16868
|
}
|
|
16774
16869
|
displayMoves(plan2);
|
|
16775
16870
|
displayRewrites(plan2.rewrites);
|
|
16776
16871
|
console.log(
|
|
16777
|
-
|
|
16872
|
+
chalk169.dim(
|
|
16778
16873
|
`
|
|
16779
16874
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
16780
16875
|
)
|
|
@@ -16784,18 +16879,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
16784
16879
|
// src/commands/refactor/restructure/executePlan.ts
|
|
16785
16880
|
import fs28 from "fs";
|
|
16786
16881
|
import path45 from "path";
|
|
16787
|
-
import
|
|
16882
|
+
import chalk170 from "chalk";
|
|
16788
16883
|
function executePlan(plan2) {
|
|
16789
16884
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
16790
16885
|
for (const [file, content] of updatedContents) {
|
|
16791
16886
|
fs28.writeFileSync(file, content, "utf8");
|
|
16792
16887
|
console.log(
|
|
16793
|
-
|
|
16888
|
+
chalk170.cyan(` Rewrote imports in ${path45.relative(process.cwd(), file)}`)
|
|
16794
16889
|
);
|
|
16795
16890
|
}
|
|
16796
16891
|
for (const dir of plan2.newDirectories) {
|
|
16797
16892
|
fs28.mkdirSync(dir, { recursive: true });
|
|
16798
|
-
console.log(
|
|
16893
|
+
console.log(chalk170.green(` Created ${path45.relative(process.cwd(), dir)}/`));
|
|
16799
16894
|
}
|
|
16800
16895
|
for (const move2 of plan2.moves) {
|
|
16801
16896
|
const targetDir = path45.dirname(move2.to);
|
|
@@ -16804,7 +16899,7 @@ function executePlan(plan2) {
|
|
|
16804
16899
|
}
|
|
16805
16900
|
fs28.renameSync(move2.from, move2.to);
|
|
16806
16901
|
console.log(
|
|
16807
|
-
|
|
16902
|
+
chalk170.white(
|
|
16808
16903
|
` Moved ${path45.relative(process.cwd(), move2.from)} \u2192 ${path45.relative(process.cwd(), move2.to)}`
|
|
16809
16904
|
)
|
|
16810
16905
|
);
|
|
@@ -16819,7 +16914,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
16819
16914
|
if (entries.length === 0) {
|
|
16820
16915
|
fs28.rmdirSync(dir);
|
|
16821
16916
|
console.log(
|
|
16822
|
-
|
|
16917
|
+
chalk170.dim(
|
|
16823
16918
|
` Removed empty directory ${path45.relative(process.cwd(), dir)}`
|
|
16824
16919
|
)
|
|
16825
16920
|
);
|
|
@@ -16952,22 +17047,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
16952
17047
|
const targetPattern = pattern2 ?? "src";
|
|
16953
17048
|
const files = findSourceFiles2(targetPattern);
|
|
16954
17049
|
if (files.length === 0) {
|
|
16955
|
-
console.log(
|
|
17050
|
+
console.log(chalk171.yellow("No files found matching pattern"));
|
|
16956
17051
|
return;
|
|
16957
17052
|
}
|
|
16958
17053
|
const tsConfigPath = path48.resolve("tsconfig.json");
|
|
16959
17054
|
const plan2 = buildPlan3(files, tsConfigPath);
|
|
16960
17055
|
if (plan2.moves.length === 0) {
|
|
16961
|
-
console.log(
|
|
17056
|
+
console.log(chalk171.green("No restructuring needed"));
|
|
16962
17057
|
return;
|
|
16963
17058
|
}
|
|
16964
17059
|
displayPlan2(plan2);
|
|
16965
17060
|
if (options2.apply) {
|
|
16966
|
-
console.log(
|
|
17061
|
+
console.log(chalk171.bold("\nApplying changes..."));
|
|
16967
17062
|
executePlan(plan2);
|
|
16968
|
-
console.log(
|
|
17063
|
+
console.log(chalk171.green("\nRestructuring complete"));
|
|
16969
17064
|
} else {
|
|
16970
|
-
console.log(
|
|
17065
|
+
console.log(chalk171.dim("\nDry run. Use --apply to execute."));
|
|
16971
17066
|
}
|
|
16972
17067
|
}
|
|
16973
17068
|
|
|
@@ -17541,18 +17636,18 @@ function partitionFindingsByDiff(findings, index3) {
|
|
|
17541
17636
|
}
|
|
17542
17637
|
|
|
17543
17638
|
// src/commands/review/warnOutOfDiff.ts
|
|
17544
|
-
import
|
|
17639
|
+
import chalk172 from "chalk";
|
|
17545
17640
|
function warnOutOfDiff(outOfDiff) {
|
|
17546
17641
|
if (outOfDiff.length === 0) return;
|
|
17547
17642
|
console.warn(
|
|
17548
|
-
|
|
17643
|
+
chalk172.yellow(
|
|
17549
17644
|
`Skipped ${outOfDiff.length} finding(s) whose lines fall outside the PR diff (GitHub would silently drop these):`
|
|
17550
17645
|
)
|
|
17551
17646
|
);
|
|
17552
17647
|
for (const finding of outOfDiff) {
|
|
17553
17648
|
const range = finding.startLine !== void 0 ? `${finding.startLine}-${finding.line}` : `${finding.line}`;
|
|
17554
17649
|
console.warn(
|
|
17555
|
-
` ${
|
|
17650
|
+
` ${chalk172.yellow("\xB7")} ${finding.title} ${chalk172.dim(
|
|
17556
17651
|
`(${finding.file}:${range})`
|
|
17557
17652
|
)}`
|
|
17558
17653
|
);
|
|
@@ -17571,26 +17666,26 @@ function selectInDiffFindings(lineBound, prDiff) {
|
|
|
17571
17666
|
}
|
|
17572
17667
|
|
|
17573
17668
|
// src/commands/review/warnUnlocated.ts
|
|
17574
|
-
import
|
|
17669
|
+
import chalk173 from "chalk";
|
|
17575
17670
|
function warnUnlocated(unlocated) {
|
|
17576
17671
|
if (unlocated.length === 0) return;
|
|
17577
17672
|
console.warn(
|
|
17578
|
-
|
|
17673
|
+
chalk173.yellow(
|
|
17579
17674
|
`Skipped ${unlocated.length} finding(s) without a parseable file:line:`
|
|
17580
17675
|
)
|
|
17581
17676
|
);
|
|
17582
17677
|
for (const finding of unlocated) {
|
|
17583
|
-
const where = finding.location ||
|
|
17678
|
+
const where = finding.location || chalk173.dim("missing");
|
|
17584
17679
|
console.warn(
|
|
17585
|
-
` ${
|
|
17680
|
+
` ${chalk173.yellow("\xB7")} ${finding.title} ${chalk173.dim(`(${where})`)}`
|
|
17586
17681
|
);
|
|
17587
17682
|
}
|
|
17588
17683
|
}
|
|
17589
17684
|
|
|
17590
17685
|
// src/commands/review/postReviewToPr.ts
|
|
17591
|
-
async function confirmPost(prNumber,
|
|
17686
|
+
async function confirmPost(prNumber, count8, options2) {
|
|
17592
17687
|
if (!options2.prompt) return true;
|
|
17593
|
-
return promptConfirm(`Post ${
|
|
17688
|
+
return promptConfirm(`Post ${count8} comment(s) to PR #${prNumber}?`, false);
|
|
17594
17689
|
}
|
|
17595
17690
|
async function postReviewToPr(synthesisPath, options2) {
|
|
17596
17691
|
const prInfo = fetchPrDiffInfo();
|
|
@@ -18637,9 +18732,9 @@ async function runReviewPipeline(paths, options2) {
|
|
|
18637
18732
|
}
|
|
18638
18733
|
|
|
18639
18734
|
// src/commands/review/reviewPr.ts
|
|
18640
|
-
function logPriorComments(
|
|
18641
|
-
if (
|
|
18642
|
-
console.log(`Including ${
|
|
18735
|
+
function logPriorComments(count8) {
|
|
18736
|
+
if (count8 === 0) return;
|
|
18737
|
+
console.log(`Including ${count8} prior review comment(s) in request.md.`);
|
|
18643
18738
|
}
|
|
18644
18739
|
function gatherChangedContext() {
|
|
18645
18740
|
const context = gatherContext();
|
|
@@ -18754,7 +18849,7 @@ function registerReview(program2) {
|
|
|
18754
18849
|
}
|
|
18755
18850
|
|
|
18756
18851
|
// src/commands/seq/seqAuth.ts
|
|
18757
|
-
import
|
|
18852
|
+
import chalk175 from "chalk";
|
|
18758
18853
|
|
|
18759
18854
|
// src/commands/seq/loadConnections.ts
|
|
18760
18855
|
function loadConnections2() {
|
|
@@ -18783,10 +18878,10 @@ function setDefaultConnection(name) {
|
|
|
18783
18878
|
}
|
|
18784
18879
|
|
|
18785
18880
|
// src/shared/assertUniqueName.ts
|
|
18786
|
-
import
|
|
18881
|
+
import chalk174 from "chalk";
|
|
18787
18882
|
function assertUniqueName(existingNames, name) {
|
|
18788
18883
|
if (existingNames.includes(name)) {
|
|
18789
|
-
console.error(
|
|
18884
|
+
console.error(chalk174.red(`Connection "${name}" already exists.`));
|
|
18790
18885
|
process.exit(1);
|
|
18791
18886
|
}
|
|
18792
18887
|
}
|
|
@@ -18804,16 +18899,16 @@ async function promptConnection2(existingNames) {
|
|
|
18804
18899
|
var seqAuth = createConnectionAuth({
|
|
18805
18900
|
load: loadConnections2,
|
|
18806
18901
|
save: saveConnections2,
|
|
18807
|
-
format: (c) => `${
|
|
18902
|
+
format: (c) => `${chalk175.bold(c.name)} ${c.url}`,
|
|
18808
18903
|
promptNew: promptConnection2,
|
|
18809
18904
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
18810
18905
|
});
|
|
18811
18906
|
|
|
18812
18907
|
// src/commands/seq/seqQuery.ts
|
|
18813
|
-
import
|
|
18908
|
+
import chalk179 from "chalk";
|
|
18814
18909
|
|
|
18815
18910
|
// src/commands/seq/fetchSeq.ts
|
|
18816
|
-
import
|
|
18911
|
+
import chalk176 from "chalk";
|
|
18817
18912
|
async function fetchSeq(conn, path57, params) {
|
|
18818
18913
|
const url = `${conn.url}${path57}?${params}`;
|
|
18819
18914
|
const response = await fetch(url, {
|
|
@@ -18824,7 +18919,7 @@ async function fetchSeq(conn, path57, params) {
|
|
|
18824
18919
|
});
|
|
18825
18920
|
if (!response.ok) {
|
|
18826
18921
|
const body = await response.text();
|
|
18827
|
-
console.error(
|
|
18922
|
+
console.error(chalk176.red(`Seq returned ${response.status}: ${body}`));
|
|
18828
18923
|
process.exit(1);
|
|
18829
18924
|
}
|
|
18830
18925
|
return response;
|
|
@@ -18836,16 +18931,16 @@ function filterToSql(filter) {
|
|
|
18836
18931
|
}
|
|
18837
18932
|
|
|
18838
18933
|
// src/commands/seq/fetchSeqData.ts
|
|
18839
|
-
function buildDataParams(filter,
|
|
18934
|
+
function buildDataParams(filter, count8, from, to) {
|
|
18840
18935
|
const sqlFilter = filterToSql(filter);
|
|
18841
|
-
const sql9 = `select @Timestamp, @Level, @Exception, @Message from stream where ${sqlFilter} order by @Timestamp desc limit ${
|
|
18936
|
+
const sql9 = `select @Timestamp, @Level, @Exception, @Message from stream where ${sqlFilter} order by @Timestamp desc limit ${count8}`;
|
|
18842
18937
|
const params = new URLSearchParams({ q: sql9 });
|
|
18843
18938
|
if (from) params.set("rangeStartUtc", from);
|
|
18844
18939
|
if (to) params.set("rangeEndUtc", to);
|
|
18845
18940
|
return params;
|
|
18846
18941
|
}
|
|
18847
|
-
async function fetchSeqData(conn, filter,
|
|
18848
|
-
const params = buildDataParams(filter,
|
|
18942
|
+
async function fetchSeqData(conn, filter, count8, from, to) {
|
|
18943
|
+
const params = buildDataParams(filter, count8, from, to);
|
|
18849
18944
|
const response = await fetchSeq(conn, "/api/data", params);
|
|
18850
18945
|
const data = await response.json();
|
|
18851
18946
|
return mapDataToEvents(data);
|
|
@@ -18883,23 +18978,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
18883
18978
|
}
|
|
18884
18979
|
|
|
18885
18980
|
// src/commands/seq/formatEvent.ts
|
|
18886
|
-
import
|
|
18981
|
+
import chalk177 from "chalk";
|
|
18887
18982
|
function levelColor(level) {
|
|
18888
18983
|
switch (level) {
|
|
18889
18984
|
case "Fatal":
|
|
18890
|
-
return
|
|
18985
|
+
return chalk177.bgRed.white;
|
|
18891
18986
|
case "Error":
|
|
18892
|
-
return
|
|
18987
|
+
return chalk177.red;
|
|
18893
18988
|
case "Warning":
|
|
18894
|
-
return
|
|
18989
|
+
return chalk177.yellow;
|
|
18895
18990
|
case "Information":
|
|
18896
|
-
return
|
|
18991
|
+
return chalk177.cyan;
|
|
18897
18992
|
case "Debug":
|
|
18898
|
-
return
|
|
18993
|
+
return chalk177.gray;
|
|
18899
18994
|
case "Verbose":
|
|
18900
|
-
return
|
|
18995
|
+
return chalk177.dim;
|
|
18901
18996
|
default:
|
|
18902
|
-
return
|
|
18997
|
+
return chalk177.white;
|
|
18903
18998
|
}
|
|
18904
18999
|
}
|
|
18905
19000
|
function levelAbbrev(level) {
|
|
@@ -18940,12 +19035,12 @@ function formatTimestamp(iso) {
|
|
|
18940
19035
|
function formatEvent(event) {
|
|
18941
19036
|
const color = levelColor(event.Level);
|
|
18942
19037
|
const abbrev = levelAbbrev(event.Level);
|
|
18943
|
-
const ts8 =
|
|
19038
|
+
const ts8 = chalk177.dim(formatTimestamp(event.Timestamp));
|
|
18944
19039
|
const msg = renderMessage(event);
|
|
18945
19040
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
18946
19041
|
if (event.Exception) {
|
|
18947
19042
|
for (const line of event.Exception.split("\n")) {
|
|
18948
|
-
lines.push(
|
|
19043
|
+
lines.push(chalk177.red(` ${line}`));
|
|
18949
19044
|
}
|
|
18950
19045
|
}
|
|
18951
19046
|
return lines.join("\n");
|
|
@@ -18978,11 +19073,11 @@ function rejectTimestampFilter(filter) {
|
|
|
18978
19073
|
}
|
|
18979
19074
|
|
|
18980
19075
|
// src/shared/resolveNamedConnection.ts
|
|
18981
|
-
import
|
|
19076
|
+
import chalk178 from "chalk";
|
|
18982
19077
|
function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
|
|
18983
19078
|
if (connections.length === 0) {
|
|
18984
19079
|
console.error(
|
|
18985
|
-
|
|
19080
|
+
chalk178.red(
|
|
18986
19081
|
`No ${kind} connections configured. Run '${authCommand}' first.`
|
|
18987
19082
|
)
|
|
18988
19083
|
);
|
|
@@ -18991,7 +19086,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
|
|
|
18991
19086
|
const target = requested ?? defaultName ?? connections[0].name;
|
|
18992
19087
|
const connection = connections.find((c) => c.name === target);
|
|
18993
19088
|
if (!connection) {
|
|
18994
|
-
console.error(
|
|
19089
|
+
console.error(chalk178.red(`${kind} connection "${target}" not found.`));
|
|
18995
19090
|
process.exit(1);
|
|
18996
19091
|
}
|
|
18997
19092
|
return connection;
|
|
@@ -19012,15 +19107,15 @@ function resolveConnection2(name) {
|
|
|
19012
19107
|
async function seqQuery(filter, options2) {
|
|
19013
19108
|
rejectTimestampFilter(filter);
|
|
19014
19109
|
const conn = resolveConnection2(options2.connection);
|
|
19015
|
-
const
|
|
19110
|
+
const count8 = Number.parseInt(options2.count ?? "1000", 10);
|
|
19016
19111
|
const from = options2.from ? parseRelativeTime(options2.from) : void 0;
|
|
19017
19112
|
const to = options2.to ? parseRelativeTime(options2.to) : void 0;
|
|
19018
|
-
const events = from || to ? await fetchSeqData(conn, filter,
|
|
19113
|
+
const events = from || to ? await fetchSeqData(conn, filter, count8, from, to) : await fetchSeqEvents(
|
|
19019
19114
|
conn,
|
|
19020
|
-
new URLSearchParams({ filter, count: String(
|
|
19115
|
+
new URLSearchParams({ filter, count: String(count8) })
|
|
19021
19116
|
);
|
|
19022
19117
|
if (events.length === 0) {
|
|
19023
|
-
console.log(
|
|
19118
|
+
console.log(chalk179.yellow("No events found."));
|
|
19024
19119
|
return;
|
|
19025
19120
|
}
|
|
19026
19121
|
if (options2.json) {
|
|
@@ -19031,22 +19126,22 @@ async function seqQuery(filter, options2) {
|
|
|
19031
19126
|
for (const event of chronological) {
|
|
19032
19127
|
console.log(formatEvent(event));
|
|
19033
19128
|
}
|
|
19034
|
-
console.log(
|
|
19129
|
+
console.log(chalk179.dim(`
|
|
19035
19130
|
${events.length} events`));
|
|
19036
|
-
if (events.length >=
|
|
19131
|
+
if (events.length >= count8) {
|
|
19037
19132
|
console.log(
|
|
19038
|
-
|
|
19039
|
-
`Results limited to ${
|
|
19133
|
+
chalk179.yellow(
|
|
19134
|
+
`Results limited to ${count8}. Use --count to retrieve more.`
|
|
19040
19135
|
)
|
|
19041
19136
|
);
|
|
19042
19137
|
}
|
|
19043
19138
|
}
|
|
19044
19139
|
|
|
19045
19140
|
// src/shared/setNamedDefaultConnection.ts
|
|
19046
|
-
import
|
|
19141
|
+
import chalk180 from "chalk";
|
|
19047
19142
|
function setNamedDefaultConnection(connections, name, setDefault, kind) {
|
|
19048
19143
|
if (!connections.find((c) => c.name === name)) {
|
|
19049
|
-
console.error(
|
|
19144
|
+
console.error(chalk180.red(`Connection "${name}" not found.`));
|
|
19050
19145
|
process.exit(1);
|
|
19051
19146
|
}
|
|
19052
19147
|
setDefault(name);
|
|
@@ -19094,7 +19189,7 @@ function registerSignal(program2) {
|
|
|
19094
19189
|
}
|
|
19095
19190
|
|
|
19096
19191
|
// src/commands/sql/sqlAuth.ts
|
|
19097
|
-
import
|
|
19192
|
+
import chalk182 from "chalk";
|
|
19098
19193
|
|
|
19099
19194
|
// src/commands/sql/loadConnections.ts
|
|
19100
19195
|
function loadConnections3() {
|
|
@@ -19123,7 +19218,7 @@ function setDefaultConnection2(name) {
|
|
|
19123
19218
|
}
|
|
19124
19219
|
|
|
19125
19220
|
// src/commands/sql/promptConnection.ts
|
|
19126
|
-
import
|
|
19221
|
+
import chalk181 from "chalk";
|
|
19127
19222
|
async function promptConnection3(existingNames) {
|
|
19128
19223
|
const name = await promptInput("name", "Connection name:", "default");
|
|
19129
19224
|
assertUniqueName(existingNames, name);
|
|
@@ -19131,7 +19226,7 @@ async function promptConnection3(existingNames) {
|
|
|
19131
19226
|
const portStr = await promptInput("port", "Port:", "1433");
|
|
19132
19227
|
const port = Number.parseInt(portStr, 10);
|
|
19133
19228
|
if (!Number.isFinite(port)) {
|
|
19134
|
-
console.error(
|
|
19229
|
+
console.error(chalk181.red(`Invalid port "${portStr}".`));
|
|
19135
19230
|
process.exit(1);
|
|
19136
19231
|
}
|
|
19137
19232
|
const user = await promptInput("user", "User:");
|
|
@@ -19144,13 +19239,13 @@ async function promptConnection3(existingNames) {
|
|
|
19144
19239
|
var sqlAuth = createConnectionAuth({
|
|
19145
19240
|
load: loadConnections3,
|
|
19146
19241
|
save: saveConnections3,
|
|
19147
|
-
format: (c) => `${
|
|
19242
|
+
format: (c) => `${chalk182.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
|
|
19148
19243
|
promptNew: promptConnection3,
|
|
19149
19244
|
onFirst: (c) => setDefaultConnection2(c.name)
|
|
19150
19245
|
});
|
|
19151
19246
|
|
|
19152
19247
|
// src/commands/sql/printTable.ts
|
|
19153
|
-
import
|
|
19248
|
+
import chalk183 from "chalk";
|
|
19154
19249
|
function formatCell(value) {
|
|
19155
19250
|
if (value === null || value === void 0) return "";
|
|
19156
19251
|
if (value instanceof Date) return value.toISOString();
|
|
@@ -19159,7 +19254,7 @@ function formatCell(value) {
|
|
|
19159
19254
|
}
|
|
19160
19255
|
function printTable(rows) {
|
|
19161
19256
|
if (rows.length === 0) {
|
|
19162
|
-
console.log(
|
|
19257
|
+
console.log(chalk183.yellow("(no rows)"));
|
|
19163
19258
|
return;
|
|
19164
19259
|
}
|
|
19165
19260
|
const columns = Object.keys(rows[0]);
|
|
@@ -19167,13 +19262,13 @@ function printTable(rows) {
|
|
|
19167
19262
|
(col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
|
|
19168
19263
|
);
|
|
19169
19264
|
const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
|
|
19170
|
-
console.log(
|
|
19171
|
-
console.log(
|
|
19265
|
+
console.log(chalk183.dim(header));
|
|
19266
|
+
console.log(chalk183.dim("-".repeat(header.length)));
|
|
19172
19267
|
for (const row of rows) {
|
|
19173
19268
|
const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
|
|
19174
19269
|
console.log(line);
|
|
19175
19270
|
}
|
|
19176
|
-
console.log(
|
|
19271
|
+
console.log(chalk183.dim(`
|
|
19177
19272
|
${rows.length} row${rows.length === 1 ? "" : "s"}`));
|
|
19178
19273
|
}
|
|
19179
19274
|
|
|
@@ -19233,7 +19328,7 @@ async function sqlColumns(table, connectionName) {
|
|
|
19233
19328
|
}
|
|
19234
19329
|
|
|
19235
19330
|
// src/commands/sql/sqlMutate.ts
|
|
19236
|
-
import
|
|
19331
|
+
import chalk184 from "chalk";
|
|
19237
19332
|
|
|
19238
19333
|
// src/commands/sql/isMutation.ts
|
|
19239
19334
|
var MUTATION_KEYWORDS = [
|
|
@@ -19267,7 +19362,7 @@ function isMutation(sql9) {
|
|
|
19267
19362
|
async function sqlMutate(query, connectionName) {
|
|
19268
19363
|
if (!isMutation(query)) {
|
|
19269
19364
|
console.error(
|
|
19270
|
-
|
|
19365
|
+
chalk184.red(
|
|
19271
19366
|
"assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
|
|
19272
19367
|
)
|
|
19273
19368
|
);
|
|
@@ -19277,18 +19372,18 @@ async function sqlMutate(query, connectionName) {
|
|
|
19277
19372
|
const pool = await sqlConnect(conn);
|
|
19278
19373
|
try {
|
|
19279
19374
|
const result = await pool.request().query(query);
|
|
19280
|
-
console.log(
|
|
19375
|
+
console.log(chalk184.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
|
|
19281
19376
|
} finally {
|
|
19282
19377
|
await pool.close();
|
|
19283
19378
|
}
|
|
19284
19379
|
}
|
|
19285
19380
|
|
|
19286
19381
|
// src/commands/sql/sqlQuery.ts
|
|
19287
|
-
import
|
|
19382
|
+
import chalk185 from "chalk";
|
|
19288
19383
|
async function sqlQuery(query, connectionName) {
|
|
19289
19384
|
if (isMutation(query)) {
|
|
19290
19385
|
console.error(
|
|
19291
|
-
|
|
19386
|
+
chalk185.red(
|
|
19292
19387
|
"assist sql query refuses mutating statements. Use `assist sql mutate` instead."
|
|
19293
19388
|
)
|
|
19294
19389
|
);
|
|
@@ -19303,7 +19398,7 @@ async function sqlQuery(query, connectionName) {
|
|
|
19303
19398
|
printTable(rows);
|
|
19304
19399
|
} else {
|
|
19305
19400
|
console.log(
|
|
19306
|
-
|
|
19401
|
+
chalk185.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
|
|
19307
19402
|
);
|
|
19308
19403
|
}
|
|
19309
19404
|
} finally {
|
|
@@ -19780,13 +19875,13 @@ function logs(options2) {
|
|
|
19780
19875
|
console.log("No voice log file found");
|
|
19781
19876
|
return;
|
|
19782
19877
|
}
|
|
19783
|
-
const
|
|
19878
|
+
const count8 = Number.parseInt(options2.lines ?? "150", 10);
|
|
19784
19879
|
const content = readFileSync39(voicePaths.log, "utf8").trim();
|
|
19785
19880
|
if (!content) {
|
|
19786
19881
|
console.log("Voice log is empty");
|
|
19787
19882
|
return;
|
|
19788
19883
|
}
|
|
19789
|
-
const lines = content.split("\n").slice(-
|
|
19884
|
+
const lines = content.split("\n").slice(-count8);
|
|
19790
19885
|
for (const line of lines) {
|
|
19791
19886
|
try {
|
|
19792
19887
|
const event = JSON.parse(line);
|
|
@@ -19933,10 +20028,10 @@ function isProcessAlive3(pid) {
|
|
|
19933
20028
|
return false;
|
|
19934
20029
|
}
|
|
19935
20030
|
}
|
|
19936
|
-
function readRecentLogs(
|
|
20031
|
+
function readRecentLogs(count8) {
|
|
19937
20032
|
if (!existsSync47(voicePaths.log)) return [];
|
|
19938
20033
|
const lines = readFileSync41(voicePaths.log, "utf8").trim().split("\n");
|
|
19939
|
-
return lines.slice(-
|
|
20034
|
+
return lines.slice(-count8);
|
|
19940
20035
|
}
|
|
19941
20036
|
function status() {
|
|
19942
20037
|
if (!existsSync47(voicePaths.pid)) {
|
|
@@ -20000,7 +20095,7 @@ function registerVoice(program2) {
|
|
|
20000
20095
|
|
|
20001
20096
|
// src/commands/roam/auth.ts
|
|
20002
20097
|
import { randomBytes } from "crypto";
|
|
20003
|
-
import
|
|
20098
|
+
import chalk186 from "chalk";
|
|
20004
20099
|
|
|
20005
20100
|
// src/commands/roam/waitForCallback.ts
|
|
20006
20101
|
import { createServer as createServer3 } from "http";
|
|
@@ -20131,13 +20226,13 @@ async function auth() {
|
|
|
20131
20226
|
saveGlobalConfig(config);
|
|
20132
20227
|
const state = randomBytes(16).toString("hex");
|
|
20133
20228
|
console.log(
|
|
20134
|
-
|
|
20229
|
+
chalk186.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
20135
20230
|
);
|
|
20136
|
-
console.log(
|
|
20137
|
-
console.log(
|
|
20138
|
-
console.log(
|
|
20231
|
+
console.log(chalk186.white("http://localhost:14523/callback\n"));
|
|
20232
|
+
console.log(chalk186.blue("Opening browser for authorization..."));
|
|
20233
|
+
console.log(chalk186.dim("Waiting for authorization callback..."));
|
|
20139
20234
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
20140
|
-
console.log(
|
|
20235
|
+
console.log(chalk186.dim("Exchanging code for tokens..."));
|
|
20141
20236
|
const tokens = await exchangeToken({
|
|
20142
20237
|
code,
|
|
20143
20238
|
clientId,
|
|
@@ -20153,7 +20248,7 @@ async function auth() {
|
|
|
20153
20248
|
};
|
|
20154
20249
|
saveGlobalConfig(config);
|
|
20155
20250
|
console.log(
|
|
20156
|
-
|
|
20251
|
+
chalk186.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
20157
20252
|
);
|
|
20158
20253
|
}
|
|
20159
20254
|
|
|
@@ -20605,7 +20700,7 @@ import { execSync as execSync52 } from "child_process";
|
|
|
20605
20700
|
import { existsSync as existsSync51, mkdirSync as mkdirSync22, unlinkSync as unlinkSync19, writeFileSync as writeFileSync39 } from "fs";
|
|
20606
20701
|
import { tmpdir as tmpdir7 } from "os";
|
|
20607
20702
|
import { join as join61, resolve as resolve15 } from "path";
|
|
20608
|
-
import
|
|
20703
|
+
import chalk187 from "chalk";
|
|
20609
20704
|
|
|
20610
20705
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
20611
20706
|
var captureWindowPs1 = `
|
|
@@ -20756,13 +20851,13 @@ function screenshot(processName) {
|
|
|
20756
20851
|
const config = loadConfig();
|
|
20757
20852
|
const outputDir = resolve15(config.screenshot.outputDir);
|
|
20758
20853
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
20759
|
-
console.log(
|
|
20854
|
+
console.log(chalk187.gray(`Capturing window for process "${processName}" ...`));
|
|
20760
20855
|
try {
|
|
20761
20856
|
runPowerShellScript(processName, outputPath);
|
|
20762
|
-
console.log(
|
|
20857
|
+
console.log(chalk187.green(`Screenshot saved: ${outputPath}`));
|
|
20763
20858
|
} catch (error) {
|
|
20764
20859
|
const msg = error instanceof Error ? error.message : String(error);
|
|
20765
|
-
console.error(
|
|
20860
|
+
console.error(chalk187.red(`Failed to capture screenshot: ${msg}`));
|
|
20766
20861
|
process.exit(1);
|
|
20767
20862
|
}
|
|
20768
20863
|
}
|
|
@@ -20975,9 +21070,9 @@ async function drainDaemon() {
|
|
|
20975
21070
|
console.log("Sessions daemon is not running; cleared persisted sessions");
|
|
20976
21071
|
return;
|
|
20977
21072
|
}
|
|
20978
|
-
const
|
|
21073
|
+
const count8 = await requestDrain(socket);
|
|
20979
21074
|
socket.destroy();
|
|
20980
|
-
console.log(`Drained ${
|
|
21075
|
+
console.log(`Drained ${count8} session(s)`);
|
|
20981
21076
|
}
|
|
20982
21077
|
function requestDrain(socket) {
|
|
20983
21078
|
socket.write(`${JSON.stringify({ type: "drain" })}
|
|
@@ -21763,10 +21858,10 @@ function applyReviewPause(session, activity2) {
|
|
|
21763
21858
|
}
|
|
21764
21859
|
|
|
21765
21860
|
// src/shared/db/getPhaseActiveMs.ts
|
|
21766
|
-
import { and as
|
|
21861
|
+
import { and as and17, eq as eq36 } from "drizzle-orm";
|
|
21767
21862
|
async function getPhaseActiveMs(db, itemId, phaseIdx) {
|
|
21768
21863
|
const [row] = await db.select({ activeMs: phaseUsage.activeMs }).from(phaseUsage).where(
|
|
21769
|
-
|
|
21864
|
+
and17(eq36(phaseUsage.itemId, itemId), eq36(phaseUsage.phaseIdx, phaseIdx))
|
|
21770
21865
|
);
|
|
21771
21866
|
return row?.activeMs ?? 0;
|
|
21772
21867
|
}
|
|
@@ -23278,7 +23373,7 @@ function registerDaemon(program2) {
|
|
|
23278
23373
|
|
|
23279
23374
|
// src/commands/sessions/summarise/index.ts
|
|
23280
23375
|
import * as fs36 from "fs";
|
|
23281
|
-
import
|
|
23376
|
+
import chalk188 from "chalk";
|
|
23282
23377
|
|
|
23283
23378
|
// src/commands/sessions/summarise/shared.ts
|
|
23284
23379
|
import * as fs34 from "fs";
|
|
@@ -23432,22 +23527,22 @@ ${firstMessage}`);
|
|
|
23432
23527
|
async function summarise2(options2) {
|
|
23433
23528
|
const files = await discoverSessionFiles();
|
|
23434
23529
|
if (files.length === 0) {
|
|
23435
|
-
console.log(
|
|
23530
|
+
console.log(chalk188.yellow("No sessions found."));
|
|
23436
23531
|
return;
|
|
23437
23532
|
}
|
|
23438
23533
|
const toProcess = selectCandidates(files, options2);
|
|
23439
23534
|
if (toProcess.length === 0) {
|
|
23440
|
-
console.log(
|
|
23535
|
+
console.log(chalk188.green("All sessions already summarised."));
|
|
23441
23536
|
return;
|
|
23442
23537
|
}
|
|
23443
23538
|
console.log(
|
|
23444
|
-
|
|
23539
|
+
chalk188.cyan(
|
|
23445
23540
|
`Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
|
|
23446
23541
|
)
|
|
23447
23542
|
);
|
|
23448
23543
|
const { succeeded, failed: failed2 } = processSessions(toProcess);
|
|
23449
23544
|
console.log(
|
|
23450
|
-
|
|
23545
|
+
chalk188.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk188.yellow(`, ${failed2} skipped`) : "")
|
|
23451
23546
|
);
|
|
23452
23547
|
}
|
|
23453
23548
|
function selectCandidates(files, options2) {
|
|
@@ -23467,16 +23562,16 @@ function processSessions(files) {
|
|
|
23467
23562
|
let failed2 = 0;
|
|
23468
23563
|
for (let i = 0; i < files.length; i++) {
|
|
23469
23564
|
const file = files[i];
|
|
23470
|
-
process.stdout.write(
|
|
23565
|
+
process.stdout.write(chalk188.dim(` [${i + 1}/${files.length}] `));
|
|
23471
23566
|
const summary = summariseSession(file);
|
|
23472
23567
|
if (summary) {
|
|
23473
23568
|
writeSummary(file, summary);
|
|
23474
23569
|
succeeded++;
|
|
23475
|
-
process.stdout.write(`${
|
|
23570
|
+
process.stdout.write(`${chalk188.green("\u2713")} ${summary}
|
|
23476
23571
|
`);
|
|
23477
23572
|
} else {
|
|
23478
23573
|
failed2++;
|
|
23479
|
-
process.stdout.write(` ${
|
|
23574
|
+
process.stdout.write(` ${chalk188.yellow("skip")}
|
|
23480
23575
|
`);
|
|
23481
23576
|
}
|
|
23482
23577
|
}
|
|
@@ -23494,10 +23589,10 @@ function registerSessions(program2) {
|
|
|
23494
23589
|
}
|
|
23495
23590
|
|
|
23496
23591
|
// src/commands/statusLine.ts
|
|
23497
|
-
import
|
|
23592
|
+
import chalk190 from "chalk";
|
|
23498
23593
|
|
|
23499
23594
|
// src/commands/buildLimitsSegment.ts
|
|
23500
|
-
import
|
|
23595
|
+
import chalk189 from "chalk";
|
|
23501
23596
|
|
|
23502
23597
|
// src/shared/rateLimitLevel.ts
|
|
23503
23598
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
@@ -23528,9 +23623,9 @@ function rateLimitLevel(pct, resetsAt, windowSeconds, now) {
|
|
|
23528
23623
|
|
|
23529
23624
|
// src/commands/buildLimitsSegment.ts
|
|
23530
23625
|
var LEVEL_COLOR = {
|
|
23531
|
-
ok:
|
|
23532
|
-
warn:
|
|
23533
|
-
over:
|
|
23626
|
+
ok: chalk189.green,
|
|
23627
|
+
warn: chalk189.yellow,
|
|
23628
|
+
over: chalk189.red
|
|
23534
23629
|
};
|
|
23535
23630
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel, now) {
|
|
23536
23631
|
const level = rateLimitLevel(pct, resetsAt, windowSeconds, now);
|
|
@@ -23579,14 +23674,14 @@ async function relayUsage(claudeSessionId, totalIn, totalOut) {
|
|
|
23579
23674
|
}
|
|
23580
23675
|
|
|
23581
23676
|
// src/commands/statusLine.ts
|
|
23582
|
-
|
|
23677
|
+
chalk190.level = 3;
|
|
23583
23678
|
function formatNumber(num) {
|
|
23584
23679
|
return num.toLocaleString("en-US");
|
|
23585
23680
|
}
|
|
23586
23681
|
function colorizePercent(pct) {
|
|
23587
23682
|
const label2 = `${Math.round(pct)}%`;
|
|
23588
|
-
if (pct > 80) return
|
|
23589
|
-
if (pct > 40) return
|
|
23683
|
+
if (pct > 80) return chalk190.red(label2);
|
|
23684
|
+
if (pct > 40) return chalk190.yellow(label2);
|
|
23590
23685
|
return label2;
|
|
23591
23686
|
}
|
|
23592
23687
|
async function statusLine() {
|
|
@@ -23611,7 +23706,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
23611
23706
|
// src/commands/sync/syncClaudeMd.ts
|
|
23612
23707
|
import * as fs37 from "fs";
|
|
23613
23708
|
import * as path53 from "path";
|
|
23614
|
-
import
|
|
23709
|
+
import chalk191 from "chalk";
|
|
23615
23710
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
23616
23711
|
const source = path53.join(claudeDir, "CLAUDE.md");
|
|
23617
23712
|
const target = path53.join(targetBase, "CLAUDE.md");
|
|
@@ -23620,12 +23715,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
23620
23715
|
const targetContent = fs37.readFileSync(target, "utf8");
|
|
23621
23716
|
if (sourceContent !== targetContent) {
|
|
23622
23717
|
console.log(
|
|
23623
|
-
|
|
23718
|
+
chalk191.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
23624
23719
|
);
|
|
23625
23720
|
console.log();
|
|
23626
23721
|
printDiff(targetContent, sourceContent);
|
|
23627
23722
|
const confirm = options2?.yes || await promptConfirm(
|
|
23628
|
-
|
|
23723
|
+
chalk191.red("Overwrite existing CLAUDE.md?"),
|
|
23629
23724
|
false
|
|
23630
23725
|
);
|
|
23631
23726
|
if (!confirm) {
|
|
@@ -23641,7 +23736,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
23641
23736
|
// src/commands/sync/syncSettings.ts
|
|
23642
23737
|
import * as fs38 from "fs";
|
|
23643
23738
|
import * as path54 from "path";
|
|
23644
|
-
import
|
|
23739
|
+
import chalk192 from "chalk";
|
|
23645
23740
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
23646
23741
|
const source = path54.join(claudeDir, "settings.json");
|
|
23647
23742
|
const target = path54.join(targetBase, "settings.json");
|
|
@@ -23660,14 +23755,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
23660
23755
|
if (mergedContent !== normalizedTarget) {
|
|
23661
23756
|
if (!options2?.yes) {
|
|
23662
23757
|
console.log(
|
|
23663
|
-
|
|
23758
|
+
chalk192.yellow(
|
|
23664
23759
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
23665
23760
|
)
|
|
23666
23761
|
);
|
|
23667
23762
|
console.log();
|
|
23668
23763
|
printDiff(targetContent, mergedContent);
|
|
23669
23764
|
const confirm = await promptConfirm(
|
|
23670
|
-
|
|
23765
|
+
chalk192.red("Overwrite existing settings.json?"),
|
|
23671
23766
|
false
|
|
23672
23767
|
);
|
|
23673
23768
|
if (!confirm) {
|