@staff0rd/assist 0.575.0 → 0.576.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/allowed.cli-reads +1 -0
- package/claude/commands/github.md +1 -1
- package/dist/allowed.cli-reads +1 -0
- package/dist/commands/sessions/web/bundle.js +1 -1
- package/dist/index.js +914 -435
- 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.576.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -13949,7 +13949,7 @@ import chalk71 from "chalk";
|
|
|
13949
13949
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
13950
13950
|
|
|
13951
13951
|
// src/commands/sessions/shared/reportPreviewRejection.ts
|
|
13952
|
-
function reportPreviewRejection(subject, decision) {
|
|
13952
|
+
function reportPreviewRejection(subject, decision, advice) {
|
|
13953
13953
|
console.error(
|
|
13954
13954
|
`${subject} rejected${decision.reason ? `: ${decision.reason}` : "."}`
|
|
13955
13955
|
);
|
|
@@ -13968,6 +13968,7 @@ ${quoted}
|
|
|
13968
13968
|
`);
|
|
13969
13969
|
}
|
|
13970
13970
|
}
|
|
13971
|
+
if (advice) console.error(advice);
|
|
13971
13972
|
process.exit(1);
|
|
13972
13973
|
}
|
|
13973
13974
|
|
|
@@ -14030,7 +14031,7 @@ function requestPreviewDecision(request) {
|
|
|
14030
14031
|
}
|
|
14031
14032
|
|
|
14032
14033
|
// src/commands/sessions/shared/awaitPreviewApproval.ts
|
|
14033
|
-
async function awaitPreviewApproval(subject, request,
|
|
14034
|
+
async function awaitPreviewApproval(subject, request, options2 = {}) {
|
|
14034
14035
|
console.log("Awaiting your approval in the assist web UI preview pane\u2026");
|
|
14035
14036
|
let decision;
|
|
14036
14037
|
try {
|
|
@@ -14041,8 +14042,9 @@ async function awaitPreviewApproval(subject, request, saveEditedBody) {
|
|
|
14041
14042
|
);
|
|
14042
14043
|
process.exit(1);
|
|
14043
14044
|
}
|
|
14044
|
-
if (decision.body !== void 0) saveEditedBody?.(decision.body);
|
|
14045
|
-
if (decision.decision === "reject")
|
|
14045
|
+
if (decision.body !== void 0) options2.saveEditedBody?.(decision.body);
|
|
14046
|
+
if (decision.decision === "reject")
|
|
14047
|
+
reportPreviewRejection(subject, decision, options2.rejectionAdvice);
|
|
14046
14048
|
return decision;
|
|
14047
14049
|
}
|
|
14048
14050
|
|
|
@@ -20500,14 +20502,8 @@ import { spawnSync as spawnSync4 } from "child_process";
|
|
|
20500
20502
|
import { unlinkSync as unlinkSync12, writeFileSync as writeFileSync30 } from "fs";
|
|
20501
20503
|
import { tmpdir as tmpdir5 } from "os";
|
|
20502
20504
|
import { join as join49 } from "path";
|
|
20503
|
-
|
|
20504
|
-
|
|
20505
|
-
for (const [key, value] of Object.entries(vars)) {
|
|
20506
|
-
const flag = typeof value === "number" ? "-F" : "-f";
|
|
20507
|
-
args.push(flag, `${key}=${value}`);
|
|
20508
|
-
}
|
|
20509
|
-
return args;
|
|
20510
|
-
}
|
|
20505
|
+
|
|
20506
|
+
// src/shared/throwOnGraphqlErrors.ts
|
|
20511
20507
|
function throwOnGraphqlErrors(stdout) {
|
|
20512
20508
|
let parsed;
|
|
20513
20509
|
try {
|
|
@@ -20523,6 +20519,16 @@ function throwOnGraphqlErrors(stdout) {
|
|
|
20523
20519
|
).join("; ");
|
|
20524
20520
|
throw new Error(messages || "GraphQL request returned errors");
|
|
20525
20521
|
}
|
|
20522
|
+
|
|
20523
|
+
// src/shared/runGhGraphql.ts
|
|
20524
|
+
function buildArgs2(queryFile, vars) {
|
|
20525
|
+
const args = ["api", "graphql", "-F", `query=@${queryFile}`];
|
|
20526
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
20527
|
+
const flag = typeof value === "number" ? "-F" : "-f";
|
|
20528
|
+
args.push(flag, `${key}=${value}`);
|
|
20529
|
+
}
|
|
20530
|
+
return args;
|
|
20531
|
+
}
|
|
20526
20532
|
function runGhGraphql(mutation, vars) {
|
|
20527
20533
|
const queryFile = join49(tmpdir5(), `gh-query-${Date.now()}.graphql`);
|
|
20528
20534
|
writeFileSync30(queryFile, mutation);
|
|
@@ -20830,6 +20836,83 @@ function fetchIssue2(number, repo) {
|
|
|
20830
20836
|
}
|
|
20831
20837
|
}
|
|
20832
20838
|
|
|
20839
|
+
// src/commands/github/issue/resumeIssueBody.ts
|
|
20840
|
+
import { existsSync as existsSync48, readFileSync as readFileSync37 } from "fs";
|
|
20841
|
+
|
|
20842
|
+
// src/commands/github/issue/issueWorkingFile.ts
|
|
20843
|
+
import { join as join50 } from "path";
|
|
20844
|
+
function issueWorkingFile(slug, number) {
|
|
20845
|
+
const [owner = "unknown", repo = "unknown"] = slug.split("/");
|
|
20846
|
+
const dir = join50(getStoreDir(), "github-issues", owner, repo);
|
|
20847
|
+
return {
|
|
20848
|
+
dir,
|
|
20849
|
+
bodyPath: join50(dir, `${number}.md`),
|
|
20850
|
+
metaPath: join50(dir, `${number}.json`)
|
|
20851
|
+
};
|
|
20852
|
+
}
|
|
20853
|
+
|
|
20854
|
+
// src/commands/github/issue/resumeIssueBody.ts
|
|
20855
|
+
function resumeIssueBody(slug, number, updatedAt) {
|
|
20856
|
+
const { bodyPath, metaPath } = issueWorkingFile(slug, number);
|
|
20857
|
+
if (!existsSync48(bodyPath) || !existsSync48(metaPath)) return void 0;
|
|
20858
|
+
try {
|
|
20859
|
+
const meta = JSON.parse(readFileSync37(metaPath, "utf8"));
|
|
20860
|
+
if (meta.updatedAt !== updatedAt) return void 0;
|
|
20861
|
+
return readFileSync37(bodyPath, "utf8");
|
|
20862
|
+
} catch {
|
|
20863
|
+
return void 0;
|
|
20864
|
+
}
|
|
20865
|
+
}
|
|
20866
|
+
|
|
20867
|
+
// src/commands/github/issue/validateIssueBody.ts
|
|
20868
|
+
function validateIssueBody(title, body) {
|
|
20869
|
+
validateProposedContent(
|
|
20870
|
+
{ subject: "Issue", context: "GitHub issues" },
|
|
20871
|
+
title,
|
|
20872
|
+
body
|
|
20873
|
+
);
|
|
20874
|
+
}
|
|
20875
|
+
|
|
20876
|
+
// src/commands/github/issue/writeIssueWorkingFile.ts
|
|
20877
|
+
import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync31 } from "fs";
|
|
20878
|
+
function writeIssueWorkingFile(slug, number, target, updatedAt, body) {
|
|
20879
|
+
const { dir, bodyPath, metaPath } = issueWorkingFile(slug, number);
|
|
20880
|
+
mkdirSync16(dir, { recursive: true });
|
|
20881
|
+
writeFileSync31(bodyPath, body);
|
|
20882
|
+
writeFileSync31(
|
|
20883
|
+
metaPath,
|
|
20884
|
+
`${JSON.stringify({ target, updatedAt }, null, 2)}
|
|
20885
|
+
`
|
|
20886
|
+
);
|
|
20887
|
+
return bodyPath;
|
|
20888
|
+
}
|
|
20889
|
+
|
|
20890
|
+
// src/commands/github/issue/prepareIssueEdit.ts
|
|
20891
|
+
function slugFromUrl(url) {
|
|
20892
|
+
const match = /github\.com\/([^/]+\/[^/]+)\//.exec(url ?? "");
|
|
20893
|
+
return match ? match[1] : "unknown/unknown";
|
|
20894
|
+
}
|
|
20895
|
+
function prepareIssueEdit(number, repo, fresh) {
|
|
20896
|
+
const issue = fetchIssue2(number, repo);
|
|
20897
|
+
const slug = repo ?? slugFromUrl(issue.url);
|
|
20898
|
+
const target = `${slug}#${number}`;
|
|
20899
|
+
const resumed = fresh ? void 0 : resumeIssueBody(slug, number, issue.updatedAt);
|
|
20900
|
+
const body = resumed ?? issue.body;
|
|
20901
|
+
validateIssueBody(issue.title, body);
|
|
20902
|
+
const save = (markdown) => writeIssueWorkingFile(slug, number, target, issue.updatedAt, markdown);
|
|
20903
|
+
const bodyPath = save(body);
|
|
20904
|
+
if (resumed !== void 0)
|
|
20905
|
+
console.log(`Previewing the in-progress markdown from ${bodyPath}`);
|
|
20906
|
+
return {
|
|
20907
|
+
title: issue.title,
|
|
20908
|
+
target,
|
|
20909
|
+
updatedAt: issue.updatedAt,
|
|
20910
|
+
body,
|
|
20911
|
+
bodyPath,
|
|
20912
|
+
save
|
|
20913
|
+
};
|
|
20914
|
+
}
|
|
20915
|
+
|
|
20833
20916
|
// src/commands/github/issue/pushIssueBody.ts
|
|
20834
20917
|
import { execFileSync as execFileSync9 } from "child_process";
|
|
20835
20918
|
function pushIssueBody(number, repo, bodyPath) {
|
|
@@ -20856,7 +20939,7 @@ function pushUnchangedIssue(number, repo, target, fetchedAt, bodyPath) {
|
|
|
20856
20939
|
|
|
20857
20940
|
// src/commands/github/issue/reviewProposedIssueEdit.ts
|
|
20858
20941
|
import { randomUUID as randomUUID9 } from "crypto";
|
|
20859
|
-
async function reviewProposedIssueEdit(title, body,
|
|
20942
|
+
async function reviewProposedIssueEdit(title, body, working) {
|
|
20860
20943
|
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
20861
20944
|
if (process.env.ASSIST_SESSION !== "1" || !sessionId) return body;
|
|
20862
20945
|
const decision = await awaitPreviewApproval(
|
|
@@ -20869,7 +20952,10 @@ async function reviewProposedIssueEdit(title, body, saveEditedBody) {
|
|
|
20869
20952
|
prNumber: null,
|
|
20870
20953
|
kind: "github-issue-edit"
|
|
20871
20954
|
},
|
|
20872
|
-
|
|
20955
|
+
{
|
|
20956
|
+
saveEditedBody: working.save,
|
|
20957
|
+
rejectionAdvice: `Nothing was pushed. The pane's markdown, including any collapses already applied, is at ${working.path}. Revise that file in place \u2014 do not recompose the body from scratch \u2014 then re-run this command to preview the revision.`
|
|
20958
|
+
}
|
|
20873
20959
|
);
|
|
20874
20960
|
return decision.body ?? body;
|
|
20875
20961
|
}
|
|
@@ -20886,40 +20972,8 @@ function viewIssue(number, repo) {
|
|
|
20886
20972
|
}
|
|
20887
20973
|
}
|
|
20888
20974
|
|
|
20889
|
-
// src/commands/github/issue/writeIssueWorkingFile.ts
|
|
20890
|
-
import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync31 } from "fs";
|
|
20891
|
-
|
|
20892
|
-
// src/commands/github/issue/issueWorkingFile.ts
|
|
20893
|
-
import { join as join50 } from "path";
|
|
20894
|
-
function issueWorkingFile(slug, number) {
|
|
20895
|
-
const [owner = "unknown", repo = "unknown"] = slug.split("/");
|
|
20896
|
-
const dir = join50(getStoreDir(), "github-issues", owner, repo);
|
|
20897
|
-
return {
|
|
20898
|
-
dir,
|
|
20899
|
-
bodyPath: join50(dir, `${number}.md`),
|
|
20900
|
-
metaPath: join50(dir, `${number}.json`)
|
|
20901
|
-
};
|
|
20902
|
-
}
|
|
20903
|
-
|
|
20904
|
-
// src/commands/github/issue/writeIssueWorkingFile.ts
|
|
20905
|
-
function writeIssueWorkingFile(slug, number, target, updatedAt, body) {
|
|
20906
|
-
const { dir, bodyPath, metaPath } = issueWorkingFile(slug, number);
|
|
20907
|
-
mkdirSync16(dir, { recursive: true });
|
|
20908
|
-
writeFileSync31(bodyPath, body);
|
|
20909
|
-
writeFileSync31(
|
|
20910
|
-
metaPath,
|
|
20911
|
-
`${JSON.stringify({ target, updatedAt }, null, 2)}
|
|
20912
|
-
`
|
|
20913
|
-
);
|
|
20914
|
-
return bodyPath;
|
|
20915
|
-
}
|
|
20916
|
-
|
|
20917
20975
|
// src/commands/github/issue/editIssue.ts
|
|
20918
20976
|
var USAGE3 = "Usage: assist github issue edit <number> [-R <owner>/<repo>]";
|
|
20919
|
-
function slugFromUrl(url) {
|
|
20920
|
-
const match = /github\.com\/([^/]+\/[^/]+)\//.exec(url ?? "");
|
|
20921
|
-
return match ? match[1] : "unknown/unknown";
|
|
20922
|
-
}
|
|
20923
20977
|
async function editIssue(numberArg, options2) {
|
|
20924
20978
|
const number = Number.parseInt(numberArg, 10);
|
|
20925
20979
|
if (!Number.isInteger(number) || number <= 0) {
|
|
@@ -20930,27 +20984,419 @@ async function editIssue(numberArg, options2) {
|
|
|
20930
20984
|
viewIssue(number, options2.repo);
|
|
20931
20985
|
return;
|
|
20932
20986
|
}
|
|
20933
|
-
const issue =
|
|
20934
|
-
const slug = options2.repo ?? slugFromUrl(issue.url);
|
|
20935
|
-
const target = `${slug}#${number}`;
|
|
20936
|
-
validateProposedContent(
|
|
20937
|
-
{ subject: "Issue", context: "GitHub issues" },
|
|
20938
|
-
issue.title,
|
|
20939
|
-
issue.body
|
|
20940
|
-
);
|
|
20941
|
-
const save = (markdown) => writeIssueWorkingFile(slug, number, target, issue.updatedAt, markdown);
|
|
20942
|
-
const bodyPath = save(issue.body);
|
|
20987
|
+
const issue = prepareIssueEdit(number, options2.repo, options2.fresh);
|
|
20943
20988
|
const edited = await reviewProposedIssueEdit(
|
|
20944
|
-
`Edit ${target}: ${issue.title}`,
|
|
20989
|
+
`Edit ${issue.target}: ${issue.title}`,
|
|
20945
20990
|
issue.body,
|
|
20946
|
-
save
|
|
20991
|
+
{ path: issue.bodyPath, save: issue.save }
|
|
20947
20992
|
);
|
|
20948
|
-
|
|
20949
|
-
|
|
20950
|
-
|
|
20951
|
-
|
|
20993
|
+
validateIssueBody(issue.title, edited);
|
|
20994
|
+
pushUnchangedIssue(
|
|
20995
|
+
number,
|
|
20996
|
+
options2.repo,
|
|
20997
|
+
issue.target,
|
|
20998
|
+
issue.updatedAt,
|
|
20999
|
+
issue.bodyPath
|
|
21000
|
+
);
|
|
21001
|
+
}
|
|
21002
|
+
|
|
21003
|
+
// src/commands/github/issue/fixStructure/matchedLabels.ts
|
|
21004
|
+
function matchedLabels(labels, stripLabels) {
|
|
21005
|
+
if (stripLabels.length === 0) return [];
|
|
21006
|
+
const wanted = new Set(stripLabels.map((name) => name.trim().toLowerCase()));
|
|
21007
|
+
return labels.filter((label2) => wanted.has(label2.name.trim().toLowerCase()));
|
|
21008
|
+
}
|
|
21009
|
+
|
|
21010
|
+
// src/commands/github/issue/fixStructure/normaliseTypeName.ts
|
|
21011
|
+
function normaliseTypeName(name) {
|
|
21012
|
+
return name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
21013
|
+
}
|
|
21014
|
+
|
|
21015
|
+
// src/commands/github/issue/fixStructure/resolveIssueType.ts
|
|
21016
|
+
function resolveIssueType(issueTypes, levelName) {
|
|
21017
|
+
const wanted = normaliseTypeName(levelName);
|
|
21018
|
+
const match = issueTypes.find(
|
|
21019
|
+
(type) => normaliseTypeName(type.name) === wanted
|
|
21020
|
+
);
|
|
21021
|
+
if (!match) {
|
|
21022
|
+
throw new Error(
|
|
21023
|
+
`The organisation has no ${levelName} issue type. It has ${issueTypes.map((type) => type.name).join(", ")}`
|
|
21024
|
+
);
|
|
21025
|
+
}
|
|
21026
|
+
return match;
|
|
21027
|
+
}
|
|
21028
|
+
|
|
21029
|
+
// src/commands/github/issue/fixStructure/resolveLevelIndex.ts
|
|
21030
|
+
function resolveLevelIndex(chain2, name) {
|
|
21031
|
+
if (!name) return -1;
|
|
21032
|
+
const wanted = normaliseTypeName(name);
|
|
21033
|
+
return chain2.findIndex((level) => normaliseTypeName(level) === wanted);
|
|
21034
|
+
}
|
|
21035
|
+
|
|
21036
|
+
// src/commands/github/issue/fixStructure/buildPlanEntry.ts
|
|
21037
|
+
function buildPlanEntry(issue, context) {
|
|
21038
|
+
const labelRemovals = matchedLabels(issue.labels, context.stripLabels);
|
|
21039
|
+
const level = context.chain[context.rootLevelIndex + issue.depth];
|
|
21040
|
+
if (level === void 0) {
|
|
21041
|
+
return { issue, level: null, typeChange: null, labelRemovals };
|
|
21042
|
+
}
|
|
21043
|
+
const settled = resolveLevelIndex([level], issue.typeName) === 0 || issue.depth === 0 && !context.rootAsserted;
|
|
21044
|
+
if (settled) return { issue, level, typeChange: null, labelRemovals };
|
|
21045
|
+
const target = resolveIssueType(context.issueTypes, level);
|
|
21046
|
+
return {
|
|
21047
|
+
issue,
|
|
21048
|
+
level,
|
|
21049
|
+
typeChange: { from: issue.typeName, to: target.name, typeId: target.id },
|
|
21050
|
+
labelRemovals
|
|
21051
|
+
};
|
|
21052
|
+
}
|
|
21053
|
+
|
|
21054
|
+
// src/commands/github/issue/fixStructure/orderDepthFirst.ts
|
|
21055
|
+
function orderDepthFirst(issues) {
|
|
21056
|
+
const byParent = /* @__PURE__ */ new Map();
|
|
21057
|
+
for (const issue of issues) {
|
|
21058
|
+
const siblings = byParent.get(issue.parentId) ?? [];
|
|
21059
|
+
siblings.push(issue);
|
|
21060
|
+
byParent.set(issue.parentId, siblings);
|
|
21061
|
+
}
|
|
21062
|
+
const ordered = [];
|
|
21063
|
+
const visit = (issue) => {
|
|
21064
|
+
ordered.push(issue);
|
|
21065
|
+
for (const child of byParent.get(issue.id) ?? []) visit(child);
|
|
21066
|
+
};
|
|
21067
|
+
for (const root of byParent.get(null) ?? []) visit(root);
|
|
21068
|
+
return ordered;
|
|
21069
|
+
}
|
|
21070
|
+
|
|
21071
|
+
// src/commands/github/issue/fixStructure/buildFixStructurePlan.ts
|
|
21072
|
+
function buildFixStructurePlan(issues, options2) {
|
|
21073
|
+
const context = { ...options2, stripLabels: options2.stripLabels ?? [] };
|
|
21074
|
+
const byId = new Map(issues.map((issue) => [issue.id, issue]));
|
|
21075
|
+
const entries = [];
|
|
21076
|
+
const tooDeep = [];
|
|
21077
|
+
for (const issue of orderDepthFirst(issues)) {
|
|
21078
|
+
const entry = buildPlanEntry(issue, context);
|
|
21079
|
+
entries.push(entry);
|
|
21080
|
+
if (entry.level === null) {
|
|
21081
|
+
tooDeep.push({
|
|
21082
|
+
issue,
|
|
21083
|
+
parent: issue.parentId ? byId.get(issue.parentId) ?? null : null
|
|
21084
|
+
});
|
|
21085
|
+
}
|
|
21086
|
+
}
|
|
21087
|
+
return {
|
|
21088
|
+
entries,
|
|
21089
|
+
tooDeep,
|
|
21090
|
+
typeChangeCount: entries.filter((entry) => entry.typeChange).length,
|
|
21091
|
+
labelRemovalCount: entries.reduce(
|
|
21092
|
+
(total, entry) => total + entry.labelRemovals.length,
|
|
21093
|
+
0
|
|
21094
|
+
)
|
|
21095
|
+
};
|
|
21096
|
+
}
|
|
21097
|
+
|
|
21098
|
+
// src/shared/runGhGraphqlJson.ts
|
|
21099
|
+
import { spawnSync as spawnSync5 } from "child_process";
|
|
21100
|
+
function runGhGraphqlJson(query, vars = {}) {
|
|
21101
|
+
const result = spawnSync5("gh", ["api", "graphql", "--input", "-"], {
|
|
21102
|
+
encoding: "utf8",
|
|
21103
|
+
windowsHide: true,
|
|
21104
|
+
input: JSON.stringify({ query, variables: vars }),
|
|
21105
|
+
maxBuffer: 64 * 1024 * 1024
|
|
21106
|
+
});
|
|
21107
|
+
if (result.status !== 0) throw new Error(result.stderr || result.stdout);
|
|
21108
|
+
throwOnGraphqlErrors(result.stdout);
|
|
21109
|
+
return result.stdout;
|
|
21110
|
+
}
|
|
21111
|
+
|
|
21112
|
+
// src/commands/github/issue/fixStructure/issueFieldsFragment.ts
|
|
21113
|
+
var issueFieldsFragment = `fragment issueFields on Issue {
|
|
21114
|
+
id
|
|
21115
|
+
number
|
|
21116
|
+
title
|
|
21117
|
+
issueType { name }
|
|
21118
|
+
repository { nameWithOwner }
|
|
21119
|
+
labels(first: 100) { nodes { id name } pageInfo { hasNextPage } }
|
|
21120
|
+
subIssues(first: 100) { nodes { id } pageInfo { hasNextPage } }
|
|
21121
|
+
}`;
|
|
21122
|
+
|
|
21123
|
+
// src/commands/github/issue/fixStructure/parseIssueNode.ts
|
|
21124
|
+
function parseIssueNode(node) {
|
|
21125
|
+
const raw = node;
|
|
21126
|
+
const repo = raw.repository?.nameWithOwner ?? "";
|
|
21127
|
+
const where = `${repo}#${raw.number}`;
|
|
21128
|
+
if (raw.labels?.pageInfo?.hasNextPage) {
|
|
21129
|
+
throw new Error(
|
|
21130
|
+
`${where} carries more than 100 labels, which is not supported`
|
|
21131
|
+
);
|
|
21132
|
+
}
|
|
21133
|
+
if (raw.subIssues?.pageInfo?.hasNextPage) {
|
|
21134
|
+
throw new Error(
|
|
21135
|
+
`${where} has more than 100 sub-issues, which is not supported`
|
|
21136
|
+
);
|
|
21137
|
+
}
|
|
21138
|
+
return {
|
|
21139
|
+
id: raw.id,
|
|
21140
|
+
number: raw.number,
|
|
21141
|
+
title: raw.title,
|
|
21142
|
+
repo,
|
|
21143
|
+
typeName: raw.issueType?.name ?? null,
|
|
21144
|
+
labels: (raw.labels?.nodes ?? []).filter((label2) => label2 !== null),
|
|
21145
|
+
childIds: (raw.subIssues?.nodes ?? []).filter((child) => child !== null).map((child) => child.id)
|
|
21146
|
+
};
|
|
21147
|
+
}
|
|
21148
|
+
|
|
21149
|
+
// src/commands/github/issue/fixStructure/fetchRootIssue.ts
|
|
21150
|
+
var QUERY = `query($owner: String!, $repo: String!, $number: Int!) {
|
|
21151
|
+
repository(owner: $owner, name: $repo) {
|
|
21152
|
+
issue(number: $number) { ...issueFields }
|
|
21153
|
+
}
|
|
21154
|
+
}
|
|
21155
|
+
${issueFieldsFragment}`;
|
|
21156
|
+
function fetchRootIssue(target) {
|
|
21157
|
+
const raw = runGhGraphqlJson(QUERY, {
|
|
21158
|
+
owner: target.owner,
|
|
21159
|
+
repo: target.repo,
|
|
21160
|
+
number: target.number
|
|
21161
|
+
});
|
|
21162
|
+
const issue = JSON.parse(raw).data?.repository?.issue;
|
|
21163
|
+
if (!issue) {
|
|
21164
|
+
throw new Error(
|
|
21165
|
+
`No issue ${target.owner}/${target.repo}#${target.number} could be read`
|
|
21166
|
+
);
|
|
21167
|
+
}
|
|
21168
|
+
return parseIssueNode(issue);
|
|
21169
|
+
}
|
|
21170
|
+
|
|
21171
|
+
// src/commands/github/issue/fixStructure/printFixStructurePlan.ts
|
|
21172
|
+
import chalk162 from "chalk";
|
|
21173
|
+
function annotate(entry) {
|
|
21174
|
+
const notes = [];
|
|
21175
|
+
if (entry.level === null) {
|
|
21176
|
+
notes.push(chalk162.red("deeper than the leaf level"));
|
|
21177
|
+
} else if (entry.typeChange) {
|
|
21178
|
+
notes.push(
|
|
21179
|
+
chalk162.yellow(
|
|
21180
|
+
`${entry.typeChange.from ?? "no type"} -> ${entry.typeChange.to}`
|
|
21181
|
+
)
|
|
21182
|
+
);
|
|
21183
|
+
} else {
|
|
21184
|
+
notes.push(chalk162.dim(entry.issue.typeName ?? "no type"));
|
|
21185
|
+
}
|
|
21186
|
+
for (const label2 of entry.labelRemovals) {
|
|
21187
|
+
notes.push(chalk162.yellow(`-${label2.name}`));
|
|
21188
|
+
}
|
|
21189
|
+
return notes;
|
|
21190
|
+
}
|
|
21191
|
+
function formatCount(count8, noun) {
|
|
21192
|
+
return `${count8} ${noun}${count8 === 1 ? "" : "s"}`;
|
|
21193
|
+
}
|
|
21194
|
+
function printFixStructurePlan(plan2, chain2) {
|
|
21195
|
+
console.log(chalk162.dim(`chain: ${chain2.join(" > ")}`));
|
|
21196
|
+
for (const entry of plan2.entries) {
|
|
21197
|
+
const indent3 = " ".repeat(entry.issue.depth);
|
|
21198
|
+
const name = chalk162.cyan(`${entry.issue.repo}#${entry.issue.number}`);
|
|
21199
|
+
console.log(
|
|
21200
|
+
`${indent3}${name} ${entry.issue.title} [${annotate(entry).join(", ")}]`
|
|
21201
|
+
);
|
|
21202
|
+
}
|
|
21203
|
+
for (const { issue, parent } of plan2.tooDeep) {
|
|
21204
|
+
const where = parent ? ` under ${parent.repo}#${parent.number}` : "";
|
|
21205
|
+
console.error(
|
|
21206
|
+
chalk162.red(
|
|
21207
|
+
`${issue.repo}#${issue.number}${where} sits below ${chain2[chain2.length - 1]}, the leaf level`
|
|
21208
|
+
)
|
|
21209
|
+
);
|
|
21210
|
+
}
|
|
21211
|
+
if (plan2.typeChangeCount === 0 && plan2.labelRemovalCount === 0) {
|
|
21212
|
+
console.log(chalk162.green("Nothing to change"));
|
|
21213
|
+
return;
|
|
21214
|
+
}
|
|
21215
|
+
console.log(
|
|
21216
|
+
`${formatCount(plan2.typeChangeCount, "type change")}, ${formatCount(plan2.labelRemovalCount, "label removal")} planned`
|
|
20952
21217
|
);
|
|
20953
|
-
|
|
21218
|
+
console.log(chalk162.dim("Dry run \u2014 nothing written"));
|
|
21219
|
+
}
|
|
21220
|
+
|
|
21221
|
+
// src/commands/github/issue/fixStructure/resolveFixStructureTarget.ts
|
|
21222
|
+
var BARE_NUMBER = /^#?(\d+)$/;
|
|
21223
|
+
var REPO_SLUG = /^([^/\s]+)\/([^/\s]+)$/;
|
|
21224
|
+
function resolveFixStructureTarget(target, repo) {
|
|
21225
|
+
const shorthand = normalizeGithubIssue(target);
|
|
21226
|
+
if (shorthand) {
|
|
21227
|
+
const [slug2, number] = shorthand.split("#");
|
|
21228
|
+
const [owner, name] = (slug2 ?? "").split("/");
|
|
21229
|
+
return { owner: owner ?? "", repo: name ?? "", number: Number(number) };
|
|
21230
|
+
}
|
|
21231
|
+
const bare = BARE_NUMBER.exec(target.trim());
|
|
21232
|
+
if (!bare) {
|
|
21233
|
+
throw new Error(
|
|
21234
|
+
`Could not read "${target}" as a GitHub issue. Pass owner/repo#number, a github.com issue URL, or a bare number with --repo owner/repo`
|
|
21235
|
+
);
|
|
21236
|
+
}
|
|
21237
|
+
if (!repo) {
|
|
21238
|
+
throw new Error(
|
|
21239
|
+
`A bare issue number needs a repository. Re-run with --repo owner/repo, or pass the issue as owner/repo#${bare[1]}`
|
|
21240
|
+
);
|
|
21241
|
+
}
|
|
21242
|
+
const slug = REPO_SLUG.exec(repo.trim());
|
|
21243
|
+
if (!slug) {
|
|
21244
|
+
throw new Error(`--repo must be owner/repo, not "${repo}"`);
|
|
21245
|
+
}
|
|
21246
|
+
return {
|
|
21247
|
+
owner: slug[1] ?? "",
|
|
21248
|
+
repo: slug[2] ?? "",
|
|
21249
|
+
number: Number(bare[1])
|
|
21250
|
+
};
|
|
21251
|
+
}
|
|
21252
|
+
|
|
21253
|
+
// src/commands/github/issue/fixStructure/resolveOrgIssueTypes.ts
|
|
21254
|
+
var QUERY2 = `query($owner: String!) {
|
|
21255
|
+
organization(login: $owner) {
|
|
21256
|
+
issueTypes(first: 50) { nodes { id name } }
|
|
21257
|
+
}
|
|
21258
|
+
}`;
|
|
21259
|
+
function missingOrg(owner) {
|
|
21260
|
+
return new Error(
|
|
21261
|
+
`Issue types live on the organisation, and ${owner} is not one this token can read`
|
|
21262
|
+
);
|
|
21263
|
+
}
|
|
21264
|
+
function resolveOrgIssueTypes(owner) {
|
|
21265
|
+
let raw;
|
|
21266
|
+
try {
|
|
21267
|
+
raw = runGhGraphqlJson(QUERY2, { owner });
|
|
21268
|
+
} catch (error) {
|
|
21269
|
+
const message3 = error instanceof Error ? error.message : String(error);
|
|
21270
|
+
if (message3.includes("Could not resolve to an Organization")) {
|
|
21271
|
+
throw missingOrg(owner);
|
|
21272
|
+
}
|
|
21273
|
+
throw error;
|
|
21274
|
+
}
|
|
21275
|
+
const organization = JSON.parse(raw).data?.organization;
|
|
21276
|
+
if (!organization) throw missingOrg(owner);
|
|
21277
|
+
const types = (organization.issueTypes?.nodes ?? []).filter(
|
|
21278
|
+
(type) => type !== null
|
|
21279
|
+
);
|
|
21280
|
+
if (types.length === 0) {
|
|
21281
|
+
throw new Error(`The ${owner} organisation has no issue types defined`);
|
|
21282
|
+
}
|
|
21283
|
+
return types;
|
|
21284
|
+
}
|
|
21285
|
+
|
|
21286
|
+
// src/commands/github/issue/fixStructure/resolveRootLevelIndex.ts
|
|
21287
|
+
function resolveRootLevelIndex(chain2, targetTypeName, level) {
|
|
21288
|
+
if (level) {
|
|
21289
|
+
const index4 = resolveLevelIndex(chain2, level);
|
|
21290
|
+
if (index4 === -1) {
|
|
21291
|
+
throw new Error(
|
|
21292
|
+
`--level must name one of ${chain2.join(", ")}, not "${level}"`
|
|
21293
|
+
);
|
|
21294
|
+
}
|
|
21295
|
+
return { index: index4, asserted: true };
|
|
21296
|
+
}
|
|
21297
|
+
const index3 = resolveLevelIndex(chain2, targetTypeName);
|
|
21298
|
+
if (index3 === -1) {
|
|
21299
|
+
const has = targetTypeName ? `has the type ${targetTypeName}, which is not in the ${chain2.join(" > ")} chain` : "has no issue type";
|
|
21300
|
+
throw new Error(
|
|
21301
|
+
`The target ${has}, so its level cannot be inferred. Re-run with --level ${chain2.map((name) => name.toLowerCase()).join("|")} to assert where it sits.`
|
|
21302
|
+
);
|
|
21303
|
+
}
|
|
21304
|
+
return { index: index3, asserted: false };
|
|
21305
|
+
}
|
|
21306
|
+
|
|
21307
|
+
// src/commands/github/issue/fixStructure/types.ts
|
|
21308
|
+
var defaultTypeChain = ["Epic", "Story", "Subtask"];
|
|
21309
|
+
|
|
21310
|
+
// src/commands/github/issue/fixStructure/fetchSubtreeIssues.ts
|
|
21311
|
+
var QUERY3 = `query($ids: [ID!]!) {
|
|
21312
|
+
nodes(ids: $ids) { ... on Issue { ...issueFields } }
|
|
21313
|
+
}
|
|
21314
|
+
${issueFieldsFragment}`;
|
|
21315
|
+
var BATCH = 50;
|
|
21316
|
+
function fetchSubtreeIssues(ids) {
|
|
21317
|
+
const issues = [];
|
|
21318
|
+
for (let start3 = 0; start3 < ids.length; start3 += BATCH) {
|
|
21319
|
+
const raw = runGhGraphqlJson(QUERY3, {
|
|
21320
|
+
ids: ids.slice(start3, start3 + BATCH)
|
|
21321
|
+
});
|
|
21322
|
+
const nodes = JSON.parse(raw).data?.nodes ?? [];
|
|
21323
|
+
for (const node of nodes) {
|
|
21324
|
+
if (node) issues.push(parseIssueNode(node));
|
|
21325
|
+
}
|
|
21326
|
+
}
|
|
21327
|
+
return issues;
|
|
21328
|
+
}
|
|
21329
|
+
|
|
21330
|
+
// src/commands/github/issue/fixStructure/walkSubtree.ts
|
|
21331
|
+
function walkSubtree(root, maxDepth, fetchIssues = fetchSubtreeIssues) {
|
|
21332
|
+
const placed = [{ ...root, depth: 0, parentId: null }];
|
|
21333
|
+
const seen = /* @__PURE__ */ new Set([root.id]);
|
|
21334
|
+
let frontier = placed;
|
|
21335
|
+
for (let depth = 1; depth <= maxDepth && frontier.length > 0; depth += 1) {
|
|
21336
|
+
const parentOf2 = /* @__PURE__ */ new Map();
|
|
21337
|
+
for (const parent of frontier) {
|
|
21338
|
+
for (const childId of parent.childIds) {
|
|
21339
|
+
if (seen.has(childId)) continue;
|
|
21340
|
+
seen.add(childId);
|
|
21341
|
+
parentOf2.set(childId, parent.id);
|
|
21342
|
+
}
|
|
21343
|
+
}
|
|
21344
|
+
if (parentOf2.size === 0) break;
|
|
21345
|
+
const children = fetchIssues([...parentOf2.keys()]).map((issue) => ({
|
|
21346
|
+
...issue,
|
|
21347
|
+
depth,
|
|
21348
|
+
parentId: parentOf2.get(issue.id) ?? null
|
|
21349
|
+
}));
|
|
21350
|
+
placed.push(...children);
|
|
21351
|
+
frontier = children;
|
|
21352
|
+
}
|
|
21353
|
+
return placed;
|
|
21354
|
+
}
|
|
21355
|
+
|
|
21356
|
+
// src/commands/github/issue/fixStructure/fixStructure.ts
|
|
21357
|
+
function fixStructure(target, options2) {
|
|
21358
|
+
const chain2 = defaultTypeChain;
|
|
21359
|
+
try {
|
|
21360
|
+
const resolved = resolveFixStructureTarget(target, options2.repo);
|
|
21361
|
+
const root = fetchRootIssue(resolved);
|
|
21362
|
+
const { index: index3, asserted } = resolveRootLevelIndex(
|
|
21363
|
+
chain2,
|
|
21364
|
+
root.typeName,
|
|
21365
|
+
options2.level
|
|
21366
|
+
);
|
|
21367
|
+
const issueTypes = resolveOrgIssueTypes(resolved.owner);
|
|
21368
|
+
const issues = walkSubtree(root, chain2.length - index3);
|
|
21369
|
+
const plan2 = buildFixStructurePlan(issues, {
|
|
21370
|
+
chain: chain2,
|
|
21371
|
+
rootLevelIndex: index3,
|
|
21372
|
+
rootAsserted: asserted,
|
|
21373
|
+
issueTypes
|
|
21374
|
+
});
|
|
21375
|
+
printFixStructurePlan(plan2, chain2);
|
|
21376
|
+
} catch (error) {
|
|
21377
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
21378
|
+
process.exit(1);
|
|
21379
|
+
}
|
|
21380
|
+
}
|
|
21381
|
+
|
|
21382
|
+
// src/commands/github/issue/fixStructure/registerFixStructure.ts
|
|
21383
|
+
var chain = defaultTypeChain.join(" > ");
|
|
21384
|
+
var levels = defaultTypeChain.map((name) => name.toLowerCase()).join("|");
|
|
21385
|
+
function registerFixStructure(issueCommand) {
|
|
21386
|
+
issueCommand.command("fix-structure <target>").description("Report the issue type drift across one issue subtree").option(
|
|
21387
|
+
"-R, --repo <owner/repo>",
|
|
21388
|
+
"Repository a bare issue number belongs to"
|
|
21389
|
+
).option(
|
|
21390
|
+
"--level <level>",
|
|
21391
|
+
`The target's own position in the ${chain} chain, when it cannot be inferred from its type`
|
|
21392
|
+
).addHelpText(
|
|
21393
|
+
"after",
|
|
21394
|
+
`
|
|
21395
|
+
Walks the subtree reachable from <target> via sub-issues and reports the type each issue should carry: every level below the target is typed to the next level down the ${chain} chain. Nothing outside the subtree is ever read or written.
|
|
21396
|
+
The target's own level is inferred from its issue type, so aiming at a story types its children as subtasks. When the target's type is not in the chain the level cannot be inferred, and --level ${levels} asserts it instead \u2014 which also plans the target's own type.
|
|
21397
|
+
The target is owner/repo#number, a github.com issue URL, or a bare number with --repo.
|
|
21398
|
+
This reports only; nothing is written.`
|
|
21399
|
+
).action(fixStructure);
|
|
20954
21400
|
}
|
|
20955
21401
|
|
|
20956
21402
|
// src/commands/prs/readBodyArgument.ts
|
|
@@ -20977,9 +21423,12 @@ function registerGithubIssue(githubCommand) {
|
|
|
20977
21423
|
issueCommand.command("edit <number>").description("Edit an existing GitHub issue's body in the preview pane").option(
|
|
20978
21424
|
"-R, --repo <owner/repo>",
|
|
20979
21425
|
"Target repository (defaults to the current repo)"
|
|
21426
|
+
).option(
|
|
21427
|
+
"--fresh",
|
|
21428
|
+
"Discard any working file for the issue and re-fetch its body from GitHub"
|
|
20980
21429
|
).addHelpText(
|
|
20981
21430
|
"after",
|
|
20982
|
-
"\nFetches the issue's current body and opens it in the assist web preview pane, where it can be reworked before it is pushed back. Approving pushes the pane's markdown to the issue; nothing is pushed if the issue moved on GitHub after it was fetched, or outside a web session.\nOnly the body is touched \u2014 the title, labels, assignees and state are left alone."
|
|
21431
|
+
"\nFetches the issue's current body and opens it in the assist web preview pane, where it can be reworked before it is pushed back. Approving pushes the pane's markdown to the issue; nothing is pushed if the issue moved on GitHub after it was fetched, or outside a web session.\nRejecting writes the pane's markdown to a working file and names it: revise that file in place and re-run to preview the revision, which keeps any collapses already applied. A re-run resumes from the working file while the issue has not moved on GitHub; --fresh discards it and re-fetches.\nOnly the body is touched \u2014 the title, labels, assignees and state are left alone."
|
|
20983
21432
|
).action(editIssue);
|
|
20984
21433
|
issueCommand.command("comment <number>").description("Comment on a GitHub issue (body of - reads it from stdin)").option("--body <body>", "Comment body (- reads it from stdin)").option(
|
|
20985
21434
|
"-R, --repo <owner/repo>",
|
|
@@ -20995,6 +21444,7 @@ function registerGithubIssue(githubCommand) {
|
|
|
20995
21444
|
});
|
|
20996
21445
|
}
|
|
20997
21446
|
);
|
|
21447
|
+
registerFixStructure(issueCommand);
|
|
20998
21448
|
}
|
|
20999
21449
|
|
|
21000
21450
|
// src/commands/registerGithub.ts
|
|
@@ -21021,9 +21471,9 @@ async function countPendingHandovers(orm, origin) {
|
|
|
21021
21471
|
|
|
21022
21472
|
// src/commands/handover/migrateDiskHandovers.ts
|
|
21023
21473
|
import {
|
|
21024
|
-
existsSync as
|
|
21474
|
+
existsSync as existsSync49,
|
|
21025
21475
|
readdirSync as readdirSync10,
|
|
21026
|
-
readFileSync as
|
|
21476
|
+
readFileSync as readFileSync38,
|
|
21027
21477
|
rmSync as rmSync3,
|
|
21028
21478
|
statSync as statSync8
|
|
21029
21479
|
} from "fs";
|
|
@@ -21076,7 +21526,7 @@ function summariseHandoverContent(content) {
|
|
|
21076
21526
|
|
|
21077
21527
|
// src/commands/handover/migrateDiskHandovers.ts
|
|
21078
21528
|
function collectMarkdown(dir) {
|
|
21079
|
-
if (!
|
|
21529
|
+
if (!existsSync49(dir)) return [];
|
|
21080
21530
|
const out = [];
|
|
21081
21531
|
for (const entry of readdirSync10(dir, { withFileTypes: true })) {
|
|
21082
21532
|
const full = join53(dir, entry.name);
|
|
@@ -21086,7 +21536,7 @@ function collectMarkdown(dir) {
|
|
|
21086
21536
|
return out;
|
|
21087
21537
|
}
|
|
21088
21538
|
async function migrateFile(orm, origin, file, createdAt) {
|
|
21089
|
-
const content =
|
|
21539
|
+
const content = readFileSync38(file, "utf8");
|
|
21090
21540
|
await saveHandover(orm, {
|
|
21091
21541
|
origin,
|
|
21092
21542
|
summary: summariseHandoverContent(content),
|
|
@@ -21103,7 +21553,7 @@ async function migrateDiskHandovers(orm, origin, cwd = process.cwd()) {
|
|
|
21103
21553
|
migrated++;
|
|
21104
21554
|
}
|
|
21105
21555
|
const handoverPath = getHandoverPath(cwd);
|
|
21106
|
-
if (
|
|
21556
|
+
if (existsSync49(handoverPath)) {
|
|
21107
21557
|
await migrateFile(orm, origin, handoverPath, statSync8(handoverPath).mtime);
|
|
21108
21558
|
migrated++;
|
|
21109
21559
|
}
|
|
@@ -21234,7 +21684,7 @@ function registerHandover(program2) {
|
|
|
21234
21684
|
}
|
|
21235
21685
|
|
|
21236
21686
|
// src/commands/jira/acceptanceCriteria.ts
|
|
21237
|
-
import
|
|
21687
|
+
import chalk163 from "chalk";
|
|
21238
21688
|
|
|
21239
21689
|
// src/commands/jira/adfToText.ts
|
|
21240
21690
|
function renderInline(node) {
|
|
@@ -21301,7 +21751,7 @@ function acceptanceCriteria(issueKey) {
|
|
|
21301
21751
|
const parsed = fetchIssue(issueKey, field);
|
|
21302
21752
|
const acValue = parsed?.fields?.[field];
|
|
21303
21753
|
if (!acValue) {
|
|
21304
|
-
console.log(
|
|
21754
|
+
console.log(chalk163.yellow(`No acceptance criteria found on ${issueKey}.`));
|
|
21305
21755
|
return;
|
|
21306
21756
|
}
|
|
21307
21757
|
if (typeof acValue === "string") {
|
|
@@ -21367,14 +21817,14 @@ async function jiraAuth() {
|
|
|
21367
21817
|
}
|
|
21368
21818
|
|
|
21369
21819
|
// src/commands/jira/viewIssue.ts
|
|
21370
|
-
import
|
|
21820
|
+
import chalk164 from "chalk";
|
|
21371
21821
|
function viewIssue2(issueKey) {
|
|
21372
21822
|
const parsed = fetchIssue(issueKey, "summary,description");
|
|
21373
21823
|
const fields = parsed?.fields;
|
|
21374
21824
|
const summary = fields?.summary;
|
|
21375
21825
|
const description = fields?.description;
|
|
21376
21826
|
if (summary) {
|
|
21377
|
-
console.log(
|
|
21827
|
+
console.log(chalk164.bold(summary));
|
|
21378
21828
|
}
|
|
21379
21829
|
if (description) {
|
|
21380
21830
|
if (summary) console.log();
|
|
@@ -21388,7 +21838,7 @@ function viewIssue2(issueKey) {
|
|
|
21388
21838
|
}
|
|
21389
21839
|
if (!summary && !description) {
|
|
21390
21840
|
console.log(
|
|
21391
|
-
|
|
21841
|
+
chalk164.yellow(`No summary or description found on ${issueKey}.`)
|
|
21392
21842
|
);
|
|
21393
21843
|
}
|
|
21394
21844
|
}
|
|
@@ -21423,7 +21873,7 @@ import { randomUUID as randomUUID10 } from "crypto";
|
|
|
21423
21873
|
|
|
21424
21874
|
// src/commands/review/checkoutPr.ts
|
|
21425
21875
|
import { execFileSync as execFileSync12 } from "child_process";
|
|
21426
|
-
import
|
|
21876
|
+
import chalk165 from "chalk";
|
|
21427
21877
|
|
|
21428
21878
|
// src/commands/sessions/daemon/daemonLog.ts
|
|
21429
21879
|
var RING_CAPACITY = 1e3;
|
|
@@ -21460,7 +21910,7 @@ function canonicalTreePath(path80) {
|
|
|
21460
21910
|
}
|
|
21461
21911
|
|
|
21462
21912
|
// src/commands/sessions/daemon/worktree/createWorktree.ts
|
|
21463
|
-
import { existsSync as
|
|
21913
|
+
import { existsSync as existsSync50 } from "fs";
|
|
21464
21914
|
import { basename as basename16, dirname as dirname25 } from "path";
|
|
21465
21915
|
|
|
21466
21916
|
// src/commands/sessions/daemon/worktree/planAllocation.ts
|
|
@@ -21507,7 +21957,7 @@ function createWorktree(clone, strategy, boundTreeRoots2, preferredPath) {
|
|
|
21507
21957
|
const base = strategy.root ? expandTilde2(strategy.root) : dirname25(clone);
|
|
21508
21958
|
const registered = new Set(listWorktreePaths(clone));
|
|
21509
21959
|
const branches = new Set(listLocalBranches(clone));
|
|
21510
|
-
const isTaken = (candidate) => registered.has(candidate) ||
|
|
21960
|
+
const isTaken = (candidate) => registered.has(candidate) || existsSync50(candidate) || boundTreeRoots2.has(candidate) || branches.has(basename16(candidate));
|
|
21511
21961
|
const path80 = preferredPath && !isTaken(preferredPath) ? preferredPath : nextWorktreePath(clone, base, isTaken);
|
|
21512
21962
|
const start3 = worktreeStartPoint(clone, strategy.trunk);
|
|
21513
21963
|
gitSync(clone, [
|
|
@@ -21533,7 +21983,7 @@ function keptInTree(cwd, reason4) {
|
|
|
21533
21983
|
}
|
|
21534
21984
|
|
|
21535
21985
|
// src/commands/sessions/daemon/worktree/treeDurability.ts
|
|
21536
|
-
import { existsSync as
|
|
21986
|
+
import { existsSync as existsSync51 } from "fs";
|
|
21537
21987
|
var treeIsGone = { durable: true, gone: true };
|
|
21538
21988
|
function treeDurability(state) {
|
|
21539
21989
|
if (state.dirty) return { durable: false, reason: "uncommitted changes" };
|
|
@@ -21564,14 +22014,14 @@ function* durabilityProbes() {
|
|
|
21564
22014
|
});
|
|
21565
22015
|
}
|
|
21566
22016
|
async function checkDurability(cwd) {
|
|
21567
|
-
if (!
|
|
22017
|
+
if (!existsSync51(cwd)) return treeIsGone;
|
|
21568
22018
|
const probes = durabilityProbes();
|
|
21569
22019
|
let step2 = probes.next();
|
|
21570
22020
|
while (!step2.done) step2 = probes.next(await gitResult(cwd, step2.value));
|
|
21571
22021
|
return step2.value;
|
|
21572
22022
|
}
|
|
21573
22023
|
function checkDurabilitySync(cwd) {
|
|
21574
|
-
if (!
|
|
22024
|
+
if (!existsSync51(cwd)) return treeIsGone;
|
|
21575
22025
|
const probes = durabilityProbes();
|
|
21576
22026
|
let step2 = probes.next();
|
|
21577
22027
|
while (!step2.done) step2 = probes.next(gitSyncResult(cwd, step2.value));
|
|
@@ -21814,20 +22264,20 @@ function persistedTreeRoots() {
|
|
|
21814
22264
|
}
|
|
21815
22265
|
|
|
21816
22266
|
// src/commands/sessions/daemon/worktree/seedWorktree.ts
|
|
21817
|
-
import { copyFileSync, existsSync as
|
|
22267
|
+
import { copyFileSync, existsSync as existsSync53, mkdirSync as mkdirSync17 } from "fs";
|
|
21818
22268
|
import { dirname as dirname26, join as join56 } from "path";
|
|
21819
22269
|
|
|
21820
22270
|
// src/commands/sessions/daemon/worktree/runInstall.ts
|
|
21821
22271
|
import { spawn as spawn5 } from "child_process";
|
|
21822
22272
|
|
|
21823
22273
|
// src/commands/sessions/daemon/worktree/resolveInstallCommand.ts
|
|
21824
|
-
import { existsSync as
|
|
22274
|
+
import { existsSync as existsSync52 } from "fs";
|
|
21825
22275
|
import { join as join55 } from "path";
|
|
21826
22276
|
function detectInstallCommand(repoRoot2) {
|
|
21827
|
-
if (!
|
|
21828
|
-
if (
|
|
21829
|
-
if (
|
|
21830
|
-
if (
|
|
22277
|
+
if (!existsSync52(join55(repoRoot2, "package.json"))) return null;
|
|
22278
|
+
if (existsSync52(join55(repoRoot2, "pnpm-lock.yaml"))) return "pnpm install";
|
|
22279
|
+
if (existsSync52(join55(repoRoot2, "yarn.lock"))) return "yarn install";
|
|
22280
|
+
if (existsSync52(join55(repoRoot2, "bun.lockb"))) return "bun install";
|
|
21831
22281
|
return "npm install";
|
|
21832
22282
|
}
|
|
21833
22283
|
function resolveInstallCommand(repoRoot2, install) {
|
|
@@ -21940,7 +22390,7 @@ function seedWorktree(worktreePath, clone, onSeeded = () => {
|
|
|
21940
22390
|
function copyConfigFiles(worktreePath, clone, copy) {
|
|
21941
22391
|
for (const rel of copy) {
|
|
21942
22392
|
const src = join56(clone, rel);
|
|
21943
|
-
if (!
|
|
22393
|
+
if (!existsSync53(src)) continue;
|
|
21944
22394
|
const dest = join56(worktreePath, rel);
|
|
21945
22395
|
try {
|
|
21946
22396
|
mkdirSync17(dirname26(dest), { recursive: true });
|
|
@@ -22035,7 +22485,7 @@ async function checkoutPr(number) {
|
|
|
22035
22485
|
try {
|
|
22036
22486
|
execFileSync12("gh", ["pr", "checkout", number], { stdio: "inherit" });
|
|
22037
22487
|
} catch {
|
|
22038
|
-
console.error(
|
|
22488
|
+
console.error(chalk165.red(`gh pr checkout ${number} failed; aborting.`));
|
|
22039
22489
|
process.exit(1);
|
|
22040
22490
|
}
|
|
22041
22491
|
}
|
|
@@ -22172,15 +22622,15 @@ function registerList(program2) {
|
|
|
22172
22622
|
// src/commands/mermaid/index.ts
|
|
22173
22623
|
import { mkdirSync as mkdirSync18, readdirSync as readdirSync11 } from "fs";
|
|
22174
22624
|
import { resolve as resolve16 } from "path";
|
|
22175
|
-
import
|
|
22625
|
+
import chalk168 from "chalk";
|
|
22176
22626
|
|
|
22177
22627
|
// src/commands/mermaid/exportFile.ts
|
|
22178
|
-
import { readFileSync as
|
|
22628
|
+
import { readFileSync as readFileSync39, writeFileSync as writeFileSync32 } from "fs";
|
|
22179
22629
|
import { basename as basename17, extname as extname2, resolve as resolve15 } from "path";
|
|
22180
|
-
import
|
|
22630
|
+
import chalk167 from "chalk";
|
|
22181
22631
|
|
|
22182
22632
|
// src/commands/mermaid/renderBlock.ts
|
|
22183
|
-
import
|
|
22633
|
+
import chalk166 from "chalk";
|
|
22184
22634
|
async function renderBlock(krokiUrl, source) {
|
|
22185
22635
|
const response = await fetch(`${krokiUrl}/mermaid/svg`, {
|
|
22186
22636
|
method: "POST",
|
|
@@ -22189,7 +22639,7 @@ async function renderBlock(krokiUrl, source) {
|
|
|
22189
22639
|
});
|
|
22190
22640
|
if (!response.ok) {
|
|
22191
22641
|
console.error(
|
|
22192
|
-
|
|
22642
|
+
chalk166.red(
|
|
22193
22643
|
`Kroki request failed: ${response.status} ${response.statusText}`
|
|
22194
22644
|
)
|
|
22195
22645
|
);
|
|
@@ -22201,25 +22651,25 @@ async function renderBlock(krokiUrl, source) {
|
|
|
22201
22651
|
|
|
22202
22652
|
// src/commands/mermaid/exportFile.ts
|
|
22203
22653
|
async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
22204
|
-
const content =
|
|
22654
|
+
const content = readFileSync39(file, "utf8");
|
|
22205
22655
|
const blocks = extractMermaidBlocks(content);
|
|
22206
22656
|
const stem = basename17(file, extname2(file));
|
|
22207
22657
|
if (onlyIndex !== void 0) {
|
|
22208
22658
|
if (onlyIndex < 1 || onlyIndex > blocks.length) {
|
|
22209
22659
|
console.error(
|
|
22210
|
-
|
|
22660
|
+
chalk167.red(
|
|
22211
22661
|
`${file}: --index ${onlyIndex} out of range (file has ${blocks.length} diagram(s))`
|
|
22212
22662
|
)
|
|
22213
22663
|
);
|
|
22214
22664
|
process.exit(1);
|
|
22215
22665
|
}
|
|
22216
22666
|
console.log(
|
|
22217
|
-
|
|
22667
|
+
chalk167.gray(
|
|
22218
22668
|
`${file} \u2014 rendering diagram ${onlyIndex} of ${blocks.length}`
|
|
22219
22669
|
)
|
|
22220
22670
|
);
|
|
22221
22671
|
} else {
|
|
22222
|
-
console.log(
|
|
22672
|
+
console.log(chalk167.gray(`${file} \u2014 ${blocks.length} diagram(s)`));
|
|
22223
22673
|
}
|
|
22224
22674
|
for (const [i, source] of blocks.entries()) {
|
|
22225
22675
|
const idx = i + 1;
|
|
@@ -22227,7 +22677,7 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
|
|
|
22227
22677
|
const outPath = resolve15(outDir, `${stem}-${idx}.svg`);
|
|
22228
22678
|
const svg = await renderBlock(krokiUrl, source);
|
|
22229
22679
|
writeFileSync32(outPath, svg, "utf8");
|
|
22230
|
-
console.log(
|
|
22680
|
+
console.log(chalk167.green(` \u2192 ${outPath}`));
|
|
22231
22681
|
}
|
|
22232
22682
|
}
|
|
22233
22683
|
function extractMermaidBlocks(markdown) {
|
|
@@ -22243,18 +22693,18 @@ async function mermaidExport(file, options2 = {}) {
|
|
|
22243
22693
|
if (options2.index !== void 0) {
|
|
22244
22694
|
if (!Number.isInteger(options2.index) || options2.index < 1) {
|
|
22245
22695
|
console.error(
|
|
22246
|
-
|
|
22696
|
+
chalk168.red(`--index must be a positive integer (got ${options2.index})`)
|
|
22247
22697
|
);
|
|
22248
22698
|
process.exit(1);
|
|
22249
22699
|
}
|
|
22250
22700
|
if (!file) {
|
|
22251
|
-
console.error(
|
|
22701
|
+
console.error(chalk168.red("--index requires a file argument"));
|
|
22252
22702
|
process.exit(1);
|
|
22253
22703
|
}
|
|
22254
22704
|
}
|
|
22255
22705
|
const files = file ? [file] : readdirSync11(process.cwd()).filter((name) => name.toLowerCase().endsWith(".md")).sort();
|
|
22256
22706
|
if (files.length === 0) {
|
|
22257
|
-
console.log(
|
|
22707
|
+
console.log(chalk168.gray("No markdown files found in current directory."));
|
|
22258
22708
|
return;
|
|
22259
22709
|
}
|
|
22260
22710
|
for (const f of files) {
|
|
@@ -22281,7 +22731,7 @@ function registerMermaid(program2) {
|
|
|
22281
22731
|
import { mkdir as mkdir4 } from "fs/promises";
|
|
22282
22732
|
import { createServer as createServer2 } from "http";
|
|
22283
22733
|
import { dirname as dirname28 } from "path";
|
|
22284
|
-
import
|
|
22734
|
+
import chalk170 from "chalk";
|
|
22285
22735
|
|
|
22286
22736
|
// src/commands/netcap/corsHeaders.ts
|
|
22287
22737
|
var corsHeaders = {
|
|
@@ -22360,7 +22810,7 @@ function createNetcapHandler(options2) {
|
|
|
22360
22810
|
import { cp, readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
|
|
22361
22811
|
import { networkInterfaces } from "os";
|
|
22362
22812
|
import { join as join58 } from "path";
|
|
22363
|
-
import
|
|
22813
|
+
import chalk169 from "chalk";
|
|
22364
22814
|
|
|
22365
22815
|
// src/commands/netcap/netcapExtensionDir.ts
|
|
22366
22816
|
import { dirname as dirname27, join as join57 } from "path";
|
|
@@ -22404,7 +22854,7 @@ async function prepareExtensionForLoad(port, filter = "") {
|
|
|
22404
22854
|
const host = lanIPv4();
|
|
22405
22855
|
if (!host) {
|
|
22406
22856
|
console.log(
|
|
22407
|
-
|
|
22857
|
+
chalk169.yellow("could not determine the WSL IP for the extension")
|
|
22408
22858
|
);
|
|
22409
22859
|
await configureBackground(source, "127.0.0.1", port, filter);
|
|
22410
22860
|
return source;
|
|
@@ -22415,7 +22865,7 @@ async function prepareExtensionForLoad(port, filter = "") {
|
|
|
22415
22865
|
return WSL_WINDOWS_PATH;
|
|
22416
22866
|
} catch {
|
|
22417
22867
|
console.log(
|
|
22418
|
-
|
|
22868
|
+
chalk169.yellow(`could not copy extension to ${WSL_WINDOWS_PATH}`)
|
|
22419
22869
|
);
|
|
22420
22870
|
return source;
|
|
22421
22871
|
}
|
|
@@ -22448,30 +22898,30 @@ async function netcap(options2) {
|
|
|
22448
22898
|
let count8 = 0;
|
|
22449
22899
|
const handler = createNetcapHandler({
|
|
22450
22900
|
outPath,
|
|
22451
|
-
onPing: () => console.log(
|
|
22901
|
+
onPing: () => console.log(chalk170.dim("ping from extension")),
|
|
22452
22902
|
onCapture: (entry) => {
|
|
22453
22903
|
count8 += 1;
|
|
22454
22904
|
console.log(
|
|
22455
|
-
|
|
22456
|
-
|
|
22905
|
+
chalk170.green(`captured #${count8}`),
|
|
22906
|
+
chalk170.dim(`${entry.method ?? "?"} ${entry.url ?? "?"}`)
|
|
22457
22907
|
);
|
|
22458
22908
|
}
|
|
22459
22909
|
});
|
|
22460
22910
|
const server = createServer2(handler);
|
|
22461
22911
|
server.listen(port, () => {
|
|
22462
22912
|
console.log(
|
|
22463
|
-
|
|
22913
|
+
chalk170.bold(`netcap receiver listening on http://127.0.0.1:${port}`)
|
|
22464
22914
|
);
|
|
22465
|
-
console.log(
|
|
22915
|
+
console.log(chalk170.dim(`appending captures to ${outPath}`));
|
|
22466
22916
|
if (filter)
|
|
22467
|
-
console.log(
|
|
22468
|
-
console.log(
|
|
22469
|
-
console.log(
|
|
22917
|
+
console.log(chalk170.dim(`forwarding only URLs matching "${filter}"`));
|
|
22918
|
+
console.log(chalk170.dim(`load the unpacked extension from ${extensionPath}`));
|
|
22919
|
+
console.log(chalk170.dim("press Ctrl-C to stop"));
|
|
22470
22920
|
});
|
|
22471
22921
|
process.on("SIGINT", () => {
|
|
22472
22922
|
server.close();
|
|
22473
22923
|
console.log(
|
|
22474
|
-
|
|
22924
|
+
chalk170.bold(
|
|
22475
22925
|
`
|
|
22476
22926
|
netcap stopped \u2014 captured ${count8} ${count8 === 1 ? "entry" : "entries"} to ${outPath}`
|
|
22477
22927
|
)
|
|
@@ -22483,10 +22933,10 @@ netcap stopped \u2014 captured ${count8} ${count8 === 1 ? "entry" : "entries"} t
|
|
|
22483
22933
|
// src/commands/netcap/netcapExtract.ts
|
|
22484
22934
|
import { writeFileSync as writeFileSync33 } from "fs";
|
|
22485
22935
|
import { join as join61 } from "path";
|
|
22486
|
-
import
|
|
22936
|
+
import chalk171 from "chalk";
|
|
22487
22937
|
|
|
22488
22938
|
// src/commands/netcap/extractPostsFromCapture.ts
|
|
22489
|
-
import { readFileSync as
|
|
22939
|
+
import { readFileSync as readFileSync40 } from "fs";
|
|
22490
22940
|
|
|
22491
22941
|
// src/commands/netcap/parseRscRows.ts
|
|
22492
22942
|
var isRscRef = (v) => typeof v === "string" && /^\$[0-9a-fL@]/.test(v);
|
|
@@ -22882,7 +23332,7 @@ function extractVoyagerPosts(body) {
|
|
|
22882
23332
|
|
|
22883
23333
|
// src/commands/netcap/extractPostsFromCapture.ts
|
|
22884
23334
|
function captureEntries(captureFile) {
|
|
22885
|
-
const lines2 =
|
|
23335
|
+
const lines2 = readFileSync40(captureFile, "utf8").split("\n").filter(Boolean);
|
|
22886
23336
|
const entries = [];
|
|
22887
23337
|
for (const line of lines2) {
|
|
22888
23338
|
let entry;
|
|
@@ -22931,8 +23381,8 @@ function netcapExtract(file) {
|
|
|
22931
23381
|
writeFileSync33(outFile, `${JSON.stringify(posts, null, 2)}
|
|
22932
23382
|
`);
|
|
22933
23383
|
console.log(
|
|
22934
|
-
|
|
22935
|
-
|
|
23384
|
+
chalk171.green(`extracted ${posts.length} posts`),
|
|
23385
|
+
chalk171.dim(`-> ${outFile}`)
|
|
22936
23386
|
);
|
|
22937
23387
|
}
|
|
22938
23388
|
|
|
@@ -22953,7 +23403,7 @@ function registerNetcap(program2) {
|
|
|
22953
23403
|
}
|
|
22954
23404
|
|
|
22955
23405
|
// src/commands/news/add/index.ts
|
|
22956
|
-
import
|
|
23406
|
+
import chalk172 from "chalk";
|
|
22957
23407
|
import enquirer8 from "enquirer";
|
|
22958
23408
|
async function add2(url) {
|
|
22959
23409
|
if (!url) {
|
|
@@ -22975,10 +23425,10 @@ async function add2(url) {
|
|
|
22975
23425
|
const { orm } = await getReady();
|
|
22976
23426
|
const added = await addFeed(orm, url);
|
|
22977
23427
|
if (!added) {
|
|
22978
|
-
console.log(
|
|
23428
|
+
console.log(chalk172.yellow("Feed already exists"));
|
|
22979
23429
|
return;
|
|
22980
23430
|
}
|
|
22981
|
-
console.log(
|
|
23431
|
+
console.log(chalk172.green(`Added feed: ${url}`));
|
|
22982
23432
|
}
|
|
22983
23433
|
|
|
22984
23434
|
// src/commands/registerNews.ts
|
|
@@ -23025,7 +23475,7 @@ function registerPiHook(program2) {
|
|
|
23025
23475
|
}
|
|
23026
23476
|
|
|
23027
23477
|
// src/commands/prompts/printPromptsTable.ts
|
|
23028
|
-
import
|
|
23478
|
+
import chalk173 from "chalk";
|
|
23029
23479
|
function truncate(str, max) {
|
|
23030
23480
|
if (str.length <= max) return str;
|
|
23031
23481
|
return `${str.slice(0, max - 1)}\u2026`;
|
|
@@ -23043,14 +23493,14 @@ function printPromptsTable(rows) {
|
|
|
23043
23493
|
"Command".padEnd(commandWidth),
|
|
23044
23494
|
"Repos"
|
|
23045
23495
|
].join(" ");
|
|
23046
|
-
console.log(
|
|
23047
|
-
console.log(
|
|
23496
|
+
console.log(chalk173.dim(header));
|
|
23497
|
+
console.log(chalk173.dim("-".repeat(header.length)));
|
|
23048
23498
|
for (const row of rows) {
|
|
23049
23499
|
const count8 = String(row.count).padStart(countWidth);
|
|
23050
23500
|
const tool = row.tool.padEnd(toolWidth);
|
|
23051
23501
|
const command = truncate(row.command, 60).padEnd(commandWidth);
|
|
23052
23502
|
console.log(
|
|
23053
|
-
`${
|
|
23503
|
+
`${chalk173.yellow(count8)} ${tool} ${command} ${chalk173.dim(row.repos)}`
|
|
23054
23504
|
);
|
|
23055
23505
|
}
|
|
23056
23506
|
}
|
|
@@ -23456,7 +23906,7 @@ import { tmpdir as tmpdir6 } from "os";
|
|
|
23456
23906
|
import { join as join63 } from "path";
|
|
23457
23907
|
|
|
23458
23908
|
// src/commands/prs/loadCommentsCache.ts
|
|
23459
|
-
import { existsSync as
|
|
23909
|
+
import { existsSync as existsSync54, readFileSync as readFileSync41, unlinkSync as unlinkSync13 } from "fs";
|
|
23460
23910
|
import { parse as parse2 } from "yaml";
|
|
23461
23911
|
|
|
23462
23912
|
// src/commands/prs/commentsCachePath.ts
|
|
@@ -23476,24 +23926,24 @@ function commentsCachePath(org, repo, prNumber) {
|
|
|
23476
23926
|
// src/commands/prs/loadCommentsCache.ts
|
|
23477
23927
|
function loadCommentsCache(org, repo, prNumber) {
|
|
23478
23928
|
const cachePath = commentsCachePath(org, repo, prNumber);
|
|
23479
|
-
if (!
|
|
23929
|
+
if (!existsSync54(cachePath)) {
|
|
23480
23930
|
return null;
|
|
23481
23931
|
}
|
|
23482
|
-
const content =
|
|
23932
|
+
const content = readFileSync41(cachePath, "utf8");
|
|
23483
23933
|
return parse2(content);
|
|
23484
23934
|
}
|
|
23485
23935
|
function deleteCommentsCache(org, repo, prNumber) {
|
|
23486
23936
|
const cachePath = commentsCachePath(org, repo, prNumber);
|
|
23487
|
-
if (
|
|
23937
|
+
if (existsSync54(cachePath)) {
|
|
23488
23938
|
unlinkSync13(cachePath);
|
|
23489
23939
|
console.log("No more unresolved line comments. Cache dropped.");
|
|
23490
23940
|
}
|
|
23491
23941
|
}
|
|
23492
23942
|
|
|
23493
23943
|
// src/commands/prs/replyToComment.ts
|
|
23494
|
-
import { spawnSync as
|
|
23944
|
+
import { spawnSync as spawnSync6 } from "child_process";
|
|
23495
23945
|
function replyToComment(org, repo, prNumber, commentId, message3) {
|
|
23496
|
-
const result =
|
|
23946
|
+
const result = spawnSync6(
|
|
23497
23947
|
"gh",
|
|
23498
23948
|
[
|
|
23499
23949
|
"api",
|
|
@@ -23717,13 +24167,13 @@ function agentFooter(unresolvedCount) {
|
|
|
23717
24167
|
}
|
|
23718
24168
|
|
|
23719
24169
|
// src/commands/prs/listComments/commentStyle.ts
|
|
23720
|
-
import
|
|
24170
|
+
import chalk174 from "chalk";
|
|
23721
24171
|
var plain = (text18) => text18;
|
|
23722
24172
|
function colouredState(state) {
|
|
23723
24173
|
const label2 = `[${state}]`;
|
|
23724
|
-
if (state === "APPROVED") return
|
|
23725
|
-
if (state === "CHANGES_REQUESTED") return
|
|
23726
|
-
return
|
|
24174
|
+
if (state === "APPROVED") return chalk174.green(label2);
|
|
24175
|
+
if (state === "CHANGES_REQUESTED") return chalk174.red(label2);
|
|
24176
|
+
return chalk174.yellow(label2);
|
|
23727
24177
|
}
|
|
23728
24178
|
function commentStyle() {
|
|
23729
24179
|
if (isClaudeCode()) {
|
|
@@ -23737,9 +24187,9 @@ function commentStyle() {
|
|
|
23737
24187
|
};
|
|
23738
24188
|
}
|
|
23739
24189
|
return {
|
|
23740
|
-
cyan:
|
|
23741
|
-
bold:
|
|
23742
|
-
dim:
|
|
24190
|
+
cyan: chalk174.cyan,
|
|
24191
|
+
bold: chalk174.bold,
|
|
24192
|
+
dim: chalk174.dim,
|
|
23743
24193
|
state: colouredState,
|
|
23744
24194
|
diffHunk: true,
|
|
23745
24195
|
agent: false
|
|
@@ -23909,13 +24359,13 @@ import { execSync as execSync48 } from "child_process";
|
|
|
23909
24359
|
import enquirer9 from "enquirer";
|
|
23910
24360
|
|
|
23911
24361
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
23912
|
-
import
|
|
24362
|
+
import chalk175 from "chalk";
|
|
23913
24363
|
var STATUS_MAP = {
|
|
23914
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
23915
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
24364
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk175.magenta("merged"), date: pr.mergedAt } : null,
|
|
24365
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk175.red("closed"), date: pr.closedAt } : null
|
|
23916
24366
|
};
|
|
23917
24367
|
function defaultStatus(pr) {
|
|
23918
|
-
return { label:
|
|
24368
|
+
return { label: chalk175.green("opened"), date: pr.createdAt };
|
|
23919
24369
|
}
|
|
23920
24370
|
function getStatus2(pr) {
|
|
23921
24371
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -23924,11 +24374,11 @@ function formatDate(dateStr) {
|
|
|
23924
24374
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
23925
24375
|
}
|
|
23926
24376
|
function formatPrHeader(pr, status3) {
|
|
23927
|
-
return `${
|
|
24377
|
+
return `${chalk175.cyan(`#${pr.number}`)} ${pr.title} ${chalk175.dim(`(${pr.author.login},`)} ${status3.label} ${chalk175.dim(`${formatDate(status3.date)})`)}`;
|
|
23928
24378
|
}
|
|
23929
24379
|
function logPrDetails(pr) {
|
|
23930
24380
|
console.log(
|
|
23931
|
-
|
|
24381
|
+
chalk175.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
23932
24382
|
);
|
|
23933
24383
|
console.log();
|
|
23934
24384
|
}
|
|
@@ -24643,10 +25093,10 @@ function registerPrs(program2) {
|
|
|
24643
25093
|
}
|
|
24644
25094
|
|
|
24645
25095
|
// src/commands/ravendb/ravendbAuth.ts
|
|
24646
|
-
import
|
|
25096
|
+
import chalk181 from "chalk";
|
|
24647
25097
|
|
|
24648
25098
|
// src/shared/createConnectionAuth.ts
|
|
24649
|
-
import
|
|
25099
|
+
import chalk176 from "chalk";
|
|
24650
25100
|
function listConnections(connections, format) {
|
|
24651
25101
|
if (connections.length === 0) {
|
|
24652
25102
|
console.log("No connections configured.");
|
|
@@ -24659,7 +25109,7 @@ function listConnections(connections, format) {
|
|
|
24659
25109
|
function removeConnection(connections, name, save) {
|
|
24660
25110
|
const filtered = connections.filter((c) => c.name !== name);
|
|
24661
25111
|
if (filtered.length === connections.length) {
|
|
24662
|
-
console.error(
|
|
25112
|
+
console.error(chalk176.red(`Connection "${name}" not found.`));
|
|
24663
25113
|
process.exit(1);
|
|
24664
25114
|
}
|
|
24665
25115
|
save(filtered);
|
|
@@ -24705,15 +25155,15 @@ function saveConnections(connections) {
|
|
|
24705
25155
|
}
|
|
24706
25156
|
|
|
24707
25157
|
// src/commands/ravendb/promptConnection.ts
|
|
24708
|
-
import
|
|
25158
|
+
import chalk179 from "chalk";
|
|
24709
25159
|
|
|
24710
25160
|
// src/commands/ravendb/selectOpSecret.ts
|
|
24711
|
-
import
|
|
25161
|
+
import chalk178 from "chalk";
|
|
24712
25162
|
import Enquirer2 from "enquirer";
|
|
24713
25163
|
|
|
24714
25164
|
// src/commands/ravendb/searchItems.ts
|
|
24715
25165
|
import { execSync as execSync51 } from "child_process";
|
|
24716
|
-
import
|
|
25166
|
+
import chalk177 from "chalk";
|
|
24717
25167
|
function opExec(args) {
|
|
24718
25168
|
return execSync51(`op ${args}`, {
|
|
24719
25169
|
encoding: "utf8",
|
|
@@ -24726,7 +25176,7 @@ function searchItems(search2) {
|
|
|
24726
25176
|
items2 = JSON.parse(opExec("item list --format=json"));
|
|
24727
25177
|
} catch {
|
|
24728
25178
|
console.error(
|
|
24729
|
-
|
|
25179
|
+
chalk177.red(
|
|
24730
25180
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
24731
25181
|
)
|
|
24732
25182
|
);
|
|
@@ -24740,7 +25190,7 @@ function getItemFields(itemId2) {
|
|
|
24740
25190
|
const item = JSON.parse(opExec(`item get "${itemId2}" --format=json`));
|
|
24741
25191
|
return item.fields.filter((f) => f.reference && f.label);
|
|
24742
25192
|
} catch {
|
|
24743
|
-
console.error(
|
|
25193
|
+
console.error(chalk177.red("Failed to get item details from 1Password."));
|
|
24744
25194
|
process.exit(1);
|
|
24745
25195
|
}
|
|
24746
25196
|
}
|
|
@@ -24759,7 +25209,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
24759
25209
|
}).run();
|
|
24760
25210
|
const items2 = searchItems(search2);
|
|
24761
25211
|
if (items2.length === 0) {
|
|
24762
|
-
console.error(
|
|
25212
|
+
console.error(chalk178.red(`No items found matching "${search2}".`));
|
|
24763
25213
|
process.exit(1);
|
|
24764
25214
|
}
|
|
24765
25215
|
const itemId2 = await selectOne(
|
|
@@ -24768,7 +25218,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
24768
25218
|
);
|
|
24769
25219
|
const fields = getItemFields(itemId2);
|
|
24770
25220
|
if (fields.length === 0) {
|
|
24771
|
-
console.error(
|
|
25221
|
+
console.error(chalk178.red("No fields with references found on this item."));
|
|
24772
25222
|
process.exit(1);
|
|
24773
25223
|
}
|
|
24774
25224
|
const ref = await selectOne(
|
|
@@ -24782,7 +25232,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
24782
25232
|
async function promptConnection(existingNames) {
|
|
24783
25233
|
const name = await promptInput("name", "Connection name:");
|
|
24784
25234
|
if (existingNames.includes(name)) {
|
|
24785
|
-
console.error(
|
|
25235
|
+
console.error(chalk179.red(`Connection "${name}" already exists.`));
|
|
24786
25236
|
process.exit(1);
|
|
24787
25237
|
}
|
|
24788
25238
|
const url = await promptInput(
|
|
@@ -24791,22 +25241,22 @@ async function promptConnection(existingNames) {
|
|
|
24791
25241
|
);
|
|
24792
25242
|
const database = await promptInput("database", "Database name:");
|
|
24793
25243
|
if (!name || !url || !database) {
|
|
24794
|
-
console.error(
|
|
25244
|
+
console.error(chalk179.red("All fields are required."));
|
|
24795
25245
|
process.exit(1);
|
|
24796
25246
|
}
|
|
24797
25247
|
const apiKeyRef = await selectOpSecret();
|
|
24798
|
-
console.log(
|
|
25248
|
+
console.log(chalk179.dim(`Using: ${apiKeyRef}`));
|
|
24799
25249
|
return { name, url, database, apiKeyRef };
|
|
24800
25250
|
}
|
|
24801
25251
|
|
|
24802
25252
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
24803
|
-
import
|
|
25253
|
+
import chalk180 from "chalk";
|
|
24804
25254
|
function ravendbSetConnection(name) {
|
|
24805
25255
|
const raw = loadGlobalConfigRaw();
|
|
24806
25256
|
const ravendb = raw.ravendb ?? {};
|
|
24807
25257
|
const connections = ravendb.connections ?? [];
|
|
24808
25258
|
if (!connections.some((c) => c.name === name)) {
|
|
24809
|
-
console.error(
|
|
25259
|
+
console.error(chalk180.red(`Connection "${name}" not found.`));
|
|
24810
25260
|
console.error(
|
|
24811
25261
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
24812
25262
|
);
|
|
@@ -24822,16 +25272,16 @@ function ravendbSetConnection(name) {
|
|
|
24822
25272
|
var ravendbAuth = createConnectionAuth({
|
|
24823
25273
|
load: loadConnections,
|
|
24824
25274
|
save: saveConnections,
|
|
24825
|
-
format: (c) => `${
|
|
25275
|
+
format: (c) => `${chalk181.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
24826
25276
|
promptNew: promptConnection,
|
|
24827
25277
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
24828
25278
|
});
|
|
24829
25279
|
|
|
24830
25280
|
// src/commands/ravendb/ravendbCollections.ts
|
|
24831
|
-
import
|
|
25281
|
+
import chalk185 from "chalk";
|
|
24832
25282
|
|
|
24833
25283
|
// src/commands/ravendb/ravenFetch.ts
|
|
24834
|
-
import
|
|
25284
|
+
import chalk183 from "chalk";
|
|
24835
25285
|
|
|
24836
25286
|
// src/commands/ravendb/getAccessToken.ts
|
|
24837
25287
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -24868,10 +25318,10 @@ ${errorText}`
|
|
|
24868
25318
|
|
|
24869
25319
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
24870
25320
|
import { execSync as execSync52 } from "child_process";
|
|
24871
|
-
import
|
|
25321
|
+
import chalk182 from "chalk";
|
|
24872
25322
|
function resolveOpSecret(reference) {
|
|
24873
25323
|
if (!reference.startsWith("op://")) {
|
|
24874
|
-
console.error(
|
|
25324
|
+
console.error(chalk182.red(`Invalid secret reference: must start with op://`));
|
|
24875
25325
|
process.exit(1);
|
|
24876
25326
|
}
|
|
24877
25327
|
try {
|
|
@@ -24881,7 +25331,7 @@ function resolveOpSecret(reference) {
|
|
|
24881
25331
|
}).trim();
|
|
24882
25332
|
} catch {
|
|
24883
25333
|
console.error(
|
|
24884
|
-
|
|
25334
|
+
chalk182.red(
|
|
24885
25335
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
24886
25336
|
)
|
|
24887
25337
|
);
|
|
@@ -24908,7 +25358,7 @@ async function ravenFetch(connection, path80) {
|
|
|
24908
25358
|
if (!response.ok) {
|
|
24909
25359
|
const body = await response.text();
|
|
24910
25360
|
console.error(
|
|
24911
|
-
|
|
25361
|
+
chalk183.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
24912
25362
|
);
|
|
24913
25363
|
console.error(body.substring(0, 500));
|
|
24914
25364
|
process.exit(1);
|
|
@@ -24917,7 +25367,7 @@ async function ravenFetch(connection, path80) {
|
|
|
24917
25367
|
}
|
|
24918
25368
|
|
|
24919
25369
|
// src/commands/ravendb/resolveConnection.ts
|
|
24920
|
-
import
|
|
25370
|
+
import chalk184 from "chalk";
|
|
24921
25371
|
function loadRavendb() {
|
|
24922
25372
|
const raw = loadGlobalConfigRaw();
|
|
24923
25373
|
const ravendb = raw.ravendb;
|
|
@@ -24931,7 +25381,7 @@ function resolveConnection(name) {
|
|
|
24931
25381
|
const connectionName = name ?? defaultConnection;
|
|
24932
25382
|
if (!connectionName) {
|
|
24933
25383
|
console.error(
|
|
24934
|
-
|
|
25384
|
+
chalk184.red(
|
|
24935
25385
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
24936
25386
|
)
|
|
24937
25387
|
);
|
|
@@ -24939,7 +25389,7 @@ function resolveConnection(name) {
|
|
|
24939
25389
|
}
|
|
24940
25390
|
const connection = connections.find((c) => c.name === connectionName);
|
|
24941
25391
|
if (!connection) {
|
|
24942
|
-
console.error(
|
|
25392
|
+
console.error(chalk184.red(`Connection "${connectionName}" not found.`));
|
|
24943
25393
|
console.error(
|
|
24944
25394
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
24945
25395
|
);
|
|
@@ -24970,15 +25420,15 @@ async function ravendbCollections(connectionName) {
|
|
|
24970
25420
|
return;
|
|
24971
25421
|
}
|
|
24972
25422
|
for (const c of collections) {
|
|
24973
|
-
console.log(`${
|
|
25423
|
+
console.log(`${chalk185.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
24974
25424
|
}
|
|
24975
25425
|
}
|
|
24976
25426
|
|
|
24977
25427
|
// src/commands/ravendb/ravendbQuery.ts
|
|
24978
|
-
import
|
|
25428
|
+
import chalk187 from "chalk";
|
|
24979
25429
|
|
|
24980
25430
|
// src/commands/ravendb/fetchAllPages.ts
|
|
24981
|
-
import
|
|
25431
|
+
import chalk186 from "chalk";
|
|
24982
25432
|
|
|
24983
25433
|
// src/commands/ravendb/buildQueryPath.ts
|
|
24984
25434
|
function buildQueryPath(opts) {
|
|
@@ -25016,7 +25466,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
25016
25466
|
allResults.push(...results);
|
|
25017
25467
|
start3 += results.length;
|
|
25018
25468
|
process.stderr.write(
|
|
25019
|
-
`\r${
|
|
25469
|
+
`\r${chalk186.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
25020
25470
|
);
|
|
25021
25471
|
if (start3 >= totalResults) break;
|
|
25022
25472
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -25031,7 +25481,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
25031
25481
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
25032
25482
|
const resolved = resolveArgs(connectionName, collection);
|
|
25033
25483
|
if (!resolved.collection && !options2.query) {
|
|
25034
|
-
console.error(
|
|
25484
|
+
console.error(chalk187.red("Provide a collection name or --query filter."));
|
|
25035
25485
|
process.exit(1);
|
|
25036
25486
|
}
|
|
25037
25487
|
const { collection: col } = resolved;
|
|
@@ -25070,7 +25520,7 @@ import { spawn as spawn6 } from "child_process";
|
|
|
25070
25520
|
import * as path42 from "path";
|
|
25071
25521
|
|
|
25072
25522
|
// src/commands/refactor/logViolations.ts
|
|
25073
|
-
import
|
|
25523
|
+
import chalk188 from "chalk";
|
|
25074
25524
|
var DEFAULT_MAX_LINES2 = 100;
|
|
25075
25525
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES2) {
|
|
25076
25526
|
if (violations.length === 0) {
|
|
@@ -25079,43 +25529,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES2) {
|
|
|
25079
25529
|
}
|
|
25080
25530
|
return;
|
|
25081
25531
|
}
|
|
25082
|
-
console.error(
|
|
25532
|
+
console.error(chalk188.red(`
|
|
25083
25533
|
Refactor check failed:
|
|
25084
25534
|
`));
|
|
25085
|
-
console.error(
|
|
25535
|
+
console.error(chalk188.red(` The following files exceed ${maxLines} lines:
|
|
25086
25536
|
`));
|
|
25087
25537
|
for (const violation of violations) {
|
|
25088
|
-
console.error(
|
|
25538
|
+
console.error(chalk188.red(` ${violation.file} (${violation.lines} lines)`));
|
|
25089
25539
|
}
|
|
25090
25540
|
console.error(
|
|
25091
|
-
|
|
25541
|
+
chalk188.yellow(
|
|
25092
25542
|
`
|
|
25093
25543
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
25094
25544
|
way to refactor it, ignore it with:
|
|
25095
25545
|
`
|
|
25096
25546
|
)
|
|
25097
25547
|
);
|
|
25098
|
-
console.error(
|
|
25548
|
+
console.error(chalk188.gray(` assist refactor ignore <file>
|
|
25099
25549
|
`));
|
|
25100
25550
|
if (process.env.CLAUDECODE) {
|
|
25101
|
-
console.error(
|
|
25551
|
+
console.error(chalk188.cyan(`
|
|
25102
25552
|
## Extracting Code to New Files
|
|
25103
25553
|
`));
|
|
25104
25554
|
console.error(
|
|
25105
|
-
|
|
25555
|
+
chalk188.cyan(
|
|
25106
25556
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
25107
25557
|
`
|
|
25108
25558
|
)
|
|
25109
25559
|
);
|
|
25110
25560
|
console.error(
|
|
25111
|
-
|
|
25561
|
+
chalk188.cyan(
|
|
25112
25562
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
25113
25563
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
25114
25564
|
`
|
|
25115
25565
|
)
|
|
25116
25566
|
);
|
|
25117
25567
|
console.error(
|
|
25118
|
-
|
|
25568
|
+
chalk188.cyan(
|
|
25119
25569
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
25120
25570
|
domains, move it to a common/shared folder.
|
|
25121
25571
|
`
|
|
@@ -25271,7 +25721,7 @@ async function check(pattern2, options2) {
|
|
|
25271
25721
|
|
|
25272
25722
|
// src/commands/refactor/extract/index.ts
|
|
25273
25723
|
import path50 from "path";
|
|
25274
|
-
import
|
|
25724
|
+
import chalk191 from "chalk";
|
|
25275
25725
|
|
|
25276
25726
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
25277
25727
|
import { SyntaxKind as SyntaxKind4 } from "ts-morph";
|
|
@@ -25870,23 +26320,23 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
25870
26320
|
|
|
25871
26321
|
// src/commands/refactor/extract/displayPlan.ts
|
|
25872
26322
|
import path46 from "path";
|
|
25873
|
-
import
|
|
26323
|
+
import chalk189 from "chalk";
|
|
25874
26324
|
function section2(title) {
|
|
25875
26325
|
return `
|
|
25876
|
-
${
|
|
26326
|
+
${chalk189.cyan(title)}`;
|
|
25877
26327
|
}
|
|
25878
26328
|
function displayImporters(plan2, cwd) {
|
|
25879
26329
|
if (plan2.importersToUpdate.length === 0) return;
|
|
25880
26330
|
console.log(section2("Update importers:"));
|
|
25881
26331
|
for (const imp of plan2.importersToUpdate) {
|
|
25882
26332
|
const rel = path46.relative(cwd, imp.file.getFilePath());
|
|
25883
|
-
console.log(` ${
|
|
26333
|
+
console.log(` ${chalk189.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
25884
26334
|
}
|
|
25885
26335
|
}
|
|
25886
26336
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
25887
|
-
console.log(
|
|
26337
|
+
console.log(chalk189.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
25888
26338
|
`));
|
|
25889
|
-
console.log(` ${
|
|
26339
|
+
console.log(` ${chalk189.cyan("Functions to move:")}`);
|
|
25890
26340
|
for (const name of plan2.extractedNames) {
|
|
25891
26341
|
console.log(` ${name}`);
|
|
25892
26342
|
}
|
|
@@ -25920,7 +26370,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
25920
26370
|
|
|
25921
26371
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
25922
26372
|
import path49 from "path";
|
|
25923
|
-
import
|
|
26373
|
+
import chalk190 from "chalk";
|
|
25924
26374
|
import { Project as Project4 } from "ts-morph";
|
|
25925
26375
|
|
|
25926
26376
|
// src/commands/refactor/extract/findTsConfig.ts
|
|
@@ -26012,7 +26462,7 @@ function loadProjectFile(file) {
|
|
|
26012
26462
|
});
|
|
26013
26463
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
26014
26464
|
if (!sourceFile) {
|
|
26015
|
-
console.log(
|
|
26465
|
+
console.log(chalk190.red(`File not found in project: ${file}`));
|
|
26016
26466
|
process.exit(1);
|
|
26017
26467
|
}
|
|
26018
26468
|
return { project, sourceFile };
|
|
@@ -26035,19 +26485,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
26035
26485
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
26036
26486
|
if (options2.apply) {
|
|
26037
26487
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
26038
|
-
console.log(
|
|
26488
|
+
console.log(chalk191.green("\nExtraction complete"));
|
|
26039
26489
|
} else {
|
|
26040
|
-
console.log(
|
|
26490
|
+
console.log(chalk191.dim("\nDry run. Use --apply to execute."));
|
|
26041
26491
|
}
|
|
26042
26492
|
}
|
|
26043
26493
|
|
|
26044
26494
|
// src/commands/refactor/ignore.ts
|
|
26045
26495
|
import fs33 from "fs";
|
|
26046
|
-
import
|
|
26496
|
+
import chalk192 from "chalk";
|
|
26047
26497
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
26048
26498
|
function ignore2(file) {
|
|
26049
26499
|
if (!fs33.existsSync(file)) {
|
|
26050
|
-
console.error(
|
|
26500
|
+
console.error(chalk192.red(`Error: File does not exist: ${file}`));
|
|
26051
26501
|
process.exit(1);
|
|
26052
26502
|
}
|
|
26053
26503
|
const content = fs33.readFileSync(file, "utf8");
|
|
@@ -26063,7 +26513,7 @@ function ignore2(file) {
|
|
|
26063
26513
|
fs33.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
26064
26514
|
}
|
|
26065
26515
|
console.log(
|
|
26066
|
-
|
|
26516
|
+
chalk192.green(
|
|
26067
26517
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
26068
26518
|
)
|
|
26069
26519
|
);
|
|
@@ -26072,12 +26522,12 @@ function ignore2(file) {
|
|
|
26072
26522
|
// src/commands/refactor/rename/index.ts
|
|
26073
26523
|
import fs36 from "fs";
|
|
26074
26524
|
import path55 from "path";
|
|
26075
|
-
import
|
|
26525
|
+
import chalk195 from "chalk";
|
|
26076
26526
|
|
|
26077
26527
|
// src/commands/refactor/rename/applyRename.ts
|
|
26078
26528
|
import fs35 from "fs";
|
|
26079
26529
|
import path52 from "path";
|
|
26080
|
-
import
|
|
26530
|
+
import chalk193 from "chalk";
|
|
26081
26531
|
|
|
26082
26532
|
// src/commands/refactor/restructure/computeRewrites/index.ts
|
|
26083
26533
|
import path51 from "path";
|
|
@@ -26182,13 +26632,13 @@ function applyRename(rewrites, sourcePath, destPath, cwd) {
|
|
|
26182
26632
|
const updatedContents = applyRewrites(rewrites);
|
|
26183
26633
|
for (const [file, content] of updatedContents) {
|
|
26184
26634
|
fs35.writeFileSync(file, content, "utf8");
|
|
26185
|
-
console.log(
|
|
26635
|
+
console.log(chalk193.cyan(` Updated imports in ${path52.relative(cwd, file)}`));
|
|
26186
26636
|
}
|
|
26187
26637
|
const destDir = path52.dirname(destPath);
|
|
26188
26638
|
if (!fs35.existsSync(destDir)) fs35.mkdirSync(destDir, { recursive: true });
|
|
26189
26639
|
fs35.renameSync(sourcePath, destPath);
|
|
26190
26640
|
console.log(
|
|
26191
|
-
|
|
26641
|
+
chalk193.white(
|
|
26192
26642
|
` Moved ${path52.relative(cwd, sourcePath)} \u2192 ${path52.relative(cwd, destPath)}`
|
|
26193
26643
|
)
|
|
26194
26644
|
);
|
|
@@ -26275,16 +26725,16 @@ function computeRenameRewrites(sourcePath, destPath) {
|
|
|
26275
26725
|
|
|
26276
26726
|
// src/commands/refactor/rename/printRenamePreview.ts
|
|
26277
26727
|
import path54 from "path";
|
|
26278
|
-
import
|
|
26728
|
+
import chalk194 from "chalk";
|
|
26279
26729
|
function printRenamePreview(rewrites, cwd) {
|
|
26280
26730
|
for (const rewrite of rewrites) {
|
|
26281
26731
|
console.log(
|
|
26282
|
-
|
|
26732
|
+
chalk194.dim(
|
|
26283
26733
|
` ${path54.relative(cwd, rewrite.file)}: ${rewrite.oldSpecifier} \u2192 ${rewrite.newSpecifier}`
|
|
26284
26734
|
)
|
|
26285
26735
|
);
|
|
26286
26736
|
}
|
|
26287
|
-
console.log(
|
|
26737
|
+
console.log(chalk194.dim("Dry run. Use --apply to execute."));
|
|
26288
26738
|
}
|
|
26289
26739
|
|
|
26290
26740
|
// src/commands/refactor/rename/index.ts
|
|
@@ -26295,20 +26745,20 @@ async function rename(source, destination, options2 = {}) {
|
|
|
26295
26745
|
const relSource = path55.relative(cwd, sourcePath);
|
|
26296
26746
|
const relDest = path55.relative(cwd, destPath);
|
|
26297
26747
|
if (!fs36.existsSync(sourcePath)) {
|
|
26298
|
-
console.log(
|
|
26748
|
+
console.log(chalk195.red(`File not found: ${source}`));
|
|
26299
26749
|
process.exit(1);
|
|
26300
26750
|
}
|
|
26301
26751
|
if (destPath !== sourcePath && fs36.existsSync(destPath)) {
|
|
26302
|
-
console.log(
|
|
26752
|
+
console.log(chalk195.red(`Destination already exists: ${destination}`));
|
|
26303
26753
|
process.exit(1);
|
|
26304
26754
|
}
|
|
26305
|
-
console.log(
|
|
26306
|
-
console.log(
|
|
26307
|
-
console.log(
|
|
26755
|
+
console.log(chalk195.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
26756
|
+
console.log(chalk195.dim("Loading project..."));
|
|
26757
|
+
console.log(chalk195.dim("Scanning imports across the project..."));
|
|
26308
26758
|
const rewrites = computeRenameRewrites(sourcePath, destPath);
|
|
26309
26759
|
const affectedFiles = new Set(rewrites.map((r) => r.file)).size;
|
|
26310
26760
|
console.log(
|
|
26311
|
-
|
|
26761
|
+
chalk195.dim(
|
|
26312
26762
|
`${rewrites.length} import path(s) to update across ${affectedFiles} file(s)`
|
|
26313
26763
|
)
|
|
26314
26764
|
);
|
|
@@ -26317,11 +26767,11 @@ async function rename(source, destination, options2 = {}) {
|
|
|
26317
26767
|
return;
|
|
26318
26768
|
}
|
|
26319
26769
|
applyRename(rewrites, sourcePath, destPath, cwd);
|
|
26320
|
-
console.log(
|
|
26770
|
+
console.log(chalk195.green("Done"));
|
|
26321
26771
|
}
|
|
26322
26772
|
|
|
26323
26773
|
// src/commands/refactor/renameSymbol/index.ts
|
|
26324
|
-
import
|
|
26774
|
+
import chalk196 from "chalk";
|
|
26325
26775
|
|
|
26326
26776
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
26327
26777
|
import { SyntaxKind as SyntaxKind15 } from "ts-morph";
|
|
@@ -26367,33 +26817,33 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
26367
26817
|
const { project, sourceFile } = loadProjectFile(file);
|
|
26368
26818
|
const symbol = findSymbol(sourceFile, oldName);
|
|
26369
26819
|
if (!symbol) {
|
|
26370
|
-
console.log(
|
|
26820
|
+
console.log(chalk196.red(`Symbol "${oldName}" not found in ${file}`));
|
|
26371
26821
|
process.exit(1);
|
|
26372
26822
|
}
|
|
26373
26823
|
const grouped = groupReferences(symbol, cwd);
|
|
26374
26824
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
26375
26825
|
console.log(
|
|
26376
|
-
|
|
26826
|
+
chalk196.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
26377
26827
|
`)
|
|
26378
26828
|
);
|
|
26379
26829
|
for (const [refFile, lines2] of grouped) {
|
|
26380
26830
|
console.log(
|
|
26381
|
-
` ${
|
|
26831
|
+
` ${chalk196.dim(refFile)}: lines ${chalk196.cyan(lines2.join(", "))}`
|
|
26382
26832
|
);
|
|
26383
26833
|
}
|
|
26384
26834
|
if (options2.apply) {
|
|
26385
26835
|
symbol.rename(newName);
|
|
26386
26836
|
await project.save();
|
|
26387
|
-
console.log(
|
|
26837
|
+
console.log(chalk196.green(`
|
|
26388
26838
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
26389
26839
|
} else {
|
|
26390
|
-
console.log(
|
|
26840
|
+
console.log(chalk196.dim("\nDry run. Use --apply to execute."));
|
|
26391
26841
|
}
|
|
26392
26842
|
}
|
|
26393
26843
|
|
|
26394
26844
|
// src/commands/refactor/restructure/index.ts
|
|
26395
26845
|
import path63 from "path";
|
|
26396
|
-
import
|
|
26846
|
+
import chalk199 from "chalk";
|
|
26397
26847
|
|
|
26398
26848
|
// src/commands/refactor/restructure/clusterDirectories.ts
|
|
26399
26849
|
import path57 from "path";
|
|
@@ -26472,50 +26922,50 @@ function clusterFiles(graph) {
|
|
|
26472
26922
|
|
|
26473
26923
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
26474
26924
|
import path59 from "path";
|
|
26475
|
-
import
|
|
26925
|
+
import chalk197 from "chalk";
|
|
26476
26926
|
function relPath(filePath) {
|
|
26477
26927
|
return path59.relative(process.cwd(), filePath);
|
|
26478
26928
|
}
|
|
26479
26929
|
function displayMoves(plan2) {
|
|
26480
26930
|
if (plan2.moves.length === 0) return;
|
|
26481
|
-
console.log(
|
|
26931
|
+
console.log(chalk197.bold("\nFile moves:"));
|
|
26482
26932
|
for (const move2 of plan2.moves) {
|
|
26483
26933
|
console.log(
|
|
26484
|
-
` ${
|
|
26934
|
+
` ${chalk197.red(relPath(move2.from))} \u2192 ${chalk197.green(relPath(move2.to))}`
|
|
26485
26935
|
);
|
|
26486
|
-
console.log(
|
|
26936
|
+
console.log(chalk197.dim(` ${move2.reason}`));
|
|
26487
26937
|
}
|
|
26488
26938
|
}
|
|
26489
26939
|
function displayRewrites(rewrites) {
|
|
26490
26940
|
if (rewrites.length === 0) return;
|
|
26491
26941
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
26492
|
-
console.log(
|
|
26942
|
+
console.log(chalk197.bold(`
|
|
26493
26943
|
Import rewrites (${affectedFiles.size} files):`));
|
|
26494
26944
|
for (const file of affectedFiles) {
|
|
26495
|
-
console.log(` ${
|
|
26945
|
+
console.log(` ${chalk197.cyan(relPath(file))}:`);
|
|
26496
26946
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
26497
26947
|
(r) => r.file === file
|
|
26498
26948
|
)) {
|
|
26499
26949
|
console.log(
|
|
26500
|
-
` ${
|
|
26950
|
+
` ${chalk197.red(`"${oldSpecifier}"`)} \u2192 ${chalk197.green(`"${newSpecifier}"`)}`
|
|
26501
26951
|
);
|
|
26502
26952
|
}
|
|
26503
26953
|
}
|
|
26504
26954
|
}
|
|
26505
26955
|
function displayPlan2(plan2) {
|
|
26506
26956
|
if (plan2.warnings.length > 0) {
|
|
26507
|
-
console.log(
|
|
26508
|
-
for (const w of plan2.warnings) console.log(
|
|
26957
|
+
console.log(chalk197.yellow("\nWarnings:"));
|
|
26958
|
+
for (const w of plan2.warnings) console.log(chalk197.yellow(` ${w}`));
|
|
26509
26959
|
}
|
|
26510
26960
|
if (plan2.newDirectories.length > 0) {
|
|
26511
|
-
console.log(
|
|
26961
|
+
console.log(chalk197.bold("\nNew directories:"));
|
|
26512
26962
|
for (const dir of plan2.newDirectories)
|
|
26513
|
-
console.log(
|
|
26963
|
+
console.log(chalk197.green(` ${dir}/`));
|
|
26514
26964
|
}
|
|
26515
26965
|
displayMoves(plan2);
|
|
26516
26966
|
displayRewrites(plan2.rewrites);
|
|
26517
26967
|
console.log(
|
|
26518
|
-
|
|
26968
|
+
chalk197.dim(
|
|
26519
26969
|
`
|
|
26520
26970
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
26521
26971
|
)
|
|
@@ -26525,18 +26975,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
26525
26975
|
// src/commands/refactor/restructure/executePlan.ts
|
|
26526
26976
|
import fs37 from "fs";
|
|
26527
26977
|
import path60 from "path";
|
|
26528
|
-
import
|
|
26978
|
+
import chalk198 from "chalk";
|
|
26529
26979
|
function executePlan(plan2) {
|
|
26530
26980
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
26531
26981
|
for (const [file, content] of updatedContents) {
|
|
26532
26982
|
fs37.writeFileSync(file, content, "utf8");
|
|
26533
26983
|
console.log(
|
|
26534
|
-
|
|
26984
|
+
chalk198.cyan(` Rewrote imports in ${path60.relative(process.cwd(), file)}`)
|
|
26535
26985
|
);
|
|
26536
26986
|
}
|
|
26537
26987
|
for (const dir of plan2.newDirectories) {
|
|
26538
26988
|
fs37.mkdirSync(dir, { recursive: true });
|
|
26539
|
-
console.log(
|
|
26989
|
+
console.log(chalk198.green(` Created ${path60.relative(process.cwd(), dir)}/`));
|
|
26540
26990
|
}
|
|
26541
26991
|
for (const move2 of plan2.moves) {
|
|
26542
26992
|
const targetDir = path60.dirname(move2.to);
|
|
@@ -26545,7 +26995,7 @@ function executePlan(plan2) {
|
|
|
26545
26995
|
}
|
|
26546
26996
|
fs37.renameSync(move2.from, move2.to);
|
|
26547
26997
|
console.log(
|
|
26548
|
-
|
|
26998
|
+
chalk198.white(
|
|
26549
26999
|
` Moved ${path60.relative(process.cwd(), move2.from)} \u2192 ${path60.relative(process.cwd(), move2.to)}`
|
|
26550
27000
|
)
|
|
26551
27001
|
);
|
|
@@ -26560,7 +27010,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
26560
27010
|
if (entries.length === 0) {
|
|
26561
27011
|
fs37.rmdirSync(dir);
|
|
26562
27012
|
console.log(
|
|
26563
|
-
|
|
27013
|
+
chalk198.dim(
|
|
26564
27014
|
` Removed empty directory ${path60.relative(process.cwd(), dir)}`
|
|
26565
27015
|
)
|
|
26566
27016
|
);
|
|
@@ -26693,22 +27143,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
26693
27143
|
const targetPattern = pattern2 ?? "src";
|
|
26694
27144
|
const files = findSourceFiles2(targetPattern);
|
|
26695
27145
|
if (files.length === 0) {
|
|
26696
|
-
console.log(
|
|
27146
|
+
console.log(chalk199.yellow("No files found matching pattern"));
|
|
26697
27147
|
return;
|
|
26698
27148
|
}
|
|
26699
27149
|
const tsConfigPath = findTsConfig(path63.resolve(files[0]));
|
|
26700
27150
|
const plan2 = buildPlan3(files, tsConfigPath);
|
|
26701
27151
|
if (plan2.moves.length === 0) {
|
|
26702
|
-
console.log(
|
|
27152
|
+
console.log(chalk199.green("No restructuring needed"));
|
|
26703
27153
|
return;
|
|
26704
27154
|
}
|
|
26705
27155
|
displayPlan2(plan2);
|
|
26706
27156
|
if (options2.apply) {
|
|
26707
|
-
console.log(
|
|
27157
|
+
console.log(chalk199.bold("\nApplying changes..."));
|
|
26708
27158
|
executePlan(plan2);
|
|
26709
|
-
console.log(
|
|
27159
|
+
console.log(chalk199.green("\nRestructuring complete"));
|
|
26710
27160
|
} else {
|
|
26711
|
-
console.log(
|
|
27161
|
+
console.log(chalk199.dim("\nDry run. Use --apply to execute."));
|
|
26712
27162
|
}
|
|
26713
27163
|
}
|
|
26714
27164
|
|
|
@@ -27031,7 +27481,7 @@ function gatherContext() {
|
|
|
27031
27481
|
}
|
|
27032
27482
|
|
|
27033
27483
|
// src/commands/review/postReviewToPr.ts
|
|
27034
|
-
import { readFileSync as
|
|
27484
|
+
import { readFileSync as readFileSync42 } from "fs";
|
|
27035
27485
|
|
|
27036
27486
|
// src/commands/review/carriedUnanchoredFindings.ts
|
|
27037
27487
|
function carriedUnanchoredFindings(unanchored) {
|
|
@@ -27366,18 +27816,18 @@ function partitionFindingsByDiff(findings, index3) {
|
|
|
27366
27816
|
}
|
|
27367
27817
|
|
|
27368
27818
|
// src/commands/review/warnOutOfDiff.ts
|
|
27369
|
-
import
|
|
27819
|
+
import chalk200 from "chalk";
|
|
27370
27820
|
function warnOutOfDiff(outOfDiff) {
|
|
27371
27821
|
if (outOfDiff.length === 0) return;
|
|
27372
27822
|
console.warn(
|
|
27373
|
-
|
|
27823
|
+
chalk200.yellow(
|
|
27374
27824
|
`Moved ${outOfDiff.length} finding(s) whose lines fall outside the PR diff into the review body (GitHub cannot anchor a comment on these):`
|
|
27375
27825
|
)
|
|
27376
27826
|
);
|
|
27377
27827
|
for (const finding of outOfDiff) {
|
|
27378
27828
|
const range = finding.startLine !== void 0 ? `${finding.startLine}-${finding.line}` : `${finding.line}`;
|
|
27379
27829
|
console.warn(
|
|
27380
|
-
` ${
|
|
27830
|
+
` ${chalk200.yellow("\xB7")} ${finding.title} ${chalk200.dim(
|
|
27381
27831
|
`(${finding.file}:${range})`
|
|
27382
27832
|
)}`
|
|
27383
27833
|
);
|
|
@@ -27401,18 +27851,18 @@ function selectInDiffFindings(lineBound, prDiff) {
|
|
|
27401
27851
|
}
|
|
27402
27852
|
|
|
27403
27853
|
// src/commands/review/warnUnlocated.ts
|
|
27404
|
-
import
|
|
27854
|
+
import chalk201 from "chalk";
|
|
27405
27855
|
function warnUnlocated(unlocated) {
|
|
27406
27856
|
if (unlocated.length === 0) return;
|
|
27407
27857
|
console.warn(
|
|
27408
|
-
|
|
27858
|
+
chalk201.yellow(
|
|
27409
27859
|
`Moved ${unlocated.length} finding(s) without a parseable file:line into the review body:`
|
|
27410
27860
|
)
|
|
27411
27861
|
);
|
|
27412
27862
|
for (const finding of unlocated) {
|
|
27413
|
-
const where = finding.location ||
|
|
27863
|
+
const where = finding.location || chalk201.dim("missing");
|
|
27414
27864
|
console.warn(
|
|
27415
|
-
` ${
|
|
27865
|
+
` ${chalk201.yellow("\xB7")} ${finding.title} ${chalk201.dim(`(${where})`)}`
|
|
27416
27866
|
);
|
|
27417
27867
|
}
|
|
27418
27868
|
}
|
|
@@ -27479,7 +27929,7 @@ async function confirmPost(prNumber, work, options2) {
|
|
|
27479
27929
|
return promptConfirm(`Post ${work} to PR #${prNumber}?`, false);
|
|
27480
27930
|
}
|
|
27481
27931
|
async function postFindingsToPr(prInfo, synthesisPath, options2) {
|
|
27482
|
-
const markdown =
|
|
27932
|
+
const markdown = readFileSync42(synthesisPath, "utf8");
|
|
27483
27933
|
const { inDiff, unanchored } = selectPostableFindings(markdown, prInfo);
|
|
27484
27934
|
const carried = carriedUnanchoredFindings(unanchored);
|
|
27485
27935
|
if (inDiff.length === 0 && carried.length === 0) return NOTHING_POSTED;
|
|
@@ -27615,10 +28065,10 @@ async function handlePostSynthesis(synthesisPath, prInfo, options2) {
|
|
|
27615
28065
|
}
|
|
27616
28066
|
|
|
27617
28067
|
// src/commands/review/prepareReviewDir.ts
|
|
27618
|
-
import { existsSync as
|
|
28068
|
+
import { existsSync as existsSync55, mkdirSync as mkdirSync20, unlinkSync as unlinkSync17, writeFileSync as writeFileSync37 } from "fs";
|
|
27619
28069
|
function clearReviewFiles(paths) {
|
|
27620
28070
|
for (const path80 of [paths.claudePath, paths.codexPath, paths.synthesisPath]) {
|
|
27621
|
-
if (
|
|
28071
|
+
if (existsSync55(path80)) unlinkSync17(path80);
|
|
27622
28072
|
}
|
|
27623
28073
|
}
|
|
27624
28074
|
function prepareReviewDir(paths, requestBody, force) {
|
|
@@ -27744,9 +28194,9 @@ var MultiSpinner = class {
|
|
|
27744
28194
|
};
|
|
27745
28195
|
|
|
27746
28196
|
// src/commands/review/ensureCodexAvailable.ts
|
|
27747
|
-
import { spawnSync as
|
|
28197
|
+
import { spawnSync as spawnSync7 } from "child_process";
|
|
27748
28198
|
function runNpmInstall() {
|
|
27749
|
-
const result =
|
|
28199
|
+
const result = spawnSync7("npm", ["install", "-g", "@openai/codex"], {
|
|
27750
28200
|
stdio: "inherit",
|
|
27751
28201
|
shell: true
|
|
27752
28202
|
});
|
|
@@ -27845,7 +28295,7 @@ function printReviewerFailures(results) {
|
|
|
27845
28295
|
}
|
|
27846
28296
|
|
|
27847
28297
|
// src/commands/review/runAndSynthesise.ts
|
|
27848
|
-
import { existsSync as
|
|
28298
|
+
import { existsSync as existsSync57, unlinkSync as unlinkSync19 } from "fs";
|
|
27849
28299
|
|
|
27850
28300
|
// src/commands/review/buildReviewerStdin.ts
|
|
27851
28301
|
var REVIEW_PROMPT = `You are acting as a reviewer for a proposed code change made by another engineer. The full review request \u2014 branch, base, changed files, and unified diff \u2014 is in the request file whose absolute path is given below.
|
|
@@ -28274,7 +28724,7 @@ function resolveClaude(args) {
|
|
|
28274
28724
|
}
|
|
28275
28725
|
|
|
28276
28726
|
// src/commands/review/runCodexReviewer.ts
|
|
28277
|
-
import { existsSync as
|
|
28727
|
+
import { existsSync as existsSync56, unlinkSync as unlinkSync18 } from "fs";
|
|
28278
28728
|
|
|
28279
28729
|
// src/commands/review/parseCodexEvent.ts
|
|
28280
28730
|
function isItemStarted(value) {
|
|
@@ -28326,7 +28776,7 @@ async function runCodexReviewer(spec) {
|
|
|
28326
28776
|
reportReviewerToolUse(spec.name, event, spinner);
|
|
28327
28777
|
}
|
|
28328
28778
|
});
|
|
28329
|
-
if (result.exitCode !== 0 &&
|
|
28779
|
+
if (result.exitCode !== 0 && existsSync56(spec.outputPath)) {
|
|
28330
28780
|
unlinkSync18(spec.outputPath);
|
|
28331
28781
|
}
|
|
28332
28782
|
return finaliseReviewerRun({ ...spec, command }, spinner, result);
|
|
@@ -28368,7 +28818,7 @@ async function runReviewers(reviewDir, claudePath, codexPath, stdinPrompt, optio
|
|
|
28368
28818
|
}
|
|
28369
28819
|
|
|
28370
28820
|
// src/commands/review/synthesise.ts
|
|
28371
|
-
import { readFileSync as
|
|
28821
|
+
import { readFileSync as readFileSync43 } from "fs";
|
|
28372
28822
|
|
|
28373
28823
|
// src/commands/review/buildSynthesisStdin.ts
|
|
28374
28824
|
var SYNTHESIS_PROMPT = `You are consolidating two independent code reviews of the same change. The original review request is in request.md. The two reviews are in claude.md and codex.md in the current working directory.
|
|
@@ -28433,7 +28883,7 @@ Files:
|
|
|
28433
28883
|
|
|
28434
28884
|
// src/commands/review/synthesise.ts
|
|
28435
28885
|
function printSummary2(synthesisPath) {
|
|
28436
|
-
const markdown =
|
|
28886
|
+
const markdown = readFileSync43(synthesisPath, "utf8");
|
|
28437
28887
|
console.log("");
|
|
28438
28888
|
console.log(buildReviewSummary(markdown));
|
|
28439
28889
|
console.log("");
|
|
@@ -28481,7 +28931,7 @@ async function runAndSynthesise(args) {
|
|
|
28481
28931
|
console.error("Both reviewers failed; skipping synthesis.");
|
|
28482
28932
|
return { ok: false, failures };
|
|
28483
28933
|
}
|
|
28484
|
-
if (anyFresh &&
|
|
28934
|
+
if (anyFresh && existsSync57(paths.synthesisPath)) {
|
|
28485
28935
|
unlinkSync19(paths.synthesisPath);
|
|
28486
28936
|
}
|
|
28487
28937
|
const synthesisResult = await synthesise(paths, { multi });
|
|
@@ -28667,7 +29117,7 @@ function registerReview(program2) {
|
|
|
28667
29117
|
}
|
|
28668
29118
|
|
|
28669
29119
|
// src/commands/seq/seqAuth.ts
|
|
28670
|
-
import
|
|
29120
|
+
import chalk203 from "chalk";
|
|
28671
29121
|
|
|
28672
29122
|
// src/commands/seq/loadConnections.ts
|
|
28673
29123
|
function loadConnections2() {
|
|
@@ -28696,10 +29146,10 @@ function setDefaultConnection(name) {
|
|
|
28696
29146
|
}
|
|
28697
29147
|
|
|
28698
29148
|
// src/shared/assertUniqueName.ts
|
|
28699
|
-
import
|
|
29149
|
+
import chalk202 from "chalk";
|
|
28700
29150
|
function assertUniqueName(existingNames, name) {
|
|
28701
29151
|
if (existingNames.includes(name)) {
|
|
28702
|
-
console.error(
|
|
29152
|
+
console.error(chalk202.red(`Connection "${name}" already exists.`));
|
|
28703
29153
|
process.exit(1);
|
|
28704
29154
|
}
|
|
28705
29155
|
}
|
|
@@ -28717,16 +29167,16 @@ async function promptConnection2(existingNames) {
|
|
|
28717
29167
|
var seqAuth = createConnectionAuth({
|
|
28718
29168
|
load: loadConnections2,
|
|
28719
29169
|
save: saveConnections2,
|
|
28720
|
-
format: (c) => `${
|
|
29170
|
+
format: (c) => `${chalk203.bold(c.name)} ${c.url}`,
|
|
28721
29171
|
promptNew: promptConnection2,
|
|
28722
29172
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
28723
29173
|
});
|
|
28724
29174
|
|
|
28725
29175
|
// src/commands/seq/seqQuery.ts
|
|
28726
|
-
import
|
|
29176
|
+
import chalk207 from "chalk";
|
|
28727
29177
|
|
|
28728
29178
|
// src/commands/seq/fetchSeq.ts
|
|
28729
|
-
import
|
|
29179
|
+
import chalk204 from "chalk";
|
|
28730
29180
|
async function fetchSeq(conn, path80, params) {
|
|
28731
29181
|
const url = `${conn.url}${path80}?${params}`;
|
|
28732
29182
|
const response = await fetch(url, {
|
|
@@ -28737,7 +29187,7 @@ async function fetchSeq(conn, path80, params) {
|
|
|
28737
29187
|
});
|
|
28738
29188
|
if (!response.ok) {
|
|
28739
29189
|
const body = await response.text();
|
|
28740
|
-
console.error(
|
|
29190
|
+
console.error(chalk204.red(`Seq returned ${response.status}: ${body}`));
|
|
28741
29191
|
process.exit(1);
|
|
28742
29192
|
}
|
|
28743
29193
|
return response;
|
|
@@ -28796,23 +29246,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
28796
29246
|
}
|
|
28797
29247
|
|
|
28798
29248
|
// src/commands/seq/formatEvent.ts
|
|
28799
|
-
import
|
|
29249
|
+
import chalk205 from "chalk";
|
|
28800
29250
|
function levelColor(level) {
|
|
28801
29251
|
switch (level) {
|
|
28802
29252
|
case "Fatal":
|
|
28803
|
-
return
|
|
29253
|
+
return chalk205.bgRed.white;
|
|
28804
29254
|
case "Error":
|
|
28805
|
-
return
|
|
29255
|
+
return chalk205.red;
|
|
28806
29256
|
case "Warning":
|
|
28807
|
-
return
|
|
29257
|
+
return chalk205.yellow;
|
|
28808
29258
|
case "Information":
|
|
28809
|
-
return
|
|
29259
|
+
return chalk205.cyan;
|
|
28810
29260
|
case "Debug":
|
|
28811
|
-
return
|
|
29261
|
+
return chalk205.gray;
|
|
28812
29262
|
case "Verbose":
|
|
28813
|
-
return
|
|
29263
|
+
return chalk205.dim;
|
|
28814
29264
|
default:
|
|
28815
|
-
return
|
|
29265
|
+
return chalk205.white;
|
|
28816
29266
|
}
|
|
28817
29267
|
}
|
|
28818
29268
|
function levelAbbrev(level) {
|
|
@@ -28853,12 +29303,12 @@ function formatTimestamp(iso) {
|
|
|
28853
29303
|
function formatEvent(event) {
|
|
28854
29304
|
const color = levelColor(event.Level);
|
|
28855
29305
|
const abbrev = levelAbbrev(event.Level);
|
|
28856
|
-
const ts8 =
|
|
29306
|
+
const ts8 = chalk205.dim(formatTimestamp(event.Timestamp));
|
|
28857
29307
|
const msg = renderMessage(event);
|
|
28858
29308
|
const lines2 = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
28859
29309
|
if (event.Exception) {
|
|
28860
29310
|
for (const line of event.Exception.split("\n")) {
|
|
28861
|
-
lines2.push(
|
|
29311
|
+
lines2.push(chalk205.red(` ${line}`));
|
|
28862
29312
|
}
|
|
28863
29313
|
}
|
|
28864
29314
|
return lines2.join("\n");
|
|
@@ -28891,11 +29341,11 @@ function rejectTimestampFilter(filter) {
|
|
|
28891
29341
|
}
|
|
28892
29342
|
|
|
28893
29343
|
// src/shared/resolveNamedConnection.ts
|
|
28894
|
-
import
|
|
29344
|
+
import chalk206 from "chalk";
|
|
28895
29345
|
function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
|
|
28896
29346
|
if (connections.length === 0) {
|
|
28897
29347
|
console.error(
|
|
28898
|
-
|
|
29348
|
+
chalk206.red(
|
|
28899
29349
|
`No ${kind} connections configured. Run '${authCommand}' first.`
|
|
28900
29350
|
)
|
|
28901
29351
|
);
|
|
@@ -28904,7 +29354,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
|
|
|
28904
29354
|
const target = requested ?? defaultName ?? connections[0].name;
|
|
28905
29355
|
const connection = connections.find((c) => c.name === target);
|
|
28906
29356
|
if (!connection) {
|
|
28907
|
-
console.error(
|
|
29357
|
+
console.error(chalk206.red(`${kind} connection "${target}" not found.`));
|
|
28908
29358
|
process.exit(1);
|
|
28909
29359
|
}
|
|
28910
29360
|
return connection;
|
|
@@ -28933,7 +29383,7 @@ async function seqQuery(filter, options2) {
|
|
|
28933
29383
|
new URLSearchParams({ filter, count: String(count8) })
|
|
28934
29384
|
);
|
|
28935
29385
|
if (events.length === 0) {
|
|
28936
|
-
console.log(
|
|
29386
|
+
console.log(chalk207.yellow("No events found."));
|
|
28937
29387
|
return;
|
|
28938
29388
|
}
|
|
28939
29389
|
if (options2.json) {
|
|
@@ -28944,11 +29394,11 @@ async function seqQuery(filter, options2) {
|
|
|
28944
29394
|
for (const event of chronological) {
|
|
28945
29395
|
console.log(formatEvent(event));
|
|
28946
29396
|
}
|
|
28947
|
-
console.log(
|
|
29397
|
+
console.log(chalk207.dim(`
|
|
28948
29398
|
${events.length} events`));
|
|
28949
29399
|
if (events.length >= count8) {
|
|
28950
29400
|
console.log(
|
|
28951
|
-
|
|
29401
|
+
chalk207.yellow(
|
|
28952
29402
|
`Results limited to ${count8}. Use --count to retrieve more.`
|
|
28953
29403
|
)
|
|
28954
29404
|
);
|
|
@@ -28956,10 +29406,10 @@ ${events.length} events`));
|
|
|
28956
29406
|
}
|
|
28957
29407
|
|
|
28958
29408
|
// src/shared/setNamedDefaultConnection.ts
|
|
28959
|
-
import
|
|
29409
|
+
import chalk208 from "chalk";
|
|
28960
29410
|
function setNamedDefaultConnection(connections, name, setDefault, kind) {
|
|
28961
29411
|
if (!connections.find((c) => c.name === name)) {
|
|
28962
|
-
console.error(
|
|
29412
|
+
console.error(chalk208.red(`Connection "${name}" not found.`));
|
|
28963
29413
|
process.exit(1);
|
|
28964
29414
|
}
|
|
28965
29415
|
setDefault(name);
|
|
@@ -29008,7 +29458,7 @@ function registerSignal(program2) {
|
|
|
29008
29458
|
}
|
|
29009
29459
|
|
|
29010
29460
|
// src/commands/sql/sqlAuth.ts
|
|
29011
|
-
import
|
|
29461
|
+
import chalk210 from "chalk";
|
|
29012
29462
|
|
|
29013
29463
|
// src/commands/sql/loadConnections.ts
|
|
29014
29464
|
function loadConnections3() {
|
|
@@ -29037,7 +29487,7 @@ function setDefaultConnection2(name) {
|
|
|
29037
29487
|
}
|
|
29038
29488
|
|
|
29039
29489
|
// src/commands/sql/promptConnection.ts
|
|
29040
|
-
import
|
|
29490
|
+
import chalk209 from "chalk";
|
|
29041
29491
|
async function promptConnection3(existingNames) {
|
|
29042
29492
|
const name = await promptInput("name", "Connection name:", "default");
|
|
29043
29493
|
assertUniqueName(existingNames, name);
|
|
@@ -29045,7 +29495,7 @@ async function promptConnection3(existingNames) {
|
|
|
29045
29495
|
const portStr = await promptInput("port", "Port:", "1433");
|
|
29046
29496
|
const port = Number.parseInt(portStr, 10);
|
|
29047
29497
|
if (!Number.isFinite(port)) {
|
|
29048
|
-
console.error(
|
|
29498
|
+
console.error(chalk209.red(`Invalid port "${portStr}".`));
|
|
29049
29499
|
process.exit(1);
|
|
29050
29500
|
}
|
|
29051
29501
|
const user = await promptInput("user", "User:");
|
|
@@ -29058,13 +29508,13 @@ async function promptConnection3(existingNames) {
|
|
|
29058
29508
|
var sqlAuth = createConnectionAuth({
|
|
29059
29509
|
load: loadConnections3,
|
|
29060
29510
|
save: saveConnections3,
|
|
29061
|
-
format: (c) => `${
|
|
29511
|
+
format: (c) => `${chalk210.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
|
|
29062
29512
|
promptNew: promptConnection3,
|
|
29063
29513
|
onFirst: (c) => setDefaultConnection2(c.name)
|
|
29064
29514
|
});
|
|
29065
29515
|
|
|
29066
29516
|
// src/commands/sql/printTable.ts
|
|
29067
|
-
import
|
|
29517
|
+
import chalk211 from "chalk";
|
|
29068
29518
|
function formatCell(value) {
|
|
29069
29519
|
if (value === null || value === void 0) return "";
|
|
29070
29520
|
if (value instanceof Date) return value.toISOString();
|
|
@@ -29073,7 +29523,7 @@ function formatCell(value) {
|
|
|
29073
29523
|
}
|
|
29074
29524
|
function printTable(rows) {
|
|
29075
29525
|
if (rows.length === 0) {
|
|
29076
|
-
console.log(
|
|
29526
|
+
console.log(chalk211.yellow("(no rows)"));
|
|
29077
29527
|
return;
|
|
29078
29528
|
}
|
|
29079
29529
|
const columns = Object.keys(rows[0]);
|
|
@@ -29081,13 +29531,13 @@ function printTable(rows) {
|
|
|
29081
29531
|
(col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
|
|
29082
29532
|
);
|
|
29083
29533
|
const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
|
|
29084
|
-
console.log(
|
|
29085
|
-
console.log(
|
|
29534
|
+
console.log(chalk211.dim(header));
|
|
29535
|
+
console.log(chalk211.dim("-".repeat(header.length)));
|
|
29086
29536
|
for (const row of rows) {
|
|
29087
29537
|
const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
|
|
29088
29538
|
console.log(line);
|
|
29089
29539
|
}
|
|
29090
|
-
console.log(
|
|
29540
|
+
console.log(chalk211.dim(`
|
|
29091
29541
|
${rows.length} row${rows.length === 1 ? "" : "s"}`));
|
|
29092
29542
|
}
|
|
29093
29543
|
|
|
@@ -29147,7 +29597,7 @@ async function sqlColumns(table, connectionName) {
|
|
|
29147
29597
|
}
|
|
29148
29598
|
|
|
29149
29599
|
// src/commands/sql/sqlMutate.ts
|
|
29150
|
-
import
|
|
29600
|
+
import chalk212 from "chalk";
|
|
29151
29601
|
|
|
29152
29602
|
// src/commands/sql/isMutation.ts
|
|
29153
29603
|
var MUTATION_KEYWORDS = [
|
|
@@ -29181,7 +29631,7 @@ function isMutation(sql25) {
|
|
|
29181
29631
|
async function sqlMutate(query, connectionName) {
|
|
29182
29632
|
if (!isMutation(query)) {
|
|
29183
29633
|
console.error(
|
|
29184
|
-
|
|
29634
|
+
chalk212.red(
|
|
29185
29635
|
"assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
|
|
29186
29636
|
)
|
|
29187
29637
|
);
|
|
@@ -29191,18 +29641,18 @@ async function sqlMutate(query, connectionName) {
|
|
|
29191
29641
|
const pool = await sqlConnect(conn);
|
|
29192
29642
|
try {
|
|
29193
29643
|
const result = await pool.request().query(query);
|
|
29194
|
-
console.log(
|
|
29644
|
+
console.log(chalk212.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
|
|
29195
29645
|
} finally {
|
|
29196
29646
|
await pool.close();
|
|
29197
29647
|
}
|
|
29198
29648
|
}
|
|
29199
29649
|
|
|
29200
29650
|
// src/commands/sql/sqlQuery.ts
|
|
29201
|
-
import
|
|
29651
|
+
import chalk213 from "chalk";
|
|
29202
29652
|
async function sqlQuery(query, connectionName) {
|
|
29203
29653
|
if (isMutation(query)) {
|
|
29204
29654
|
console.error(
|
|
29205
|
-
|
|
29655
|
+
chalk213.red(
|
|
29206
29656
|
"assist sql query refuses mutating statements. Use `assist sql mutate` instead."
|
|
29207
29657
|
)
|
|
29208
29658
|
);
|
|
@@ -29217,7 +29667,7 @@ async function sqlQuery(query, connectionName) {
|
|
|
29217
29667
|
printTable(rows);
|
|
29218
29668
|
} else {
|
|
29219
29669
|
console.log(
|
|
29220
|
-
|
|
29670
|
+
chalk213.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
|
|
29221
29671
|
);
|
|
29222
29672
|
}
|
|
29223
29673
|
} finally {
|
|
@@ -29362,7 +29812,7 @@ function reportPrune(label2, result, force) {
|
|
|
29362
29812
|
// src/commands/sync/syncClaudeMd.ts
|
|
29363
29813
|
import * as fs41 from "fs";
|
|
29364
29814
|
import * as path66 from "path";
|
|
29365
|
-
import
|
|
29815
|
+
import chalk214 from "chalk";
|
|
29366
29816
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
29367
29817
|
const source = path66.join(claudeDir, "CLAUDE.md");
|
|
29368
29818
|
const target = path66.join(targetBase, "CLAUDE.md");
|
|
@@ -29371,14 +29821,14 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
29371
29821
|
const targetContent = fs41.readFileSync(target, "utf8");
|
|
29372
29822
|
if (sourceContent !== targetContent) {
|
|
29373
29823
|
console.log(
|
|
29374
|
-
|
|
29824
|
+
chalk214.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
29375
29825
|
);
|
|
29376
29826
|
console.log();
|
|
29377
29827
|
printDiff(targetContent, sourceContent);
|
|
29378
29828
|
if (!options2?.yes) {
|
|
29379
29829
|
printAutoConfirmHint();
|
|
29380
29830
|
const confirm = await promptConfirm(
|
|
29381
|
-
|
|
29831
|
+
chalk214.red("Overwrite existing CLAUDE.md?"),
|
|
29382
29832
|
false
|
|
29383
29833
|
);
|
|
29384
29834
|
if (!confirm) {
|
|
@@ -29611,7 +30061,7 @@ function syncPi(claudeDir, options2) {
|
|
|
29611
30061
|
// src/commands/sync/syncSettings.ts
|
|
29612
30062
|
import * as fs47 from "fs";
|
|
29613
30063
|
import * as path73 from "path";
|
|
29614
|
-
import
|
|
30064
|
+
import chalk215 from "chalk";
|
|
29615
30065
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
29616
30066
|
const source = path73.join(claudeDir, "settings.json");
|
|
29617
30067
|
const target = path73.join(targetBase, "settings.json");
|
|
@@ -29630,7 +30080,7 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
29630
30080
|
if (mergedContent !== normalizedTarget) {
|
|
29631
30081
|
if (!options2?.yes) {
|
|
29632
30082
|
console.log(
|
|
29633
|
-
|
|
30083
|
+
chalk215.yellow(
|
|
29634
30084
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
29635
30085
|
)
|
|
29636
30086
|
);
|
|
@@ -29638,7 +30088,7 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
29638
30088
|
printDiff(targetContent, mergedContent);
|
|
29639
30089
|
printAutoConfirmHint();
|
|
29640
30090
|
const confirm = await promptConfirm(
|
|
29641
|
-
|
|
30091
|
+
chalk215.red("Overwrite existing settings.json?"),
|
|
29642
30092
|
false
|
|
29643
30093
|
);
|
|
29644
30094
|
if (!confirm) {
|
|
@@ -29780,11 +30230,11 @@ async function configure() {
|
|
|
29780
30230
|
}
|
|
29781
30231
|
|
|
29782
30232
|
// src/commands/transcript/list.ts
|
|
29783
|
-
import { existsSync as
|
|
30233
|
+
import { existsSync as existsSync62, readdirSync as readdirSync19, statSync as statSync10 } from "fs";
|
|
29784
30234
|
import { join as join77 } from "path";
|
|
29785
30235
|
function list4() {
|
|
29786
30236
|
const { vttDir } = getTranscriptConfig();
|
|
29787
|
-
if (!
|
|
30237
|
+
if (!existsSync62(vttDir)) return;
|
|
29788
30238
|
for (const entry of readdirSync19(vttDir)) {
|
|
29789
30239
|
if (!entry.endsWith(".vtt")) continue;
|
|
29790
30240
|
if (statSync10(join77(vttDir, entry)).isDirectory()) continue;
|
|
@@ -29794,9 +30244,9 @@ function list4() {
|
|
|
29794
30244
|
|
|
29795
30245
|
// src/commands/transcript/move.ts
|
|
29796
30246
|
import {
|
|
29797
|
-
existsSync as
|
|
30247
|
+
existsSync as existsSync63,
|
|
29798
30248
|
mkdirSync as mkdirSync26,
|
|
29799
|
-
readFileSync as
|
|
30249
|
+
readFileSync as readFileSync48,
|
|
29800
30250
|
renameSync as renameSync2,
|
|
29801
30251
|
writeFileSync as writeFileSync42
|
|
29802
30252
|
} from "fs";
|
|
@@ -30008,7 +30458,7 @@ function formatChatLog(messages) {
|
|
|
30008
30458
|
// src/commands/transcript/move.ts
|
|
30009
30459
|
var DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;
|
|
30010
30460
|
function convertVttToMarkdown(inputPath) {
|
|
30011
|
-
const cues = parseVtt(
|
|
30461
|
+
const cues = parseVtt(readFileSync48(inputPath, "utf8"));
|
|
30012
30462
|
const messages = cuesToChatMessages(deduplicateCues(cues));
|
|
30013
30463
|
return formatChatLog(messages);
|
|
30014
30464
|
}
|
|
@@ -30026,7 +30476,7 @@ function move(file, options2) {
|
|
|
30026
30476
|
const { vttDir, transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
30027
30477
|
const filename = basename21(file);
|
|
30028
30478
|
const sourcePath = join78(vttDir, filename);
|
|
30029
|
-
if (!
|
|
30479
|
+
if (!existsSync63(sourcePath)) {
|
|
30030
30480
|
console.error(`Error: VTT file not found: ${sourcePath}`);
|
|
30031
30481
|
process.exit(1);
|
|
30032
30482
|
}
|
|
@@ -30118,7 +30568,7 @@ function registerVerify(program2) {
|
|
|
30118
30568
|
}
|
|
30119
30569
|
|
|
30120
30570
|
// src/commands/voice/devices.ts
|
|
30121
|
-
import { spawnSync as
|
|
30571
|
+
import { spawnSync as spawnSync8 } from "child_process";
|
|
30122
30572
|
import { join as join80 } from "path";
|
|
30123
30573
|
|
|
30124
30574
|
// src/commands/voice/shared.ts
|
|
@@ -30151,18 +30601,18 @@ function getLockFile() {
|
|
|
30151
30601
|
// src/commands/voice/devices.ts
|
|
30152
30602
|
function devices() {
|
|
30153
30603
|
const script = join80(getPythonDir(), "list_devices.py");
|
|
30154
|
-
|
|
30604
|
+
spawnSync8(getVenvPython(), [script], { stdio: "inherit" });
|
|
30155
30605
|
}
|
|
30156
30606
|
|
|
30157
30607
|
// src/commands/voice/logs.ts
|
|
30158
|
-
import { existsSync as
|
|
30608
|
+
import { existsSync as existsSync64, readFileSync as readFileSync49 } from "fs";
|
|
30159
30609
|
function logs(options2) {
|
|
30160
|
-
if (!
|
|
30610
|
+
if (!existsSync64(voicePaths.log)) {
|
|
30161
30611
|
console.log("No voice log file found");
|
|
30162
30612
|
return;
|
|
30163
30613
|
}
|
|
30164
30614
|
const count8 = Number.parseInt(options2.lines ?? "150", 10);
|
|
30165
|
-
const content =
|
|
30615
|
+
const content = readFileSync49(voicePaths.log, "utf8").trim();
|
|
30166
30616
|
if (!content) {
|
|
30167
30617
|
console.log("Voice log is empty");
|
|
30168
30618
|
return;
|
|
@@ -30183,13 +30633,13 @@ function logs(options2) {
|
|
|
30183
30633
|
}
|
|
30184
30634
|
|
|
30185
30635
|
// src/commands/voice/setup.ts
|
|
30186
|
-
import { spawnSync as
|
|
30636
|
+
import { spawnSync as spawnSync9 } from "child_process";
|
|
30187
30637
|
import { mkdirSync as mkdirSync28 } from "fs";
|
|
30188
30638
|
import { join as join82 } from "path";
|
|
30189
30639
|
|
|
30190
30640
|
// src/commands/voice/checkLockFile.ts
|
|
30191
30641
|
import { execSync as execSync58 } from "child_process";
|
|
30192
|
-
import { existsSync as
|
|
30642
|
+
import { existsSync as existsSync65, mkdirSync as mkdirSync27, readFileSync as readFileSync50, writeFileSync as writeFileSync43 } from "fs";
|
|
30193
30643
|
import { join as join81 } from "path";
|
|
30194
30644
|
function isProcessAlive2(pid) {
|
|
30195
30645
|
try {
|
|
@@ -30201,9 +30651,9 @@ function isProcessAlive2(pid) {
|
|
|
30201
30651
|
}
|
|
30202
30652
|
function checkLockFile() {
|
|
30203
30653
|
const lockFile = getLockFile();
|
|
30204
|
-
if (!
|
|
30654
|
+
if (!existsSync65(lockFile)) return;
|
|
30205
30655
|
try {
|
|
30206
|
-
const lock2 = JSON.parse(
|
|
30656
|
+
const lock2 = JSON.parse(readFileSync50(lockFile, "utf8"));
|
|
30207
30657
|
if (lock2.pid && isProcessAlive2(lock2.pid)) {
|
|
30208
30658
|
console.error(
|
|
30209
30659
|
`Voice daemon already running (PID ${lock2.pid}, env: ${lock2.env}). Stop it first with: assist voice stop`
|
|
@@ -30214,7 +30664,7 @@ function checkLockFile() {
|
|
|
30214
30664
|
}
|
|
30215
30665
|
}
|
|
30216
30666
|
function bootstrapVenv() {
|
|
30217
|
-
if (
|
|
30667
|
+
if (existsSync65(getVenvPython())) return;
|
|
30218
30668
|
console.log("Setting up Python environment...");
|
|
30219
30669
|
const pythonDir = getPythonDir();
|
|
30220
30670
|
execSync58(
|
|
@@ -30244,7 +30694,7 @@ function setup() {
|
|
|
30244
30694
|
bootstrapVenv();
|
|
30245
30695
|
console.log("\nDownloading models...\n");
|
|
30246
30696
|
const script = join82(getPythonDir(), "setup_models.py");
|
|
30247
|
-
const result =
|
|
30697
|
+
const result = spawnSync9(getVenvPython(), [script], {
|
|
30248
30698
|
stdio: "inherit",
|
|
30249
30699
|
env: { ...process.env, VOICE_LOG_FILE: voicePaths.log }
|
|
30250
30700
|
});
|
|
@@ -30305,7 +30755,7 @@ function start2(options2) {
|
|
|
30305
30755
|
}
|
|
30306
30756
|
|
|
30307
30757
|
// src/commands/voice/status.ts
|
|
30308
|
-
import { existsSync as
|
|
30758
|
+
import { existsSync as existsSync66, readFileSync as readFileSync51 } from "fs";
|
|
30309
30759
|
function isProcessAlive3(pid) {
|
|
30310
30760
|
try {
|
|
30311
30761
|
process.kill(pid, 0);
|
|
@@ -30315,16 +30765,16 @@ function isProcessAlive3(pid) {
|
|
|
30315
30765
|
}
|
|
30316
30766
|
}
|
|
30317
30767
|
function readRecentLogs(count8) {
|
|
30318
|
-
if (!
|
|
30319
|
-
const lines2 =
|
|
30768
|
+
if (!existsSync66(voicePaths.log)) return [];
|
|
30769
|
+
const lines2 = readFileSync51(voicePaths.log, "utf8").trim().split("\n");
|
|
30320
30770
|
return lines2.slice(-count8);
|
|
30321
30771
|
}
|
|
30322
30772
|
function status2() {
|
|
30323
|
-
if (!
|
|
30773
|
+
if (!existsSync66(voicePaths.pid)) {
|
|
30324
30774
|
console.log("Voice daemon: not running (no PID file)");
|
|
30325
30775
|
return;
|
|
30326
30776
|
}
|
|
30327
|
-
const pid = Number.parseInt(
|
|
30777
|
+
const pid = Number.parseInt(readFileSync51(voicePaths.pid, "utf8").trim(), 10);
|
|
30328
30778
|
const alive = isProcessAlive3(pid);
|
|
30329
30779
|
console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
|
|
30330
30780
|
const recent = readRecentLogs(5);
|
|
@@ -30343,13 +30793,13 @@ function status2() {
|
|
|
30343
30793
|
}
|
|
30344
30794
|
|
|
30345
30795
|
// src/commands/voice/stop.ts
|
|
30346
|
-
import { existsSync as
|
|
30796
|
+
import { existsSync as existsSync67, readFileSync as readFileSync52, unlinkSync as unlinkSync20 } from "fs";
|
|
30347
30797
|
function stop2() {
|
|
30348
|
-
if (!
|
|
30798
|
+
if (!existsSync67(voicePaths.pid)) {
|
|
30349
30799
|
console.log("Voice daemon is not running (no PID file)");
|
|
30350
30800
|
return;
|
|
30351
30801
|
}
|
|
30352
|
-
const pid = Number.parseInt(
|
|
30802
|
+
const pid = Number.parseInt(readFileSync52(voicePaths.pid, "utf8").trim(), 10);
|
|
30353
30803
|
try {
|
|
30354
30804
|
process.kill(pid, "SIGTERM");
|
|
30355
30805
|
console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
|
|
@@ -30362,7 +30812,7 @@ function stop2() {
|
|
|
30362
30812
|
}
|
|
30363
30813
|
try {
|
|
30364
30814
|
const lockFile = getLockFile();
|
|
30365
|
-
if (
|
|
30815
|
+
if (existsSync67(lockFile)) unlinkSync20(lockFile);
|
|
30366
30816
|
} catch {
|
|
30367
30817
|
}
|
|
30368
30818
|
console.log("Voice daemon stopped");
|
|
@@ -30380,9 +30830,6 @@ function registerVoice(program2) {
|
|
|
30380
30830
|
configHelp(voiceCommand, voiceConfigHelp);
|
|
30381
30831
|
}
|
|
30382
30832
|
|
|
30383
|
-
// src/commands/watch/readBuiltVersion.ts
|
|
30384
|
-
import { join as join84 } from "path";
|
|
30385
|
-
|
|
30386
30833
|
// src/commands/watch/resolveUpstream.ts
|
|
30387
30834
|
import { execFileSync as execFileSync15 } from "child_process";
|
|
30388
30835
|
function runGit3(args, cwd) {
|
|
@@ -30423,7 +30870,13 @@ function resolveUpstream(cwd) {
|
|
|
30423
30870
|
}
|
|
30424
30871
|
}
|
|
30425
30872
|
|
|
30873
|
+
// src/commands/watch/changedPaths.ts
|
|
30874
|
+
function changedPaths(from, cwd) {
|
|
30875
|
+
return runGit3(["diff", "--name-only", `${from}..HEAD`], cwd).split("\n").filter((line) => line.length > 0);
|
|
30876
|
+
}
|
|
30877
|
+
|
|
30426
30878
|
// src/commands/watch/readBuiltVersion.ts
|
|
30879
|
+
import { join as join84 } from "path";
|
|
30427
30880
|
function readBuiltVersion(cwd) {
|
|
30428
30881
|
try {
|
|
30429
30882
|
const root = runGit3(["rev-parse", "--show-toplevel"], cwd);
|
|
@@ -30534,12 +30987,11 @@ function syncAdvice(paths) {
|
|
|
30534
30987
|
// src/commands/watch/buildWatchReport.ts
|
|
30535
30988
|
var lines = (output) => output.split("\n").filter((line) => line.length > 0);
|
|
30536
30989
|
function buildWatchReport(from, cwd) {
|
|
30537
|
-
const
|
|
30538
|
-
const changed = range ? lines(runGit3(["diff", "--name-only", range], cwd)) : [];
|
|
30990
|
+
const changed = from ? changedPaths(from, cwd) : [];
|
|
30539
30991
|
return renderWatchReport({
|
|
30540
30992
|
version: readBuiltVersion(cwd),
|
|
30541
30993
|
commits: readRecentCommits(10, cwd),
|
|
30542
|
-
newShas:
|
|
30994
|
+
newShas: from ? lines(runGit3(["rev-list", `${from}..HEAD`], cwd)) : [],
|
|
30543
30995
|
restarts: restartAdvice(changed),
|
|
30544
30996
|
syncs: syncAdvice(changed)
|
|
30545
30997
|
});
|
|
@@ -30765,7 +31217,7 @@ function resolveParams(params, cliArgs) {
|
|
|
30765
31217
|
}
|
|
30766
31218
|
|
|
30767
31219
|
// src/commands/run/resolveRunCwd.ts
|
|
30768
|
-
import { existsSync as
|
|
31220
|
+
import { existsSync as existsSync68 } from "fs";
|
|
30769
31221
|
import { resolve as resolve18 } from "path";
|
|
30770
31222
|
var MissingRunCwdError = class extends Error {
|
|
30771
31223
|
constructor(runName, cwd) {
|
|
@@ -30778,17 +31230,17 @@ var MissingRunCwdError = class extends Error {
|
|
|
30778
31230
|
function resolveRunCwd(config, baseDir = runConfigBaseDir()) {
|
|
30779
31231
|
if (!config.cwd) return void 0;
|
|
30780
31232
|
const cwd = resolve18(baseDir, config.cwd);
|
|
30781
|
-
if (!
|
|
31233
|
+
if (!existsSync68(cwd)) throw new MissingRunCwdError(config.name, cwd);
|
|
30782
31234
|
return cwd;
|
|
30783
31235
|
}
|
|
30784
31236
|
|
|
30785
31237
|
// src/commands/run/runCommandToCompletion.ts
|
|
30786
31238
|
import { spawn as spawn9 } from "child_process";
|
|
30787
|
-
import { existsSync as
|
|
31239
|
+
import { existsSync as existsSync70 } from "fs";
|
|
30788
31240
|
|
|
30789
31241
|
// src/commands/run/resolveCommand.ts
|
|
30790
31242
|
import { execFileSync as execFileSync16 } from "child_process";
|
|
30791
|
-
import { existsSync as
|
|
31243
|
+
import { existsSync as existsSync69 } from "fs";
|
|
30792
31244
|
import { dirname as dirname35, join as join85, resolve as resolve19 } from "path";
|
|
30793
31245
|
function resolveCommand2(command) {
|
|
30794
31246
|
if (process.platform !== "win32" || command !== "bash") return command;
|
|
@@ -30796,7 +31248,7 @@ function resolveCommand2(command) {
|
|
|
30796
31248
|
const gitPath = execFileSync16("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
|
|
30797
31249
|
const gitRoot = resolve19(dirname35(gitPath), "..");
|
|
30798
31250
|
const gitBash = join85(gitRoot, "bin", "bash.exe");
|
|
30799
|
-
if (
|
|
31251
|
+
if (existsSync69(gitBash)) return gitBash;
|
|
30800
31252
|
} catch {
|
|
30801
31253
|
return command;
|
|
30802
31254
|
}
|
|
@@ -30806,7 +31258,7 @@ function resolveCommand2(command) {
|
|
|
30806
31258
|
// src/commands/run/runCommandToCompletion.ts
|
|
30807
31259
|
function runCommandToCompletion(command, args, env, cwd, quiet) {
|
|
30808
31260
|
return new Promise((resolveResult) => {
|
|
30809
|
-
if (cwd && !
|
|
31261
|
+
if (cwd && !existsSync70(cwd)) {
|
|
30810
31262
|
resolveResult({
|
|
30811
31263
|
kind: "failed",
|
|
30812
31264
|
message: `Failed to execute command: cwd ${cwd} does not exist`
|
|
@@ -30852,6 +31304,15 @@ function runPreCommands(pre, cwd) {
|
|
|
30852
31304
|
}
|
|
30853
31305
|
}
|
|
30854
31306
|
|
|
31307
|
+
// src/commands/watch/toBuildOutcome.ts
|
|
31308
|
+
function toBuildOutcome(result) {
|
|
31309
|
+
if (result.kind === "failed")
|
|
31310
|
+
return { kind: "failed", exitCode: 1, output: result.message };
|
|
31311
|
+
if (result.exitCode !== 0)
|
|
31312
|
+
return { kind: "failed", exitCode: result.exitCode, output: result.output };
|
|
31313
|
+
return { kind: "built" };
|
|
31314
|
+
}
|
|
31315
|
+
|
|
30855
31316
|
// src/commands/watch/runWatchBuild.ts
|
|
30856
31317
|
async function runWatchBuild(entry) {
|
|
30857
31318
|
const config = findRunConfig(entry);
|
|
@@ -30863,18 +31324,15 @@ async function runWatchBuild(entry) {
|
|
|
30863
31324
|
return { kind: "failed", exitCode: 1, output: error.message };
|
|
30864
31325
|
}
|
|
30865
31326
|
if (config.pre) runPreCommands(config.pre, cwd);
|
|
30866
|
-
|
|
30867
|
-
|
|
30868
|
-
|
|
30869
|
-
|
|
30870
|
-
|
|
30871
|
-
|
|
31327
|
+
return toBuildOutcome(
|
|
31328
|
+
await runCommandToCompletion(
|
|
31329
|
+
config.command,
|
|
31330
|
+
[...config.args ?? [], ...resolveParams(config.params, [])],
|
|
31331
|
+
config.env,
|
|
31332
|
+
cwd,
|
|
31333
|
+
config.quiet
|
|
31334
|
+
)
|
|
30872
31335
|
);
|
|
30873
|
-
if (result.kind === "failed")
|
|
30874
|
-
return { kind: "failed", exitCode: 1, output: result.message };
|
|
30875
|
-
if (result.exitCode !== 0)
|
|
30876
|
-
return { kind: "failed", exitCode: result.exitCode, output: result.output };
|
|
30877
|
-
return { kind: "built" };
|
|
30878
31336
|
}
|
|
30879
31337
|
|
|
30880
31338
|
// src/commands/watch/reportBuildOrExit.ts
|
|
@@ -30889,6 +31347,25 @@ async function reportBuildOrExit(entry) {
|
|
|
30889
31347
|
process.exit(4);
|
|
30890
31348
|
}
|
|
30891
31349
|
|
|
31350
|
+
// src/commands/watch/runPostBuildSync.ts
|
|
31351
|
+
async function runPostBuildSync() {
|
|
31352
|
+
return toBuildOutcome(
|
|
31353
|
+
await runCommandToCompletion("assist", ["sync", "--yes"])
|
|
31354
|
+
);
|
|
31355
|
+
}
|
|
31356
|
+
|
|
31357
|
+
// src/commands/watch/reportSyncOrExit.ts
|
|
31358
|
+
async function reportSyncOrExit() {
|
|
31359
|
+
const outcome = await runPostBuildSync();
|
|
31360
|
+
if (outcome.kind === "built") {
|
|
31361
|
+
console.log("synced ~/.claude");
|
|
31362
|
+
return;
|
|
31363
|
+
}
|
|
31364
|
+
if (outcome.output.length > 0) process.stdout.write(outcome.output);
|
|
31365
|
+
console.error(`sync failed with exit code ${outcome.exitCode}`);
|
|
31366
|
+
process.exit(4);
|
|
31367
|
+
}
|
|
31368
|
+
|
|
30892
31369
|
// src/commands/watch/fetchQuietly.ts
|
|
30893
31370
|
import { execFileSync as execFileSync17 } from "child_process";
|
|
30894
31371
|
var MIN_FETCH_TIMEOUT_MS = 6e4;
|
|
@@ -31000,6 +31477,8 @@ ${buildWatchReport(outcome.from)}`);
|
|
|
31000
31477
|
await reportBuildOrExit(
|
|
31001
31478
|
typeof options2.build === "string" ? options2.build : DEFAULT_BUILD_ENTRY
|
|
31002
31479
|
);
|
|
31480
|
+
if (syncAdvice(changedPaths(outcome.from)).length > 0)
|
|
31481
|
+
await reportSyncOrExit();
|
|
31003
31482
|
}
|
|
31004
31483
|
process.exit(0);
|
|
31005
31484
|
}
|
|
@@ -31008,7 +31487,7 @@ ${buildWatchReport(outcome.from)}`);
|
|
|
31008
31487
|
function registerWatch(program2) {
|
|
31009
31488
|
const watchCommand = program2.command("watch").description("Wait on upstream movement for the current branch");
|
|
31010
31489
|
watchCommand.command("wait").description(
|
|
31011
|
-
"Block until the current branch's upstream gains commits, then exit 0 (2 on timeout, 3 when --pull hits genuine divergence, 4 when --build fails, 1 when waiting is impossible, 130 on interrupt)"
|
|
31490
|
+
"Block until the current branch's upstream gains commits, then exit 0 (2 on timeout, 3 when --pull hits genuine divergence, 4 when --build or the post-build sync fails, 1 when waiting is impossible, 130 on interrupt)"
|
|
31012
31491
|
).option(
|
|
31013
31492
|
"--interval <duration>",
|
|
31014
31493
|
"How often to fetch after the fetch at startup (e.g. 30s, 2m)",
|
|
@@ -31022,7 +31501,7 @@ function registerWatch(program2) {
|
|
|
31022
31501
|
"On movement, fast-forward with git pull --ff-only, recovering a dirty tree or a merely-behind branch; exit 3 with git's reason on genuine divergence"
|
|
31023
31502
|
).option(
|
|
31024
31503
|
"--build [entry]",
|
|
31025
|
-
"After a successful pull, run this run entry (default auto-build); exit 4 with
|
|
31504
|
+
"After a successful pull, run this run entry (default auto-build), then run assist sync --yes when the pulled commits touched the files sync installs; exit 4 with the output of whichever fails"
|
|
31026
31505
|
).action(
|
|
31027
31506
|
(options2) => watchWait(options2)
|
|
31028
31507
|
);
|
|
@@ -31036,7 +31515,7 @@ function registerWatch(program2) {
|
|
|
31036
31515
|
|
|
31037
31516
|
// src/commands/roam/auth.ts
|
|
31038
31517
|
import { randomBytes } from "crypto";
|
|
31039
|
-
import
|
|
31518
|
+
import chalk216 from "chalk";
|
|
31040
31519
|
|
|
31041
31520
|
// src/commands/roam/waitForCallback.ts
|
|
31042
31521
|
import { createServer as createServer3 } from "http";
|
|
@@ -31167,13 +31646,13 @@ async function auth() {
|
|
|
31167
31646
|
saveGlobalConfig(config);
|
|
31168
31647
|
const state = randomBytes(16).toString("hex");
|
|
31169
31648
|
console.log(
|
|
31170
|
-
|
|
31649
|
+
chalk216.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
31171
31650
|
);
|
|
31172
|
-
console.log(
|
|
31173
|
-
console.log(
|
|
31174
|
-
console.log(
|
|
31651
|
+
console.log(chalk216.white("http://localhost:14523/callback\n"));
|
|
31652
|
+
console.log(chalk216.blue("Opening browser for authorization..."));
|
|
31653
|
+
console.log(chalk216.dim("Waiting for authorization callback..."));
|
|
31175
31654
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
31176
|
-
console.log(
|
|
31655
|
+
console.log(chalk216.dim("Exchanging code for tokens..."));
|
|
31177
31656
|
const tokens = await exchangeToken({
|
|
31178
31657
|
code,
|
|
31179
31658
|
clientId,
|
|
@@ -31189,13 +31668,13 @@ async function auth() {
|
|
|
31189
31668
|
};
|
|
31190
31669
|
saveGlobalConfig(config);
|
|
31191
31670
|
console.log(
|
|
31192
|
-
|
|
31671
|
+
chalk216.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
31193
31672
|
);
|
|
31194
31673
|
}
|
|
31195
31674
|
|
|
31196
31675
|
// src/commands/roam/postRoamActivity.ts
|
|
31197
31676
|
import { execFileSync as execFileSync18 } from "child_process";
|
|
31198
|
-
import { readdirSync as readdirSync20, readFileSync as
|
|
31677
|
+
import { readdirSync as readdirSync20, readFileSync as readFileSync53, statSync as statSync11 } from "fs";
|
|
31199
31678
|
import { join as join86 } from "path";
|
|
31200
31679
|
function findPortFile(roamDir) {
|
|
31201
31680
|
let entries;
|
|
@@ -31221,7 +31700,7 @@ function postRoamActivity(app, event) {
|
|
|
31221
31700
|
if (!portFile) return;
|
|
31222
31701
|
let port;
|
|
31223
31702
|
try {
|
|
31224
|
-
port =
|
|
31703
|
+
port = readFileSync53(portFile, "utf8").trim();
|
|
31225
31704
|
} catch {
|
|
31226
31705
|
return;
|
|
31227
31706
|
}
|
|
@@ -31475,7 +31954,7 @@ function link2() {
|
|
|
31475
31954
|
}
|
|
31476
31955
|
|
|
31477
31956
|
// src/commands/run/remove.ts
|
|
31478
|
-
import { existsSync as
|
|
31957
|
+
import { existsSync as existsSync71, unlinkSync as unlinkSync21 } from "fs";
|
|
31479
31958
|
import { join as join88 } from "path";
|
|
31480
31959
|
function findRemoveIndex() {
|
|
31481
31960
|
const idx = process.argv.indexOf("remove");
|
|
@@ -31492,7 +31971,7 @@ function parseRemoveName() {
|
|
|
31492
31971
|
}
|
|
31493
31972
|
function deleteCommandFile(name) {
|
|
31494
31973
|
const filePath = join88(".claude", "commands", `${name}.md`);
|
|
31495
|
-
if (
|
|
31974
|
+
if (existsSync71(filePath)) {
|
|
31496
31975
|
unlinkSync21(filePath);
|
|
31497
31976
|
console.log(`Deleted command file: ${filePath}`);
|
|
31498
31977
|
}
|
|
@@ -31537,10 +32016,10 @@ function registerRun(program2) {
|
|
|
31537
32016
|
|
|
31538
32017
|
// src/commands/screenshot/index.ts
|
|
31539
32018
|
import { execSync as execSync60 } from "child_process";
|
|
31540
|
-
import { existsSync as
|
|
32019
|
+
import { existsSync as existsSync72, mkdirSync as mkdirSync31, unlinkSync as unlinkSync22, writeFileSync as writeFileSync46 } from "fs";
|
|
31541
32020
|
import { tmpdir as tmpdir8 } from "os";
|
|
31542
32021
|
import { join as join89, resolve as resolve20 } from "path";
|
|
31543
|
-
import
|
|
32022
|
+
import chalk217 from "chalk";
|
|
31544
32023
|
|
|
31545
32024
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
31546
32025
|
var captureWindowPs1 = `
|
|
@@ -31669,7 +32148,7 @@ Write-Output $OutputPath
|
|
|
31669
32148
|
|
|
31670
32149
|
// src/commands/screenshot/index.ts
|
|
31671
32150
|
function buildOutputPath(outputDir, processName) {
|
|
31672
|
-
if (!
|
|
32151
|
+
if (!existsSync72(outputDir)) {
|
|
31673
32152
|
mkdirSync31(outputDir, { recursive: true });
|
|
31674
32153
|
}
|
|
31675
32154
|
const timestamp6 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
@@ -31691,13 +32170,13 @@ function screenshot(processName) {
|
|
|
31691
32170
|
const config = loadConfig();
|
|
31692
32171
|
const outputDir = resolve20(config.screenshot.outputDir);
|
|
31693
32172
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
31694
|
-
console.log(
|
|
32173
|
+
console.log(chalk217.gray(`Capturing window for process "${processName}" ...`));
|
|
31695
32174
|
try {
|
|
31696
32175
|
runPowerShellScript(processName, outputPath);
|
|
31697
|
-
console.log(
|
|
32176
|
+
console.log(chalk217.green(`Screenshot saved: ${outputPath}`));
|
|
31698
32177
|
} catch (error) {
|
|
31699
32178
|
const msg = error instanceof Error ? error.message : String(error);
|
|
31700
|
-
console.error(
|
|
32179
|
+
console.error(chalk217.red(`Failed to capture screenshot: ${msg}`));
|
|
31701
32180
|
process.exit(1);
|
|
31702
32181
|
}
|
|
31703
32182
|
}
|
|
@@ -31753,11 +32232,11 @@ function applyLine(result, pending, line) {
|
|
|
31753
32232
|
}
|
|
31754
32233
|
|
|
31755
32234
|
// src/commands/sessions/daemon/readDaemonPidFile.ts
|
|
31756
|
-
import { readFileSync as
|
|
32235
|
+
import { readFileSync as readFileSync54 } from "fs";
|
|
31757
32236
|
function readDaemonPidFile() {
|
|
31758
32237
|
try {
|
|
31759
32238
|
const pid = Number.parseInt(
|
|
31760
|
-
|
|
32239
|
+
readFileSync54(daemonPaths.pid, "utf8").trim(),
|
|
31761
32240
|
10
|
|
31762
32241
|
);
|
|
31763
32242
|
return Number.isInteger(pid) ? pid : void 0;
|
|
@@ -32014,12 +32493,12 @@ function toSessionRunInfo({
|
|
|
32014
32493
|
}
|
|
32015
32494
|
|
|
32016
32495
|
// src/commands/sessions/daemon/worktree/joinRefusal.ts
|
|
32017
|
-
import { existsSync as
|
|
32496
|
+
import { existsSync as existsSync73 } from "fs";
|
|
32018
32497
|
function joinRefusal(session) {
|
|
32019
32498
|
if (session.commandType === "run") return "a server run has no agent stream";
|
|
32020
32499
|
if (session.closing === true) return "the session is closing";
|
|
32021
32500
|
if (!session.cwd) return "the session has no working directory";
|
|
32022
|
-
if (!
|
|
32501
|
+
if (!existsSync73(session.cwd))
|
|
32023
32502
|
return "the session's workspace no longer exists";
|
|
32024
32503
|
return void 0;
|
|
32025
32504
|
}
|
|
@@ -32183,11 +32662,11 @@ function sessionBase(id, status3) {
|
|
|
32183
32662
|
}
|
|
32184
32663
|
|
|
32185
32664
|
// src/commands/sessions/daemon/spawnPty.ts
|
|
32186
|
-
import { existsSync as
|
|
32665
|
+
import { existsSync as existsSync75 } from "fs";
|
|
32187
32666
|
import * as pty from "node-pty";
|
|
32188
32667
|
|
|
32189
32668
|
// src/commands/sessions/daemon/ensureSpawnHelperExecutable.ts
|
|
32190
|
-
import { chmodSync, existsSync as
|
|
32669
|
+
import { chmodSync, existsSync as existsSync74, statSync as statSync12 } from "fs";
|
|
32191
32670
|
import { createRequire as createRequire3 } from "module";
|
|
32192
32671
|
import path75 from "path";
|
|
32193
32672
|
var require4 = createRequire3(import.meta.url);
|
|
@@ -32202,7 +32681,7 @@ function ensureSpawnHelperExecutable() {
|
|
|
32202
32681
|
`${process.platform}-${process.arch}`,
|
|
32203
32682
|
"spawn-helper"
|
|
32204
32683
|
);
|
|
32205
|
-
if (!
|
|
32684
|
+
if (!existsSync74(helper)) return;
|
|
32206
32685
|
const mode = statSync12(helper).mode;
|
|
32207
32686
|
if ((mode & 73) === 0) chmodSync(helper, mode | 493);
|
|
32208
32687
|
}
|
|
@@ -32238,7 +32717,7 @@ function spawnPty(args, cwd, sessionId, extraEnv) {
|
|
|
32238
32717
|
});
|
|
32239
32718
|
}
|
|
32240
32719
|
function refuseMissingCwd(cwd, sessionId) {
|
|
32241
|
-
if (!cwd ||
|
|
32720
|
+
if (!cwd || existsSync75(cwd)) return;
|
|
32242
32721
|
daemonLog(
|
|
32243
32722
|
`${sessionId ? `session ${sessionId}` : "pty"} not spawned: working directory ${cwd} no longer exists`
|
|
32244
32723
|
);
|
|
@@ -32420,11 +32899,11 @@ function setStatus2(session, newStatus) {
|
|
|
32420
32899
|
}
|
|
32421
32900
|
|
|
32422
32901
|
// src/commands/sessions/daemon/worktree/reapWorktree.ts
|
|
32423
|
-
import { existsSync as
|
|
32902
|
+
import { existsSync as existsSync77 } from "fs";
|
|
32424
32903
|
import { basename as basename22 } from "path";
|
|
32425
32904
|
|
|
32426
32905
|
// src/commands/sessions/daemon/worktree/deleteStrandedTree.ts
|
|
32427
|
-
import { existsSync as
|
|
32906
|
+
import { existsSync as existsSync76 } from "fs";
|
|
32428
32907
|
import { join as join92 } from "path";
|
|
32429
32908
|
|
|
32430
32909
|
// src/commands/sessions/daemon/worktree/deleteTreeDirectly.ts
|
|
@@ -32494,7 +32973,7 @@ async function deleteStrandedTree(clone, worktreePath, cause) {
|
|
|
32494
32973
|
);
|
|
32495
32974
|
}
|
|
32496
32975
|
function strandedReason(worktreePath, cause) {
|
|
32497
|
-
if (!
|
|
32976
|
+
if (!existsSync76(join92(worktreePath, ".git")))
|
|
32498
32977
|
return "its .git link is already gone";
|
|
32499
32978
|
if (/not a working tree|not a git repository/i.test(reason2(cause)))
|
|
32500
32979
|
return "git no longer recognises it as a working tree";
|
|
@@ -32546,7 +33025,7 @@ function reason3(error) {
|
|
|
32546
33025
|
|
|
32547
33026
|
// src/commands/sessions/daemon/worktree/reapWorktree.ts
|
|
32548
33027
|
async function reapWorktree(worktreePath, force = false) {
|
|
32549
|
-
if (!
|
|
33028
|
+
if (!existsSync77(worktreePath)) {
|
|
32550
33029
|
forgetWorktree(worktreePath);
|
|
32551
33030
|
daemonLog(
|
|
32552
33031
|
`worktree ${worktreePath} already gone; its record was forgotten`
|
|
@@ -32571,7 +33050,7 @@ async function reapWorktree(worktreePath, force = false) {
|
|
|
32571
33050
|
}
|
|
32572
33051
|
function owningClone(worktreePath) {
|
|
32573
33052
|
const recorded = worktreeAttributionIncludingReaped(worktreePath)?.clone;
|
|
32574
|
-
if (recorded &&
|
|
33053
|
+
if (recorded && existsSync77(recorded)) return recorded;
|
|
32575
33054
|
const detected = mainWorktree(worktreePath);
|
|
32576
33055
|
if (detected) return detected;
|
|
32577
33056
|
daemonLog(
|
|
@@ -32702,12 +33181,12 @@ function closeGateApplies(sessions, session) {
|
|
|
32702
33181
|
}
|
|
32703
33182
|
|
|
32704
33183
|
// src/commands/sessions/daemon/worktree/watchGitState.ts
|
|
32705
|
-
import { existsSync as
|
|
33184
|
+
import { existsSync as existsSync78, watch } from "fs";
|
|
32706
33185
|
var DEBOUNCE_MS = 500;
|
|
32707
33186
|
var POLL_MS = 3e4;
|
|
32708
33187
|
function watchGitState(cwd, onChange) {
|
|
32709
33188
|
const common = gitCommonDir(cwd);
|
|
32710
|
-
if (!common || !
|
|
33189
|
+
if (!common || !existsSync78(common)) return void 0;
|
|
32711
33190
|
const watchers = [
|
|
32712
33191
|
watchGitDir(common, onChange),
|
|
32713
33192
|
pollGitState(cwd, onChange)
|
|
@@ -32882,9 +33361,9 @@ function flushPhaseActiveMs(session) {
|
|
|
32882
33361
|
if (await persistPhaseActiveMs(phase.itemId, phase.phaseIdx, delta))
|
|
32883
33362
|
session.activeMsFlushedForStretch = { since, ms: flushed + delta };
|
|
32884
33363
|
};
|
|
32885
|
-
const
|
|
32886
|
-
session.activeMsFlushChain =
|
|
32887
|
-
return
|
|
33364
|
+
const chain2 = (session.activeMsFlushChain ?? Promise.resolve()).then(run4);
|
|
33365
|
+
session.activeMsFlushChain = chain2;
|
|
33366
|
+
return chain2;
|
|
32888
33367
|
}
|
|
32889
33368
|
|
|
32890
33369
|
// src/commands/sessions/daemon/stripReplayQueries.ts
|
|
@@ -33182,10 +33661,10 @@ function emitSessionOutput(session, clients, data) {
|
|
|
33182
33661
|
}
|
|
33183
33662
|
|
|
33184
33663
|
// src/commands/sessions/daemon/exitReason.ts
|
|
33185
|
-
import { existsSync as
|
|
33664
|
+
import { existsSync as existsSync79 } from "fs";
|
|
33186
33665
|
import { resolve as resolve21 } from "path";
|
|
33187
33666
|
function exitDetail(session) {
|
|
33188
|
-
if (session.cwd && !
|
|
33667
|
+
if (session.cwd && !existsSync79(session.cwd))
|
|
33189
33668
|
return `working directory ${session.cwd} no longer exists`;
|
|
33190
33669
|
return missingRunConfigCwd(session);
|
|
33191
33670
|
}
|
|
@@ -33199,7 +33678,7 @@ function missingRunConfigCwd(session) {
|
|
|
33199
33678
|
const config = resolveRunConfig(session.runName, dir);
|
|
33200
33679
|
if (!config?.cwd) return void 0;
|
|
33201
33680
|
const configured = resolve21(runConfigBaseDirFrom(dir), config.cwd);
|
|
33202
|
-
if (
|
|
33681
|
+
if (existsSync79(configured)) return void 0;
|
|
33203
33682
|
return `run config "${config.name}": cwd ${configured} does not exist`;
|
|
33204
33683
|
}
|
|
33205
33684
|
|
|
@@ -33240,7 +33719,7 @@ function handleFailedResume(session, exitCode, onStatusChange) {
|
|
|
33240
33719
|
}
|
|
33241
33720
|
|
|
33242
33721
|
// src/commands/sessions/daemon/watchActivity.ts
|
|
33243
|
-
import { existsSync as
|
|
33722
|
+
import { existsSync as existsSync80, mkdirSync as mkdirSync32, watch as watch2 } from "fs";
|
|
33244
33723
|
import { dirname as dirname37 } from "path";
|
|
33245
33724
|
|
|
33246
33725
|
// src/commands/sessions/daemon/applyActivityToSession.ts
|
|
@@ -33326,7 +33805,7 @@ function watchActivity(session, notify2, onClaudeSessionId) {
|
|
|
33326
33805
|
if (timer) clearTimeout(timer);
|
|
33327
33806
|
timer = setTimeout(read2, DEBOUNCE_MS2);
|
|
33328
33807
|
});
|
|
33329
|
-
if (
|
|
33808
|
+
if (existsSync80(path80)) read2();
|
|
33330
33809
|
}
|
|
33331
33810
|
function refreshActivity(session) {
|
|
33332
33811
|
if (session.commandType !== "assist" || !session.cwd) return;
|
|
@@ -34948,7 +35427,7 @@ function rearmStoppedSessions(sessions, notify2) {
|
|
|
34948
35427
|
}
|
|
34949
35428
|
|
|
34950
35429
|
// src/commands/sessions/daemon/worktree/reconcileWorktreesOnRestore.ts
|
|
34951
|
-
import { existsSync as
|
|
35430
|
+
import { existsSync as existsSync83 } from "fs";
|
|
34952
35431
|
import { basename as basename24 } from "path";
|
|
34953
35432
|
|
|
34954
35433
|
// src/commands/sessions/daemon/worktree/accountedTrees.ts
|
|
@@ -35003,9 +35482,9 @@ function bindResumedWorktree(session, cwd, notify2) {
|
|
|
35003
35482
|
}
|
|
35004
35483
|
|
|
35005
35484
|
// src/commands/sessions/daemon/worktree/reclaimVanishedWorktrees.ts
|
|
35006
|
-
import { existsSync as
|
|
35485
|
+
import { existsSync as existsSync82 } from "fs";
|
|
35007
35486
|
async function reclaimVanishedWorktrees(clone, paths) {
|
|
35008
|
-
if (!
|
|
35487
|
+
if (!existsSync82(clone)) {
|
|
35009
35488
|
for (const { path: path80 } of paths) forgetWorktree(path80);
|
|
35010
35489
|
daemonLog(
|
|
35011
35490
|
`clone ${clone} is gone; forgot ${paths.length} worktree record(s) it owned`
|
|
@@ -35171,7 +35650,7 @@ async function recoverOrphanedWorktrees(sessions, spawnWith, notify2) {
|
|
|
35171
35650
|
);
|
|
35172
35651
|
continue;
|
|
35173
35652
|
}
|
|
35174
|
-
if (!
|
|
35653
|
+
if (!existsSync83(path80)) {
|
|
35175
35654
|
logVanishedTree(sessions, path80);
|
|
35176
35655
|
vanished.set(clone, [
|
|
35177
35656
|
...vanished.get(clone) ?? [],
|
|
@@ -35788,14 +36267,14 @@ async function defaultConnect() {
|
|
|
35788
36267
|
}
|
|
35789
36268
|
|
|
35790
36269
|
// src/commands/sessions/daemon/hasPersistedWindowsSessions.ts
|
|
35791
|
-
import { existsSync as
|
|
36270
|
+
import { existsSync as existsSync84, readFileSync as readFileSync56 } from "fs";
|
|
35792
36271
|
import { posix as posix3 } from "path";
|
|
35793
36272
|
function hasPersistedWindowsSessions() {
|
|
35794
36273
|
const sessionsFile = windowsSessionsFileFromWsl();
|
|
35795
36274
|
if (!sessionsFile) return false;
|
|
35796
36275
|
try {
|
|
35797
|
-
if (!
|
|
35798
|
-
const data = JSON.parse(
|
|
36276
|
+
if (!existsSync84(sessionsFile)) return false;
|
|
36277
|
+
const data = JSON.parse(readFileSync56(sessionsFile, "utf8"));
|
|
35799
36278
|
return Array.isArray(data) && data.length > 0;
|
|
35800
36279
|
} catch (error) {
|
|
35801
36280
|
const message3 = error instanceof Error ? error.message : String(error);
|
|
@@ -36529,7 +37008,7 @@ function setAutoAdvance(sessions, id, enabled) {
|
|
|
36529
37008
|
}
|
|
36530
37009
|
|
|
36531
37010
|
// src/commands/sessions/daemon/worktree/resumeInTree.ts
|
|
36532
|
-
import { existsSync as
|
|
37011
|
+
import { existsSync as existsSync87 } from "fs";
|
|
36533
37012
|
|
|
36534
37013
|
// src/commands/sessions/daemon/resumeSession.ts
|
|
36535
37014
|
function resumeSession(id, sessionId, cwd, name, holdPty, harness) {
|
|
@@ -36560,10 +37039,10 @@ function resumeSession(id, sessionId, cwd, name, holdPty, harness) {
|
|
|
36560
37039
|
}
|
|
36561
37040
|
|
|
36562
37041
|
// src/commands/sessions/daemon/worktree/resumeInReplacementTree.ts
|
|
36563
|
-
import { existsSync as
|
|
37042
|
+
import { existsSync as existsSync86 } from "fs";
|
|
36564
37043
|
|
|
36565
37044
|
// src/commands/sessions/daemon/worktree/carryTranscriptToTree.ts
|
|
36566
|
-
import { copyFileSync as copyFileSync7, existsSync as
|
|
37045
|
+
import { copyFileSync as copyFileSync7, existsSync as existsSync85, mkdirSync as mkdirSync34 } from "fs";
|
|
36567
37046
|
import { join as join94 } from "path";
|
|
36568
37047
|
function carryTranscriptToTree(claudeSessionId, fromCwd, toCwd) {
|
|
36569
37048
|
const dir = projectDirForCwd(toCwd);
|
|
@@ -36574,7 +37053,7 @@ function carryTranscriptToTree(claudeSessionId, fromCwd, toCwd) {
|
|
|
36574
37053
|
return;
|
|
36575
37054
|
}
|
|
36576
37055
|
const dest = join94(dir, `${claudeSessionId}.jsonl`);
|
|
36577
|
-
if (
|
|
37056
|
+
if (existsSync85(dest)) {
|
|
36578
37057
|
daemonLog(`transcript ${claudeSessionId} already present in ${dir}`);
|
|
36579
37058
|
return;
|
|
36580
37059
|
}
|
|
@@ -36625,7 +37104,7 @@ function resumeInReplacementTree(ctx, claudeSessionId, missingCwd, name, harness
|
|
|
36625
37104
|
}
|
|
36626
37105
|
function cloneForReapedTree(missingCwd) {
|
|
36627
37106
|
const clone = worktreeAttributionIncludingReaped(missingCwd)?.clone;
|
|
36628
|
-
if (!clone || !
|
|
37107
|
+
if (!clone || !existsSync86(clone))
|
|
36629
37108
|
throw new Error(
|
|
36630
37109
|
`working directory no longer exists and no clone is recorded to re-allocate from: ${missingCwd}`
|
|
36631
37110
|
);
|
|
@@ -36634,7 +37113,7 @@ function cloneForReapedTree(missingCwd) {
|
|
|
36634
37113
|
|
|
36635
37114
|
// src/commands/sessions/daemon/worktree/resumeInTree.ts
|
|
36636
37115
|
function resumeInTree(ctx, sessionId, cwd, name, harness) {
|
|
36637
|
-
if (!
|
|
37116
|
+
if (!existsSync87(cwd))
|
|
36638
37117
|
return resumeInReplacementTree(ctx, sessionId, cwd, name, harness);
|
|
36639
37118
|
const id = ctx.spawnWith(
|
|
36640
37119
|
(sid) => resumeSession(sid, sessionId, cwd, name, void 0, harness)
|
|
@@ -37213,7 +37692,7 @@ function handleConnection(socket, manager) {
|
|
|
37213
37692
|
import { unlinkSync as unlinkSync23, writeFileSync as writeFileSync47 } from "fs";
|
|
37214
37693
|
|
|
37215
37694
|
// src/commands/sessions/daemon/startPidFileWatchdog.ts
|
|
37216
|
-
import { readFileSync as
|
|
37695
|
+
import { readFileSync as readFileSync57 } from "fs";
|
|
37217
37696
|
var WATCHDOG_INTERVAL_MS = 5e3;
|
|
37218
37697
|
function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
|
|
37219
37698
|
const timer = setInterval(() => {
|
|
@@ -37224,7 +37703,7 @@ function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
|
|
|
37224
37703
|
}
|
|
37225
37704
|
function ownsPidFile() {
|
|
37226
37705
|
try {
|
|
37227
|
-
return
|
|
37706
|
+
return readFileSync57(daemonPaths.pid, "utf8").trim() === String(process.pid);
|
|
37228
37707
|
} catch {
|
|
37229
37708
|
return false;
|
|
37230
37709
|
}
|
|
@@ -37474,7 +37953,7 @@ function registerSetStatusCommand(cmd) {
|
|
|
37474
37953
|
|
|
37475
37954
|
// src/commands/sessions/summarise/index.ts
|
|
37476
37955
|
import * as fs56 from "fs";
|
|
37477
|
-
import
|
|
37956
|
+
import chalk218 from "chalk";
|
|
37478
37957
|
|
|
37479
37958
|
// src/commands/sessions/summarise/shared.ts
|
|
37480
37959
|
import * as fs55 from "fs";
|
|
@@ -37533,22 +38012,22 @@ ${firstMessage}`);
|
|
|
37533
38012
|
async function summarise2(options2) {
|
|
37534
38013
|
const files = await discoverSessionFiles();
|
|
37535
38014
|
if (files.length === 0) {
|
|
37536
|
-
console.log(
|
|
38015
|
+
console.log(chalk218.yellow("No sessions found."));
|
|
37537
38016
|
return;
|
|
37538
38017
|
}
|
|
37539
38018
|
const toProcess = selectCandidates(files, options2);
|
|
37540
38019
|
if (toProcess.length === 0) {
|
|
37541
|
-
console.log(
|
|
38020
|
+
console.log(chalk218.green("All sessions already summarised."));
|
|
37542
38021
|
return;
|
|
37543
38022
|
}
|
|
37544
38023
|
console.log(
|
|
37545
|
-
|
|
38024
|
+
chalk218.cyan(
|
|
37546
38025
|
`Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
|
|
37547
38026
|
)
|
|
37548
38027
|
);
|
|
37549
38028
|
const { succeeded, failed: failed2 } = processSessions(toProcess);
|
|
37550
38029
|
console.log(
|
|
37551
|
-
|
|
38030
|
+
chalk218.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk218.yellow(`, ${failed2} skipped`) : "")
|
|
37552
38031
|
);
|
|
37553
38032
|
}
|
|
37554
38033
|
function selectCandidates(files, options2) {
|
|
@@ -37568,16 +38047,16 @@ function processSessions(files) {
|
|
|
37568
38047
|
let failed2 = 0;
|
|
37569
38048
|
for (let i = 0; i < files.length; i++) {
|
|
37570
38049
|
const file = files[i];
|
|
37571
|
-
process.stdout.write(
|
|
38050
|
+
process.stdout.write(chalk218.dim(` [${i + 1}/${files.length}] `));
|
|
37572
38051
|
const summary = summariseSession(file);
|
|
37573
38052
|
if (summary) {
|
|
37574
38053
|
writeSummary(file, summary);
|
|
37575
38054
|
succeeded++;
|
|
37576
|
-
process.stdout.write(`${
|
|
38055
|
+
process.stdout.write(`${chalk218.green("\u2713")} ${summary}
|
|
37577
38056
|
`);
|
|
37578
38057
|
} else {
|
|
37579
38058
|
failed2++;
|
|
37580
|
-
process.stdout.write(` ${
|
|
38059
|
+
process.stdout.write(` ${chalk218.yellow("skip")}
|
|
37581
38060
|
`);
|
|
37582
38061
|
}
|
|
37583
38062
|
}
|
|
@@ -37598,7 +38077,7 @@ function registerSessions(program2) {
|
|
|
37598
38077
|
}
|
|
37599
38078
|
|
|
37600
38079
|
// src/commands/statusLine.ts
|
|
37601
|
-
import
|
|
38080
|
+
import chalk220 from "chalk";
|
|
37602
38081
|
|
|
37603
38082
|
// src/shared/contextLevel.ts
|
|
37604
38083
|
function contextLevel(pct) {
|
|
@@ -37608,7 +38087,7 @@ function contextLevel(pct) {
|
|
|
37608
38087
|
}
|
|
37609
38088
|
|
|
37610
38089
|
// src/commands/buildLimitsSegment.ts
|
|
37611
|
-
import
|
|
38090
|
+
import chalk219 from "chalk";
|
|
37612
38091
|
|
|
37613
38092
|
// src/shared/rateLimitLevel.ts
|
|
37614
38093
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
@@ -37646,9 +38125,9 @@ function rateLimitLevel(pct, resetsAt, windowSeconds, now) {
|
|
|
37646
38125
|
|
|
37647
38126
|
// src/commands/buildLimitsSegment.ts
|
|
37648
38127
|
var LEVEL_COLOR = {
|
|
37649
|
-
ok:
|
|
37650
|
-
warn:
|
|
37651
|
-
over:
|
|
38128
|
+
ok: chalk219.green,
|
|
38129
|
+
warn: chalk219.yellow,
|
|
38130
|
+
over: chalk219.red
|
|
37652
38131
|
};
|
|
37653
38132
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel, now) {
|
|
37654
38133
|
const level = rateLimitLevel(pct, resetsAt, windowSeconds, now);
|
|
@@ -37679,7 +38158,7 @@ function buildLimitsSegment(rateLimits) {
|
|
|
37679
38158
|
}
|
|
37680
38159
|
|
|
37681
38160
|
// src/commands/readGitBranch.ts
|
|
37682
|
-
import { readFileSync as
|
|
38161
|
+
import { readFileSync as readFileSync59, statSync as statSync15 } from "fs";
|
|
37683
38162
|
import { isAbsolute as isAbsolute4, join as join95, resolve as resolve22 } from "path";
|
|
37684
38163
|
function resolveGitDir(cwd) {
|
|
37685
38164
|
const dotGit = join95(cwd, ".git");
|
|
@@ -37694,7 +38173,7 @@ function resolveGitDir(cwd) {
|
|
|
37694
38173
|
}
|
|
37695
38174
|
let contents;
|
|
37696
38175
|
try {
|
|
37697
|
-
contents =
|
|
38176
|
+
contents = readFileSync59(dotGit, "utf8");
|
|
37698
38177
|
} catch {
|
|
37699
38178
|
return null;
|
|
37700
38179
|
}
|
|
@@ -37712,7 +38191,7 @@ function readGitBranch(cwd) {
|
|
|
37712
38191
|
}
|
|
37713
38192
|
let head;
|
|
37714
38193
|
try {
|
|
37715
|
-
head =
|
|
38194
|
+
head = readFileSync59(join95(gitDir, "HEAD"), "utf8");
|
|
37716
38195
|
} catch {
|
|
37717
38196
|
return null;
|
|
37718
38197
|
}
|
|
@@ -37744,7 +38223,7 @@ async function relayUsage(claudeSessionId, transcriptPath2, usedPct) {
|
|
|
37744
38223
|
}
|
|
37745
38224
|
|
|
37746
38225
|
// src/commands/statusLine.ts
|
|
37747
|
-
|
|
38226
|
+
chalk220.level = 3;
|
|
37748
38227
|
function formatNumber(num) {
|
|
37749
38228
|
return num.toLocaleString("en-US");
|
|
37750
38229
|
}
|
|
@@ -37752,9 +38231,9 @@ function colorizePercent(pct) {
|
|
|
37752
38231
|
const label2 = `${Math.round(pct)}%`;
|
|
37753
38232
|
switch (contextLevel(pct)) {
|
|
37754
38233
|
case "red":
|
|
37755
|
-
return
|
|
38234
|
+
return chalk220.red(label2);
|
|
37756
38235
|
case "yellow":
|
|
37757
|
-
return
|
|
38236
|
+
return chalk220.yellow(label2);
|
|
37758
38237
|
default:
|
|
37759
38238
|
return label2;
|
|
37760
38239
|
}
|
|
@@ -37767,7 +38246,7 @@ async function statusLine() {
|
|
|
37767
38246
|
const usedPct = data.context_window.used_percentage ?? 0;
|
|
37768
38247
|
const dir = data.workspace?.current_dir ?? data.cwd;
|
|
37769
38248
|
const branch2 = dir ? readGitBranch(toGitCwd(dir)) : null;
|
|
37770
|
-
const branchSegment = branch2 ? `\u{1F33F}\uFE0F ${
|
|
38249
|
+
const branchSegment = branch2 ? `\u{1F33F}\uFE0F ${chalk220.cyan(branch2)} | ` : "";
|
|
37771
38250
|
console.log(
|
|
37772
38251
|
`${branchSegment}${model} | Tokens - ${formatNumber(totalIn)} \u2191 : ${formatNumber(totalOut)} \u2193 | Context - ${colorizePercent(usedPct)}${buildLimitsSegment(data.rate_limits)}`
|
|
37773
38252
|
);
|
|
@@ -37837,10 +38316,10 @@ async function update2() {
|
|
|
37837
38316
|
}
|
|
37838
38317
|
|
|
37839
38318
|
// src/reportCliError.ts
|
|
37840
|
-
import
|
|
38319
|
+
import chalk221 from "chalk";
|
|
37841
38320
|
function reportCliError(error) {
|
|
37842
38321
|
if (error instanceof InvalidItemIdError || error instanceof AmbiguousRepoConfigError || error instanceof UnknownRepoConfigError || error instanceof MissingRunCwdError) {
|
|
37843
|
-
console.error(
|
|
38322
|
+
console.error(chalk221.red(error.message));
|
|
37844
38323
|
} else {
|
|
37845
38324
|
console.error(error);
|
|
37846
38325
|
}
|