@staff0rd/assist 0.267.0 → 0.269.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.js +171 -178
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -229,7 +229,7 @@ The first backlog command in a repository that still has a local `.assist/backlo
|
|
|
229
229
|
- `assist complexity <pattern>` - Analyze a file (all metrics if single match, maintainability if multiple)
|
|
230
230
|
- `assist complexity cyclomatic [pattern]` - Calculate cyclomatic complexity per function
|
|
231
231
|
- `assist complexity halstead [pattern]` - Calculate Halstead metrics per function
|
|
232
|
-
- `assist complexity maintainability [pattern]` - Calculate maintainability index per file
|
|
232
|
+
- `assist complexity maintainability [pattern]` - Calculate maintainability index per file (`--ignore <glob>`, repeatable, excludes extra files on top of `complexity.ignore`)
|
|
233
233
|
- `assist complexity sloc [pattern]` - Count source lines of code per file
|
|
234
234
|
- `assist transcript configure` - Configure transcript directories
|
|
235
235
|
- `assist transcript format` - Convert VTT files to formatted markdown transcripts
|
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.269.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -7596,11 +7596,10 @@ import ts5 from "typescript";
|
|
|
7596
7596
|
import fs12 from "fs";
|
|
7597
7597
|
import path18 from "path";
|
|
7598
7598
|
import { minimatch as minimatch4 } from "minimatch";
|
|
7599
|
-
function applyIgnoreGlobs(files) {
|
|
7599
|
+
function applyIgnoreGlobs(files, extraIgnore = []) {
|
|
7600
7600
|
const { complexity } = loadConfig();
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
);
|
|
7601
|
+
const ignore2 = [...complexity.ignore, ...extraIgnore];
|
|
7602
|
+
return files.filter((f) => !ignore2.some((glob) => minimatch4(f, glob)));
|
|
7604
7603
|
}
|
|
7605
7604
|
function walk(dir, results) {
|
|
7606
7605
|
if (!fs12.existsSync(dir)) {
|
|
@@ -7619,21 +7618,27 @@ function walk(dir, results) {
|
|
|
7619
7618
|
}
|
|
7620
7619
|
}
|
|
7621
7620
|
}
|
|
7622
|
-
function findSourceFiles2(pattern2, baseDir = ".") {
|
|
7621
|
+
function findSourceFiles2(pattern2, baseDir = ".", extraIgnore = []) {
|
|
7623
7622
|
const results = [];
|
|
7624
7623
|
if (pattern2.includes("*")) {
|
|
7625
7624
|
walk(baseDir, results);
|
|
7626
|
-
return applyIgnoreGlobs(
|
|
7625
|
+
return applyIgnoreGlobs(
|
|
7626
|
+
results.filter((f) => minimatch4(f, pattern2)),
|
|
7627
|
+
extraIgnore
|
|
7628
|
+
);
|
|
7627
7629
|
}
|
|
7628
7630
|
if (fs12.existsSync(pattern2) && fs12.statSync(pattern2).isFile()) {
|
|
7629
7631
|
return [pattern2];
|
|
7630
7632
|
}
|
|
7631
7633
|
if (fs12.existsSync(pattern2) && fs12.statSync(pattern2).isDirectory()) {
|
|
7632
7634
|
walk(pattern2, results);
|
|
7633
|
-
return applyIgnoreGlobs(results);
|
|
7635
|
+
return applyIgnoreGlobs(results, extraIgnore);
|
|
7634
7636
|
}
|
|
7635
7637
|
walk(baseDir, results);
|
|
7636
|
-
return applyIgnoreGlobs(
|
|
7638
|
+
return applyIgnoreGlobs(
|
|
7639
|
+
results.filter((f) => minimatch4(f, pattern2)),
|
|
7640
|
+
extraIgnore
|
|
7641
|
+
);
|
|
7637
7642
|
}
|
|
7638
7643
|
|
|
7639
7644
|
// src/commands/complexity/shared/getNodeName.ts
|
|
@@ -7832,8 +7837,8 @@ function createSourceFromFile(filePath) {
|
|
|
7832
7837
|
filePath.endsWith(".tsx") ? ts5.ScriptKind.TSX : ts5.ScriptKind.TS
|
|
7833
7838
|
);
|
|
7834
7839
|
}
|
|
7835
|
-
function withSourceFiles(pattern2, callback) {
|
|
7836
|
-
const files = findSourceFiles2(pattern2);
|
|
7840
|
+
function withSourceFiles(pattern2, callback, extraIgnore = []) {
|
|
7841
|
+
const files = findSourceFiles2(pattern2, ".", extraIgnore);
|
|
7837
7842
|
if (files.length === 0) {
|
|
7838
7843
|
console.log(chalk79.yellow("No files found matching pattern"));
|
|
7839
7844
|
return void 0;
|
|
@@ -7919,6 +7924,15 @@ Analyzed ${results.length} functions across ${files.length} files`
|
|
|
7919
7924
|
// src/commands/complexity/maintainability/index.ts
|
|
7920
7925
|
import fs14 from "fs";
|
|
7921
7926
|
|
|
7927
|
+
// src/commands/complexity/maintainability/calculateMaintainabilityIndex.ts
|
|
7928
|
+
function calculateMaintainabilityIndex(halsteadVolume, cyclomaticComplexity, sloc2) {
|
|
7929
|
+
if (halsteadVolume === 0 || sloc2 === 0) {
|
|
7930
|
+
return 100;
|
|
7931
|
+
}
|
|
7932
|
+
const mi = 171 - 5.2 * Math.log(halsteadVolume) - 0.23 * cyclomaticComplexity - 16.2 * Math.log(sloc2);
|
|
7933
|
+
return Math.max(0, Math.min(100, mi));
|
|
7934
|
+
}
|
|
7935
|
+
|
|
7922
7936
|
// src/commands/complexity/maintainability/displayMaintainabilityResults.ts
|
|
7923
7937
|
import chalk82 from "chalk";
|
|
7924
7938
|
function displayMaintainabilityResults(results, threshold) {
|
|
@@ -7956,13 +7970,6 @@ function printMaintainabilityFormula() {
|
|
|
7956
7970
|
}
|
|
7957
7971
|
|
|
7958
7972
|
// src/commands/complexity/maintainability/index.ts
|
|
7959
|
-
function calculateMaintainabilityIndex(halsteadVolume, cyclomaticComplexity, sloc2) {
|
|
7960
|
-
if (halsteadVolume === 0 || sloc2 === 0) {
|
|
7961
|
-
return 100;
|
|
7962
|
-
}
|
|
7963
|
-
const mi = 171 - 5.2 * Math.log(halsteadVolume) - 0.23 * cyclomaticComplexity - 16.2 * Math.log(sloc2);
|
|
7964
|
-
return Math.max(0, Math.min(100, mi));
|
|
7965
|
-
}
|
|
7966
7973
|
function collectFileMetrics(files) {
|
|
7967
7974
|
const fileMetrics = /* @__PURE__ */ new Map();
|
|
7968
7975
|
for (const file of files) {
|
|
@@ -7997,11 +8004,15 @@ function aggregateResults(fileMetrics) {
|
|
|
7997
8004
|
}
|
|
7998
8005
|
async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
|
|
7999
8006
|
printMaintainabilityFormula();
|
|
8000
|
-
withSourceFiles(
|
|
8001
|
-
|
|
8002
|
-
|
|
8003
|
-
|
|
8004
|
-
|
|
8007
|
+
withSourceFiles(
|
|
8008
|
+
pattern2,
|
|
8009
|
+
(files) => {
|
|
8010
|
+
const fileMetrics = collectFileMetrics(files);
|
|
8011
|
+
const results = aggregateResults(fileMetrics);
|
|
8012
|
+
displayMaintainabilityResults(results, options2.threshold);
|
|
8013
|
+
},
|
|
8014
|
+
options2.ignore ?? []
|
|
8015
|
+
);
|
|
8005
8016
|
}
|
|
8006
8017
|
|
|
8007
8018
|
// src/commands/complexity/sloc.ts
|
|
@@ -8077,6 +8088,11 @@ function registerComplexity(program2) {
|
|
|
8077
8088
|
"--threshold <number>",
|
|
8078
8089
|
"Min maintainability threshold",
|
|
8079
8090
|
Number.parseInt
|
|
8091
|
+
).option(
|
|
8092
|
+
"--ignore <glob>",
|
|
8093
|
+
"Glob of files to exclude (repeatable, additive to config)",
|
|
8094
|
+
(value, previous) => previous.concat([value]),
|
|
8095
|
+
[]
|
|
8080
8096
|
).action(maintainability);
|
|
8081
8097
|
complexityCommand.command("sloc [pattern]").description("Count source lines of code per file").option("--threshold <number>", "Max lines threshold", Number.parseInt).action(sloc);
|
|
8082
8098
|
}
|
|
@@ -12810,8 +12826,8 @@ function findRootParent(file, importedBy, visited) {
|
|
|
12810
12826
|
function clusterFiles(graph) {
|
|
12811
12827
|
const clusters = /* @__PURE__ */ new Map();
|
|
12812
12828
|
for (const file of graph.files) {
|
|
12813
|
-
const
|
|
12814
|
-
if (
|
|
12829
|
+
const basename11 = path38.basename(file, path38.extname(file));
|
|
12830
|
+
if (basename11 === "index") continue;
|
|
12815
12831
|
const importers = graph.importedBy.get(file);
|
|
12816
12832
|
if (!importers || importers.size !== 1) continue;
|
|
12817
12833
|
const parent = [...importers][0];
|
|
@@ -13321,9 +13337,16 @@ ${annotateDiffWithLineNumbers(context.diff.trimEnd())}
|
|
|
13321
13337
|
}
|
|
13322
13338
|
|
|
13323
13339
|
// src/commands/review/buildReviewPaths.ts
|
|
13324
|
-
import {
|
|
13340
|
+
import { homedir as homedir11 } from "os";
|
|
13341
|
+
import { basename as basename6, join as join36 } from "path";
|
|
13325
13342
|
function buildReviewPaths(repoRoot, key) {
|
|
13326
|
-
const reviewDir = join36(
|
|
13343
|
+
const reviewDir = join36(
|
|
13344
|
+
homedir11(),
|
|
13345
|
+
".assist",
|
|
13346
|
+
"reviews",
|
|
13347
|
+
basename6(repoRoot),
|
|
13348
|
+
key
|
|
13349
|
+
);
|
|
13327
13350
|
return {
|
|
13328
13351
|
reviewDir,
|
|
13329
13352
|
requestPath: join36(reviewDir, "request.md"),
|
|
@@ -13333,35 +13356,6 @@ function buildReviewPaths(repoRoot, key) {
|
|
|
13333
13356
|
};
|
|
13334
13357
|
}
|
|
13335
13358
|
|
|
13336
|
-
// src/commands/review/ensureReviewsIgnored.ts
|
|
13337
|
-
import {
|
|
13338
|
-
appendFileSync,
|
|
13339
|
-
existsSync as existsSync35,
|
|
13340
|
-
readFileSync as readFileSync30,
|
|
13341
|
-
writeFileSync as writeFileSync25
|
|
13342
|
-
} from "fs";
|
|
13343
|
-
import { join as join37 } from "path";
|
|
13344
|
-
var REVIEWS_ENTRY = ".assist/reviews";
|
|
13345
|
-
function coversReviews(line) {
|
|
13346
|
-
const pattern2 = line.trim().replace(/^\//, "").replace(/\/$/, "");
|
|
13347
|
-
return pattern2 === ".assist" || pattern2 === REVIEWS_ENTRY;
|
|
13348
|
-
}
|
|
13349
|
-
function ensureReviewsIgnored(repoRoot) {
|
|
13350
|
-
const gitignorePath = join37(repoRoot, ".gitignore");
|
|
13351
|
-
if (!existsSync35(gitignorePath)) {
|
|
13352
|
-
writeFileSync25(gitignorePath, `${REVIEWS_ENTRY}
|
|
13353
|
-
`);
|
|
13354
|
-
console.log(`Created .gitignore with ${REVIEWS_ENTRY} entry.`);
|
|
13355
|
-
return;
|
|
13356
|
-
}
|
|
13357
|
-
const content = readFileSync30(gitignorePath, "utf-8");
|
|
13358
|
-
if (content.split("\n").some(coversReviews)) return;
|
|
13359
|
-
const separator = content === "" || content.endsWith("\n") ? "" : "\n";
|
|
13360
|
-
appendFileSync(gitignorePath, `${separator}${REVIEWS_ENTRY}
|
|
13361
|
-
`);
|
|
13362
|
-
console.log(`Added ${REVIEWS_ENTRY} to .gitignore.`);
|
|
13363
|
-
}
|
|
13364
|
-
|
|
13365
13359
|
// src/commands/review/fetchExistingComments.ts
|
|
13366
13360
|
import { execSync as execSync41 } from "child_process";
|
|
13367
13361
|
function fetchRawComments(org, repo, prNumber) {
|
|
@@ -13501,7 +13495,7 @@ function gatherContext() {
|
|
|
13501
13495
|
}
|
|
13502
13496
|
|
|
13503
13497
|
// src/commands/review/postReviewToPr.ts
|
|
13504
|
-
import { readFileSync as
|
|
13498
|
+
import { readFileSync as readFileSync30 } from "fs";
|
|
13505
13499
|
|
|
13506
13500
|
// src/commands/review/parseFindings.ts
|
|
13507
13501
|
var SEVERITIES = ["blocker", "major", "minor", "nit"];
|
|
@@ -13811,7 +13805,7 @@ async function confirmPost(prNumber, count6, options2) {
|
|
|
13811
13805
|
async function postReviewToPr(synthesisPath, options2) {
|
|
13812
13806
|
const prInfo = fetchPrDiffInfo();
|
|
13813
13807
|
const prNumber = prInfo.prNumber;
|
|
13814
|
-
const markdown =
|
|
13808
|
+
const markdown = readFileSync30(synthesisPath, "utf-8");
|
|
13815
13809
|
const findings = parseFindings(markdown);
|
|
13816
13810
|
if (findings.length === 0) {
|
|
13817
13811
|
console.log("Synthesis contains no findings; nothing to post.");
|
|
@@ -13893,16 +13887,16 @@ async function handlePostSynthesis(synthesisPath, options2) {
|
|
|
13893
13887
|
}
|
|
13894
13888
|
|
|
13895
13889
|
// src/commands/review/prepareReviewDir.ts
|
|
13896
|
-
import { existsSync as
|
|
13890
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync13, unlinkSync as unlinkSync11, writeFileSync as writeFileSync25 } from "fs";
|
|
13897
13891
|
function clearReviewFiles(paths) {
|
|
13898
13892
|
for (const path53 of [paths.claudePath, paths.codexPath, paths.synthesisPath]) {
|
|
13899
|
-
if (
|
|
13893
|
+
if (existsSync35(path53)) unlinkSync11(path53);
|
|
13900
13894
|
}
|
|
13901
13895
|
}
|
|
13902
13896
|
function prepareReviewDir(paths, requestBody, force) {
|
|
13903
13897
|
mkdirSync13(paths.reviewDir, { recursive: true });
|
|
13904
13898
|
if (force) clearReviewFiles(paths);
|
|
13905
|
-
|
|
13899
|
+
writeFileSync25(paths.requestPath, requestBody);
|
|
13906
13900
|
}
|
|
13907
13901
|
|
|
13908
13902
|
// src/commands/review/runApplySession.ts
|
|
@@ -14181,7 +14175,7 @@ function printReviewerFailures(results) {
|
|
|
14181
14175
|
}
|
|
14182
14176
|
|
|
14183
14177
|
// src/commands/review/runAndSynthesise.ts
|
|
14184
|
-
import { existsSync as
|
|
14178
|
+
import { existsSync as existsSync37, unlinkSync as unlinkSync13 } from "fs";
|
|
14185
14179
|
|
|
14186
14180
|
// src/commands/review/buildReviewerStdin.ts
|
|
14187
14181
|
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 request.md in the current working directory.
|
|
@@ -14245,7 +14239,7 @@ The review request is at: ${requestPath}
|
|
|
14245
14239
|
}
|
|
14246
14240
|
|
|
14247
14241
|
// src/commands/review/runClaudeReviewer.ts
|
|
14248
|
-
import { writeFileSync as
|
|
14242
|
+
import { writeFileSync as writeFileSync26 } from "fs";
|
|
14249
14243
|
|
|
14250
14244
|
// src/commands/review/finaliseReviewerSpinner.ts
|
|
14251
14245
|
var SUMMARY_MAX_LEN = 80;
|
|
@@ -14581,7 +14575,7 @@ async function runClaudeReviewer(spec) {
|
|
|
14581
14575
|
}
|
|
14582
14576
|
});
|
|
14583
14577
|
if (result.exitCode === 0 && finalText)
|
|
14584
|
-
|
|
14578
|
+
writeFileSync26(spec.outputPath, finalText);
|
|
14585
14579
|
return finaliseReviewerRun({ ...spec, command }, spinner, result);
|
|
14586
14580
|
}
|
|
14587
14581
|
|
|
@@ -14599,7 +14593,7 @@ function resolveClaude(args) {
|
|
|
14599
14593
|
}
|
|
14600
14594
|
|
|
14601
14595
|
// src/commands/review/runCodexReviewer.ts
|
|
14602
|
-
import { existsSync as
|
|
14596
|
+
import { existsSync as existsSync36, unlinkSync as unlinkSync12 } from "fs";
|
|
14603
14597
|
|
|
14604
14598
|
// src/commands/review/parseCodexEvent.ts
|
|
14605
14599
|
function isItemStarted(value) {
|
|
@@ -14653,7 +14647,7 @@ async function runCodexReviewer(spec) {
|
|
|
14653
14647
|
reportReviewerToolUse(spec.name, event, spinner);
|
|
14654
14648
|
}
|
|
14655
14649
|
});
|
|
14656
|
-
if (result.exitCode !== 0 &&
|
|
14650
|
+
if (result.exitCode !== 0 && existsSync36(spec.outputPath)) {
|
|
14657
14651
|
unlinkSync12(spec.outputPath);
|
|
14658
14652
|
}
|
|
14659
14653
|
return finaliseReviewerRun({ ...spec, command }, spinner, result);
|
|
@@ -14697,7 +14691,7 @@ async function runReviewers(reviewDir, claudePath, codexPath, stdinPrompt, optio
|
|
|
14697
14691
|
}
|
|
14698
14692
|
|
|
14699
14693
|
// src/commands/review/synthesise.ts
|
|
14700
|
-
import { readFileSync as
|
|
14694
|
+
import { readFileSync as readFileSync31 } from "fs";
|
|
14701
14695
|
|
|
14702
14696
|
// src/commands/review/buildSynthesisStdin.ts
|
|
14703
14697
|
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.
|
|
@@ -14753,7 +14747,7 @@ Files:
|
|
|
14753
14747
|
|
|
14754
14748
|
// src/commands/review/synthesise.ts
|
|
14755
14749
|
function printSummary2(synthesisPath) {
|
|
14756
|
-
const markdown =
|
|
14750
|
+
const markdown = readFileSync31(synthesisPath, "utf-8");
|
|
14757
14751
|
console.log("");
|
|
14758
14752
|
console.log(buildReviewSummary(markdown));
|
|
14759
14753
|
console.log("");
|
|
@@ -14801,7 +14795,7 @@ async function runAndSynthesise(args) {
|
|
|
14801
14795
|
console.error("Both reviewers failed; skipping synthesis.");
|
|
14802
14796
|
return { ok: false, failures };
|
|
14803
14797
|
}
|
|
14804
|
-
if (anyFresh &&
|
|
14798
|
+
if (anyFresh && existsSync37(paths.synthesisPath)) {
|
|
14805
14799
|
unlinkSync13(paths.synthesisPath);
|
|
14806
14800
|
}
|
|
14807
14801
|
const synthesisResult = await synthesise(paths, { multi });
|
|
@@ -14895,7 +14889,6 @@ async function runPostSynthesis(synthesisPath, options2) {
|
|
|
14895
14889
|
}
|
|
14896
14890
|
async function reviewPr(repoRoot, options2) {
|
|
14897
14891
|
const context = gatherChangedContext();
|
|
14898
|
-
ensureReviewsIgnored(repoRoot);
|
|
14899
14892
|
const paths = setupReviewDir(repoRoot, context, options2.force ?? false);
|
|
14900
14893
|
const synthesisOk = await runReviewPipeline(paths, {
|
|
14901
14894
|
verbose: options2.verbose ?? false
|
|
@@ -15577,8 +15570,8 @@ function registerSql(program2) {
|
|
|
15577
15570
|
}
|
|
15578
15571
|
|
|
15579
15572
|
// src/commands/transcript/shared.ts
|
|
15580
|
-
import { existsSync as
|
|
15581
|
-
import { basename as
|
|
15573
|
+
import { existsSync as existsSync38, readdirSync as readdirSync6, statSync as statSync4 } from "fs";
|
|
15574
|
+
import { basename as basename7, join as join37, relative as relative2 } from "path";
|
|
15582
15575
|
import * as readline2 from "readline";
|
|
15583
15576
|
var DATE_PREFIX_REGEX = /^\d{4}-\d{2}-\d{2}/;
|
|
15584
15577
|
function getDatePrefix(daysOffset = 0) {
|
|
@@ -15593,10 +15586,10 @@ function isValidDatePrefix(filename) {
|
|
|
15593
15586
|
return DATE_PREFIX_REGEX.test(filename);
|
|
15594
15587
|
}
|
|
15595
15588
|
function collectFiles(dir, extension) {
|
|
15596
|
-
if (!
|
|
15589
|
+
if (!existsSync38(dir)) return [];
|
|
15597
15590
|
const results = [];
|
|
15598
15591
|
for (const entry of readdirSync6(dir)) {
|
|
15599
|
-
const fullPath =
|
|
15592
|
+
const fullPath = join37(dir, entry);
|
|
15600
15593
|
if (statSync4(fullPath).isDirectory()) {
|
|
15601
15594
|
results.push(...collectFiles(fullPath, extension));
|
|
15602
15595
|
} else if (entry.endsWith(extension)) {
|
|
@@ -15609,7 +15602,7 @@ function toFileInfo(baseDir, fullPath) {
|
|
|
15609
15602
|
return {
|
|
15610
15603
|
absolutePath: fullPath,
|
|
15611
15604
|
relativePath: relative2(baseDir, fullPath),
|
|
15612
|
-
filename:
|
|
15605
|
+
filename: basename7(fullPath)
|
|
15613
15606
|
};
|
|
15614
15607
|
}
|
|
15615
15608
|
function findVttFilesRecursive(dir, baseDir = dir) {
|
|
@@ -15619,7 +15612,7 @@ function findMdFilesRecursive(dir, baseDir = dir) {
|
|
|
15619
15612
|
return collectFiles(dir, ".md").map((f) => toFileInfo(baseDir, f));
|
|
15620
15613
|
}
|
|
15621
15614
|
function getTranscriptBaseName(transcriptFile) {
|
|
15622
|
-
return
|
|
15615
|
+
return basename7(transcriptFile, ".md").replace(/ Transcription$/, "");
|
|
15623
15616
|
}
|
|
15624
15617
|
function createReadlineInterface() {
|
|
15625
15618
|
return readline2.createInterface({
|
|
@@ -15690,14 +15683,14 @@ async function configure() {
|
|
|
15690
15683
|
}
|
|
15691
15684
|
|
|
15692
15685
|
// src/commands/transcript/format/index.ts
|
|
15693
|
-
import { existsSync as
|
|
15686
|
+
import { existsSync as existsSync40 } from "fs";
|
|
15694
15687
|
|
|
15695
15688
|
// src/commands/transcript/format/fixInvalidDatePrefixes/index.ts
|
|
15696
|
-
import { dirname as dirname20, join as
|
|
15689
|
+
import { dirname as dirname20, join as join39 } from "path";
|
|
15697
15690
|
|
|
15698
15691
|
// src/commands/transcript/format/fixInvalidDatePrefixes/promptForDateFix.ts
|
|
15699
15692
|
import { renameSync as renameSync3 } from "fs";
|
|
15700
|
-
import { join as
|
|
15693
|
+
import { join as join38 } from "path";
|
|
15701
15694
|
async function resolveDate(rl, choice) {
|
|
15702
15695
|
if (choice === "1") return getDatePrefix(0);
|
|
15703
15696
|
if (choice === "2") return getDatePrefix(-1);
|
|
@@ -15712,7 +15705,7 @@ async function resolveDate(rl, choice) {
|
|
|
15712
15705
|
}
|
|
15713
15706
|
function renameWithPrefix(vttDir, vttFile, prefix2) {
|
|
15714
15707
|
const newFilename = `${prefix2}.${vttFile}`;
|
|
15715
|
-
renameSync3(
|
|
15708
|
+
renameSync3(join38(vttDir, vttFile), join38(vttDir, newFilename));
|
|
15716
15709
|
console.log(`Renamed to: ${newFilename}`);
|
|
15717
15710
|
return newFilename;
|
|
15718
15711
|
}
|
|
@@ -15746,12 +15739,12 @@ async function fixInvalidDatePrefixes(vttFiles) {
|
|
|
15746
15739
|
const vttFileDir = dirname20(vttFile.absolutePath);
|
|
15747
15740
|
const newFilename = await promptForDateFix(vttFile.filename, vttFileDir);
|
|
15748
15741
|
if (newFilename) {
|
|
15749
|
-
const newRelativePath =
|
|
15742
|
+
const newRelativePath = join39(
|
|
15750
15743
|
dirname20(vttFile.relativePath),
|
|
15751
15744
|
newFilename
|
|
15752
15745
|
);
|
|
15753
15746
|
vttFiles[i] = {
|
|
15754
|
-
absolutePath:
|
|
15747
|
+
absolutePath: join39(vttFileDir, newFilename),
|
|
15755
15748
|
relativePath: newRelativePath,
|
|
15756
15749
|
filename: newFilename
|
|
15757
15750
|
};
|
|
@@ -15764,8 +15757,8 @@ async function fixInvalidDatePrefixes(vttFiles) {
|
|
|
15764
15757
|
}
|
|
15765
15758
|
|
|
15766
15759
|
// src/commands/transcript/format/processVttFile/index.ts
|
|
15767
|
-
import { existsSync as
|
|
15768
|
-
import { basename as
|
|
15760
|
+
import { existsSync as existsSync39, mkdirSync as mkdirSync14, readFileSync as readFileSync32, writeFileSync as writeFileSync27 } from "fs";
|
|
15761
|
+
import { basename as basename8, dirname as dirname21, join as join40 } from "path";
|
|
15769
15762
|
|
|
15770
15763
|
// src/commands/transcript/cleanText.ts
|
|
15771
15764
|
function cleanText(text2) {
|
|
@@ -15972,24 +15965,24 @@ function formatChatLog(messages) {
|
|
|
15972
15965
|
|
|
15973
15966
|
// src/commands/transcript/format/processVttFile/index.ts
|
|
15974
15967
|
function toMdFilename(vttFilename) {
|
|
15975
|
-
return `${
|
|
15968
|
+
return `${basename8(vttFilename, ".vtt").replace(/\s*Transcription\s*/g, " ").trim()}.md`;
|
|
15976
15969
|
}
|
|
15977
15970
|
function resolveOutputDir(relativeDir, transcriptsDir) {
|
|
15978
|
-
return relativeDir === "." ? transcriptsDir :
|
|
15971
|
+
return relativeDir === "." ? transcriptsDir : join40(transcriptsDir, relativeDir);
|
|
15979
15972
|
}
|
|
15980
15973
|
function buildOutputPaths(vttFile, transcriptsDir) {
|
|
15981
15974
|
const mdFile = toMdFilename(vttFile.filename);
|
|
15982
15975
|
const relativeDir = dirname21(vttFile.relativePath);
|
|
15983
15976
|
const outputDir = resolveOutputDir(relativeDir, transcriptsDir);
|
|
15984
|
-
const outputPath =
|
|
15977
|
+
const outputPath = join40(outputDir, mdFile);
|
|
15985
15978
|
return { outputDir, outputPath, mdFile, relativeDir };
|
|
15986
15979
|
}
|
|
15987
15980
|
function logSkipped(relativeDir, mdFile) {
|
|
15988
|
-
console.log(`Skipping (already exists): ${
|
|
15981
|
+
console.log(`Skipping (already exists): ${join40(relativeDir, mdFile)}`);
|
|
15989
15982
|
return "skipped";
|
|
15990
15983
|
}
|
|
15991
15984
|
function ensureDirectory(dir, label2) {
|
|
15992
|
-
if (!
|
|
15985
|
+
if (!existsSync39(dir)) {
|
|
15993
15986
|
mkdirSync14(dir, { recursive: true });
|
|
15994
15987
|
console.log(`Created ${label2}: ${dir}`);
|
|
15995
15988
|
}
|
|
@@ -16012,10 +16005,10 @@ function logReduction(cueCount, messageCount) {
|
|
|
16012
16005
|
}
|
|
16013
16006
|
function readAndParseCues(inputPath) {
|
|
16014
16007
|
console.log(`Reading: ${inputPath}`);
|
|
16015
|
-
return processCues(
|
|
16008
|
+
return processCues(readFileSync32(inputPath, "utf-8"));
|
|
16016
16009
|
}
|
|
16017
16010
|
function writeFormatted(outputPath, content) {
|
|
16018
|
-
|
|
16011
|
+
writeFileSync27(outputPath, content, "utf-8");
|
|
16019
16012
|
console.log(`Written: ${outputPath}`);
|
|
16020
16013
|
}
|
|
16021
16014
|
function convertVttToMarkdown(inputPath, outputPath) {
|
|
@@ -16025,7 +16018,7 @@ function convertVttToMarkdown(inputPath, outputPath) {
|
|
|
16025
16018
|
logReduction(cues.length, chatMessages.length);
|
|
16026
16019
|
}
|
|
16027
16020
|
function tryProcessVtt(vttFile, paths) {
|
|
16028
|
-
if (
|
|
16021
|
+
if (existsSync39(paths.outputPath))
|
|
16029
16022
|
return logSkipped(paths.relativeDir, paths.mdFile);
|
|
16030
16023
|
convertVttToMarkdown(vttFile.absolutePath, paths.outputPath);
|
|
16031
16024
|
return "processed";
|
|
@@ -16051,7 +16044,7 @@ function processAllFiles(vttFiles, transcriptsDir) {
|
|
|
16051
16044
|
logSummary(counts);
|
|
16052
16045
|
}
|
|
16053
16046
|
function requireVttDir(vttDir) {
|
|
16054
|
-
if (!
|
|
16047
|
+
if (!existsSync40(vttDir)) {
|
|
16055
16048
|
console.error(`VTT directory not found: ${vttDir}`);
|
|
16056
16049
|
process.exit(1);
|
|
16057
16050
|
}
|
|
@@ -16083,18 +16076,18 @@ async function format() {
|
|
|
16083
16076
|
}
|
|
16084
16077
|
|
|
16085
16078
|
// src/commands/transcript/summarise/index.ts
|
|
16086
|
-
import { existsSync as
|
|
16087
|
-
import { basename as
|
|
16079
|
+
import { existsSync as existsSync42 } from "fs";
|
|
16080
|
+
import { basename as basename9, dirname as dirname23, join as join42, relative as relative3 } from "path";
|
|
16088
16081
|
|
|
16089
16082
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
16090
16083
|
import {
|
|
16091
|
-
existsSync as
|
|
16084
|
+
existsSync as existsSync41,
|
|
16092
16085
|
mkdirSync as mkdirSync15,
|
|
16093
|
-
readFileSync as
|
|
16086
|
+
readFileSync as readFileSync33,
|
|
16094
16087
|
renameSync as renameSync4,
|
|
16095
16088
|
rmSync as rmSync2
|
|
16096
16089
|
} from "fs";
|
|
16097
|
-
import { dirname as dirname22, join as
|
|
16090
|
+
import { dirname as dirname22, join as join41 } from "path";
|
|
16098
16091
|
|
|
16099
16092
|
// src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
|
|
16100
16093
|
import chalk156 from "chalk";
|
|
@@ -16123,9 +16116,9 @@ function validateStagedContent(filename, content) {
|
|
|
16123
16116
|
}
|
|
16124
16117
|
|
|
16125
16118
|
// src/commands/transcript/summarise/processStagedFile/index.ts
|
|
16126
|
-
var STAGING_DIR =
|
|
16119
|
+
var STAGING_DIR = join41(process.cwd(), ".assist", "transcript");
|
|
16127
16120
|
function processStagedFile() {
|
|
16128
|
-
if (!
|
|
16121
|
+
if (!existsSync41(STAGING_DIR)) {
|
|
16129
16122
|
return false;
|
|
16130
16123
|
}
|
|
16131
16124
|
const stagedFiles = findMdFilesRecursive(STAGING_DIR);
|
|
@@ -16134,7 +16127,7 @@ function processStagedFile() {
|
|
|
16134
16127
|
}
|
|
16135
16128
|
const { transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
16136
16129
|
const stagedFile = stagedFiles[0];
|
|
16137
|
-
const content =
|
|
16130
|
+
const content = readFileSync33(stagedFile.absolutePath, "utf-8");
|
|
16138
16131
|
validateStagedContent(stagedFile.filename, content);
|
|
16139
16132
|
const stagedBaseName = getTranscriptBaseName(stagedFile.filename);
|
|
16140
16133
|
const transcriptFiles = findMdFilesRecursive(transcriptsDir);
|
|
@@ -16147,9 +16140,9 @@ function processStagedFile() {
|
|
|
16147
16140
|
);
|
|
16148
16141
|
process.exit(1);
|
|
16149
16142
|
}
|
|
16150
|
-
const destPath =
|
|
16143
|
+
const destPath = join41(summaryDir, matchingTranscript.relativePath);
|
|
16151
16144
|
const destDir = dirname22(destPath);
|
|
16152
|
-
if (!
|
|
16145
|
+
if (!existsSync41(destDir)) {
|
|
16153
16146
|
mkdirSync15(destDir, { recursive: true });
|
|
16154
16147
|
}
|
|
16155
16148
|
renameSync4(stagedFile.absolutePath, destPath);
|
|
@@ -16163,20 +16156,20 @@ function processStagedFile() {
|
|
|
16163
16156
|
// src/commands/transcript/summarise/index.ts
|
|
16164
16157
|
function buildRelativeKey(relativePath, baseName) {
|
|
16165
16158
|
const relDir = dirname23(relativePath);
|
|
16166
|
-
return relDir === "." ? baseName :
|
|
16159
|
+
return relDir === "." ? baseName : join42(relDir, baseName);
|
|
16167
16160
|
}
|
|
16168
16161
|
function buildSummaryIndex(summaryDir) {
|
|
16169
16162
|
const summaryFiles = findMdFilesRecursive(summaryDir);
|
|
16170
16163
|
return new Set(
|
|
16171
16164
|
summaryFiles.map(
|
|
16172
|
-
(f) => buildRelativeKey(f.relativePath,
|
|
16165
|
+
(f) => buildRelativeKey(f.relativePath, basename9(f.filename, ".md"))
|
|
16173
16166
|
)
|
|
16174
16167
|
);
|
|
16175
16168
|
}
|
|
16176
16169
|
function summarise3() {
|
|
16177
16170
|
processStagedFile();
|
|
16178
16171
|
const { transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
16179
|
-
if (!
|
|
16172
|
+
if (!existsSync42(transcriptsDir)) {
|
|
16180
16173
|
console.log("No transcripts directory found.");
|
|
16181
16174
|
return;
|
|
16182
16175
|
}
|
|
@@ -16197,8 +16190,8 @@ function summarise3() {
|
|
|
16197
16190
|
}
|
|
16198
16191
|
const next3 = missing[0];
|
|
16199
16192
|
const outputFilename = `${getTranscriptBaseName(next3.filename)}.md`;
|
|
16200
|
-
const outputPath =
|
|
16201
|
-
const summaryFileDir =
|
|
16193
|
+
const outputPath = join42(STAGING_DIR, outputFilename);
|
|
16194
|
+
const summaryFileDir = join42(summaryDir, dirname23(next3.relativePath));
|
|
16202
16195
|
const relativeTranscriptPath = encodeURI(
|
|
16203
16196
|
relative3(summaryFileDir, next3.absolutePath).replace(/\\/g, "/")
|
|
16204
16197
|
);
|
|
@@ -16248,50 +16241,50 @@ function registerVerify(program2) {
|
|
|
16248
16241
|
|
|
16249
16242
|
// src/commands/voice/devices.ts
|
|
16250
16243
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
16251
|
-
import { join as
|
|
16244
|
+
import { join as join44 } from "path";
|
|
16252
16245
|
|
|
16253
16246
|
// src/commands/voice/shared.ts
|
|
16254
|
-
import { homedir as
|
|
16255
|
-
import { dirname as dirname24, join as
|
|
16247
|
+
import { homedir as homedir12 } from "os";
|
|
16248
|
+
import { dirname as dirname24, join as join43 } from "path";
|
|
16256
16249
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
16257
16250
|
var __dirname6 = dirname24(fileURLToPath6(import.meta.url));
|
|
16258
|
-
var VOICE_DIR =
|
|
16251
|
+
var VOICE_DIR = join43(homedir12(), ".assist", "voice");
|
|
16259
16252
|
var voicePaths = {
|
|
16260
16253
|
dir: VOICE_DIR,
|
|
16261
|
-
pid:
|
|
16262
|
-
log:
|
|
16263
|
-
venv:
|
|
16264
|
-
lock:
|
|
16254
|
+
pid: join43(VOICE_DIR, "voice.pid"),
|
|
16255
|
+
log: join43(VOICE_DIR, "voice.log"),
|
|
16256
|
+
venv: join43(VOICE_DIR, ".venv"),
|
|
16257
|
+
lock: join43(VOICE_DIR, "voice.lock")
|
|
16265
16258
|
};
|
|
16266
16259
|
function getPythonDir() {
|
|
16267
|
-
return
|
|
16260
|
+
return join43(__dirname6, "commands", "voice", "python");
|
|
16268
16261
|
}
|
|
16269
16262
|
function getVenvPython() {
|
|
16270
|
-
return process.platform === "win32" ?
|
|
16263
|
+
return process.platform === "win32" ? join43(voicePaths.venv, "Scripts", "python.exe") : join43(voicePaths.venv, "bin", "python");
|
|
16271
16264
|
}
|
|
16272
16265
|
function getLockDir() {
|
|
16273
16266
|
const config = loadConfig();
|
|
16274
16267
|
return config.voice?.lockDir ?? VOICE_DIR;
|
|
16275
16268
|
}
|
|
16276
16269
|
function getLockFile() {
|
|
16277
|
-
return
|
|
16270
|
+
return join43(getLockDir(), "voice.lock");
|
|
16278
16271
|
}
|
|
16279
16272
|
|
|
16280
16273
|
// src/commands/voice/devices.ts
|
|
16281
16274
|
function devices() {
|
|
16282
|
-
const script =
|
|
16275
|
+
const script = join44(getPythonDir(), "list_devices.py");
|
|
16283
16276
|
spawnSync4(getVenvPython(), [script], { stdio: "inherit" });
|
|
16284
16277
|
}
|
|
16285
16278
|
|
|
16286
16279
|
// src/commands/voice/logs.ts
|
|
16287
|
-
import { existsSync as
|
|
16280
|
+
import { existsSync as existsSync43, readFileSync as readFileSync34 } from "fs";
|
|
16288
16281
|
function logs(options2) {
|
|
16289
|
-
if (!
|
|
16282
|
+
if (!existsSync43(voicePaths.log)) {
|
|
16290
16283
|
console.log("No voice log file found");
|
|
16291
16284
|
return;
|
|
16292
16285
|
}
|
|
16293
16286
|
const count6 = Number.parseInt(options2.lines ?? "150", 10);
|
|
16294
|
-
const content =
|
|
16287
|
+
const content = readFileSync34(voicePaths.log, "utf-8").trim();
|
|
16295
16288
|
if (!content) {
|
|
16296
16289
|
console.log("Voice log is empty");
|
|
16297
16290
|
return;
|
|
@@ -16314,12 +16307,12 @@ function logs(options2) {
|
|
|
16314
16307
|
// src/commands/voice/setup.ts
|
|
16315
16308
|
import { spawnSync as spawnSync5 } from "child_process";
|
|
16316
16309
|
import { mkdirSync as mkdirSync17 } from "fs";
|
|
16317
|
-
import { join as
|
|
16310
|
+
import { join as join46 } from "path";
|
|
16318
16311
|
|
|
16319
16312
|
// src/commands/voice/checkLockFile.ts
|
|
16320
16313
|
import { execSync as execSync45 } from "child_process";
|
|
16321
|
-
import { existsSync as
|
|
16322
|
-
import { join as
|
|
16314
|
+
import { existsSync as existsSync44, mkdirSync as mkdirSync16, readFileSync as readFileSync35, writeFileSync as writeFileSync28 } from "fs";
|
|
16315
|
+
import { join as join45 } from "path";
|
|
16323
16316
|
function isProcessAlive2(pid) {
|
|
16324
16317
|
try {
|
|
16325
16318
|
process.kill(pid, 0);
|
|
@@ -16330,9 +16323,9 @@ function isProcessAlive2(pid) {
|
|
|
16330
16323
|
}
|
|
16331
16324
|
function checkLockFile() {
|
|
16332
16325
|
const lockFile = getLockFile();
|
|
16333
|
-
if (!
|
|
16326
|
+
if (!existsSync44(lockFile)) return;
|
|
16334
16327
|
try {
|
|
16335
|
-
const lock = JSON.parse(
|
|
16328
|
+
const lock = JSON.parse(readFileSync35(lockFile, "utf-8"));
|
|
16336
16329
|
if (lock.pid && isProcessAlive2(lock.pid)) {
|
|
16337
16330
|
console.error(
|
|
16338
16331
|
`Voice daemon already running (PID ${lock.pid}, env: ${lock.env}). Stop it first with: assist voice stop`
|
|
@@ -16343,7 +16336,7 @@ function checkLockFile() {
|
|
|
16343
16336
|
}
|
|
16344
16337
|
}
|
|
16345
16338
|
function bootstrapVenv() {
|
|
16346
|
-
if (
|
|
16339
|
+
if (existsSync44(getVenvPython())) return;
|
|
16347
16340
|
console.log("Setting up Python environment...");
|
|
16348
16341
|
const pythonDir = getPythonDir();
|
|
16349
16342
|
execSync45(
|
|
@@ -16356,8 +16349,8 @@ function bootstrapVenv() {
|
|
|
16356
16349
|
}
|
|
16357
16350
|
function writeLockFile(pid) {
|
|
16358
16351
|
const lockFile = getLockFile();
|
|
16359
|
-
mkdirSync16(
|
|
16360
|
-
|
|
16352
|
+
mkdirSync16(join45(lockFile, ".."), { recursive: true });
|
|
16353
|
+
writeFileSync28(
|
|
16361
16354
|
lockFile,
|
|
16362
16355
|
JSON.stringify({
|
|
16363
16356
|
pid,
|
|
@@ -16372,7 +16365,7 @@ function setup() {
|
|
|
16372
16365
|
mkdirSync17(voicePaths.dir, { recursive: true });
|
|
16373
16366
|
bootstrapVenv();
|
|
16374
16367
|
console.log("\nDownloading models...\n");
|
|
16375
|
-
const script =
|
|
16368
|
+
const script = join46(getPythonDir(), "setup_models.py");
|
|
16376
16369
|
const result = spawnSync5(getVenvPython(), [script], {
|
|
16377
16370
|
stdio: "inherit",
|
|
16378
16371
|
env: { ...process.env, VOICE_LOG_FILE: voicePaths.log }
|
|
@@ -16385,8 +16378,8 @@ function setup() {
|
|
|
16385
16378
|
|
|
16386
16379
|
// src/commands/voice/start.ts
|
|
16387
16380
|
import { spawn as spawn7 } from "child_process";
|
|
16388
|
-
import { mkdirSync as mkdirSync18, writeFileSync as
|
|
16389
|
-
import { join as
|
|
16381
|
+
import { mkdirSync as mkdirSync18, writeFileSync as writeFileSync29 } from "fs";
|
|
16382
|
+
import { join as join47 } from "path";
|
|
16390
16383
|
|
|
16391
16384
|
// src/commands/voice/buildDaemonEnv.ts
|
|
16392
16385
|
function buildDaemonEnv(options2) {
|
|
@@ -16414,7 +16407,7 @@ function spawnBackground(python, script, env) {
|
|
|
16414
16407
|
console.error("Failed to start voice daemon");
|
|
16415
16408
|
process.exit(1);
|
|
16416
16409
|
}
|
|
16417
|
-
|
|
16410
|
+
writeFileSync29(voicePaths.pid, String(pid));
|
|
16418
16411
|
writeLockFile(pid);
|
|
16419
16412
|
console.log(`Voice daemon started (PID ${pid})`);
|
|
16420
16413
|
}
|
|
@@ -16424,7 +16417,7 @@ function start2(options2) {
|
|
|
16424
16417
|
bootstrapVenv();
|
|
16425
16418
|
const debug = options2.debug || options2.foreground || process.platform === "win32";
|
|
16426
16419
|
const env = buildDaemonEnv({ debug });
|
|
16427
|
-
const script =
|
|
16420
|
+
const script = join47(getPythonDir(), "voice_daemon.py");
|
|
16428
16421
|
const python = getVenvPython();
|
|
16429
16422
|
if (options2.foreground) {
|
|
16430
16423
|
spawnForeground(python, script, env);
|
|
@@ -16434,7 +16427,7 @@ function start2(options2) {
|
|
|
16434
16427
|
}
|
|
16435
16428
|
|
|
16436
16429
|
// src/commands/voice/status.ts
|
|
16437
|
-
import { existsSync as
|
|
16430
|
+
import { existsSync as existsSync45, readFileSync as readFileSync36 } from "fs";
|
|
16438
16431
|
function isProcessAlive3(pid) {
|
|
16439
16432
|
try {
|
|
16440
16433
|
process.kill(pid, 0);
|
|
@@ -16444,16 +16437,16 @@ function isProcessAlive3(pid) {
|
|
|
16444
16437
|
}
|
|
16445
16438
|
}
|
|
16446
16439
|
function readRecentLogs(count6) {
|
|
16447
|
-
if (!
|
|
16448
|
-
const lines =
|
|
16440
|
+
if (!existsSync45(voicePaths.log)) return [];
|
|
16441
|
+
const lines = readFileSync36(voicePaths.log, "utf-8").trim().split("\n");
|
|
16449
16442
|
return lines.slice(-count6);
|
|
16450
16443
|
}
|
|
16451
16444
|
function status() {
|
|
16452
|
-
if (!
|
|
16445
|
+
if (!existsSync45(voicePaths.pid)) {
|
|
16453
16446
|
console.log("Voice daemon: not running (no PID file)");
|
|
16454
16447
|
return;
|
|
16455
16448
|
}
|
|
16456
|
-
const pid = Number.parseInt(
|
|
16449
|
+
const pid = Number.parseInt(readFileSync36(voicePaths.pid, "utf-8").trim(), 10);
|
|
16457
16450
|
const alive = isProcessAlive3(pid);
|
|
16458
16451
|
console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
|
|
16459
16452
|
const recent = readRecentLogs(5);
|
|
@@ -16472,13 +16465,13 @@ function status() {
|
|
|
16472
16465
|
}
|
|
16473
16466
|
|
|
16474
16467
|
// src/commands/voice/stop.ts
|
|
16475
|
-
import { existsSync as
|
|
16468
|
+
import { existsSync as existsSync46, readFileSync as readFileSync37, unlinkSync as unlinkSync14 } from "fs";
|
|
16476
16469
|
function stop2() {
|
|
16477
|
-
if (!
|
|
16470
|
+
if (!existsSync46(voicePaths.pid)) {
|
|
16478
16471
|
console.log("Voice daemon is not running (no PID file)");
|
|
16479
16472
|
return;
|
|
16480
16473
|
}
|
|
16481
|
-
const pid = Number.parseInt(
|
|
16474
|
+
const pid = Number.parseInt(readFileSync37(voicePaths.pid, "utf-8").trim(), 10);
|
|
16482
16475
|
try {
|
|
16483
16476
|
process.kill(pid, "SIGTERM");
|
|
16484
16477
|
console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
|
|
@@ -16491,7 +16484,7 @@ function stop2() {
|
|
|
16491
16484
|
}
|
|
16492
16485
|
try {
|
|
16493
16486
|
const lockFile = getLockFile();
|
|
16494
|
-
if (
|
|
16487
|
+
if (existsSync46(lockFile)) unlinkSync14(lockFile);
|
|
16495
16488
|
} catch {
|
|
16496
16489
|
}
|
|
16497
16490
|
console.log("Voice daemon stopped");
|
|
@@ -16713,8 +16706,8 @@ async function auth() {
|
|
|
16713
16706
|
|
|
16714
16707
|
// src/commands/roam/postRoamActivity.ts
|
|
16715
16708
|
import { execFileSync as execFileSync7 } from "child_process";
|
|
16716
|
-
import { readdirSync as readdirSync7, readFileSync as
|
|
16717
|
-
import { join as
|
|
16709
|
+
import { readdirSync as readdirSync7, readFileSync as readFileSync38, statSync as statSync5 } from "fs";
|
|
16710
|
+
import { join as join48 } from "path";
|
|
16718
16711
|
function findPortFile(roamDir) {
|
|
16719
16712
|
let entries;
|
|
16720
16713
|
try {
|
|
@@ -16723,7 +16716,7 @@ function findPortFile(roamDir) {
|
|
|
16723
16716
|
return void 0;
|
|
16724
16717
|
}
|
|
16725
16718
|
const candidates = entries.filter((name) => /^roam-local-api(-[^.]+)?\.port$/.test(name)).map((name) => {
|
|
16726
|
-
const path53 =
|
|
16719
|
+
const path53 = join48(roamDir, name);
|
|
16727
16720
|
try {
|
|
16728
16721
|
return { path: path53, mtimeMs: statSync5(path53).mtimeMs };
|
|
16729
16722
|
} catch {
|
|
@@ -16735,11 +16728,11 @@ function findPortFile(roamDir) {
|
|
|
16735
16728
|
function postRoamActivity(app, event) {
|
|
16736
16729
|
const appData = process.env.APPDATA;
|
|
16737
16730
|
if (!appData) return;
|
|
16738
|
-
const portFile = findPortFile(
|
|
16731
|
+
const portFile = findPortFile(join48(appData, "Roam"));
|
|
16739
16732
|
if (!portFile) return;
|
|
16740
16733
|
let port;
|
|
16741
16734
|
try {
|
|
16742
|
-
port =
|
|
16735
|
+
port = readFileSync38(portFile, "utf-8").trim();
|
|
16743
16736
|
} catch {
|
|
16744
16737
|
return;
|
|
16745
16738
|
}
|
|
@@ -16881,15 +16874,15 @@ function runPreCommands(pre, cwd) {
|
|
|
16881
16874
|
|
|
16882
16875
|
// src/commands/run/spawnRunCommand.ts
|
|
16883
16876
|
import { execFileSync as execFileSync8, spawn as spawn8 } from "child_process";
|
|
16884
|
-
import { existsSync as
|
|
16885
|
-
import { dirname as dirname25, join as
|
|
16877
|
+
import { existsSync as existsSync47 } from "fs";
|
|
16878
|
+
import { dirname as dirname25, join as join49, resolve as resolve11 } from "path";
|
|
16886
16879
|
function resolveCommand2(command) {
|
|
16887
16880
|
if (process.platform !== "win32" || command !== "bash") return command;
|
|
16888
16881
|
try {
|
|
16889
16882
|
const gitPath = execFileSync8("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
|
|
16890
16883
|
const gitRoot = resolve11(dirname25(gitPath), "..");
|
|
16891
|
-
const gitBash =
|
|
16892
|
-
if (
|
|
16884
|
+
const gitBash = join49(gitRoot, "bin", "bash.exe");
|
|
16885
|
+
if (existsSync47(gitBash)) return gitBash;
|
|
16893
16886
|
} catch {
|
|
16894
16887
|
}
|
|
16895
16888
|
return command;
|
|
@@ -16974,8 +16967,8 @@ async function run3(name, args) {
|
|
|
16974
16967
|
}
|
|
16975
16968
|
|
|
16976
16969
|
// src/commands/run/add.ts
|
|
16977
|
-
import { mkdirSync as mkdirSync19, writeFileSync as
|
|
16978
|
-
import { join as
|
|
16970
|
+
import { mkdirSync as mkdirSync19, writeFileSync as writeFileSync30 } from "fs";
|
|
16971
|
+
import { join as join50 } from "path";
|
|
16979
16972
|
|
|
16980
16973
|
// src/commands/run/extractOption.ts
|
|
16981
16974
|
function extractOption(args, flag) {
|
|
@@ -17036,7 +17029,7 @@ function saveNewRunConfig(name, command, args, cwd) {
|
|
|
17036
17029
|
saveConfig(config);
|
|
17037
17030
|
}
|
|
17038
17031
|
function createCommandFile(name) {
|
|
17039
|
-
const dir =
|
|
17032
|
+
const dir = join50(".claude", "commands");
|
|
17040
17033
|
mkdirSync19(dir, { recursive: true });
|
|
17041
17034
|
const content = `---
|
|
17042
17035
|
description: Run ${name}
|
|
@@ -17044,8 +17037,8 @@ description: Run ${name}
|
|
|
17044
17037
|
|
|
17045
17038
|
Run \`assist run ${name} $ARGUMENTS 2>&1\`.
|
|
17046
17039
|
`;
|
|
17047
|
-
const filePath =
|
|
17048
|
-
|
|
17040
|
+
const filePath = join50(dir, `${name}.md`);
|
|
17041
|
+
writeFileSync30(filePath, content);
|
|
17049
17042
|
console.log(`Created command file: ${filePath}`);
|
|
17050
17043
|
}
|
|
17051
17044
|
function add3() {
|
|
@@ -17100,8 +17093,8 @@ function link2() {
|
|
|
17100
17093
|
}
|
|
17101
17094
|
|
|
17102
17095
|
// src/commands/run/remove.ts
|
|
17103
|
-
import { existsSync as
|
|
17104
|
-
import { join as
|
|
17096
|
+
import { existsSync as existsSync48, unlinkSync as unlinkSync15 } from "fs";
|
|
17097
|
+
import { join as join51 } from "path";
|
|
17105
17098
|
function findRemoveIndex() {
|
|
17106
17099
|
const idx = process.argv.indexOf("remove");
|
|
17107
17100
|
if (idx === -1 || idx + 1 >= process.argv.length) return -1;
|
|
@@ -17116,8 +17109,8 @@ function parseRemoveName() {
|
|
|
17116
17109
|
return process.argv[idx + 1];
|
|
17117
17110
|
}
|
|
17118
17111
|
function deleteCommandFile(name) {
|
|
17119
|
-
const filePath =
|
|
17120
|
-
if (
|
|
17112
|
+
const filePath = join51(".claude", "commands", `${name}.md`);
|
|
17113
|
+
if (existsSync48(filePath)) {
|
|
17121
17114
|
unlinkSync15(filePath);
|
|
17122
17115
|
console.log(`Deleted command file: ${filePath}`);
|
|
17123
17116
|
}
|
|
@@ -17156,9 +17149,9 @@ function registerRun(program2) {
|
|
|
17156
17149
|
|
|
17157
17150
|
// src/commands/screenshot/index.ts
|
|
17158
17151
|
import { execSync as execSync48 } from "child_process";
|
|
17159
|
-
import { existsSync as
|
|
17152
|
+
import { existsSync as existsSync49, mkdirSync as mkdirSync20, unlinkSync as unlinkSync16, writeFileSync as writeFileSync31 } from "fs";
|
|
17160
17153
|
import { tmpdir as tmpdir7 } from "os";
|
|
17161
|
-
import { join as
|
|
17154
|
+
import { join as join52, resolve as resolve13 } from "path";
|
|
17162
17155
|
import chalk158 from "chalk";
|
|
17163
17156
|
|
|
17164
17157
|
// src/commands/screenshot/captureWindowPs1.ts
|
|
@@ -17288,15 +17281,15 @@ Write-Output $OutputPath
|
|
|
17288
17281
|
|
|
17289
17282
|
// src/commands/screenshot/index.ts
|
|
17290
17283
|
function buildOutputPath(outputDir, processName) {
|
|
17291
|
-
if (!
|
|
17284
|
+
if (!existsSync49(outputDir)) {
|
|
17292
17285
|
mkdirSync20(outputDir, { recursive: true });
|
|
17293
17286
|
}
|
|
17294
17287
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
17295
17288
|
return resolve13(outputDir, `${processName}-${timestamp}.png`);
|
|
17296
17289
|
}
|
|
17297
17290
|
function runPowerShellScript(processName, outputPath) {
|
|
17298
|
-
const scriptPath =
|
|
17299
|
-
|
|
17291
|
+
const scriptPath = join52(tmpdir7(), `assist-screenshot-${Date.now()}.ps1`);
|
|
17292
|
+
writeFileSync31(scriptPath, captureWindowPs1, "utf-8");
|
|
17300
17293
|
try {
|
|
17301
17294
|
execSync48(
|
|
17302
17295
|
`powershell -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}" -ProcessName "${processName}" -OutputPath "${outputPath}"`,
|
|
@@ -17372,7 +17365,7 @@ function applyLine(result, pending, line) {
|
|
|
17372
17365
|
}
|
|
17373
17366
|
|
|
17374
17367
|
// src/commands/sessions/daemon/reportStolenSocket.ts
|
|
17375
|
-
import { readFileSync as
|
|
17368
|
+
import { readFileSync as readFileSync39 } from "fs";
|
|
17376
17369
|
function reportStolenSocket(socketPid) {
|
|
17377
17370
|
if (!socketPid) return;
|
|
17378
17371
|
const filePid = readPidFile();
|
|
@@ -17384,7 +17377,7 @@ function reportStolenSocket(socketPid) {
|
|
|
17384
17377
|
function readPidFile() {
|
|
17385
17378
|
try {
|
|
17386
17379
|
const pid = Number.parseInt(
|
|
17387
|
-
|
|
17380
|
+
readFileSync39(daemonPaths.pid, "utf-8").trim(),
|
|
17388
17381
|
10
|
|
17389
17382
|
);
|
|
17390
17383
|
return Number.isInteger(pid) ? pid : void 0;
|
|
@@ -17706,7 +17699,7 @@ function broadcastSessions(sessions, clients) {
|
|
|
17706
17699
|
import * as pty from "node-pty";
|
|
17707
17700
|
|
|
17708
17701
|
// src/commands/sessions/daemon/ensureSpawnHelperExecutable.ts
|
|
17709
|
-
import { chmodSync, existsSync as
|
|
17702
|
+
import { chmodSync, existsSync as existsSync50, statSync as statSync6 } from "fs";
|
|
17710
17703
|
import { createRequire as createRequire3 } from "module";
|
|
17711
17704
|
import path47 from "path";
|
|
17712
17705
|
var require4 = createRequire3(import.meta.url);
|
|
@@ -17721,7 +17714,7 @@ function ensureSpawnHelperExecutable() {
|
|
|
17721
17714
|
`${process.platform}-${process.arch}`,
|
|
17722
17715
|
"spawn-helper"
|
|
17723
17716
|
);
|
|
17724
|
-
if (!
|
|
17717
|
+
if (!existsSync50(helper)) return;
|
|
17725
17718
|
const mode = statSync6(helper).mode;
|
|
17726
17719
|
if ((mode & 73) === 0) chmodSync(helper, mode | 493);
|
|
17727
17720
|
}
|
|
@@ -17948,7 +17941,7 @@ function clearIdle(session) {
|
|
|
17948
17941
|
}
|
|
17949
17942
|
|
|
17950
17943
|
// src/commands/sessions/daemon/watchActivity.ts
|
|
17951
|
-
import { existsSync as
|
|
17944
|
+
import { existsSync as existsSync51, mkdirSync as mkdirSync21, watch } from "fs";
|
|
17952
17945
|
import { dirname as dirname27 } from "path";
|
|
17953
17946
|
var DEBOUNCE_MS = 50;
|
|
17954
17947
|
function watchActivity(session, notify2) {
|
|
@@ -17975,7 +17968,7 @@ function watchActivity(session, notify2) {
|
|
|
17975
17968
|
if (timer) clearTimeout(timer);
|
|
17976
17969
|
timer = setTimeout(read, DEBOUNCE_MS);
|
|
17977
17970
|
});
|
|
17978
|
-
if (
|
|
17971
|
+
if (existsSync51(path53)) read();
|
|
17979
17972
|
}
|
|
17980
17973
|
function refreshActivity(session) {
|
|
17981
17974
|
if (session.commandType !== "assist" || !session.cwd) return;
|
|
@@ -18344,10 +18337,10 @@ function handleConnection(socket, manager) {
|
|
|
18344
18337
|
}
|
|
18345
18338
|
|
|
18346
18339
|
// src/commands/sessions/daemon/onListening.ts
|
|
18347
|
-
import { unlinkSync as unlinkSync17, writeFileSync as
|
|
18340
|
+
import { unlinkSync as unlinkSync17, writeFileSync as writeFileSync32 } from "fs";
|
|
18348
18341
|
|
|
18349
18342
|
// src/commands/sessions/daemon/startPidFileWatchdog.ts
|
|
18350
|
-
import { readFileSync as
|
|
18343
|
+
import { readFileSync as readFileSync40 } from "fs";
|
|
18351
18344
|
var WATCHDOG_INTERVAL_MS = 5e3;
|
|
18352
18345
|
function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
|
|
18353
18346
|
const timer = setInterval(() => {
|
|
@@ -18358,7 +18351,7 @@ function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
|
|
|
18358
18351
|
}
|
|
18359
18352
|
function ownsPidFile() {
|
|
18360
18353
|
try {
|
|
18361
|
-
return
|
|
18354
|
+
return readFileSync40(daemonPaths.pid, "utf-8").trim() === String(process.pid);
|
|
18362
18355
|
} catch {
|
|
18363
18356
|
return false;
|
|
18364
18357
|
}
|
|
@@ -18366,7 +18359,7 @@ function ownsPidFile() {
|
|
|
18366
18359
|
|
|
18367
18360
|
// src/commands/sessions/daemon/onListening.ts
|
|
18368
18361
|
function onListening(manager, checkAutoExit) {
|
|
18369
|
-
|
|
18362
|
+
writeFileSync32(daemonPaths.pid, String(process.pid));
|
|
18370
18363
|
startPidFileWatchdog(() => {
|
|
18371
18364
|
daemonLog("lost daemon.pid ownership; shutting down sessions and exiting");
|
|
18372
18365
|
manager.shutdown();
|