@staff0rd/assist 0.36.1 → 0.37.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/claude/CLAUDE.md +3 -0
- package/dist/index.js +94 -63
- package/package.json +1 -1
package/claude/CLAUDE.md
ADDED
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { Command } from "commander";
|
|
|
7
7
|
// package.json
|
|
8
8
|
var package_default = {
|
|
9
9
|
name: "@staff0rd/assist",
|
|
10
|
-
version: "0.
|
|
10
|
+
version: "0.37.0",
|
|
11
11
|
type: "module",
|
|
12
12
|
main: "dist/index.js",
|
|
13
13
|
bin: {
|
|
@@ -621,8 +621,8 @@ Total: ${total} lines across ${files.length} files`)
|
|
|
621
621
|
// src/commands/config/index.ts
|
|
622
622
|
import chalk7 from "chalk";
|
|
623
623
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
624
|
-
function getNestedValue(obj,
|
|
625
|
-
const keys =
|
|
624
|
+
function getNestedValue(obj, path19) {
|
|
625
|
+
const keys = path19.split(".");
|
|
626
626
|
let current = obj;
|
|
627
627
|
for (const key of keys) {
|
|
628
628
|
if (current === null || current === void 0 || typeof current !== "object") {
|
|
@@ -632,8 +632,8 @@ function getNestedValue(obj, path18) {
|
|
|
632
632
|
}
|
|
633
633
|
return current;
|
|
634
634
|
}
|
|
635
|
-
function setNestedValue(obj,
|
|
636
|
-
const keys =
|
|
635
|
+
function setNestedValue(obj, path19, value) {
|
|
636
|
+
const keys = path19.split(".");
|
|
637
637
|
const result = { ...obj };
|
|
638
638
|
let current = result;
|
|
639
639
|
for (let i = 0; i < keys.length - 1; i++) {
|
|
@@ -660,8 +660,8 @@ function configSet(key, value) {
|
|
|
660
660
|
const result = assistConfigSchema.safeParse(updated);
|
|
661
661
|
if (!result.success) {
|
|
662
662
|
for (const issue of result.error.issues) {
|
|
663
|
-
const
|
|
664
|
-
console.error(chalk7.red(`${
|
|
663
|
+
const path19 = issue.path.length > 0 ? issue.path.join(".") : key;
|
|
664
|
+
console.error(chalk7.red(`${path19}: ${issue.message}`));
|
|
665
665
|
}
|
|
666
666
|
process.exit(1);
|
|
667
667
|
}
|
|
@@ -2949,31 +2949,61 @@ async function statusLine() {
|
|
|
2949
2949
|
}
|
|
2950
2950
|
|
|
2951
2951
|
// src/commands/sync.ts
|
|
2952
|
-
import * as
|
|
2952
|
+
import * as fs18 from "fs";
|
|
2953
2953
|
import * as os from "os";
|
|
2954
|
-
import * as
|
|
2954
|
+
import * as path17 from "path";
|
|
2955
2955
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
2956
2956
|
|
|
2957
|
-
// src/commands/sync/
|
|
2957
|
+
// src/commands/sync/syncClaudeMd.ts
|
|
2958
2958
|
import * as fs16 from "fs";
|
|
2959
2959
|
import * as path15 from "path";
|
|
2960
2960
|
import chalk35 from "chalk";
|
|
2961
|
-
async function
|
|
2962
|
-
const source = path15.join(claudeDir, "
|
|
2963
|
-
const target = path15.join(targetBase, "
|
|
2961
|
+
async function syncClaudeMd(claudeDir, targetBase) {
|
|
2962
|
+
const source = path15.join(claudeDir, "CLAUDE.md");
|
|
2963
|
+
const target = path15.join(targetBase, "CLAUDE.md");
|
|
2964
2964
|
const sourceContent = fs16.readFileSync(source, "utf-8");
|
|
2965
|
-
const normalizedSource = JSON.stringify(JSON.parse(sourceContent), null, 2);
|
|
2966
2965
|
if (fs16.existsSync(target)) {
|
|
2967
2966
|
const targetContent = fs16.readFileSync(target, "utf-8");
|
|
2967
|
+
if (sourceContent !== targetContent) {
|
|
2968
|
+
console.log(
|
|
2969
|
+
chalk35.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
|
|
2970
|
+
);
|
|
2971
|
+
console.log();
|
|
2972
|
+
printDiff(targetContent, sourceContent);
|
|
2973
|
+
const confirm = await promptConfirm(
|
|
2974
|
+
chalk35.red("Overwrite existing CLAUDE.md?"),
|
|
2975
|
+
false
|
|
2976
|
+
);
|
|
2977
|
+
if (!confirm) {
|
|
2978
|
+
console.log("Skipped CLAUDE.md");
|
|
2979
|
+
return;
|
|
2980
|
+
}
|
|
2981
|
+
}
|
|
2982
|
+
}
|
|
2983
|
+
fs16.copyFileSync(source, target);
|
|
2984
|
+
console.log("Copied CLAUDE.md to ~/.claude/CLAUDE.md");
|
|
2985
|
+
}
|
|
2986
|
+
|
|
2987
|
+
// src/commands/sync/syncSettings.ts
|
|
2988
|
+
import * as fs17 from "fs";
|
|
2989
|
+
import * as path16 from "path";
|
|
2990
|
+
import chalk36 from "chalk";
|
|
2991
|
+
async function syncSettings(claudeDir, targetBase) {
|
|
2992
|
+
const source = path16.join(claudeDir, "settings.json");
|
|
2993
|
+
const target = path16.join(targetBase, "settings.json");
|
|
2994
|
+
const sourceContent = fs17.readFileSync(source, "utf-8");
|
|
2995
|
+
const normalizedSource = JSON.stringify(JSON.parse(sourceContent), null, 2);
|
|
2996
|
+
if (fs17.existsSync(target)) {
|
|
2997
|
+
const targetContent = fs17.readFileSync(target, "utf-8");
|
|
2968
2998
|
const normalizedTarget = JSON.stringify(JSON.parse(targetContent), null, 2);
|
|
2969
2999
|
if (normalizedSource !== normalizedTarget) {
|
|
2970
3000
|
console.log(
|
|
2971
|
-
|
|
3001
|
+
chalk36.yellow("\n\u26A0\uFE0F Warning: settings.json differs from existing file")
|
|
2972
3002
|
);
|
|
2973
3003
|
console.log();
|
|
2974
3004
|
printDiff(targetContent, sourceContent);
|
|
2975
3005
|
const confirm = await promptConfirm(
|
|
2976
|
-
|
|
3006
|
+
chalk36.red("Overwrite existing settings.json?"),
|
|
2977
3007
|
false
|
|
2978
3008
|
);
|
|
2979
3009
|
if (!confirm) {
|
|
@@ -2982,34 +3012,35 @@ async function syncSettings(claudeDir, targetBase) {
|
|
|
2982
3012
|
}
|
|
2983
3013
|
}
|
|
2984
3014
|
}
|
|
2985
|
-
|
|
3015
|
+
fs17.copyFileSync(source, target);
|
|
2986
3016
|
console.log("Copied settings.json to ~/.claude/settings.json");
|
|
2987
3017
|
}
|
|
2988
3018
|
|
|
2989
3019
|
// src/commands/sync.ts
|
|
2990
3020
|
var __filename2 = fileURLToPath3(import.meta.url);
|
|
2991
|
-
var __dirname4 =
|
|
3021
|
+
var __dirname4 = path17.dirname(__filename2);
|
|
2992
3022
|
async function sync() {
|
|
2993
|
-
const claudeDir =
|
|
2994
|
-
const targetBase =
|
|
3023
|
+
const claudeDir = path17.join(__dirname4, "..", "claude");
|
|
3024
|
+
const targetBase = path17.join(os.homedir(), ".claude");
|
|
2995
3025
|
syncCommands(claudeDir, targetBase);
|
|
2996
3026
|
await syncSettings(claudeDir, targetBase);
|
|
3027
|
+
await syncClaudeMd(claudeDir, targetBase);
|
|
2997
3028
|
}
|
|
2998
3029
|
function syncCommands(claudeDir, targetBase) {
|
|
2999
|
-
const sourceDir =
|
|
3000
|
-
const targetDir =
|
|
3001
|
-
|
|
3002
|
-
const files =
|
|
3030
|
+
const sourceDir = path17.join(claudeDir, "commands");
|
|
3031
|
+
const targetDir = path17.join(targetBase, "commands");
|
|
3032
|
+
fs18.mkdirSync(targetDir, { recursive: true });
|
|
3033
|
+
const files = fs18.readdirSync(sourceDir);
|
|
3003
3034
|
for (const file of files) {
|
|
3004
|
-
|
|
3035
|
+
fs18.copyFileSync(path17.join(sourceDir, file), path17.join(targetDir, file));
|
|
3005
3036
|
console.log(`Copied ${file} to ${targetDir}`);
|
|
3006
3037
|
}
|
|
3007
3038
|
console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
|
|
3008
3039
|
}
|
|
3009
3040
|
|
|
3010
3041
|
// src/commands/transcript/shared.ts
|
|
3011
|
-
import { existsSync as
|
|
3012
|
-
import { basename as basename3, join as
|
|
3042
|
+
import { existsSync as existsSync15, readdirSync as readdirSync3, statSync } from "fs";
|
|
3043
|
+
import { basename as basename3, join as join14, relative } from "path";
|
|
3013
3044
|
import * as readline2 from "readline";
|
|
3014
3045
|
var DATE_PREFIX_REGEX = /^\d{4}-\d{2}-\d{2}/;
|
|
3015
3046
|
function getDatePrefix(daysOffset = 0) {
|
|
@@ -3024,13 +3055,13 @@ function isValidDatePrefix(filename) {
|
|
|
3024
3055
|
return DATE_PREFIX_REGEX.test(filename);
|
|
3025
3056
|
}
|
|
3026
3057
|
function findFilesRecursive(dir, baseDir, extension, createEntry) {
|
|
3027
|
-
if (!
|
|
3058
|
+
if (!existsSync15(dir)) {
|
|
3028
3059
|
return [];
|
|
3029
3060
|
}
|
|
3030
3061
|
const results = [];
|
|
3031
3062
|
const entries = readdirSync3(dir);
|
|
3032
3063
|
for (const entry of entries) {
|
|
3033
|
-
const fullPath =
|
|
3064
|
+
const fullPath = join14(dir, entry);
|
|
3034
3065
|
const stat = statSync(fullPath);
|
|
3035
3066
|
if (stat.isDirectory()) {
|
|
3036
3067
|
results.push(
|
|
@@ -3120,8 +3151,8 @@ async function configure() {
|
|
|
3120
3151
|
}
|
|
3121
3152
|
|
|
3122
3153
|
// src/commands/transcript/format.ts
|
|
3123
|
-
import { existsSync as
|
|
3124
|
-
import { basename as basename4, dirname as dirname11, join as
|
|
3154
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync5, readFileSync as readFileSync14, writeFileSync as writeFileSync11 } from "fs";
|
|
3155
|
+
import { basename as basename4, dirname as dirname11, join as join16 } from "path";
|
|
3125
3156
|
|
|
3126
3157
|
// src/commands/transcript/parseVtt.ts
|
|
3127
3158
|
function parseTimestamp(ts2) {
|
|
@@ -3283,7 +3314,7 @@ function formatChatLog(messages) {
|
|
|
3283
3314
|
|
|
3284
3315
|
// src/commands/transcript/promptForDateFix.ts
|
|
3285
3316
|
import { renameSync } from "fs";
|
|
3286
|
-
import { join as
|
|
3317
|
+
import { join as join15 } from "path";
|
|
3287
3318
|
async function promptForDateFix(vttFile, vttDir) {
|
|
3288
3319
|
const rl = createReadlineInterface();
|
|
3289
3320
|
console.log(
|
|
@@ -3324,8 +3355,8 @@ Error: File "${vttFile}" does not start with YYYY-MM-DD format.`
|
|
|
3324
3355
|
rl.close();
|
|
3325
3356
|
if (newPrefix) {
|
|
3326
3357
|
const newFilename = `${newPrefix}.${vttFile}`;
|
|
3327
|
-
const oldPath =
|
|
3328
|
-
const newPath =
|
|
3358
|
+
const oldPath = join15(vttDir, vttFile);
|
|
3359
|
+
const newPath = join15(vttDir, newFilename);
|
|
3329
3360
|
renameSync(oldPath, newPath);
|
|
3330
3361
|
console.log(`Renamed to: ${newFilename}`);
|
|
3331
3362
|
return newFilename;
|
|
@@ -3340,7 +3371,7 @@ Error: File "${vttFile}" does not start with YYYY-MM-DD format.`
|
|
|
3340
3371
|
// src/commands/transcript/format.ts
|
|
3341
3372
|
function processFile(inputPath, outputPath) {
|
|
3342
3373
|
console.log(`Reading: ${inputPath}`);
|
|
3343
|
-
const content =
|
|
3374
|
+
const content = readFileSync14(inputPath, "utf-8");
|
|
3344
3375
|
const cues = parseVtt(content);
|
|
3345
3376
|
console.log(`Parsed ${cues.length} cues`);
|
|
3346
3377
|
const dedupedCues = deduplicateCues(cues);
|
|
@@ -3357,11 +3388,11 @@ function processFile(inputPath, outputPath) {
|
|
|
3357
3388
|
}
|
|
3358
3389
|
async function format() {
|
|
3359
3390
|
const { vttDir, transcriptsDir } = getTranscriptConfig();
|
|
3360
|
-
if (!
|
|
3391
|
+
if (!existsSync16(vttDir)) {
|
|
3361
3392
|
console.error(`VTT directory not found: ${vttDir}`);
|
|
3362
3393
|
process.exit(1);
|
|
3363
3394
|
}
|
|
3364
|
-
if (!
|
|
3395
|
+
if (!existsSync16(transcriptsDir)) {
|
|
3365
3396
|
mkdirSync5(transcriptsDir, { recursive: true });
|
|
3366
3397
|
console.log(`Created output directory: ${transcriptsDir}`);
|
|
3367
3398
|
}
|
|
@@ -3378,12 +3409,12 @@ async function format() {
|
|
|
3378
3409
|
const vttFileDir = dirname11(vttFile.absolutePath);
|
|
3379
3410
|
const newFilename = await promptForDateFix(vttFile.filename, vttFileDir);
|
|
3380
3411
|
if (newFilename) {
|
|
3381
|
-
const newRelativePath =
|
|
3412
|
+
const newRelativePath = join16(
|
|
3382
3413
|
dirname11(vttFile.relativePath),
|
|
3383
3414
|
newFilename
|
|
3384
3415
|
);
|
|
3385
3416
|
vttFiles[i] = {
|
|
3386
|
-
absolutePath:
|
|
3417
|
+
absolutePath: join16(vttFileDir, newFilename),
|
|
3387
3418
|
relativePath: newRelativePath,
|
|
3388
3419
|
filename: newFilename
|
|
3389
3420
|
};
|
|
@@ -3400,14 +3431,14 @@ async function format() {
|
|
|
3400
3431
|
baseName = baseName.replace(/\s*Transcription\s*/g, " ").trim();
|
|
3401
3432
|
const mdFile = `${baseName}.md`;
|
|
3402
3433
|
const relativeDir = dirname11(vttFile.relativePath);
|
|
3403
|
-
const outputDir = relativeDir === "." ? transcriptsDir :
|
|
3404
|
-
const outputPath =
|
|
3405
|
-
if (!
|
|
3434
|
+
const outputDir = relativeDir === "." ? transcriptsDir : join16(transcriptsDir, relativeDir);
|
|
3435
|
+
const outputPath = join16(outputDir, mdFile);
|
|
3436
|
+
if (!existsSync16(outputDir)) {
|
|
3406
3437
|
mkdirSync5(outputDir, { recursive: true });
|
|
3407
3438
|
console.log(`Created output directory: ${outputDir}`);
|
|
3408
3439
|
}
|
|
3409
|
-
if (
|
|
3410
|
-
console.log(`Skipping (already exists): ${
|
|
3440
|
+
if (existsSync16(outputPath)) {
|
|
3441
|
+
console.log(`Skipping (already exists): ${join16(relativeDir, mdFile)}`);
|
|
3411
3442
|
skipped++;
|
|
3412
3443
|
continue;
|
|
3413
3444
|
}
|
|
@@ -3420,18 +3451,18 @@ Summary: ${processed} processed, ${skipped} skipped`);
|
|
|
3420
3451
|
|
|
3421
3452
|
// src/commands/transcript/summarise.ts
|
|
3422
3453
|
import {
|
|
3423
|
-
existsSync as
|
|
3454
|
+
existsSync as existsSync17,
|
|
3424
3455
|
mkdirSync as mkdirSync6,
|
|
3425
|
-
readFileSync as
|
|
3456
|
+
readFileSync as readFileSync15,
|
|
3426
3457
|
renameSync as renameSync2,
|
|
3427
3458
|
rmSync
|
|
3428
3459
|
} from "fs";
|
|
3429
|
-
import { basename as basename5, dirname as dirname12, join as
|
|
3430
|
-
import
|
|
3431
|
-
var STAGING_DIR =
|
|
3460
|
+
import { basename as basename5, dirname as dirname12, join as join17, relative as relative2 } from "path";
|
|
3461
|
+
import chalk37 from "chalk";
|
|
3462
|
+
var STAGING_DIR = join17(process.cwd(), ".assist", "transcript");
|
|
3432
3463
|
var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
|
|
3433
3464
|
function processStagedFile() {
|
|
3434
|
-
if (!
|
|
3465
|
+
if (!existsSync17(STAGING_DIR)) {
|
|
3435
3466
|
return false;
|
|
3436
3467
|
}
|
|
3437
3468
|
const stagedFiles = findMdFilesRecursive(STAGING_DIR);
|
|
@@ -3440,12 +3471,12 @@ function processStagedFile() {
|
|
|
3440
3471
|
}
|
|
3441
3472
|
const { transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
3442
3473
|
const stagedFile = stagedFiles[0];
|
|
3443
|
-
const content =
|
|
3474
|
+
const content = readFileSync15(stagedFile.absolutePath, "utf-8");
|
|
3444
3475
|
const firstLine = content.split("\n")[0];
|
|
3445
3476
|
const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
|
|
3446
3477
|
if (!match) {
|
|
3447
3478
|
console.error(
|
|
3448
|
-
|
|
3479
|
+
chalk37.red(
|
|
3449
3480
|
`Staged file ${stagedFile.filename} missing [Full Transcript](<path>) link on first line.`
|
|
3450
3481
|
)
|
|
3451
3482
|
);
|
|
@@ -3454,7 +3485,7 @@ function processStagedFile() {
|
|
|
3454
3485
|
const contentAfterLink = content.slice(firstLine.length).trim();
|
|
3455
3486
|
if (!contentAfterLink) {
|
|
3456
3487
|
console.error(
|
|
3457
|
-
|
|
3488
|
+
chalk37.red(
|
|
3458
3489
|
`Staged file ${stagedFile.filename} has no summary content after the transcript link.`
|
|
3459
3490
|
)
|
|
3460
3491
|
);
|
|
@@ -3467,16 +3498,16 @@ function processStagedFile() {
|
|
|
3467
3498
|
);
|
|
3468
3499
|
if (!matchingTranscript) {
|
|
3469
3500
|
console.error(
|
|
3470
|
-
|
|
3501
|
+
chalk37.red(
|
|
3471
3502
|
`No transcript found matching staged file: ${stagedFile.filename}`
|
|
3472
3503
|
)
|
|
3473
3504
|
);
|
|
3474
3505
|
process.exit(1);
|
|
3475
3506
|
}
|
|
3476
3507
|
const relativePath = matchingTranscript.relativePath;
|
|
3477
|
-
const destPath =
|
|
3508
|
+
const destPath = join17(summaryDir, relativePath);
|
|
3478
3509
|
const destDir = dirname12(destPath);
|
|
3479
|
-
if (!
|
|
3510
|
+
if (!existsSync17(destDir)) {
|
|
3480
3511
|
mkdirSync6(destDir, { recursive: true });
|
|
3481
3512
|
}
|
|
3482
3513
|
renameSync2(stagedFile.absolutePath, destPath);
|
|
@@ -3489,7 +3520,7 @@ function processStagedFile() {
|
|
|
3489
3520
|
function summarise() {
|
|
3490
3521
|
processStagedFile();
|
|
3491
3522
|
const { transcriptsDir, summaryDir } = getTranscriptConfig();
|
|
3492
|
-
if (!
|
|
3523
|
+
if (!existsSync17(transcriptsDir)) {
|
|
3493
3524
|
console.log("No transcripts directory found.");
|
|
3494
3525
|
return;
|
|
3495
3526
|
}
|
|
@@ -3503,14 +3534,14 @@ function summarise() {
|
|
|
3503
3534
|
summaryFiles.map((f) => {
|
|
3504
3535
|
const relDir = dirname12(f.relativePath);
|
|
3505
3536
|
const baseName = basename5(f.filename, ".md");
|
|
3506
|
-
return relDir === "." ? baseName :
|
|
3537
|
+
return relDir === "." ? baseName : join17(relDir, baseName);
|
|
3507
3538
|
})
|
|
3508
3539
|
);
|
|
3509
3540
|
const missing = [];
|
|
3510
3541
|
for (const transcript of transcriptFiles) {
|
|
3511
3542
|
const transcriptBaseName = getTranscriptBaseName(transcript.filename);
|
|
3512
3543
|
const relDir = dirname12(transcript.relativePath);
|
|
3513
|
-
const fullKey = relDir === "." ? transcriptBaseName :
|
|
3544
|
+
const fullKey = relDir === "." ? transcriptBaseName : join17(relDir, transcriptBaseName);
|
|
3514
3545
|
if (!summaryRelativePaths.has(fullKey)) {
|
|
3515
3546
|
missing.push(transcript);
|
|
3516
3547
|
}
|
|
@@ -3521,8 +3552,8 @@ function summarise() {
|
|
|
3521
3552
|
}
|
|
3522
3553
|
const next2 = missing[0];
|
|
3523
3554
|
const outputFilename = `${getTranscriptBaseName(next2.filename)}.md`;
|
|
3524
|
-
const outputPath =
|
|
3525
|
-
const summaryFileDir =
|
|
3555
|
+
const outputPath = join17(STAGING_DIR, outputFilename);
|
|
3556
|
+
const summaryFileDir = join17(summaryDir, dirname12(next2.relativePath));
|
|
3526
3557
|
const relativeTranscriptPath = encodeURI(
|
|
3527
3558
|
relative2(summaryFileDir, next2.absolutePath).replace(/\\/g, "/")
|
|
3528
3559
|
);
|
|
@@ -3573,7 +3604,7 @@ Total: ${lines.length} hardcoded color(s)`);
|
|
|
3573
3604
|
|
|
3574
3605
|
// src/commands/verify/run.ts
|
|
3575
3606
|
import { spawn as spawn4 } from "child_process";
|
|
3576
|
-
import * as
|
|
3607
|
+
import * as path18 from "path";
|
|
3577
3608
|
function formatDuration(ms) {
|
|
3578
3609
|
if (ms < 1e3) {
|
|
3579
3610
|
return `${ms}ms`;
|
|
@@ -3603,7 +3634,7 @@ async function run2(options = {}) {
|
|
|
3603
3634
|
return;
|
|
3604
3635
|
}
|
|
3605
3636
|
const { packageJsonPath, verifyScripts } = result;
|
|
3606
|
-
const packageDir =
|
|
3637
|
+
const packageDir = path18.dirname(packageJsonPath);
|
|
3607
3638
|
console.log(`Running ${verifyScripts.length} verify script(s) in parallel:`);
|
|
3608
3639
|
for (const script of verifyScripts) {
|
|
3609
3640
|
console.log(` - ${script}`);
|