@staff0rd/assist 0.195.2 → 0.196.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 +2 -0
- package/claude/commands/prompts.md +22 -0
- package/claude/settings.json +2 -0
- package/dist/index.js +388 -272
- 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.196.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -4844,6 +4844,9 @@ function registerBacklog(program2) {
|
|
|
4844
4844
|
registerUpdateCommands(cmd);
|
|
4845
4845
|
}
|
|
4846
4846
|
|
|
4847
|
+
// src/commands/cliHook/index.ts
|
|
4848
|
+
import { basename as basename2 } from "path";
|
|
4849
|
+
|
|
4847
4850
|
// src/shared/splitCompound.ts
|
|
4848
4851
|
import { parse } from "shell-quote";
|
|
4849
4852
|
|
|
@@ -4861,7 +4864,7 @@ function hasUnquotedBackticks(command) {
|
|
|
4861
4864
|
var SEPARATOR_OPS = /* @__PURE__ */ new Set(["|", "&&", "||", ";"]);
|
|
4862
4865
|
var UNSAFE_OPS = /* @__PURE__ */ new Set(["(", ")", ">", ">>", "<", "<&", "|&", ">&"]);
|
|
4863
4866
|
var FD_REDIRECT_RE = /\d+>&\d+/g;
|
|
4864
|
-
var FD_DEVNULL_RE = /\d
|
|
4867
|
+
var FD_DEVNULL_RE = /\d*>(?:\/dev\/null|\$null)/g;
|
|
4865
4868
|
function splitCompound(command) {
|
|
4866
4869
|
const tokens = tokenizeCommand(command);
|
|
4867
4870
|
if (!tokens) return void 0;
|
|
@@ -4908,6 +4911,52 @@ function stripEnvPrefix(parts) {
|
|
|
4908
4911
|
return i > 0 ? parts.slice(i) : parts;
|
|
4909
4912
|
}
|
|
4910
4913
|
|
|
4914
|
+
// src/commands/cliHook/logDeniedToolCall.ts
|
|
4915
|
+
import { mkdirSync as mkdirSync5 } from "fs";
|
|
4916
|
+
import { homedir as homedir3 } from "os";
|
|
4917
|
+
import { join as join18 } from "path";
|
|
4918
|
+
import Database2 from "better-sqlite3";
|
|
4919
|
+
var _db2;
|
|
4920
|
+
function getDbDir() {
|
|
4921
|
+
return join18(homedir3(), ".assist");
|
|
4922
|
+
}
|
|
4923
|
+
function initSchema2(db) {
|
|
4924
|
+
db.exec(`
|
|
4925
|
+
CREATE TABLE IF NOT EXISTS denied_tool_calls (
|
|
4926
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
4927
|
+
tool TEXT NOT NULL,
|
|
4928
|
+
command TEXT NOT NULL,
|
|
4929
|
+
repo TEXT NOT NULL,
|
|
4930
|
+
session_id TEXT,
|
|
4931
|
+
deny_reason TEXT NOT NULL,
|
|
4932
|
+
timestamp TEXT NOT NULL DEFAULT (datetime('now'))
|
|
4933
|
+
);
|
|
4934
|
+
`);
|
|
4935
|
+
}
|
|
4936
|
+
function openPromptsDb(dir) {
|
|
4937
|
+
if (_db2) return _db2;
|
|
4938
|
+
const dbDir = dir ?? getDbDir();
|
|
4939
|
+
mkdirSync5(dbDir, { recursive: true });
|
|
4940
|
+
const db = new Database2(join18(dbDir, "assist.db"));
|
|
4941
|
+
db.pragma("journal_mode = WAL");
|
|
4942
|
+
initSchema2(db);
|
|
4943
|
+
_db2 = db;
|
|
4944
|
+
return db;
|
|
4945
|
+
}
|
|
4946
|
+
function logDeniedToolCall(entry) {
|
|
4947
|
+
const db = openPromptsDb();
|
|
4948
|
+
db.prepare(
|
|
4949
|
+
`INSERT INTO denied_tool_calls (tool, command, repo, session_id, deny_reason)
|
|
4950
|
+
VALUES (@tool, @command, @repo, @sessionId, @denyReason)`
|
|
4951
|
+
).run({
|
|
4952
|
+
tool: entry.tool,
|
|
4953
|
+
command: entry.command,
|
|
4954
|
+
repo: entry.repo,
|
|
4955
|
+
sessionId: entry.sessionId ?? null,
|
|
4956
|
+
denyReason: entry.denyReason
|
|
4957
|
+
});
|
|
4958
|
+
}
|
|
4959
|
+
|
|
4911
4960
|
// src/shared/isApprovedRead.ts
|
|
4912
4961
|
import { resolve as resolve7, sep } from "path";
|
|
4913
4962
|
|
|
@@ -5047,13 +5096,13 @@ function findCliWrite(command) {
|
|
|
5047
5096
|
|
|
5048
5097
|
// src/shared/readSettingsPerms.ts
|
|
5049
5098
|
import { existsSync as existsSync21, readFileSync as readFileSync17 } from "fs";
|
|
5050
|
-
import { homedir as
|
|
5051
|
-
import { join as
|
|
5099
|
+
import { homedir as homedir4 } from "os";
|
|
5100
|
+
import { join as join19 } from "path";
|
|
5052
5101
|
function readSettingsPerms(key) {
|
|
5053
5102
|
const paths = [
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5103
|
+
join19(homedir4(), ".claude", "settings.json"),
|
|
5104
|
+
join19(process.cwd(), ".claude", "settings.json"),
|
|
5105
|
+
join19(process.cwd(), ".claude", "settings.local.json")
|
|
5057
5106
|
];
|
|
5058
5107
|
const entries = [];
|
|
5059
5108
|
for (const p of paths) {
|
|
@@ -5079,7 +5128,7 @@ var TOOL_RE = /^(Bash|PowerShell)\((.+?)(:.*)?\)$/;
|
|
|
5079
5128
|
var SHELL_TOOLS = ["Bash", "PowerShell"];
|
|
5080
5129
|
var DOTSLASH_RE = /^\.[\\/]/;
|
|
5081
5130
|
var FD_REDIRECT_RE2 = /\d+>&\d+/g;
|
|
5082
|
-
var FD_DEVNULL_RE2 = /\d
|
|
5131
|
+
var FD_DEVNULL_RE2 = /\d*>(?:\/dev\/null|\$null)/g;
|
|
5083
5132
|
function loadPerms(key) {
|
|
5084
5133
|
return parsePerms(readSettingsPerms(key));
|
|
5085
5134
|
}
|
|
@@ -5247,6 +5296,18 @@ async function cliHook() {
|
|
|
5247
5296
|
hookSpecificOutput: { hookEventName: "PreToolUse", ...decision }
|
|
5248
5297
|
})
|
|
5249
5298
|
);
|
|
5299
|
+
if (decision.permissionDecision === "deny") {
|
|
5300
|
+
try {
|
|
5301
|
+
logDeniedToolCall({
|
|
5302
|
+
tool: input.toolName,
|
|
5303
|
+
command: input.command,
|
|
5304
|
+
repo: basename2(process.cwd()),
|
|
5305
|
+
sessionId: process.env.CLAUDE_SESSION_ID,
|
|
5306
|
+
denyReason: decision.permissionDecisionReason
|
|
5307
|
+
});
|
|
5308
|
+
} catch {
|
|
5309
|
+
}
|
|
5310
|
+
}
|
|
5250
5311
|
}
|
|
5251
5312
|
|
|
5252
5313
|
// src/commands/cliHook/cliHookCheck.ts
|
|
@@ -5281,9 +5342,9 @@ ${reasons.join("\n")}`);
|
|
|
5281
5342
|
}
|
|
5282
5343
|
|
|
5283
5344
|
// src/commands/permitCliReads/index.ts
|
|
5284
|
-
import { existsSync as existsSync22, mkdirSync as
|
|
5285
|
-
import { homedir as
|
|
5286
|
-
import { join as
|
|
5345
|
+
import { existsSync as existsSync22, mkdirSync as mkdirSync6, readFileSync as readFileSync18, writeFileSync as writeFileSync17 } from "fs";
|
|
5346
|
+
import { homedir as homedir5 } from "os";
|
|
5347
|
+
import { join as join20 } from "path";
|
|
5287
5348
|
|
|
5288
5349
|
// src/shared/getInstallDir.ts
|
|
5289
5350
|
import { execSync as execSync16 } from "child_process";
|
|
@@ -5585,7 +5646,7 @@ function updateSettings(cli, commands) {
|
|
|
5585
5646
|
// src/commands/permitCliReads/index.ts
|
|
5586
5647
|
function logPath(cli) {
|
|
5587
5648
|
const safeName = cli.replace(/\s+/g, "-");
|
|
5588
|
-
return
|
|
5649
|
+
return join20(homedir5(), ".assist", `cli-discover-${safeName}.log`);
|
|
5589
5650
|
}
|
|
5590
5651
|
function readCache(cli) {
|
|
5591
5652
|
const path52 = logPath(cli);
|
|
@@ -5593,8 +5654,8 @@ function readCache(cli) {
|
|
|
5593
5654
|
return readFileSync18(path52, "utf-8");
|
|
5594
5655
|
}
|
|
5595
5656
|
function writeCache(cli, output) {
|
|
5596
|
-
const dir =
|
|
5597
|
-
|
|
5657
|
+
const dir = join20(homedir5(), ".assist");
|
|
5658
|
+
mkdirSync6(dir, { recursive: true });
|
|
5598
5659
|
writeFileSync17(logPath(cli), output);
|
|
5599
5660
|
}
|
|
5600
5661
|
async function permitCliReads(cli, options2 = { noCache: false }) {
|
|
@@ -6386,14 +6447,14 @@ function registerDeploy(program2) {
|
|
|
6386
6447
|
|
|
6387
6448
|
// src/commands/devlog/list/index.ts
|
|
6388
6449
|
import { execSync as execSync19 } from "child_process";
|
|
6389
|
-
import { basename as
|
|
6450
|
+
import { basename as basename4 } from "path";
|
|
6390
6451
|
|
|
6391
6452
|
// src/commands/devlog/loadBlogSkipDays.ts
|
|
6392
|
-
import { homedir as
|
|
6393
|
-
import { join as
|
|
6394
|
-
var BLOG_REPO_ROOT =
|
|
6453
|
+
import { homedir as homedir6 } from "os";
|
|
6454
|
+
import { join as join21 } from "path";
|
|
6455
|
+
var BLOG_REPO_ROOT = join21(homedir6(), "git/blog");
|
|
6395
6456
|
function loadBlogSkipDays(repoName) {
|
|
6396
|
-
const config = loadRawYaml(
|
|
6457
|
+
const config = loadRawYaml(join21(BLOG_REPO_ROOT, "assist.yml"));
|
|
6397
6458
|
const devlog = config.devlog;
|
|
6398
6459
|
const skip2 = devlog?.skip;
|
|
6399
6460
|
return new Set(skip2?.[repoName] ?? []);
|
|
@@ -6405,13 +6466,13 @@ import chalk77 from "chalk";
|
|
|
6405
6466
|
|
|
6406
6467
|
// src/shared/getRepoName.ts
|
|
6407
6468
|
import { existsSync as existsSync24, readFileSync as readFileSync20 } from "fs";
|
|
6408
|
-
import { basename as
|
|
6469
|
+
import { basename as basename3, join as join22 } from "path";
|
|
6409
6470
|
function getRepoName() {
|
|
6410
6471
|
const config = loadConfig();
|
|
6411
6472
|
if (config.devlog?.name) {
|
|
6412
6473
|
return config.devlog.name;
|
|
6413
6474
|
}
|
|
6414
|
-
const packageJsonPath =
|
|
6475
|
+
const packageJsonPath = join22(process.cwd(), "package.json");
|
|
6415
6476
|
if (existsSync24(packageJsonPath)) {
|
|
6416
6477
|
try {
|
|
6417
6478
|
const content = readFileSync20(packageJsonPath, "utf-8");
|
|
@@ -6422,13 +6483,13 @@ function getRepoName() {
|
|
|
6422
6483
|
} catch {
|
|
6423
6484
|
}
|
|
6424
6485
|
}
|
|
6425
|
-
return
|
|
6486
|
+
return basename3(process.cwd());
|
|
6426
6487
|
}
|
|
6427
6488
|
|
|
6428
6489
|
// src/commands/devlog/loadDevlogEntries.ts
|
|
6429
6490
|
import { readdirSync, readFileSync as readFileSync21 } from "fs";
|
|
6430
|
-
import { join as
|
|
6431
|
-
var DEVLOG_DIR =
|
|
6491
|
+
import { join as join23 } from "path";
|
|
6492
|
+
var DEVLOG_DIR = join23(BLOG_REPO_ROOT, "src/content/devlog");
|
|
6432
6493
|
function extractFrontmatter(content) {
|
|
6433
6494
|
const fm = content.match(/^---\n([\s\S]*?)\n---/);
|
|
6434
6495
|
return fm?.[1] ?? null;
|
|
@@ -6456,7 +6517,7 @@ function readDevlogFiles(callback) {
|
|
|
6456
6517
|
try {
|
|
6457
6518
|
const files = readdirSync(DEVLOG_DIR).filter((f) => f.endsWith(".md"));
|
|
6458
6519
|
for (const file of files) {
|
|
6459
|
-
const content = readFileSync21(
|
|
6520
|
+
const content = readFileSync21(join23(DEVLOG_DIR, file), "utf-8");
|
|
6460
6521
|
const parsed = parseFrontmatter(content, file);
|
|
6461
6522
|
if (parsed) callback(parsed);
|
|
6462
6523
|
}
|
|
@@ -6558,7 +6619,7 @@ function list3(options2) {
|
|
|
6558
6619
|
const config = loadConfig();
|
|
6559
6620
|
const days = options2.days ?? 30;
|
|
6560
6621
|
const ignore2 = options2.ignore ?? config.devlog?.ignore ?? [];
|
|
6561
|
-
const repoName =
|
|
6622
|
+
const repoName = basename4(process.cwd());
|
|
6562
6623
|
const skipDays = loadBlogSkipDays(repoName);
|
|
6563
6624
|
const devlogEntries = loadDevlogEntries(repoName);
|
|
6564
6625
|
const reverseFlag = options2.reverse ? "--reverse " : "";
|
|
@@ -6843,11 +6904,11 @@ function repos(options2) {
|
|
|
6843
6904
|
|
|
6844
6905
|
// src/commands/devlog/skip.ts
|
|
6845
6906
|
import { writeFileSync as writeFileSync19 } from "fs";
|
|
6846
|
-
import { join as
|
|
6907
|
+
import { join as join24 } from "path";
|
|
6847
6908
|
import chalk82 from "chalk";
|
|
6848
6909
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
6849
6910
|
function getBlogConfigPath() {
|
|
6850
|
-
return
|
|
6911
|
+
return join24(BLOG_REPO_ROOT, "assist.yml");
|
|
6851
6912
|
}
|
|
6852
6913
|
function skip(date) {
|
|
6853
6914
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
@@ -6908,7 +6969,7 @@ function registerDevlog(program2) {
|
|
|
6908
6969
|
|
|
6909
6970
|
// src/commands/dotnet/checkBuildLocks.ts
|
|
6910
6971
|
import { closeSync, openSync, readdirSync as readdirSync2 } from "fs";
|
|
6911
|
-
import { join as
|
|
6972
|
+
import { join as join25 } from "path";
|
|
6912
6973
|
import chalk84 from "chalk";
|
|
6913
6974
|
|
|
6914
6975
|
// src/shared/findRepoRoot.ts
|
|
@@ -6936,7 +6997,7 @@ function isLockedDll(debugDir) {
|
|
|
6936
6997
|
}
|
|
6937
6998
|
for (const file of files) {
|
|
6938
6999
|
if (!file.toLowerCase().endsWith(".dll")) continue;
|
|
6939
|
-
const dllPath =
|
|
7000
|
+
const dllPath = join25(debugDir, file);
|
|
6940
7001
|
try {
|
|
6941
7002
|
const fd = openSync(dllPath, "r+");
|
|
6942
7003
|
closeSync(fd);
|
|
@@ -6954,13 +7015,13 @@ function findFirstLockedDll(dir) {
|
|
|
6954
7015
|
return null;
|
|
6955
7016
|
}
|
|
6956
7017
|
if (entries.includes("bin")) {
|
|
6957
|
-
const locked = isLockedDll(
|
|
7018
|
+
const locked = isLockedDll(join25(dir, "bin", "Debug"));
|
|
6958
7019
|
if (locked) return locked;
|
|
6959
7020
|
}
|
|
6960
7021
|
for (const entry of entries) {
|
|
6961
7022
|
if (SKIP_DIRS.has(entry) || entry === "bin" || entry.startsWith("."))
|
|
6962
7023
|
continue;
|
|
6963
|
-
const found = findFirstLockedDll(
|
|
7024
|
+
const found = findFirstLockedDll(join25(dir, entry));
|
|
6964
7025
|
if (found) return found;
|
|
6965
7026
|
}
|
|
6966
7027
|
return null;
|
|
@@ -7307,11 +7368,11 @@ import chalk90 from "chalk";
|
|
|
7307
7368
|
|
|
7308
7369
|
// src/commands/dotnet/findSolution.ts
|
|
7309
7370
|
import { readdirSync as readdirSync4 } from "fs";
|
|
7310
|
-
import { dirname as dirname17, join as
|
|
7371
|
+
import { dirname as dirname17, join as join26 } from "path";
|
|
7311
7372
|
import chalk89 from "chalk";
|
|
7312
7373
|
function findSlnInDir(dir) {
|
|
7313
7374
|
try {
|
|
7314
|
-
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) =>
|
|
7375
|
+
return readdirSync4(dir).filter((f) => f.endsWith(".sln")).map((f) => join26(dir, f));
|
|
7315
7376
|
} catch {
|
|
7316
7377
|
return [];
|
|
7317
7378
|
}
|
|
@@ -7646,14 +7707,14 @@ function acceptanceCriteria(issueKey) {
|
|
|
7646
7707
|
import { execSync as execSync27 } from "child_process";
|
|
7647
7708
|
|
|
7648
7709
|
// src/shared/loadJson.ts
|
|
7649
|
-
import { existsSync as existsSync29, mkdirSync as
|
|
7650
|
-
import { homedir as
|
|
7651
|
-
import { join as
|
|
7710
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync7, readFileSync as readFileSync25, writeFileSync as writeFileSync20 } from "fs";
|
|
7711
|
+
import { homedir as homedir7 } from "os";
|
|
7712
|
+
import { join as join27 } from "path";
|
|
7652
7713
|
function getStoreDir() {
|
|
7653
|
-
return
|
|
7714
|
+
return join27(homedir7(), ".assist");
|
|
7654
7715
|
}
|
|
7655
7716
|
function getStorePath(filename) {
|
|
7656
|
-
return
|
|
7717
|
+
return join27(getStoreDir(), filename);
|
|
7657
7718
|
}
|
|
7658
7719
|
function loadJson(filename) {
|
|
7659
7720
|
const path52 = getStorePath(filename);
|
|
@@ -7669,7 +7730,7 @@ function loadJson(filename) {
|
|
|
7669
7730
|
function saveJson(filename, data) {
|
|
7670
7731
|
const dir = getStoreDir();
|
|
7671
7732
|
if (!existsSync29(dir)) {
|
|
7672
|
-
|
|
7733
|
+
mkdirSync7(dir, { recursive: true });
|
|
7673
7734
|
}
|
|
7674
7735
|
writeFileSync20(getStorePath(filename), JSON.stringify(data, null, 2));
|
|
7675
7736
|
}
|
|
@@ -7981,11 +8042,65 @@ function registerNews(program2) {
|
|
|
7981
8042
|
newsCommand.command("web").description("Start a web view of the news feeds").option("-p, --port <number>", "Port to listen on", "3001").action(web2);
|
|
7982
8043
|
}
|
|
7983
8044
|
|
|
8045
|
+
// src/commands/prompts/printPromptsTable.ts
|
|
8046
|
+
import chalk99 from "chalk";
|
|
8047
|
+
function truncate(str, max) {
|
|
8048
|
+
if (str.length <= max) return str;
|
|
8049
|
+
return `${str.slice(0, max - 1)}\u2026`;
|
|
8050
|
+
}
|
|
8051
|
+
function printPromptsTable(rows) {
|
|
8052
|
+
const countWidth = 5;
|
|
8053
|
+
const toolWidth = Math.max(4, ...rows.map((r) => r.tool.length));
|
|
8054
|
+
const commandWidth = Math.max(
|
|
8055
|
+
7,
|
|
8056
|
+
...rows.map((r) => truncate(r.command, 60).length)
|
|
8057
|
+
);
|
|
8058
|
+
const header = [
|
|
8059
|
+
"#".padStart(countWidth),
|
|
8060
|
+
"Tool".padEnd(toolWidth),
|
|
8061
|
+
"Command".padEnd(commandWidth),
|
|
8062
|
+
"Repos"
|
|
8063
|
+
].join(" ");
|
|
8064
|
+
console.log(chalk99.dim(header));
|
|
8065
|
+
console.log(chalk99.dim("-".repeat(header.length)));
|
|
8066
|
+
for (const row of rows) {
|
|
8067
|
+
const count = String(row.count).padStart(countWidth);
|
|
8068
|
+
const tool = row.tool.padEnd(toolWidth);
|
|
8069
|
+
const command = truncate(row.command, 60).padEnd(commandWidth);
|
|
8070
|
+
console.log(
|
|
8071
|
+
`${chalk99.yellow(count)} ${tool} ${command} ${chalk99.dim(row.repos)}`
|
|
8072
|
+
);
|
|
8073
|
+
}
|
|
8074
|
+
}
|
|
8075
|
+
|
|
8076
|
+
// src/commands/prompts/prompts.ts
|
|
8077
|
+
function prompts2() {
|
|
8078
|
+
const db = openPromptsDb();
|
|
8079
|
+
const rows = db.prepare(
|
|
8080
|
+
`SELECT tool, command, COUNT(*) as count,
|
|
8081
|
+
GROUP_CONCAT(DISTINCT repo) as repos
|
|
8082
|
+
FROM denied_tool_calls
|
|
8083
|
+
GROUP BY tool, command
|
|
8084
|
+
ORDER BY count DESC
|
|
8085
|
+
LIMIT 10`
|
|
8086
|
+
).all();
|
|
8087
|
+
if (rows.length === 0) {
|
|
8088
|
+
console.log("No denied tool calls recorded yet.");
|
|
8089
|
+
return;
|
|
8090
|
+
}
|
|
8091
|
+
printPromptsTable(rows);
|
|
8092
|
+
}
|
|
8093
|
+
|
|
8094
|
+
// src/commands/registerPrompts.ts
|
|
8095
|
+
function registerPrompts(program2) {
|
|
8096
|
+
program2.command("prompts").description("Show top denied tool calls by frequency").action(prompts2);
|
|
8097
|
+
}
|
|
8098
|
+
|
|
7984
8099
|
// src/commands/prs/comment.ts
|
|
7985
8100
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
7986
8101
|
import { unlinkSync as unlinkSync6, writeFileSync as writeFileSync21 } from "fs";
|
|
7987
8102
|
import { tmpdir as tmpdir3 } from "os";
|
|
7988
|
-
import { join as
|
|
8103
|
+
import { join as join28 } from "path";
|
|
7989
8104
|
|
|
7990
8105
|
// src/commands/prs/shared.ts
|
|
7991
8106
|
import { execSync as execSync28 } from "child_process";
|
|
@@ -8057,7 +8172,7 @@ function comment2(path52, line, body) {
|
|
|
8057
8172
|
validateLine(line);
|
|
8058
8173
|
try {
|
|
8059
8174
|
const prId = getCurrentPrNodeId();
|
|
8060
|
-
const queryFile =
|
|
8175
|
+
const queryFile = join28(tmpdir3(), `gh-query-${Date.now()}.graphql`);
|
|
8061
8176
|
writeFileSync21(queryFile, MUTATION);
|
|
8062
8177
|
try {
|
|
8063
8178
|
const result = spawnSync2(
|
|
@@ -8102,14 +8217,14 @@ import { execSync as execSync30 } from "child_process";
|
|
|
8102
8217
|
import { execSync as execSync29 } from "child_process";
|
|
8103
8218
|
import { unlinkSync as unlinkSync8, writeFileSync as writeFileSync22 } from "fs";
|
|
8104
8219
|
import { tmpdir as tmpdir4 } from "os";
|
|
8105
|
-
import { join as
|
|
8220
|
+
import { join as join30 } from "path";
|
|
8106
8221
|
|
|
8107
8222
|
// src/commands/prs/loadCommentsCache.ts
|
|
8108
8223
|
import { existsSync as existsSync30, readFileSync as readFileSync26, unlinkSync as unlinkSync7 } from "fs";
|
|
8109
|
-
import { join as
|
|
8224
|
+
import { join as join29 } from "path";
|
|
8110
8225
|
import { parse as parse2 } from "yaml";
|
|
8111
8226
|
function getCachePath(prNumber) {
|
|
8112
|
-
return
|
|
8227
|
+
return join29(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`);
|
|
8113
8228
|
}
|
|
8114
8229
|
function loadCommentsCache(prNumber) {
|
|
8115
8230
|
const cachePath = getCachePath(prNumber);
|
|
@@ -8136,7 +8251,7 @@ function replyToComment(org, repo, prNumber, commentId, message) {
|
|
|
8136
8251
|
}
|
|
8137
8252
|
function resolveThread(threadId) {
|
|
8138
8253
|
const mutation = `mutation($threadId: ID!) { resolveReviewThread(input: {threadId: $threadId}) { thread { isResolved } } }`;
|
|
8139
|
-
const queryFile =
|
|
8254
|
+
const queryFile = join30(tmpdir4(), `gh-mutation-${Date.now()}.graphql`);
|
|
8140
8255
|
writeFileSync22(queryFile, mutation);
|
|
8141
8256
|
try {
|
|
8142
8257
|
execSync29(
|
|
@@ -8218,18 +8333,18 @@ function fixed(commentId, sha) {
|
|
|
8218
8333
|
}
|
|
8219
8334
|
|
|
8220
8335
|
// src/commands/prs/listComments/index.ts
|
|
8221
|
-
import { existsSync as existsSync31, mkdirSync as
|
|
8222
|
-
import { join as
|
|
8336
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync8, writeFileSync as writeFileSync24 } from "fs";
|
|
8337
|
+
import { join as join32 } from "path";
|
|
8223
8338
|
import { stringify } from "yaml";
|
|
8224
8339
|
|
|
8225
8340
|
// src/commands/prs/fetchThreadIds.ts
|
|
8226
8341
|
import { execSync as execSync31 } from "child_process";
|
|
8227
8342
|
import { unlinkSync as unlinkSync9, writeFileSync as writeFileSync23 } from "fs";
|
|
8228
8343
|
import { tmpdir as tmpdir5 } from "os";
|
|
8229
|
-
import { join as
|
|
8344
|
+
import { join as join31 } from "path";
|
|
8230
8345
|
var THREAD_QUERY = `query($owner: String!, $repo: String!, $prNumber: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $prNumber) { reviewThreads(first: 100) { nodes { id isResolved comments(first: 100) { nodes { databaseId } } } } } } }`;
|
|
8231
8346
|
function fetchThreadIds(org, repo, prNumber) {
|
|
8232
|
-
const queryFile =
|
|
8347
|
+
const queryFile = join31(tmpdir5(), `gh-query-${Date.now()}.graphql`);
|
|
8233
8348
|
writeFileSync23(queryFile, THREAD_QUERY);
|
|
8234
8349
|
try {
|
|
8235
8350
|
const result = execSync31(
|
|
@@ -8298,20 +8413,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
|
|
|
8298
8413
|
}
|
|
8299
8414
|
|
|
8300
8415
|
// src/commands/prs/listComments/printComments.ts
|
|
8301
|
-
import
|
|
8416
|
+
import chalk100 from "chalk";
|
|
8302
8417
|
function formatForHuman(comment3) {
|
|
8303
8418
|
if (comment3.type === "review") {
|
|
8304
|
-
const stateColor = comment3.state === "APPROVED" ?
|
|
8419
|
+
const stateColor = comment3.state === "APPROVED" ? chalk100.green : comment3.state === "CHANGES_REQUESTED" ? chalk100.red : chalk100.yellow;
|
|
8305
8420
|
return [
|
|
8306
|
-
`${
|
|
8421
|
+
`${chalk100.cyan("Review")} by ${chalk100.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
|
|
8307
8422
|
comment3.body,
|
|
8308
8423
|
""
|
|
8309
8424
|
].join("\n");
|
|
8310
8425
|
}
|
|
8311
8426
|
const location = comment3.line ? `:${comment3.line}` : "";
|
|
8312
8427
|
return [
|
|
8313
|
-
`${
|
|
8314
|
-
|
|
8428
|
+
`${chalk100.cyan("Line comment")} by ${chalk100.bold(comment3.user)} on ${chalk100.dim(`${comment3.path}${location}`)}`,
|
|
8429
|
+
chalk100.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
|
|
8315
8430
|
comment3.body,
|
|
8316
8431
|
""
|
|
8317
8432
|
].join("\n");
|
|
@@ -8343,16 +8458,16 @@ function printComments2(result) {
|
|
|
8343
8458
|
|
|
8344
8459
|
// src/commands/prs/listComments/index.ts
|
|
8345
8460
|
function writeCommentsCache(prNumber, comments2) {
|
|
8346
|
-
const assistDir =
|
|
8461
|
+
const assistDir = join32(process.cwd(), ".assist");
|
|
8347
8462
|
if (!existsSync31(assistDir)) {
|
|
8348
|
-
|
|
8463
|
+
mkdirSync8(assistDir, { recursive: true });
|
|
8349
8464
|
}
|
|
8350
8465
|
const cacheData = {
|
|
8351
8466
|
prNumber,
|
|
8352
8467
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8353
8468
|
comments: comments2
|
|
8354
8469
|
};
|
|
8355
|
-
const cachePath =
|
|
8470
|
+
const cachePath = join32(assistDir, `pr-${prNumber}-comments.yaml`);
|
|
8356
8471
|
writeFileSync24(cachePath, stringify(cacheData));
|
|
8357
8472
|
}
|
|
8358
8473
|
function handleKnownErrors(error) {
|
|
@@ -8385,7 +8500,7 @@ async function listComments() {
|
|
|
8385
8500
|
];
|
|
8386
8501
|
updateCache(prNumber, allComments);
|
|
8387
8502
|
const hasLineComments = allComments.some((c) => c.type === "line");
|
|
8388
|
-
const cachePath = hasLineComments ?
|
|
8503
|
+
const cachePath = hasLineComments ? join32(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`) : null;
|
|
8389
8504
|
return { comments: allComments, cachePath };
|
|
8390
8505
|
} catch (error) {
|
|
8391
8506
|
const handled = handleKnownErrors(error);
|
|
@@ -8401,13 +8516,13 @@ import { execSync as execSync33 } from "child_process";
|
|
|
8401
8516
|
import enquirer9 from "enquirer";
|
|
8402
8517
|
|
|
8403
8518
|
// src/commands/prs/prs/displayPaginated/printPr.ts
|
|
8404
|
-
import
|
|
8519
|
+
import chalk101 from "chalk";
|
|
8405
8520
|
var STATUS_MAP = {
|
|
8406
|
-
MERGED: (pr) => pr.mergedAt ? { label:
|
|
8407
|
-
CLOSED: (pr) => pr.closedAt ? { label:
|
|
8521
|
+
MERGED: (pr) => pr.mergedAt ? { label: chalk101.magenta("merged"), date: pr.mergedAt } : null,
|
|
8522
|
+
CLOSED: (pr) => pr.closedAt ? { label: chalk101.red("closed"), date: pr.closedAt } : null
|
|
8408
8523
|
};
|
|
8409
8524
|
function defaultStatus(pr) {
|
|
8410
|
-
return { label:
|
|
8525
|
+
return { label: chalk101.green("opened"), date: pr.createdAt };
|
|
8411
8526
|
}
|
|
8412
8527
|
function getStatus2(pr) {
|
|
8413
8528
|
return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
|
|
@@ -8416,11 +8531,11 @@ function formatDate(dateStr) {
|
|
|
8416
8531
|
return new Date(dateStr).toISOString().split("T")[0];
|
|
8417
8532
|
}
|
|
8418
8533
|
function formatPrHeader(pr, status2) {
|
|
8419
|
-
return `${
|
|
8534
|
+
return `${chalk101.cyan(`#${pr.number}`)} ${pr.title} ${chalk101.dim(`(${pr.author.login},`)} ${status2.label} ${chalk101.dim(`${formatDate(status2.date)})`)}`;
|
|
8420
8535
|
}
|
|
8421
8536
|
function logPrDetails(pr) {
|
|
8422
8537
|
console.log(
|
|
8423
|
-
|
|
8538
|
+
chalk101.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
|
|
8424
8539
|
);
|
|
8425
8540
|
console.log();
|
|
8426
8541
|
}
|
|
@@ -8586,10 +8701,10 @@ function registerPrs(program2) {
|
|
|
8586
8701
|
}
|
|
8587
8702
|
|
|
8588
8703
|
// src/commands/ravendb/ravendbAuth.ts
|
|
8589
|
-
import
|
|
8704
|
+
import chalk107 from "chalk";
|
|
8590
8705
|
|
|
8591
8706
|
// src/shared/createConnectionAuth.ts
|
|
8592
|
-
import
|
|
8707
|
+
import chalk102 from "chalk";
|
|
8593
8708
|
function listConnections(connections, format2) {
|
|
8594
8709
|
if (connections.length === 0) {
|
|
8595
8710
|
console.log("No connections configured.");
|
|
@@ -8602,7 +8717,7 @@ function listConnections(connections, format2) {
|
|
|
8602
8717
|
function removeConnection(connections, name, save) {
|
|
8603
8718
|
const filtered = connections.filter((c) => c.name !== name);
|
|
8604
8719
|
if (filtered.length === connections.length) {
|
|
8605
|
-
console.error(
|
|
8720
|
+
console.error(chalk102.red(`Connection "${name}" not found.`));
|
|
8606
8721
|
process.exit(1);
|
|
8607
8722
|
}
|
|
8608
8723
|
save(filtered);
|
|
@@ -8648,15 +8763,15 @@ function saveConnections(connections) {
|
|
|
8648
8763
|
}
|
|
8649
8764
|
|
|
8650
8765
|
// src/commands/ravendb/promptConnection.ts
|
|
8651
|
-
import
|
|
8766
|
+
import chalk105 from "chalk";
|
|
8652
8767
|
|
|
8653
8768
|
// src/commands/ravendb/selectOpSecret.ts
|
|
8654
|
-
import
|
|
8769
|
+
import chalk104 from "chalk";
|
|
8655
8770
|
import Enquirer2 from "enquirer";
|
|
8656
8771
|
|
|
8657
8772
|
// src/commands/ravendb/searchItems.ts
|
|
8658
8773
|
import { execSync as execSync35 } from "child_process";
|
|
8659
|
-
import
|
|
8774
|
+
import chalk103 from "chalk";
|
|
8660
8775
|
function opExec(args) {
|
|
8661
8776
|
return execSync35(`op ${args}`, {
|
|
8662
8777
|
encoding: "utf-8",
|
|
@@ -8669,7 +8784,7 @@ function searchItems(search2) {
|
|
|
8669
8784
|
items = JSON.parse(opExec("item list --format=json"));
|
|
8670
8785
|
} catch {
|
|
8671
8786
|
console.error(
|
|
8672
|
-
|
|
8787
|
+
chalk103.red(
|
|
8673
8788
|
"Failed to search 1Password. Ensure the CLI is installed and you are signed in."
|
|
8674
8789
|
)
|
|
8675
8790
|
);
|
|
@@ -8683,7 +8798,7 @@ function getItemFields(itemId) {
|
|
|
8683
8798
|
const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
|
|
8684
8799
|
return item.fields.filter((f) => f.reference && f.label);
|
|
8685
8800
|
} catch {
|
|
8686
|
-
console.error(
|
|
8801
|
+
console.error(chalk103.red("Failed to get item details from 1Password."));
|
|
8687
8802
|
process.exit(1);
|
|
8688
8803
|
}
|
|
8689
8804
|
}
|
|
@@ -8702,7 +8817,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
8702
8817
|
}).run();
|
|
8703
8818
|
const items = searchItems(search2);
|
|
8704
8819
|
if (items.length === 0) {
|
|
8705
|
-
console.error(
|
|
8820
|
+
console.error(chalk104.red(`No items found matching "${search2}".`));
|
|
8706
8821
|
process.exit(1);
|
|
8707
8822
|
}
|
|
8708
8823
|
const itemId = await selectOne(
|
|
@@ -8711,7 +8826,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
8711
8826
|
);
|
|
8712
8827
|
const fields = getItemFields(itemId);
|
|
8713
8828
|
if (fields.length === 0) {
|
|
8714
|
-
console.error(
|
|
8829
|
+
console.error(chalk104.red("No fields with references found on this item."));
|
|
8715
8830
|
process.exit(1);
|
|
8716
8831
|
}
|
|
8717
8832
|
const ref = await selectOne(
|
|
@@ -8725,7 +8840,7 @@ async function selectOpSecret(searchTerm) {
|
|
|
8725
8840
|
async function promptConnection(existingNames) {
|
|
8726
8841
|
const name = await promptInput("name", "Connection name:");
|
|
8727
8842
|
if (existingNames.includes(name)) {
|
|
8728
|
-
console.error(
|
|
8843
|
+
console.error(chalk105.red(`Connection "${name}" already exists.`));
|
|
8729
8844
|
process.exit(1);
|
|
8730
8845
|
}
|
|
8731
8846
|
const url = await promptInput(
|
|
@@ -8734,22 +8849,22 @@ async function promptConnection(existingNames) {
|
|
|
8734
8849
|
);
|
|
8735
8850
|
const database = await promptInput("database", "Database name:");
|
|
8736
8851
|
if (!name || !url || !database) {
|
|
8737
|
-
console.error(
|
|
8852
|
+
console.error(chalk105.red("All fields are required."));
|
|
8738
8853
|
process.exit(1);
|
|
8739
8854
|
}
|
|
8740
8855
|
const apiKeyRef = await selectOpSecret();
|
|
8741
|
-
console.log(
|
|
8856
|
+
console.log(chalk105.dim(`Using: ${apiKeyRef}`));
|
|
8742
8857
|
return { name, url, database, apiKeyRef };
|
|
8743
8858
|
}
|
|
8744
8859
|
|
|
8745
8860
|
// src/commands/ravendb/ravendbSetConnection.ts
|
|
8746
|
-
import
|
|
8861
|
+
import chalk106 from "chalk";
|
|
8747
8862
|
function ravendbSetConnection(name) {
|
|
8748
8863
|
const raw = loadGlobalConfigRaw();
|
|
8749
8864
|
const ravendb = raw.ravendb ?? {};
|
|
8750
8865
|
const connections = ravendb.connections ?? [];
|
|
8751
8866
|
if (!connections.some((c) => c.name === name)) {
|
|
8752
|
-
console.error(
|
|
8867
|
+
console.error(chalk106.red(`Connection "${name}" not found.`));
|
|
8753
8868
|
console.error(
|
|
8754
8869
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
8755
8870
|
);
|
|
@@ -8765,16 +8880,16 @@ function ravendbSetConnection(name) {
|
|
|
8765
8880
|
var ravendbAuth = createConnectionAuth({
|
|
8766
8881
|
load: loadConnections,
|
|
8767
8882
|
save: saveConnections,
|
|
8768
|
-
format: (c) => `${
|
|
8883
|
+
format: (c) => `${chalk107.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
|
|
8769
8884
|
promptNew: promptConnection,
|
|
8770
8885
|
onFirst: (c) => ravendbSetConnection(c.name)
|
|
8771
8886
|
});
|
|
8772
8887
|
|
|
8773
8888
|
// src/commands/ravendb/ravendbCollections.ts
|
|
8774
|
-
import
|
|
8889
|
+
import chalk111 from "chalk";
|
|
8775
8890
|
|
|
8776
8891
|
// src/commands/ravendb/ravenFetch.ts
|
|
8777
|
-
import
|
|
8892
|
+
import chalk109 from "chalk";
|
|
8778
8893
|
|
|
8779
8894
|
// src/commands/ravendb/getAccessToken.ts
|
|
8780
8895
|
var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
|
|
@@ -8811,10 +8926,10 @@ ${errorText}`
|
|
|
8811
8926
|
|
|
8812
8927
|
// src/commands/ravendb/resolveOpSecret.ts
|
|
8813
8928
|
import { execSync as execSync36 } from "child_process";
|
|
8814
|
-
import
|
|
8929
|
+
import chalk108 from "chalk";
|
|
8815
8930
|
function resolveOpSecret(reference) {
|
|
8816
8931
|
if (!reference.startsWith("op://")) {
|
|
8817
|
-
console.error(
|
|
8932
|
+
console.error(chalk108.red(`Invalid secret reference: must start with op://`));
|
|
8818
8933
|
process.exit(1);
|
|
8819
8934
|
}
|
|
8820
8935
|
try {
|
|
@@ -8824,7 +8939,7 @@ function resolveOpSecret(reference) {
|
|
|
8824
8939
|
}).trim();
|
|
8825
8940
|
} catch {
|
|
8826
8941
|
console.error(
|
|
8827
|
-
|
|
8942
|
+
chalk108.red(
|
|
8828
8943
|
"Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
|
|
8829
8944
|
)
|
|
8830
8945
|
);
|
|
@@ -8851,7 +8966,7 @@ async function ravenFetch(connection, path52) {
|
|
|
8851
8966
|
if (!response.ok) {
|
|
8852
8967
|
const body = await response.text();
|
|
8853
8968
|
console.error(
|
|
8854
|
-
|
|
8969
|
+
chalk109.red(`RavenDB error: ${response.status} ${response.statusText}`)
|
|
8855
8970
|
);
|
|
8856
8971
|
console.error(body.substring(0, 500));
|
|
8857
8972
|
process.exit(1);
|
|
@@ -8860,7 +8975,7 @@ async function ravenFetch(connection, path52) {
|
|
|
8860
8975
|
}
|
|
8861
8976
|
|
|
8862
8977
|
// src/commands/ravendb/resolveConnection.ts
|
|
8863
|
-
import
|
|
8978
|
+
import chalk110 from "chalk";
|
|
8864
8979
|
function loadRavendb() {
|
|
8865
8980
|
const raw = loadGlobalConfigRaw();
|
|
8866
8981
|
const ravendb = raw.ravendb;
|
|
@@ -8874,7 +8989,7 @@ function resolveConnection(name) {
|
|
|
8874
8989
|
const connectionName = name ?? defaultConnection;
|
|
8875
8990
|
if (!connectionName) {
|
|
8876
8991
|
console.error(
|
|
8877
|
-
|
|
8992
|
+
chalk110.red(
|
|
8878
8993
|
"No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
|
|
8879
8994
|
)
|
|
8880
8995
|
);
|
|
@@ -8882,7 +8997,7 @@ function resolveConnection(name) {
|
|
|
8882
8997
|
}
|
|
8883
8998
|
const connection = connections.find((c) => c.name === connectionName);
|
|
8884
8999
|
if (!connection) {
|
|
8885
|
-
console.error(
|
|
9000
|
+
console.error(chalk110.red(`Connection "${connectionName}" not found.`));
|
|
8886
9001
|
console.error(
|
|
8887
9002
|
`Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
|
|
8888
9003
|
);
|
|
@@ -8913,15 +9028,15 @@ async function ravendbCollections(connectionName) {
|
|
|
8913
9028
|
return;
|
|
8914
9029
|
}
|
|
8915
9030
|
for (const c of collections) {
|
|
8916
|
-
console.log(`${
|
|
9031
|
+
console.log(`${chalk111.bold(c.Name)} ${c.CountOfDocuments} docs`);
|
|
8917
9032
|
}
|
|
8918
9033
|
}
|
|
8919
9034
|
|
|
8920
9035
|
// src/commands/ravendb/ravendbQuery.ts
|
|
8921
|
-
import
|
|
9036
|
+
import chalk113 from "chalk";
|
|
8922
9037
|
|
|
8923
9038
|
// src/commands/ravendb/fetchAllPages.ts
|
|
8924
|
-
import
|
|
9039
|
+
import chalk112 from "chalk";
|
|
8925
9040
|
|
|
8926
9041
|
// src/commands/ravendb/buildQueryPath.ts
|
|
8927
9042
|
function buildQueryPath(opts) {
|
|
@@ -8959,7 +9074,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
8959
9074
|
allResults.push(...results);
|
|
8960
9075
|
start3 += results.length;
|
|
8961
9076
|
process.stderr.write(
|
|
8962
|
-
`\r${
|
|
9077
|
+
`\r${chalk112.dim(`Fetched ${allResults.length}/${totalResults}`)}`
|
|
8963
9078
|
);
|
|
8964
9079
|
if (start3 >= totalResults) break;
|
|
8965
9080
|
if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
|
|
@@ -8974,7 +9089,7 @@ async function fetchAllPages(connection, opts) {
|
|
|
8974
9089
|
async function ravendbQuery(connectionName, collection, options2) {
|
|
8975
9090
|
const resolved = resolveArgs(connectionName, collection);
|
|
8976
9091
|
if (!resolved.collection && !options2.query) {
|
|
8977
|
-
console.error(
|
|
9092
|
+
console.error(chalk113.red("Provide a collection name or --query filter."));
|
|
8978
9093
|
process.exit(1);
|
|
8979
9094
|
}
|
|
8980
9095
|
const { collection: col } = resolved;
|
|
@@ -9012,7 +9127,7 @@ import { spawn as spawn4 } from "child_process";
|
|
|
9012
9127
|
import * as path27 from "path";
|
|
9013
9128
|
|
|
9014
9129
|
// src/commands/refactor/logViolations.ts
|
|
9015
|
-
import
|
|
9130
|
+
import chalk114 from "chalk";
|
|
9016
9131
|
var DEFAULT_MAX_LINES = 100;
|
|
9017
9132
|
function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
9018
9133
|
if (violations.length === 0) {
|
|
@@ -9021,43 +9136,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
|
|
|
9021
9136
|
}
|
|
9022
9137
|
return;
|
|
9023
9138
|
}
|
|
9024
|
-
console.error(
|
|
9139
|
+
console.error(chalk114.red(`
|
|
9025
9140
|
Refactor check failed:
|
|
9026
9141
|
`));
|
|
9027
|
-
console.error(
|
|
9142
|
+
console.error(chalk114.red(` The following files exceed ${maxLines} lines:
|
|
9028
9143
|
`));
|
|
9029
9144
|
for (const violation of violations) {
|
|
9030
|
-
console.error(
|
|
9145
|
+
console.error(chalk114.red(` ${violation.file} (${violation.lines} lines)`));
|
|
9031
9146
|
}
|
|
9032
9147
|
console.error(
|
|
9033
|
-
|
|
9148
|
+
chalk114.yellow(
|
|
9034
9149
|
`
|
|
9035
9150
|
Each file needs to be sensibly refactored, or if there is no sensible
|
|
9036
9151
|
way to refactor it, ignore it with:
|
|
9037
9152
|
`
|
|
9038
9153
|
)
|
|
9039
9154
|
);
|
|
9040
|
-
console.error(
|
|
9155
|
+
console.error(chalk114.gray(` assist refactor ignore <file>
|
|
9041
9156
|
`));
|
|
9042
9157
|
if (process.env.CLAUDECODE) {
|
|
9043
|
-
console.error(
|
|
9158
|
+
console.error(chalk114.cyan(`
|
|
9044
9159
|
## Extracting Code to New Files
|
|
9045
9160
|
`));
|
|
9046
9161
|
console.error(
|
|
9047
|
-
|
|
9162
|
+
chalk114.cyan(
|
|
9048
9163
|
` When extracting logic from one file to another, consider where the extracted code belongs:
|
|
9049
9164
|
`
|
|
9050
9165
|
)
|
|
9051
9166
|
);
|
|
9052
9167
|
console.error(
|
|
9053
|
-
|
|
9168
|
+
chalk114.cyan(
|
|
9054
9169
|
` 1. Keep related logic together: If the extracted code is tightly coupled to the
|
|
9055
9170
|
original file's domain, create a new folder containing both the original and extracted files.
|
|
9056
9171
|
`
|
|
9057
9172
|
)
|
|
9058
9173
|
);
|
|
9059
9174
|
console.error(
|
|
9060
|
-
|
|
9175
|
+
chalk114.cyan(
|
|
9061
9176
|
` 2. Share common utilities: If the extracted code can be reused across multiple
|
|
9062
9177
|
domains, move it to a common/shared folder.
|
|
9063
9178
|
`
|
|
@@ -9213,7 +9328,7 @@ async function check(pattern2, options2) {
|
|
|
9213
9328
|
|
|
9214
9329
|
// src/commands/refactor/extract/index.ts
|
|
9215
9330
|
import path33 from "path";
|
|
9216
|
-
import
|
|
9331
|
+
import chalk117 from "chalk";
|
|
9217
9332
|
|
|
9218
9333
|
// src/commands/refactor/extract/applyExtraction.ts
|
|
9219
9334
|
import { SyntaxKind as SyntaxKind3 } from "ts-morph";
|
|
@@ -9760,23 +9875,23 @@ function buildPlan(functionName, sourceFile, sourcePath, destPath, project) {
|
|
|
9760
9875
|
|
|
9761
9876
|
// src/commands/refactor/extract/displayPlan.ts
|
|
9762
9877
|
import path31 from "path";
|
|
9763
|
-
import
|
|
9878
|
+
import chalk115 from "chalk";
|
|
9764
9879
|
function section(title) {
|
|
9765
9880
|
return `
|
|
9766
|
-
${
|
|
9881
|
+
${chalk115.cyan(title)}`;
|
|
9767
9882
|
}
|
|
9768
9883
|
function displayImporters(plan2, cwd) {
|
|
9769
9884
|
if (plan2.importersToUpdate.length === 0) return;
|
|
9770
9885
|
console.log(section("Update importers:"));
|
|
9771
9886
|
for (const imp of plan2.importersToUpdate) {
|
|
9772
9887
|
const rel = path31.relative(cwd, imp.file.getFilePath());
|
|
9773
|
-
console.log(` ${
|
|
9888
|
+
console.log(` ${chalk115.dim(rel)}: \u2192 import from "${imp.relPath}"`);
|
|
9774
9889
|
}
|
|
9775
9890
|
}
|
|
9776
9891
|
function displayPlan(functionName, relDest, plan2, cwd) {
|
|
9777
|
-
console.log(
|
|
9892
|
+
console.log(chalk115.bold(`Extract: ${functionName} \u2192 ${relDest}
|
|
9778
9893
|
`));
|
|
9779
|
-
console.log(` ${
|
|
9894
|
+
console.log(` ${chalk115.cyan("Functions to move:")}`);
|
|
9780
9895
|
for (const name of plan2.extractedNames) {
|
|
9781
9896
|
console.log(` ${name}`);
|
|
9782
9897
|
}
|
|
@@ -9811,7 +9926,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
|
|
|
9811
9926
|
// src/commands/refactor/extract/loadProjectFile.ts
|
|
9812
9927
|
import fs17 from "fs";
|
|
9813
9928
|
import path32 from "path";
|
|
9814
|
-
import
|
|
9929
|
+
import chalk116 from "chalk";
|
|
9815
9930
|
import { Project as Project2 } from "ts-morph";
|
|
9816
9931
|
function findTsConfig(sourcePath) {
|
|
9817
9932
|
const rootConfig = path32.resolve("tsconfig.json");
|
|
@@ -9842,7 +9957,7 @@ function loadProjectFile(file) {
|
|
|
9842
9957
|
});
|
|
9843
9958
|
const sourceFile = project.getSourceFile(sourcePath);
|
|
9844
9959
|
if (!sourceFile) {
|
|
9845
|
-
console.log(
|
|
9960
|
+
console.log(chalk116.red(`File not found in project: ${file}`));
|
|
9846
9961
|
process.exit(1);
|
|
9847
9962
|
}
|
|
9848
9963
|
return { project, sourceFile };
|
|
@@ -9865,19 +9980,19 @@ async function extract(file, functionName, destination, options2 = {}) {
|
|
|
9865
9980
|
displayPlan(functionName, relDest, plan2, cwd);
|
|
9866
9981
|
if (options2.apply) {
|
|
9867
9982
|
await applyExtraction(functionName, sourceFile, destPath, plan2, project);
|
|
9868
|
-
console.log(
|
|
9983
|
+
console.log(chalk117.green("\nExtraction complete"));
|
|
9869
9984
|
} else {
|
|
9870
|
-
console.log(
|
|
9985
|
+
console.log(chalk117.dim("\nDry run. Use --apply to execute."));
|
|
9871
9986
|
}
|
|
9872
9987
|
}
|
|
9873
9988
|
|
|
9874
9989
|
// src/commands/refactor/ignore.ts
|
|
9875
9990
|
import fs18 from "fs";
|
|
9876
|
-
import
|
|
9991
|
+
import chalk118 from "chalk";
|
|
9877
9992
|
var REFACTOR_YML_PATH2 = "refactor.yml";
|
|
9878
9993
|
function ignore(file) {
|
|
9879
9994
|
if (!fs18.existsSync(file)) {
|
|
9880
|
-
console.error(
|
|
9995
|
+
console.error(chalk118.red(`Error: File does not exist: ${file}`));
|
|
9881
9996
|
process.exit(1);
|
|
9882
9997
|
}
|
|
9883
9998
|
const content = fs18.readFileSync(file, "utf-8");
|
|
@@ -9893,7 +10008,7 @@ function ignore(file) {
|
|
|
9893
10008
|
fs18.writeFileSync(REFACTOR_YML_PATH2, entry);
|
|
9894
10009
|
}
|
|
9895
10010
|
console.log(
|
|
9896
|
-
|
|
10011
|
+
chalk118.green(
|
|
9897
10012
|
`Added ${file} to refactor ignore list (max ${maxLines} lines)`
|
|
9898
10013
|
)
|
|
9899
10014
|
);
|
|
@@ -9901,26 +10016,26 @@ function ignore(file) {
|
|
|
9901
10016
|
|
|
9902
10017
|
// src/commands/refactor/rename/index.ts
|
|
9903
10018
|
import path34 from "path";
|
|
9904
|
-
import
|
|
10019
|
+
import chalk119 from "chalk";
|
|
9905
10020
|
async function rename(source, destination, options2 = {}) {
|
|
9906
10021
|
const destPath = path34.resolve(destination);
|
|
9907
10022
|
const cwd = process.cwd();
|
|
9908
10023
|
const relSource = path34.relative(cwd, path34.resolve(source));
|
|
9909
10024
|
const relDest = path34.relative(cwd, destPath);
|
|
9910
10025
|
const { project, sourceFile } = loadProjectFile(source);
|
|
9911
|
-
console.log(
|
|
10026
|
+
console.log(chalk119.bold(`Rename: ${relSource} \u2192 ${relDest}`));
|
|
9912
10027
|
if (options2.apply) {
|
|
9913
10028
|
sourceFile.move(destPath);
|
|
9914
10029
|
await project.save();
|
|
9915
|
-
console.log(
|
|
10030
|
+
console.log(chalk119.green("Done"));
|
|
9916
10031
|
} else {
|
|
9917
|
-
console.log(
|
|
10032
|
+
console.log(chalk119.dim("Dry run. Use --apply to execute."));
|
|
9918
10033
|
}
|
|
9919
10034
|
}
|
|
9920
10035
|
|
|
9921
10036
|
// src/commands/refactor/renameSymbol/index.ts
|
|
9922
10037
|
import path36 from "path";
|
|
9923
|
-
import
|
|
10038
|
+
import chalk120 from "chalk";
|
|
9924
10039
|
import { Project as Project3 } from "ts-morph";
|
|
9925
10040
|
|
|
9926
10041
|
// src/commands/refactor/renameSymbol/findSymbol.ts
|
|
@@ -9969,38 +10084,38 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
|
|
|
9969
10084
|
const project = new Project3({ tsConfigFilePath: tsConfigPath });
|
|
9970
10085
|
const sourceFile = project.getSourceFile(filePath);
|
|
9971
10086
|
if (!sourceFile) {
|
|
9972
|
-
console.log(
|
|
10087
|
+
console.log(chalk120.red(`File not found in project: ${file}`));
|
|
9973
10088
|
process.exit(1);
|
|
9974
10089
|
}
|
|
9975
10090
|
const symbol = findSymbol(sourceFile, oldName);
|
|
9976
10091
|
if (!symbol) {
|
|
9977
|
-
console.log(
|
|
10092
|
+
console.log(chalk120.red(`Symbol "${oldName}" not found in ${file}`));
|
|
9978
10093
|
process.exit(1);
|
|
9979
10094
|
}
|
|
9980
10095
|
const grouped = groupReferences(symbol, cwd);
|
|
9981
10096
|
const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
|
|
9982
10097
|
console.log(
|
|
9983
|
-
|
|
10098
|
+
chalk120.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
|
|
9984
10099
|
`)
|
|
9985
10100
|
);
|
|
9986
10101
|
for (const [refFile, lines] of grouped) {
|
|
9987
10102
|
console.log(
|
|
9988
|
-
` ${
|
|
10103
|
+
` ${chalk120.dim(refFile)}: lines ${chalk120.cyan(lines.join(", "))}`
|
|
9989
10104
|
);
|
|
9990
10105
|
}
|
|
9991
10106
|
if (options2.apply) {
|
|
9992
10107
|
symbol.rename(newName);
|
|
9993
10108
|
await project.save();
|
|
9994
|
-
console.log(
|
|
10109
|
+
console.log(chalk120.green(`
|
|
9995
10110
|
Renamed ${oldName} \u2192 ${newName}`));
|
|
9996
10111
|
} else {
|
|
9997
|
-
console.log(
|
|
10112
|
+
console.log(chalk120.dim("\nDry run. Use --apply to execute."));
|
|
9998
10113
|
}
|
|
9999
10114
|
}
|
|
10000
10115
|
|
|
10001
10116
|
// src/commands/refactor/restructure/index.ts
|
|
10002
10117
|
import path45 from "path";
|
|
10003
|
-
import
|
|
10118
|
+
import chalk123 from "chalk";
|
|
10004
10119
|
|
|
10005
10120
|
// src/commands/refactor/restructure/buildImportGraph/index.ts
|
|
10006
10121
|
import path37 from "path";
|
|
@@ -10123,8 +10238,8 @@ function findRootParent(file, importedBy, visited) {
|
|
|
10123
10238
|
function clusterFiles(graph) {
|
|
10124
10239
|
const clusters = /* @__PURE__ */ new Map();
|
|
10125
10240
|
for (const file of graph.files) {
|
|
10126
|
-
const
|
|
10127
|
-
if (
|
|
10241
|
+
const basename9 = path39.basename(file, path39.extname(file));
|
|
10242
|
+
if (basename9 === "index") continue;
|
|
10128
10243
|
const importers = graph.importedBy.get(file);
|
|
10129
10244
|
if (!importers || importers.size !== 1) continue;
|
|
10130
10245
|
const parent = [...importers][0];
|
|
@@ -10243,50 +10358,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
|
|
|
10243
10358
|
|
|
10244
10359
|
// src/commands/refactor/restructure/displayPlan.ts
|
|
10245
10360
|
import path41 from "path";
|
|
10246
|
-
import
|
|
10361
|
+
import chalk121 from "chalk";
|
|
10247
10362
|
function relPath(filePath) {
|
|
10248
10363
|
return path41.relative(process.cwd(), filePath);
|
|
10249
10364
|
}
|
|
10250
10365
|
function displayMoves(plan2) {
|
|
10251
10366
|
if (plan2.moves.length === 0) return;
|
|
10252
|
-
console.log(
|
|
10367
|
+
console.log(chalk121.bold("\nFile moves:"));
|
|
10253
10368
|
for (const move of plan2.moves) {
|
|
10254
10369
|
console.log(
|
|
10255
|
-
` ${
|
|
10370
|
+
` ${chalk121.red(relPath(move.from))} \u2192 ${chalk121.green(relPath(move.to))}`
|
|
10256
10371
|
);
|
|
10257
|
-
console.log(
|
|
10372
|
+
console.log(chalk121.dim(` ${move.reason}`));
|
|
10258
10373
|
}
|
|
10259
10374
|
}
|
|
10260
10375
|
function displayRewrites(rewrites) {
|
|
10261
10376
|
if (rewrites.length === 0) return;
|
|
10262
10377
|
const affectedFiles = new Set(rewrites.map((r) => r.file));
|
|
10263
|
-
console.log(
|
|
10378
|
+
console.log(chalk121.bold(`
|
|
10264
10379
|
Import rewrites (${affectedFiles.size} files):`));
|
|
10265
10380
|
for (const file of affectedFiles) {
|
|
10266
|
-
console.log(` ${
|
|
10381
|
+
console.log(` ${chalk121.cyan(relPath(file))}:`);
|
|
10267
10382
|
for (const { oldSpecifier, newSpecifier } of rewrites.filter(
|
|
10268
10383
|
(r) => r.file === file
|
|
10269
10384
|
)) {
|
|
10270
10385
|
console.log(
|
|
10271
|
-
` ${
|
|
10386
|
+
` ${chalk121.red(`"${oldSpecifier}"`)} \u2192 ${chalk121.green(`"${newSpecifier}"`)}`
|
|
10272
10387
|
);
|
|
10273
10388
|
}
|
|
10274
10389
|
}
|
|
10275
10390
|
}
|
|
10276
10391
|
function displayPlan2(plan2) {
|
|
10277
10392
|
if (plan2.warnings.length > 0) {
|
|
10278
|
-
console.log(
|
|
10279
|
-
for (const w of plan2.warnings) console.log(
|
|
10393
|
+
console.log(chalk121.yellow("\nWarnings:"));
|
|
10394
|
+
for (const w of plan2.warnings) console.log(chalk121.yellow(` ${w}`));
|
|
10280
10395
|
}
|
|
10281
10396
|
if (plan2.newDirectories.length > 0) {
|
|
10282
|
-
console.log(
|
|
10397
|
+
console.log(chalk121.bold("\nNew directories:"));
|
|
10283
10398
|
for (const dir of plan2.newDirectories)
|
|
10284
|
-
console.log(
|
|
10399
|
+
console.log(chalk121.green(` ${dir}/`));
|
|
10285
10400
|
}
|
|
10286
10401
|
displayMoves(plan2);
|
|
10287
10402
|
displayRewrites(plan2.rewrites);
|
|
10288
10403
|
console.log(
|
|
10289
|
-
|
|
10404
|
+
chalk121.dim(
|
|
10290
10405
|
`
|
|
10291
10406
|
Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
|
|
10292
10407
|
)
|
|
@@ -10296,18 +10411,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
|
|
|
10296
10411
|
// src/commands/refactor/restructure/executePlan.ts
|
|
10297
10412
|
import fs20 from "fs";
|
|
10298
10413
|
import path42 from "path";
|
|
10299
|
-
import
|
|
10414
|
+
import chalk122 from "chalk";
|
|
10300
10415
|
function executePlan(plan2) {
|
|
10301
10416
|
const updatedContents = applyRewrites(plan2.rewrites);
|
|
10302
10417
|
for (const [file, content] of updatedContents) {
|
|
10303
10418
|
fs20.writeFileSync(file, content, "utf-8");
|
|
10304
10419
|
console.log(
|
|
10305
|
-
|
|
10420
|
+
chalk122.cyan(` Rewrote imports in ${path42.relative(process.cwd(), file)}`)
|
|
10306
10421
|
);
|
|
10307
10422
|
}
|
|
10308
10423
|
for (const dir of plan2.newDirectories) {
|
|
10309
10424
|
fs20.mkdirSync(dir, { recursive: true });
|
|
10310
|
-
console.log(
|
|
10425
|
+
console.log(chalk122.green(` Created ${path42.relative(process.cwd(), dir)}/`));
|
|
10311
10426
|
}
|
|
10312
10427
|
for (const move of plan2.moves) {
|
|
10313
10428
|
const targetDir = path42.dirname(move.to);
|
|
@@ -10316,7 +10431,7 @@ function executePlan(plan2) {
|
|
|
10316
10431
|
}
|
|
10317
10432
|
fs20.renameSync(move.from, move.to);
|
|
10318
10433
|
console.log(
|
|
10319
|
-
|
|
10434
|
+
chalk122.white(
|
|
10320
10435
|
` Moved ${path42.relative(process.cwd(), move.from)} \u2192 ${path42.relative(process.cwd(), move.to)}`
|
|
10321
10436
|
)
|
|
10322
10437
|
);
|
|
@@ -10331,7 +10446,7 @@ function removeEmptyDirectories(dirs) {
|
|
|
10331
10446
|
if (entries.length === 0) {
|
|
10332
10447
|
fs20.rmdirSync(dir);
|
|
10333
10448
|
console.log(
|
|
10334
|
-
|
|
10449
|
+
chalk122.dim(
|
|
10335
10450
|
` Removed empty directory ${path42.relative(process.cwd(), dir)}`
|
|
10336
10451
|
)
|
|
10337
10452
|
);
|
|
@@ -10464,22 +10579,22 @@ async function restructure(pattern2, options2 = {}) {
|
|
|
10464
10579
|
const targetPattern = pattern2 ?? "src";
|
|
10465
10580
|
const files = findSourceFiles2(targetPattern);
|
|
10466
10581
|
if (files.length === 0) {
|
|
10467
|
-
console.log(
|
|
10582
|
+
console.log(chalk123.yellow("No files found matching pattern"));
|
|
10468
10583
|
return;
|
|
10469
10584
|
}
|
|
10470
10585
|
const tsConfigPath = path45.resolve("tsconfig.json");
|
|
10471
10586
|
const plan2 = buildPlan2(files, tsConfigPath);
|
|
10472
10587
|
if (plan2.moves.length === 0) {
|
|
10473
|
-
console.log(
|
|
10588
|
+
console.log(chalk123.green("No restructuring needed"));
|
|
10474
10589
|
return;
|
|
10475
10590
|
}
|
|
10476
10591
|
displayPlan2(plan2);
|
|
10477
10592
|
if (options2.apply) {
|
|
10478
|
-
console.log(
|
|
10593
|
+
console.log(chalk123.bold("\nApplying changes..."));
|
|
10479
10594
|
executePlan(plan2);
|
|
10480
|
-
console.log(
|
|
10595
|
+
console.log(chalk123.green("\nRestructuring complete"));
|
|
10481
10596
|
} else {
|
|
10482
|
-
console.log(
|
|
10597
|
+
console.log(chalk123.dim("\nDry run. Use --apply to execute."));
|
|
10483
10598
|
}
|
|
10484
10599
|
}
|
|
10485
10600
|
|
|
@@ -10519,7 +10634,7 @@ function registerRefactor(program2) {
|
|
|
10519
10634
|
}
|
|
10520
10635
|
|
|
10521
10636
|
// src/commands/seq/seqAuth.ts
|
|
10522
|
-
import
|
|
10637
|
+
import chalk125 from "chalk";
|
|
10523
10638
|
|
|
10524
10639
|
// src/commands/seq/loadConnections.ts
|
|
10525
10640
|
function loadConnections2() {
|
|
@@ -10548,11 +10663,11 @@ function setDefaultConnection(name) {
|
|
|
10548
10663
|
}
|
|
10549
10664
|
|
|
10550
10665
|
// src/commands/seq/promptConnection.ts
|
|
10551
|
-
import
|
|
10666
|
+
import chalk124 from "chalk";
|
|
10552
10667
|
async function promptConnection2(existingNames) {
|
|
10553
10668
|
const name = await promptInput("name", "Connection name:", "default");
|
|
10554
10669
|
if (existingNames.includes(name)) {
|
|
10555
|
-
console.error(
|
|
10670
|
+
console.error(chalk124.red(`Connection "${name}" already exists.`));
|
|
10556
10671
|
process.exit(1);
|
|
10557
10672
|
}
|
|
10558
10673
|
const url = await promptInput("url", "Seq URL:", "http://localhost:5341");
|
|
@@ -10564,16 +10679,16 @@ async function promptConnection2(existingNames) {
|
|
|
10564
10679
|
var seqAuth = createConnectionAuth({
|
|
10565
10680
|
load: loadConnections2,
|
|
10566
10681
|
save: saveConnections2,
|
|
10567
|
-
format: (c) => `${
|
|
10682
|
+
format: (c) => `${chalk125.bold(c.name)} ${c.url}`,
|
|
10568
10683
|
promptNew: promptConnection2,
|
|
10569
10684
|
onFirst: (c) => setDefaultConnection(c.name)
|
|
10570
10685
|
});
|
|
10571
10686
|
|
|
10572
10687
|
// src/commands/seq/seqQuery.ts
|
|
10573
|
-
import
|
|
10688
|
+
import chalk129 from "chalk";
|
|
10574
10689
|
|
|
10575
10690
|
// src/commands/seq/fetchSeq.ts
|
|
10576
|
-
import
|
|
10691
|
+
import chalk126 from "chalk";
|
|
10577
10692
|
async function fetchSeq(conn, path52, params) {
|
|
10578
10693
|
const url = `${conn.url}${path52}?${params}`;
|
|
10579
10694
|
const response = await fetch(url, {
|
|
@@ -10584,7 +10699,7 @@ async function fetchSeq(conn, path52, params) {
|
|
|
10584
10699
|
});
|
|
10585
10700
|
if (!response.ok) {
|
|
10586
10701
|
const body = await response.text();
|
|
10587
|
-
console.error(
|
|
10702
|
+
console.error(chalk126.red(`Seq returned ${response.status}: ${body}`));
|
|
10588
10703
|
process.exit(1);
|
|
10589
10704
|
}
|
|
10590
10705
|
return response;
|
|
@@ -10639,23 +10754,23 @@ async function fetchSeqEvents(conn, params) {
|
|
|
10639
10754
|
}
|
|
10640
10755
|
|
|
10641
10756
|
// src/commands/seq/formatEvent.ts
|
|
10642
|
-
import
|
|
10757
|
+
import chalk127 from "chalk";
|
|
10643
10758
|
function levelColor(level) {
|
|
10644
10759
|
switch (level) {
|
|
10645
10760
|
case "Fatal":
|
|
10646
|
-
return
|
|
10761
|
+
return chalk127.bgRed.white;
|
|
10647
10762
|
case "Error":
|
|
10648
|
-
return
|
|
10763
|
+
return chalk127.red;
|
|
10649
10764
|
case "Warning":
|
|
10650
|
-
return
|
|
10765
|
+
return chalk127.yellow;
|
|
10651
10766
|
case "Information":
|
|
10652
|
-
return
|
|
10767
|
+
return chalk127.cyan;
|
|
10653
10768
|
case "Debug":
|
|
10654
|
-
return
|
|
10769
|
+
return chalk127.gray;
|
|
10655
10770
|
case "Verbose":
|
|
10656
|
-
return
|
|
10771
|
+
return chalk127.dim;
|
|
10657
10772
|
default:
|
|
10658
|
-
return
|
|
10773
|
+
return chalk127.white;
|
|
10659
10774
|
}
|
|
10660
10775
|
}
|
|
10661
10776
|
function levelAbbrev(level) {
|
|
@@ -10696,12 +10811,12 @@ function formatTimestamp(iso) {
|
|
|
10696
10811
|
function formatEvent(event) {
|
|
10697
10812
|
const color = levelColor(event.Level);
|
|
10698
10813
|
const abbrev = levelAbbrev(event.Level);
|
|
10699
|
-
const ts8 =
|
|
10814
|
+
const ts8 = chalk127.dim(formatTimestamp(event.Timestamp));
|
|
10700
10815
|
const msg = renderMessage(event);
|
|
10701
10816
|
const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
|
|
10702
10817
|
if (event.Exception) {
|
|
10703
10818
|
for (const line of event.Exception.split("\n")) {
|
|
10704
|
-
lines.push(
|
|
10819
|
+
lines.push(chalk127.red(` ${line}`));
|
|
10705
10820
|
}
|
|
10706
10821
|
}
|
|
10707
10822
|
return lines.join("\n");
|
|
@@ -10734,19 +10849,19 @@ function rejectTimestampFilter(filter) {
|
|
|
10734
10849
|
}
|
|
10735
10850
|
|
|
10736
10851
|
// src/commands/seq/resolveConnection.ts
|
|
10737
|
-
import
|
|
10852
|
+
import chalk128 from "chalk";
|
|
10738
10853
|
function resolveConnection2(name) {
|
|
10739
10854
|
const connections = loadConnections2();
|
|
10740
10855
|
if (connections.length === 0) {
|
|
10741
10856
|
console.error(
|
|
10742
|
-
|
|
10857
|
+
chalk128.red("No Seq connections configured. Run 'assist seq auth' first.")
|
|
10743
10858
|
);
|
|
10744
10859
|
process.exit(1);
|
|
10745
10860
|
}
|
|
10746
10861
|
const target = name ?? getDefaultConnection() ?? connections[0].name;
|
|
10747
10862
|
const connection = connections.find((c) => c.name === target);
|
|
10748
10863
|
if (!connection) {
|
|
10749
|
-
console.error(
|
|
10864
|
+
console.error(chalk128.red(`Seq connection "${target}" not found.`));
|
|
10750
10865
|
process.exit(1);
|
|
10751
10866
|
}
|
|
10752
10867
|
return connection;
|
|
@@ -10764,7 +10879,7 @@ async function seqQuery(filter, options2) {
|
|
|
10764
10879
|
new URLSearchParams({ filter, count: String(count) })
|
|
10765
10880
|
);
|
|
10766
10881
|
if (events.length === 0) {
|
|
10767
|
-
console.log(
|
|
10882
|
+
console.log(chalk129.yellow("No events found."));
|
|
10768
10883
|
return;
|
|
10769
10884
|
}
|
|
10770
10885
|
if (options2.json) {
|
|
@@ -10775,11 +10890,11 @@ async function seqQuery(filter, options2) {
|
|
|
10775
10890
|
for (const event of chronological) {
|
|
10776
10891
|
console.log(formatEvent(event));
|
|
10777
10892
|
}
|
|
10778
|
-
console.log(
|
|
10893
|
+
console.log(chalk129.dim(`
|
|
10779
10894
|
${events.length} events`));
|
|
10780
10895
|
if (events.length >= count) {
|
|
10781
10896
|
console.log(
|
|
10782
|
-
|
|
10897
|
+
chalk129.yellow(
|
|
10783
10898
|
`Results limited to ${count}. Use --count to retrieve more.`
|
|
10784
10899
|
)
|
|
10785
10900
|
);
|
|
@@ -10787,11 +10902,11 @@ ${events.length} events`));
|
|
|
10787
10902
|
}
|
|
10788
10903
|
|
|
10789
10904
|
// src/commands/seq/seqSetConnection.ts
|
|
10790
|
-
import
|
|
10905
|
+
import chalk130 from "chalk";
|
|
10791
10906
|
function seqSetConnection(name) {
|
|
10792
10907
|
const connections = loadConnections2();
|
|
10793
10908
|
if (!connections.find((c) => c.name === name)) {
|
|
10794
|
-
console.error(
|
|
10909
|
+
console.error(chalk130.red(`Connection "${name}" not found.`));
|
|
10795
10910
|
process.exit(1);
|
|
10796
10911
|
}
|
|
10797
10912
|
setDefaultConnection(name);
|
|
@@ -10817,7 +10932,7 @@ function registerSeq(program2) {
|
|
|
10817
10932
|
|
|
10818
10933
|
// src/commands/transcript/shared.ts
|
|
10819
10934
|
import { existsSync as existsSync32, readdirSync as readdirSync5, statSync as statSync4 } from "fs";
|
|
10820
|
-
import { basename as
|
|
10935
|
+
import { basename as basename5, join as join33, relative as relative2 } from "path";
|
|
10821
10936
|
import * as readline2 from "readline";
|
|
10822
10937
|
var DATE_PREFIX_REGEX = /^\d{4}-\d{2}-\d{2}/;
|
|
10823
10938
|
function getDatePrefix(daysOffset = 0) {
|
|
@@ -10835,7 +10950,7 @@ function collectFiles(dir, extension) {
|
|
|
10835
10950
|
if (!existsSync32(dir)) return [];
|
|
10836
10951
|
const results = [];
|
|
10837
10952
|
for (const entry of readdirSync5(dir)) {
|
|
10838
|
-
const fullPath =
|
|
10953
|
+
const fullPath = join33(dir, entry);
|
|
10839
10954
|
if (statSync4(fullPath).isDirectory()) {
|
|
10840
10955
|
results.push(...collectFiles(fullPath, extension));
|
|
10841
10956
|
} else if (entry.endsWith(extension)) {
|
|
@@ -10848,7 +10963,7 @@ function toFileInfo(baseDir, fullPath) {
|
|
|
10848
10963
|
return {
|
|
10849
10964
|
absolutePath: fullPath,
|
|
10850
10965
|
relativePath: relative2(baseDir, fullPath),
|
|
10851
|
-
filename:
|
|
10966
|
+
filename: basename5(fullPath)
|
|
10852
10967
|
};
|
|
10853
10968
|
}
|
|
10854
10969
|
function findVttFilesRecursive(dir, baseDir = dir) {
|
|
@@ -10858,7 +10973,7 @@ function findMdFilesRecursive(dir, baseDir = dir) {
|
|
|
10858
10973
|
return collectFiles(dir, ".md").map((f) => toFileInfo(baseDir, f));
|
|
10859
10974
|
}
|
|
10860
10975
|
function getTranscriptBaseName(transcriptFile) {
|
|
10861
|
-
return
|
|
10976
|
+
return basename5(transcriptFile, ".md").replace(/ Transcription$/, "");
|
|
10862
10977
|
}
|
|
10863
10978
|
function createReadlineInterface() {
|
|
10864
10979
|
return readline2.createInterface({
|
|
@@ -10932,11 +11047,11 @@ async function configure() {
|
|
|
10932
11047
|
import { existsSync as existsSync34 } from "fs";
|
|
10933
11048
|
|
|
10934
11049
|
// src/commands/transcript/format/fixInvalidDatePrefixes/index.ts
|
|
10935
|
-
import { dirname as dirname19, join as
|
|
11050
|
+
import { dirname as dirname19, join as join35 } from "path";
|
|
10936
11051
|
|
|
10937
11052
|
// src/commands/transcript/format/fixInvalidDatePrefixes/promptForDateFix.ts
|
|
10938
11053
|
import { renameSync as renameSync2 } from "fs";
|
|
10939
|
-
import { join as
|
|
11054
|
+
import { join as join34 } from "path";
|
|
10940
11055
|
async function resolveDate(rl, choice) {
|
|
10941
11056
|
if (choice === "1") return getDatePrefix(0);
|
|
10942
11057
|
if (choice === "2") return getDatePrefix(-1);
|
|
@@ -10951,7 +11066,7 @@ async function resolveDate(rl, choice) {
|
|
|
10951
11066
|
}
|
|
10952
11067
|
function renameWithPrefix(vttDir, vttFile, prefix2) {
|
|
10953
11068
|
const newFilename = `${prefix2}.${vttFile}`;
|
|
10954
|
-
renameSync2(
|
|
11069
|
+
renameSync2(join34(vttDir, vttFile), join34(vttDir, newFilename));
|
|
10955
11070
|
console.log(`Renamed to: ${newFilename}`);
|
|
10956
11071
|
return newFilename;
|
|
10957
11072
|
}
|
|
@@ -10985,12 +11100,12 @@ async function fixInvalidDatePrefixes(vttFiles) {
|
|
|
10985
11100
|
const vttFileDir = dirname19(vttFile.absolutePath);
|
|
10986
11101
|
const newFilename = await promptForDateFix(vttFile.filename, vttFileDir);
|
|
10987
11102
|
if (newFilename) {
|
|
10988
|
-
const newRelativePath =
|
|
11103
|
+
const newRelativePath = join35(
|
|
10989
11104
|
dirname19(vttFile.relativePath),
|
|
10990
11105
|
newFilename
|
|
10991
11106
|
);
|
|
10992
11107
|
vttFiles[i] = {
|
|
10993
|
-
absolutePath:
|
|
11108
|
+
absolutePath: join35(vttFileDir, newFilename),
|
|
10994
11109
|
relativePath: newRelativePath,
|
|
10995
11110
|
filename: newFilename
|
|
10996
11111
|
};
|
|
@@ -11003,8 +11118,8 @@ async function fixInvalidDatePrefixes(vttFiles) {
|
|
|
11003
11118
|
}
|
|
11004
11119
|
|
|
11005
11120
|
// src/commands/transcript/format/processVttFile/index.ts
|
|
11006
|
-
import { existsSync as existsSync33, mkdirSync as
|
|
11007
|
-
import { basename as
|
|
11121
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync9, readFileSync as readFileSync27, writeFileSync as writeFileSync25 } from "fs";
|
|
11122
|
+
import { basename as basename6, dirname as dirname20, join as join36 } from "path";
|
|
11008
11123
|
|
|
11009
11124
|
// src/commands/transcript/cleanText.ts
|
|
11010
11125
|
function cleanText(text) {
|
|
@@ -11211,25 +11326,25 @@ function formatChatLog(messages) {
|
|
|
11211
11326
|
|
|
11212
11327
|
// src/commands/transcript/format/processVttFile/index.ts
|
|
11213
11328
|
function toMdFilename(vttFilename) {
|
|
11214
|
-
return `${
|
|
11329
|
+
return `${basename6(vttFilename, ".vtt").replace(/\s*Transcription\s*/g, " ").trim()}.md`;
|
|
11215
11330
|
}
|
|
11216
11331
|
function resolveOutputDir(relativeDir, transcriptsDir) {
|
|
11217
|
-
return relativeDir === "." ? transcriptsDir :
|
|
11332
|
+
return relativeDir === "." ? transcriptsDir : join36(transcriptsDir, relativeDir);
|
|
11218
11333
|
}
|
|
11219
11334
|
function buildOutputPaths(vttFile, transcriptsDir) {
|
|
11220
11335
|
const mdFile = toMdFilename(vttFile.filename);
|
|
11221
11336
|
const relativeDir = dirname20(vttFile.relativePath);
|
|
11222
11337
|
const outputDir = resolveOutputDir(relativeDir, transcriptsDir);
|
|
11223
|
-
const outputPath =
|
|
11338
|
+
const outputPath = join36(outputDir, mdFile);
|
|
11224
11339
|
return { outputDir, outputPath, mdFile, relativeDir };
|
|
11225
11340
|
}
|
|
11226
11341
|
function logSkipped(relativeDir, mdFile) {
|
|
11227
|
-
console.log(`Skipping (already exists): ${
|
|
11342
|
+
console.log(`Skipping (already exists): ${join36(relativeDir, mdFile)}`);
|
|
11228
11343
|
return "skipped";
|
|
11229
11344
|
}
|
|
11230
11345
|
function ensureDirectory(dir, label2) {
|
|
11231
11346
|
if (!existsSync33(dir)) {
|
|
11232
|
-
|
|
11347
|
+
mkdirSync9(dir, { recursive: true });
|
|
11233
11348
|
console.log(`Created ${label2}: ${dir}`);
|
|
11234
11349
|
}
|
|
11235
11350
|
}
|
|
@@ -11323,27 +11438,27 @@ async function format() {
|
|
|
11323
11438
|
|
|
11324
11439
|
// src/commands/transcript/summarise/index.ts
|
|
11325
11440
|
import { existsSync as existsSync36 } from "fs";
|
|
11326
|
-
import { basename as
|
|
11441
|
+
import { basename as basename7, dirname as dirname22, join as join38, relative as relative3 } from "path";
|
|
11327
11442
|
|
|
11328
11443
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
11329
11444
|
import {
|
|
11330
11445
|
existsSync as existsSync35,
|
|
11331
|
-
mkdirSync as
|
|
11446
|
+
mkdirSync as mkdirSync10,
|
|
11332
11447
|
readFileSync as readFileSync28,
|
|
11333
11448
|
renameSync as renameSync3,
|
|
11334
11449
|
rmSync
|
|
11335
11450
|
} from "fs";
|
|
11336
|
-
import { dirname as dirname21, join as
|
|
11451
|
+
import { dirname as dirname21, join as join37 } from "path";
|
|
11337
11452
|
|
|
11338
11453
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
11339
|
-
import
|
|
11454
|
+
import chalk131 from "chalk";
|
|
11340
11455
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
11341
11456
|
function validateStagedContent(filename, content) {
|
|
11342
11457
|
const firstLine = content.split("\n")[0];
|
|
11343
11458
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
11344
11459
|
if (!match) {
|
|
11345
11460
|
console.error(
|
|
11346
|
-
|
|
11461
|
+
chalk131.red(
|
|
11347
11462
|
`Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
|
|
11348
11463
|
)
|
|
11349
11464
|
);
|
|
@@ -11352,7 +11467,7 @@ function validateStagedContent(filename, content) {
|
|
|
11352
11467
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
11353
11468
|
if (!contentAfterLink) {
|
|
11354
11469
|
console.error(
|
|
11355
|
-
|
|
11470
|
+
chalk131.red(
|
|
11356
11471
|
`Staged file ${filename} has no summary content after the transcript link.`
|
|
11357
11472
|
)
|
|
11358
11473
|
);
|
|
@@ -11362,7 +11477,7 @@ function validateStagedContent(filename, content) {
|
|
|
11362
11477
|
}
|
|
11363
11478
|
|
|
11364
11479
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
11365
|
-
var STAGING_DIR =
|
|
11480
|
+
var STAGING_DIR = join37(process.cwd(), ".assist", "transcript");
|
|
11366
11481
|
function processStagedFile() {
|
|
11367
11482
|
if (!existsSync35(STAGING_DIR)) {
|
|
11368
11483
|
return false;
|
|
@@ -11386,10 +11501,10 @@ function processStagedFile() {
|
|
|
11386
11501
|
);
|
|
11387
11502
|
process.exit(1);
|
|
11388
11503
|
}
|
|
11389
|
-
const destPath =
|
|
11504
|
+
const destPath = join37(summaryDir, matchingTranscript.relativePath);
|
|
11390
11505
|
const destDir = dirname21(destPath);
|
|
11391
11506
|
if (!existsSync35(destDir)) {
|
|
11392
|
-
|
|
11507
|
+
mkdirSync10(destDir, { recursive: true });
|
|
11393
11508
|
}
|
|
11394
11509
|
renameSync3(stagedFile.absolutePath, destPath);
|
|
11395
11510
|
const remaining = findMdFilesRecursive(STAGING_DIR);
|
|
@@ -11402,13 +11517,13 @@ function processStagedFile() {
|
|
|
11402
11517
|
// src/commands/transcript/summarise/index.ts
|
|
11403
11518
|
function buildRelativeKey(relativePath, baseName) {
|
|
11404
11519
|
const relDir = dirname22(relativePath);
|
|
11405
|
-
return relDir === "." ? baseName :
|
|
11520
|
+
return relDir === "." ? baseName : join38(relDir, baseName);
|
|
11406
11521
|
}
|
|
11407
11522
|
function buildSummaryIndex(summaryDir) {
|
|
11408
11523
|
const summaryFiles = findMdFilesRecursive(summaryDir);
|
|
11409
11524
|
return new Set(
|
|
11410
11525
|
summaryFiles.map(
|
|
11411
|
-
(f) => buildRelativeKey(f.relativePath,
|
|
11526
|
+
(f) => buildRelativeKey(f.relativePath, basename7(f.filename, ".md"))
|
|
11412
11527
|
)
|
|
11413
11528
|
);
|
|
11414
11529
|
}
|
|
@@ -11436,8 +11551,8 @@ function summarise2() {
|
|
|
11436
11551
|
}
|
|
11437
11552
|
const next3 = missing[0];
|
|
11438
11553
|
const outputFilename = `${getTranscriptBaseName(next3.filename)}.md`;
|
|
11439
|
-
const outputPath =
|
|
11440
|
-
const summaryFileDir =
|
|
11554
|
+
const outputPath = join38(STAGING_DIR, outputFilename);
|
|
11555
|
+
const summaryFileDir = join38(summaryDir, dirname22(next3.relativePath));
|
|
11441
11556
|
const relativeTranscriptPath = encodeURI(
|
|
11442
11557
|
relative3(summaryFileDir, next3.absolutePath).replace(/\\/g, "/")
|
|
11443
11558
|
);
|
|
@@ -11483,38 +11598,38 @@ function registerVerify(program2) {
|
|
|
11483
11598
|
|
|
11484
11599
|
// src/commands/voice/devices.ts
|
|
11485
11600
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
11486
|
-
import { join as
|
|
11601
|
+
import { join as join40 } from "path";
|
|
11487
11602
|
|
|
11488
11603
|
// src/commands/voice/shared.ts
|
|
11489
|
-
import { homedir as
|
|
11490
|
-
import { dirname as dirname23, join as
|
|
11604
|
+
import { homedir as homedir8 } from "os";
|
|
11605
|
+
import { dirname as dirname23, join as join39 } from "path";
|
|
11491
11606
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
11492
11607
|
var __dirname6 = dirname23(fileURLToPath6(import.meta.url));
|
|
11493
|
-
var VOICE_DIR =
|
|
11608
|
+
var VOICE_DIR = join39(homedir8(), ".assist", "voice");
|
|
11494
11609
|
var voicePaths = {
|
|
11495
11610
|
dir: VOICE_DIR,
|
|
11496
|
-
pid:
|
|
11497
|
-
log:
|
|
11498
|
-
venv:
|
|
11499
|
-
lock:
|
|
11611
|
+
pid: join39(VOICE_DIR, "voice.pid"),
|
|
11612
|
+
log: join39(VOICE_DIR, "voice.log"),
|
|
11613
|
+
venv: join39(VOICE_DIR, ".venv"),
|
|
11614
|
+
lock: join39(VOICE_DIR, "voice.lock")
|
|
11500
11615
|
};
|
|
11501
11616
|
function getPythonDir() {
|
|
11502
|
-
return
|
|
11617
|
+
return join39(__dirname6, "commands", "voice", "python");
|
|
11503
11618
|
}
|
|
11504
11619
|
function getVenvPython() {
|
|
11505
|
-
return process.platform === "win32" ?
|
|
11620
|
+
return process.platform === "win32" ? join39(voicePaths.venv, "Scripts", "python.exe") : join39(voicePaths.venv, "bin", "python");
|
|
11506
11621
|
}
|
|
11507
11622
|
function getLockDir() {
|
|
11508
11623
|
const config = loadConfig();
|
|
11509
11624
|
return config.voice?.lockDir ?? VOICE_DIR;
|
|
11510
11625
|
}
|
|
11511
11626
|
function getLockFile() {
|
|
11512
|
-
return
|
|
11627
|
+
return join39(getLockDir(), "voice.lock");
|
|
11513
11628
|
}
|
|
11514
11629
|
|
|
11515
11630
|
// src/commands/voice/devices.ts
|
|
11516
11631
|
function devices() {
|
|
11517
|
-
const script =
|
|
11632
|
+
const script = join40(getPythonDir(), "list_devices.py");
|
|
11518
11633
|
spawnSync3(getVenvPython(), [script], { stdio: "inherit" });
|
|
11519
11634
|
}
|
|
11520
11635
|
|
|
@@ -11548,13 +11663,13 @@ function logs(options2) {
|
|
|
11548
11663
|
|
|
11549
11664
|
// src/commands/voice/setup.ts
|
|
11550
11665
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
11551
|
-
import { mkdirSync as
|
|
11552
|
-
import { join as
|
|
11666
|
+
import { mkdirSync as mkdirSync12 } from "fs";
|
|
11667
|
+
import { join as join42 } from "path";
|
|
11553
11668
|
|
|
11554
11669
|
// src/commands/voice/checkLockFile.ts
|
|
11555
11670
|
import { execSync as execSync38 } from "child_process";
|
|
11556
|
-
import { existsSync as existsSync38, mkdirSync as
|
|
11557
|
-
import { join as
|
|
11671
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync11, readFileSync as readFileSync30, writeFileSync as writeFileSync26 } from "fs";
|
|
11672
|
+
import { join as join41 } from "path";
|
|
11558
11673
|
function isProcessAlive2(pid) {
|
|
11559
11674
|
try {
|
|
11560
11675
|
process.kill(pid, 0);
|
|
@@ -11591,7 +11706,7 @@ function bootstrapVenv() {
|
|
|
11591
11706
|
}
|
|
11592
11707
|
function writeLockFile(pid) {
|
|
11593
11708
|
const lockFile = getLockFile();
|
|
11594
|
-
|
|
11709
|
+
mkdirSync11(join41(lockFile, ".."), { recursive: true });
|
|
11595
11710
|
writeFileSync26(
|
|
11596
11711
|
lockFile,
|
|
11597
11712
|
JSON.stringify({
|
|
@@ -11604,10 +11719,10 @@ function writeLockFile(pid) {
|
|
|
11604
11719
|
|
|
11605
11720
|
// src/commands/voice/setup.ts
|
|
11606
11721
|
function setup() {
|
|
11607
|
-
|
|
11722
|
+
mkdirSync12(voicePaths.dir, { recursive: true });
|
|
11608
11723
|
bootstrapVenv();
|
|
11609
11724
|
console.log("\nDownloading models...\n");
|
|
11610
|
-
const script =
|
|
11725
|
+
const script = join42(getPythonDir(), "setup_models.py");
|
|
11611
11726
|
const result = spawnSync4(getVenvPython(), [script], {
|
|
11612
11727
|
stdio: "inherit",
|
|
11613
11728
|
env: { ...process.env, VOICE_LOG_FILE: voicePaths.log }
|
|
@@ -11620,8 +11735,8 @@ function setup() {
|
|
|
11620
11735
|
|
|
11621
11736
|
// src/commands/voice/start.ts
|
|
11622
11737
|
import { spawn as spawn5 } from "child_process";
|
|
11623
|
-
import { mkdirSync as
|
|
11624
|
-
import { join as
|
|
11738
|
+
import { mkdirSync as mkdirSync13, writeFileSync as writeFileSync27 } from "fs";
|
|
11739
|
+
import { join as join43 } from "path";
|
|
11625
11740
|
|
|
11626
11741
|
// src/commands/voice/buildDaemonEnv.ts
|
|
11627
11742
|
function buildDaemonEnv(options2) {
|
|
@@ -11654,12 +11769,12 @@ function spawnBackground(python, script, env) {
|
|
|
11654
11769
|
console.log(`Voice daemon started (PID ${pid})`);
|
|
11655
11770
|
}
|
|
11656
11771
|
function start2(options2) {
|
|
11657
|
-
|
|
11772
|
+
mkdirSync13(voicePaths.dir, { recursive: true });
|
|
11658
11773
|
checkLockFile();
|
|
11659
11774
|
bootstrapVenv();
|
|
11660
11775
|
const debug = options2.debug || options2.foreground || process.platform === "win32";
|
|
11661
11776
|
const env = buildDaemonEnv({ debug });
|
|
11662
|
-
const script =
|
|
11777
|
+
const script = join43(getPythonDir(), "voice_daemon.py");
|
|
11663
11778
|
const python = getVenvPython();
|
|
11664
11779
|
if (options2.foreground) {
|
|
11665
11780
|
spawnForeground(python, script, env);
|
|
@@ -11745,7 +11860,7 @@ function registerVoice(program2) {
|
|
|
11745
11860
|
|
|
11746
11861
|
// src/commands/roam/auth.ts
|
|
11747
11862
|
import { randomBytes } from "crypto";
|
|
11748
|
-
import
|
|
11863
|
+
import chalk132 from "chalk";
|
|
11749
11864
|
|
|
11750
11865
|
// src/lib/openBrowser.ts
|
|
11751
11866
|
import { execSync as execSync39 } from "child_process";
|
|
@@ -11920,13 +12035,13 @@ async function auth() {
|
|
|
11920
12035
|
saveGlobalConfig(config);
|
|
11921
12036
|
const state = randomBytes(16).toString("hex");
|
|
11922
12037
|
console.log(
|
|
11923
|
-
|
|
12038
|
+
chalk132.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
|
|
11924
12039
|
);
|
|
11925
|
-
console.log(
|
|
11926
|
-
console.log(
|
|
11927
|
-
console.log(
|
|
12040
|
+
console.log(chalk132.white("http://localhost:14523/callback\n"));
|
|
12041
|
+
console.log(chalk132.blue("Opening browser for authorization..."));
|
|
12042
|
+
console.log(chalk132.dim("Waiting for authorization callback..."));
|
|
11928
12043
|
const { code, redirectUri } = await authorizeInBrowser(clientId, state);
|
|
11929
|
-
console.log(
|
|
12044
|
+
console.log(chalk132.dim("Exchanging code for tokens..."));
|
|
11930
12045
|
const tokens = await exchangeToken({
|
|
11931
12046
|
code,
|
|
11932
12047
|
clientId,
|
|
@@ -11942,17 +12057,17 @@ async function auth() {
|
|
|
11942
12057
|
};
|
|
11943
12058
|
saveGlobalConfig(config);
|
|
11944
12059
|
console.log(
|
|
11945
|
-
|
|
12060
|
+
chalk132.green("Roam credentials and tokens saved to ~/.assist.yml")
|
|
11946
12061
|
);
|
|
11947
12062
|
}
|
|
11948
12063
|
|
|
11949
12064
|
// src/commands/roam/showClaudeCodeIcon.ts
|
|
11950
12065
|
import { readFileSync as readFileSync33 } from "fs";
|
|
11951
|
-
import { join as
|
|
12066
|
+
import { join as join44 } from "path";
|
|
11952
12067
|
async function showClaudeCodeIcon() {
|
|
11953
12068
|
const appData = process.env.APPDATA;
|
|
11954
12069
|
if (!appData) return;
|
|
11955
|
-
const portFile =
|
|
12070
|
+
const portFile = join44(appData, "Roam", "roam-local-api.port");
|
|
11956
12071
|
let port;
|
|
11957
12072
|
try {
|
|
11958
12073
|
port = readFileSync33(portFile, "utf-8").trim();
|
|
@@ -12031,13 +12146,13 @@ function runPreCommands(pre, cwd) {
|
|
|
12031
12146
|
// src/commands/run/spawnRunCommand.ts
|
|
12032
12147
|
import { execFileSync, spawn as spawn6 } from "child_process";
|
|
12033
12148
|
import { existsSync as existsSync41 } from "fs";
|
|
12034
|
-
import { dirname as dirname24, join as
|
|
12149
|
+
import { dirname as dirname24, join as join45, resolve as resolve9 } from "path";
|
|
12035
12150
|
function resolveCommand2(command) {
|
|
12036
12151
|
if (process.platform !== "win32" || command !== "bash") return command;
|
|
12037
12152
|
try {
|
|
12038
12153
|
const gitPath = execFileSync("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
|
|
12039
12154
|
const gitRoot = resolve9(dirname24(gitPath), "..");
|
|
12040
|
-
const gitBash =
|
|
12155
|
+
const gitBash = join45(gitRoot, "bin", "bash.exe");
|
|
12041
12156
|
if (existsSync41(gitBash)) return gitBash;
|
|
12042
12157
|
} catch {
|
|
12043
12158
|
}
|
|
@@ -12124,8 +12239,8 @@ function run3(name, args) {
|
|
|
12124
12239
|
}
|
|
12125
12240
|
|
|
12126
12241
|
// src/commands/run/add.ts
|
|
12127
|
-
import { mkdirSync as
|
|
12128
|
-
import { join as
|
|
12242
|
+
import { mkdirSync as mkdirSync14, writeFileSync as writeFileSync28 } from "fs";
|
|
12243
|
+
import { join as join46 } from "path";
|
|
12129
12244
|
|
|
12130
12245
|
// src/commands/run/extractOption.ts
|
|
12131
12246
|
function extractOption(args, flag) {
|
|
@@ -12186,15 +12301,15 @@ function saveNewRunConfig(name, command, args, cwd) {
|
|
|
12186
12301
|
saveConfig(config);
|
|
12187
12302
|
}
|
|
12188
12303
|
function createCommandFile(name) {
|
|
12189
|
-
const dir =
|
|
12190
|
-
|
|
12304
|
+
const dir = join46(".claude", "commands");
|
|
12305
|
+
mkdirSync14(dir, { recursive: true });
|
|
12191
12306
|
const content = `---
|
|
12192
12307
|
description: Run ${name}
|
|
12193
12308
|
---
|
|
12194
12309
|
|
|
12195
12310
|
Run \`assist run ${name} $ARGUMENTS 2>&1\`.
|
|
12196
12311
|
`;
|
|
12197
|
-
const filePath =
|
|
12312
|
+
const filePath = join46(dir, `${name}.md`);
|
|
12198
12313
|
writeFileSync28(filePath, content);
|
|
12199
12314
|
console.log(`Created command file: ${filePath}`);
|
|
12200
12315
|
}
|
|
@@ -12249,7 +12364,7 @@ function link2() {
|
|
|
12249
12364
|
|
|
12250
12365
|
// src/commands/run/remove.ts
|
|
12251
12366
|
import { existsSync as existsSync42, unlinkSync as unlinkSync11 } from "fs";
|
|
12252
|
-
import { join as
|
|
12367
|
+
import { join as join47 } from "path";
|
|
12253
12368
|
function findRemoveIndex() {
|
|
12254
12369
|
const idx = process.argv.indexOf("remove");
|
|
12255
12370
|
if (idx === -1 || idx + 1 >= process.argv.length) return -1;
|
|
@@ -12264,7 +12379,7 @@ function parseRemoveName() {
|
|
|
12264
12379
|
return process.argv[idx + 1];
|
|
12265
12380
|
}
|
|
12266
12381
|
function deleteCommandFile(name) {
|
|
12267
|
-
const filePath =
|
|
12382
|
+
const filePath = join47(".claude", "commands", `${name}.md`);
|
|
12268
12383
|
if (existsSync42(filePath)) {
|
|
12269
12384
|
unlinkSync11(filePath);
|
|
12270
12385
|
console.log(`Deleted command file: ${filePath}`);
|
|
@@ -12301,10 +12416,10 @@ function registerRun(program2) {
|
|
|
12301
12416
|
|
|
12302
12417
|
// src/commands/screenshot/index.ts
|
|
12303
12418
|
import { execSync as execSync41 } from "child_process";
|
|
12304
|
-
import { existsSync as existsSync43, mkdirSync as
|
|
12419
|
+
import { existsSync as existsSync43, mkdirSync as mkdirSync15, unlinkSync as unlinkSync12, writeFileSync as writeFileSync29 } from "fs";
|
|
12305
12420
|
import { tmpdir as tmpdir6 } from "os";
|
|
12306
|
-
import { join as
|
|
12307
|
-
import
|
|
12421
|
+
import { join as join48, resolve as resolve11 } from "path";
|
|
12422
|
+
import chalk133 from "chalk";
|
|
12308
12423
|
|
|
12309
12424
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
12310
12425
|
var captureWindowPs1 = `
|
|
@@ -12434,13 +12549,13 @@ Write-Output $OutputPath
|
|
|
12434
12549
|
// src/commands/screenshot/index.ts
|
|
12435
12550
|
function buildOutputPath(outputDir, processName) {
|
|
12436
12551
|
if (!existsSync43(outputDir)) {
|
|
12437
|
-
|
|
12552
|
+
mkdirSync15(outputDir, { recursive: true });
|
|
12438
12553
|
}
|
|
12439
12554
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
12440
12555
|
return resolve11(outputDir, `${processName}-${timestamp}.png`);
|
|
12441
12556
|
}
|
|
12442
12557
|
function runPowerShellScript(processName, outputPath) {
|
|
12443
|
-
const scriptPath =
|
|
12558
|
+
const scriptPath = join48(tmpdir6(), `assist-screenshot-${Date.now()}.ps1`);
|
|
12444
12559
|
writeFileSync29(scriptPath, captureWindowPs1, "utf-8");
|
|
12445
12560
|
try {
|
|
12446
12561
|
execSync41(
|
|
@@ -12455,13 +12570,13 @@ function screenshot(processName) {
|
|
|
12455
12570
|
const config = loadConfig();
|
|
12456
12571
|
const outputDir = resolve11(config.screenshot.outputDir);
|
|
12457
12572
|
const outputPath = buildOutputPath(outputDir, processName);
|
|
12458
|
-
console.log(
|
|
12573
|
+
console.log(chalk133.gray(`Capturing window for process "${processName}" ...`));
|
|
12459
12574
|
try {
|
|
12460
12575
|
runPowerShellScript(processName, outputPath);
|
|
12461
|
-
console.log(
|
|
12576
|
+
console.log(chalk133.green(`Screenshot saved: ${outputPath}`));
|
|
12462
12577
|
} catch (error) {
|
|
12463
12578
|
const msg = error instanceof Error ? error.message : String(error);
|
|
12464
|
-
console.error(
|
|
12579
|
+
console.error(chalk133.red(`Failed to capture screenshot: ${msg}`));
|
|
12465
12580
|
process.exit(1);
|
|
12466
12581
|
}
|
|
12467
12582
|
}
|
|
@@ -12912,10 +13027,10 @@ function registerSessions(program2) {
|
|
|
12912
13027
|
}
|
|
12913
13028
|
|
|
12914
13029
|
// src/commands/statusLine.ts
|
|
12915
|
-
import
|
|
13030
|
+
import chalk135 from "chalk";
|
|
12916
13031
|
|
|
12917
13032
|
// src/commands/buildLimitsSegment.ts
|
|
12918
|
-
import
|
|
13033
|
+
import chalk134 from "chalk";
|
|
12919
13034
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
12920
13035
|
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
12921
13036
|
function formatTimeLeft(resetsAt) {
|
|
@@ -12938,10 +13053,10 @@ function projectUsage(pct, resetsAt, windowSeconds) {
|
|
|
12938
13053
|
function colorizeRateLimit(pct, resetsAt, windowSeconds) {
|
|
12939
13054
|
const label2 = `${Math.round(pct)}%`;
|
|
12940
13055
|
const projected = projectUsage(pct, resetsAt, windowSeconds);
|
|
12941
|
-
if (projected == null) return
|
|
12942
|
-
if (projected > 100) return
|
|
12943
|
-
if (projected > 75) return
|
|
12944
|
-
return
|
|
13056
|
+
if (projected == null) return chalk134.green(label2);
|
|
13057
|
+
if (projected > 100) return chalk134.red(label2);
|
|
13058
|
+
if (projected > 75) return chalk134.yellow(label2);
|
|
13059
|
+
return chalk134.green(label2);
|
|
12945
13060
|
}
|
|
12946
13061
|
function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel) {
|
|
12947
13062
|
const timeLabel = resetsAt ? formatTimeLeft(resetsAt) : fallbackLabel;
|
|
@@ -12967,14 +13082,14 @@ function buildLimitsSegment(rateLimits) {
|
|
|
12967
13082
|
}
|
|
12968
13083
|
|
|
12969
13084
|
// src/commands/statusLine.ts
|
|
12970
|
-
|
|
13085
|
+
chalk135.level = 3;
|
|
12971
13086
|
function formatNumber(num) {
|
|
12972
13087
|
return num.toLocaleString("en-US");
|
|
12973
13088
|
}
|
|
12974
13089
|
function colorizePercent(pct) {
|
|
12975
13090
|
const label2 = `${Math.round(pct)}%`;
|
|
12976
|
-
if (pct > 80) return
|
|
12977
|
-
if (pct > 40) return
|
|
13091
|
+
if (pct > 80) return chalk135.red(label2);
|
|
13092
|
+
if (pct > 40) return chalk135.yellow(label2);
|
|
12978
13093
|
return label2;
|
|
12979
13094
|
}
|
|
12980
13095
|
async function statusLine() {
|
|
@@ -12997,7 +13112,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
|
|
|
12997
13112
|
// src/commands/sync/syncClaudeMd.ts
|
|
12998
13113
|
import * as fs25 from "fs";
|
|
12999
13114
|
import * as path48 from "path";
|
|
13000
|
-
import
|
|
13115
|
+
import chalk136 from "chalk";
|
|
13001
13116
|
async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
13002
13117
|
const source = path48.join(claudeDir, "CLAUDE.md");
|
|
13003
13118
|
const target = path48.join(targetBase, "CLAUDE.md");
|
|
@@ -13006,12 +13121,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
13006
13121
|
const targetContent = fs25.readFileSync(target, "utf-8");
|
|
13007
13122
|
if (sourceContent !== targetContent) {
|
|
13008
13123
|
console.log(
|
|
13009
|
-
|
|
13124
|
+
chalk136.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
13010
13125
|
);
|
|
13011
13126
|
console.log();
|
|
13012
13127
|
printDiff(targetContent, sourceContent);
|
|
13013
13128
|
const confirm = options2?.yes || await promptConfirm(
|
|
13014
|
-
|
|
13129
|
+
chalk136.red("Overwrite existing CLAUDE.md?"),
|
|
13015
13130
|
false
|
|
13016
13131
|
);
|
|
13017
13132
|
if (!confirm) {
|
|
@@ -13027,7 +13142,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
|
|
|
13027
13142
|
// src/commands/sync/syncSettings.ts
|
|
13028
13143
|
import * as fs26 from "fs";
|
|
13029
13144
|
import * as path49 from "path";
|
|
13030
|
-
import
|
|
13145
|
+
import chalk137 from "chalk";
|
|
13031
13146
|
async function syncSettings(claudeDir, targetBase, options2) {
|
|
13032
13147
|
const source = path49.join(claudeDir, "settings.json");
|
|
13033
13148
|
const target = path49.join(targetBase, "settings.json");
|
|
@@ -13043,14 +13158,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
|
|
|
13043
13158
|
if (mergedContent !== normalizedTarget) {
|
|
13044
13159
|
if (!options2?.yes) {
|
|
13045
13160
|
console.log(
|
|
13046
|
-
|
|
13161
|
+
chalk137.yellow(
|
|
13047
13162
|
"\n\u26A0\uFE0F Warning: settings.json differs from existing file"
|
|
13048
13163
|
)
|
|
13049
13164
|
);
|
|
13050
13165
|
console.log();
|
|
13051
13166
|
printDiff(targetContent, mergedContent);
|
|
13052
13167
|
const confirm = await promptConfirm(
|
|
13053
|
-
|
|
13168
|
+
chalk137.red("Overwrite existing settings.json?"),
|
|
13054
13169
|
false
|
|
13055
13170
|
);
|
|
13056
13171
|
if (!confirm) {
|
|
@@ -13166,6 +13281,7 @@ registerSeq(program);
|
|
|
13166
13281
|
registerTranscript(program);
|
|
13167
13282
|
registerVoice(program);
|
|
13168
13283
|
registerSessions(program);
|
|
13284
|
+
registerPrompts(program);
|
|
13169
13285
|
registerDeny(program);
|
|
13170
13286
|
program.command("next").description("Alias for backlog next -w").action(() => next({ allowEdits: true }));
|
|
13171
13287
|
program.command("draft").alias("feat").description("Launch Claude in /draft mode, chain into next on /next signal").action(() => launchMode("draft"));
|