@staff0rd/assist 0.65.0 → 0.66.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.js +112 -86
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -66,7 +66,7 @@ After installation, the `assist` command will be available globally.
|
|
|
66
66
|
- `assist config set <key> <value>` - Set a config value (e.g. commit.push true)
|
|
67
67
|
- `assist config get <key>` - Get a config value
|
|
68
68
|
- `assist config list` - List all config values
|
|
69
|
-
- `assist verify` - Run all verify:*
|
|
69
|
+
- `assist verify` - Run all verify:* commands in parallel (from run configs in assist.yml and scripts in package.json)
|
|
70
70
|
- `assist verify init` - Add verify scripts to a project
|
|
71
71
|
- `assist verify hardcoded-colors` - Check for hardcoded hex colors in src/
|
|
72
72
|
- `assist lint` - Run lint checks for conventions not enforced by biomejs
|
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.66.1",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -147,9 +147,11 @@ function loadConfig() {
|
|
|
147
147
|
const merged = { ...globalRaw, ...projectRaw };
|
|
148
148
|
return assistConfigSchema.parse(merged);
|
|
149
149
|
}
|
|
150
|
-
function
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
function loadProjectConfig() {
|
|
151
|
+
return loadRawConfig(getConfigPath());
|
|
152
|
+
}
|
|
153
|
+
function loadGlobalConfigRaw() {
|
|
154
|
+
return loadRawConfig(getGlobalConfigPath());
|
|
153
155
|
}
|
|
154
156
|
function saveGlobalConfig(config) {
|
|
155
157
|
writeFileSync(getGlobalConfigPath(), stringifyYaml(config, { lineWidth: 0 }));
|
|
@@ -291,14 +293,10 @@ function exitValidationFailed(issues, key) {
|
|
|
291
293
|
function validateConfig(updated, key) {
|
|
292
294
|
const result = assistConfigSchema.safeParse(updated);
|
|
293
295
|
if (!result.success) return exitValidationFailed(result.error.issues, key);
|
|
294
|
-
return
|
|
296
|
+
return updated;
|
|
295
297
|
}
|
|
296
298
|
function applyConfigSet(key, coerced) {
|
|
297
|
-
const updated = setNestedValue(
|
|
298
|
-
loadConfig(),
|
|
299
|
-
key,
|
|
300
|
-
coerced
|
|
301
|
-
);
|
|
299
|
+
const updated = setNestedValue(loadProjectConfig(), key, coerced);
|
|
302
300
|
saveConfig(validateConfig(updated, key));
|
|
303
301
|
}
|
|
304
302
|
function configSet(key, value) {
|
|
@@ -1333,10 +1331,6 @@ Total: ${lines.length} hardcoded color(s)`);
|
|
|
1333
1331
|
}
|
|
1334
1332
|
}
|
|
1335
1333
|
|
|
1336
|
-
// src/commands/verify/run/index.ts
|
|
1337
|
-
import { spawn } from "child_process";
|
|
1338
|
-
import * as path13 from "path";
|
|
1339
|
-
|
|
1340
1334
|
// src/commands/verify/run/createTimerCallback/printTaskStatuses.ts
|
|
1341
1335
|
function formatDuration(ms) {
|
|
1342
1336
|
if (ms < 1e3) {
|
|
@@ -1379,41 +1373,87 @@ function initTaskStatuses(scripts) {
|
|
|
1379
1373
|
return scripts.map((script) => ({ script, startTime: Date.now() }));
|
|
1380
1374
|
}
|
|
1381
1375
|
|
|
1382
|
-
// src/commands/verify/run/
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
}
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
onComplete?.(exitCode);
|
|
1390
|
-
resolve3({ script, code: exitCode });
|
|
1391
|
-
};
|
|
1376
|
+
// src/commands/verify/run/resolveEntries.ts
|
|
1377
|
+
import * as path13 from "path";
|
|
1378
|
+
function quoteIfNeeded(arg) {
|
|
1379
|
+
return arg.includes(" ") ? `"${arg}"` : arg;
|
|
1380
|
+
}
|
|
1381
|
+
function buildFullCommand(command, args) {
|
|
1382
|
+
return [quoteIfNeeded(command), ...(args ?? []).map(quoteIfNeeded)].join(" ");
|
|
1392
1383
|
}
|
|
1393
|
-
function
|
|
1384
|
+
function getRunEntries() {
|
|
1385
|
+
const { run: run3 } = loadConfig();
|
|
1386
|
+
if (!run3) return [];
|
|
1387
|
+
return run3.filter((r) => r.name.startsWith("verify:")).map((r) => ({
|
|
1388
|
+
name: r.name,
|
|
1389
|
+
fullCommand: buildFullCommand(r.command, r.args)
|
|
1390
|
+
}));
|
|
1391
|
+
}
|
|
1392
|
+
function getPackageJsonEntries() {
|
|
1393
|
+
const result = findPackageJsonWithVerifyScripts(process.cwd());
|
|
1394
|
+
if (!result) return [];
|
|
1395
|
+
const cwd = path13.dirname(result.packageJsonPath);
|
|
1396
|
+
return result.verifyScripts.map((script) => ({
|
|
1397
|
+
name: script,
|
|
1398
|
+
fullCommand: `npm run ${script}`,
|
|
1399
|
+
cwd
|
|
1400
|
+
}));
|
|
1401
|
+
}
|
|
1402
|
+
function resolveEntries() {
|
|
1403
|
+
return [...getRunEntries(), ...getPackageJsonEntries()];
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
// src/commands/verify/run/spawnCommand.ts
|
|
1407
|
+
import { spawn } from "child_process";
|
|
1408
|
+
var isClaudeCode = !!process.env.CLAUDECODE;
|
|
1409
|
+
function spawnCommand(fullCommand, cwd) {
|
|
1410
|
+
return spawn(fullCommand, [], {
|
|
1411
|
+
stdio: isClaudeCode ? "pipe" : "inherit",
|
|
1412
|
+
shell: true,
|
|
1413
|
+
cwd: cwd ?? process.cwd()
|
|
1414
|
+
});
|
|
1415
|
+
}
|
|
1416
|
+
function collectOutput(child) {
|
|
1417
|
+
if (!isClaudeCode) return [];
|
|
1418
|
+
const chunks = [];
|
|
1419
|
+
child.stdout?.on("data", (data) => chunks.push(data));
|
|
1420
|
+
child.stderr?.on("data", (data) => chunks.push(data));
|
|
1421
|
+
return chunks;
|
|
1422
|
+
}
|
|
1423
|
+
function flushIfFailed(exitCode, chunks) {
|
|
1424
|
+
if (exitCode !== 0 && chunks.length > 0) {
|
|
1425
|
+
process.stdout.write(Buffer.concat(chunks));
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
// src/commands/verify/run/index.ts
|
|
1430
|
+
function runEntry(entry, onComplete) {
|
|
1394
1431
|
return new Promise((resolve3) => {
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1432
|
+
const child = spawnCommand(entry.fullCommand, entry.cwd);
|
|
1433
|
+
const chunks = collectOutput(child);
|
|
1434
|
+
child.on("close", (code) => {
|
|
1435
|
+
const exitCode = code ?? 1;
|
|
1436
|
+
flushIfFailed(exitCode, chunks);
|
|
1437
|
+
onComplete?.(exitCode);
|
|
1438
|
+
resolve3({ script: entry.name, code: exitCode });
|
|
1439
|
+
});
|
|
1399
1440
|
});
|
|
1400
1441
|
}
|
|
1401
|
-
function
|
|
1402
|
-
const taskStatuses = initTaskStatuses(
|
|
1442
|
+
function runAllEntries(entries, timer) {
|
|
1443
|
+
const taskStatuses = initTaskStatuses(entries.map((e) => e.name));
|
|
1403
1444
|
return Promise.all(
|
|
1404
|
-
|
|
1405
|
-
(
|
|
1406
|
-
|
|
1407
|
-
packageDir,
|
|
1445
|
+
entries.map(
|
|
1446
|
+
(entry, index) => runEntry(
|
|
1447
|
+
entry,
|
|
1408
1448
|
timer ? createTimerCallback(taskStatuses, index) : void 0
|
|
1409
1449
|
)
|
|
1410
1450
|
)
|
|
1411
1451
|
);
|
|
1412
1452
|
}
|
|
1413
|
-
function
|
|
1414
|
-
console.log(`Running ${
|
|
1415
|
-
for (const
|
|
1416
|
-
console.log(` - ${
|
|
1453
|
+
function printEntryList(entries) {
|
|
1454
|
+
console.log(`Running ${entries.length} verify command(s) in parallel:`);
|
|
1455
|
+
for (const entry of entries) {
|
|
1456
|
+
console.log(` - ${entry.name}`);
|
|
1417
1457
|
}
|
|
1418
1458
|
}
|
|
1419
1459
|
function exitIfFailed(failed) {
|
|
@@ -1424,32 +1464,17 @@ function exitIfFailed(failed) {
|
|
|
1424
1464
|
function handleResults(results, totalCount) {
|
|
1425
1465
|
exitIfFailed(results.filter((r) => r.code !== 0));
|
|
1426
1466
|
console.log(`
|
|
1427
|
-
All ${totalCount} verify
|
|
1428
|
-
}
|
|
1429
|
-
function resolveVerifyScripts() {
|
|
1430
|
-
const result = findPackageJsonWithVerifyScripts(process.cwd());
|
|
1431
|
-
if (!result) {
|
|
1432
|
-
console.log("No package.json with verify:* scripts found");
|
|
1433
|
-
return null;
|
|
1434
|
-
}
|
|
1435
|
-
return result;
|
|
1436
|
-
}
|
|
1437
|
-
function getPackageDir(found) {
|
|
1438
|
-
return path13.dirname(found.packageJsonPath);
|
|
1439
|
-
}
|
|
1440
|
-
async function executeVerifyScripts(found, timer) {
|
|
1441
|
-
printScriptList(found.verifyScripts);
|
|
1442
|
-
const results = await runAllScripts(
|
|
1443
|
-
found.verifyScripts,
|
|
1444
|
-
getPackageDir(found),
|
|
1445
|
-
timer
|
|
1446
|
-
);
|
|
1447
|
-
handleResults(results, found.verifyScripts.length);
|
|
1467
|
+
All ${totalCount} verify command(s) passed`);
|
|
1448
1468
|
}
|
|
1449
1469
|
async function run(options2 = {}) {
|
|
1450
|
-
const
|
|
1451
|
-
if (
|
|
1452
|
-
|
|
1470
|
+
const allEntries = resolveEntries();
|
|
1471
|
+
if (allEntries.length === 0) {
|
|
1472
|
+
console.log("No verify commands found");
|
|
1473
|
+
return;
|
|
1474
|
+
}
|
|
1475
|
+
printEntryList(allEntries);
|
|
1476
|
+
const results = await runAllEntries(allEntries, options2.timer ?? false);
|
|
1477
|
+
handleResults(results, allEntries.length);
|
|
1453
1478
|
}
|
|
1454
1479
|
|
|
1455
1480
|
// src/commands/new/registerNew/initGit.ts
|
|
@@ -2917,21 +2942,19 @@ function skip(date) {
|
|
|
2917
2942
|
console.log(chalk39.red("Invalid date format. Use YYYY-MM-DD"));
|
|
2918
2943
|
process.exit(1);
|
|
2919
2944
|
}
|
|
2920
|
-
const config =
|
|
2921
|
-
const
|
|
2945
|
+
const config = loadProjectConfig();
|
|
2946
|
+
const devlog = config.devlog ?? {};
|
|
2947
|
+
const skip2 = devlog.skip ?? {};
|
|
2948
|
+
const skipDays = skip2.days ?? [];
|
|
2922
2949
|
if (skipDays.includes(date)) {
|
|
2923
2950
|
console.log(chalk39.yellow(`${date} is already in skip list`));
|
|
2924
2951
|
return;
|
|
2925
2952
|
}
|
|
2926
2953
|
skipDays.push(date);
|
|
2927
2954
|
skipDays.sort();
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
...config.devlog?.skip,
|
|
2932
|
-
days: skipDays
|
|
2933
|
-
}
|
|
2934
|
-
};
|
|
2955
|
+
skip2.days = skipDays;
|
|
2956
|
+
devlog.skip = skip2;
|
|
2957
|
+
config.devlog = devlog;
|
|
2935
2958
|
saveConfig(config);
|
|
2936
2959
|
console.log(chalk39.green(`Added ${date} to skip list`));
|
|
2937
2960
|
}
|
|
@@ -3125,7 +3148,7 @@ import { join as join14 } from "path";
|
|
|
3125
3148
|
import { stringify } from "yaml";
|
|
3126
3149
|
|
|
3127
3150
|
// src/lib/isClaudeCode.ts
|
|
3128
|
-
function
|
|
3151
|
+
function isClaudeCode2() {
|
|
3129
3152
|
return process.env.CLAUDECODE !== void 0;
|
|
3130
3153
|
}
|
|
3131
3154
|
|
|
@@ -3224,7 +3247,7 @@ function formatForHuman(comment) {
|
|
|
3224
3247
|
|
|
3225
3248
|
// src/commands/prs/listComments/index.ts
|
|
3226
3249
|
function formatComment(comment) {
|
|
3227
|
-
return
|
|
3250
|
+
return isClaudeCode2() ? JSON.stringify(comment) : formatForHuman(comment);
|
|
3228
3251
|
}
|
|
3229
3252
|
function printComments(comments) {
|
|
3230
3253
|
if (comments.length === 0) {
|
|
@@ -3623,7 +3646,7 @@ function getViolations(pattern2, options2 = {}, maxLines = DEFAULT_MAX_LINES) {
|
|
|
3623
3646
|
}
|
|
3624
3647
|
|
|
3625
3648
|
// src/commands/refactor/check/index.ts
|
|
3626
|
-
function
|
|
3649
|
+
function runScript(script, cwd) {
|
|
3627
3650
|
return new Promise((resolve3) => {
|
|
3628
3651
|
const child = spawn3("npm", ["run", script], {
|
|
3629
3652
|
stdio: "pipe",
|
|
@@ -3657,7 +3680,7 @@ async function runVerifyQuietly() {
|
|
|
3657
3680
|
if (!result) return true;
|
|
3658
3681
|
const packageDir = path17.dirname(result.packageJsonPath);
|
|
3659
3682
|
const results = await Promise.all(
|
|
3660
|
-
result.verifyScripts.map((script) =>
|
|
3683
|
+
result.verifyScripts.map((script) => runScript(script, packageDir))
|
|
3661
3684
|
);
|
|
3662
3685
|
const failed = results.filter((r) => r.code !== 0);
|
|
3663
3686
|
if (failed.length > 0) {
|
|
@@ -4306,7 +4329,7 @@ function validateDirectories(transcript) {
|
|
|
4306
4329
|
}
|
|
4307
4330
|
async function configure() {
|
|
4308
4331
|
const rl = createReadlineInterface();
|
|
4309
|
-
const config =
|
|
4332
|
+
const config = loadProjectConfig();
|
|
4310
4333
|
const existing = config.transcript;
|
|
4311
4334
|
console.log("Configure transcript directories\n");
|
|
4312
4335
|
if (existing) printExisting(existing);
|
|
@@ -4857,7 +4880,7 @@ function registerTranscript(program2) {
|
|
|
4857
4880
|
|
|
4858
4881
|
// src/commands/registerVerify.ts
|
|
4859
4882
|
function registerVerify(program2) {
|
|
4860
|
-
const verifyCommand = program2.command("verify").description("Run all verify:*
|
|
4883
|
+
const verifyCommand = program2.command("verify").description("Run all verify:* commands in parallel").option("--timer", "Show timing information for each task as they complete").action((options2) => run(options2));
|
|
4861
4884
|
verifyCommand.command("init").description("Add verify scripts to a project").action(init2);
|
|
4862
4885
|
verifyCommand.command("hardcoded-colors").description("Check for hardcoded hex colors in src/").action(hardcodedColors);
|
|
4863
4886
|
}
|
|
@@ -5030,9 +5053,12 @@ async function promptCredentials(existing) {
|
|
|
5030
5053
|
|
|
5031
5054
|
// src/commands/roam/auth.ts
|
|
5032
5055
|
async function auth() {
|
|
5033
|
-
const config =
|
|
5034
|
-
const { clientId, clientSecret } = await promptCredentials(
|
|
5035
|
-
|
|
5056
|
+
const config = loadGlobalConfigRaw();
|
|
5057
|
+
const { clientId, clientSecret } = await promptCredentials(
|
|
5058
|
+
config.roam
|
|
5059
|
+
);
|
|
5060
|
+
const existingRoam = config.roam ?? {};
|
|
5061
|
+
config.roam = { ...existingRoam, clientId, clientSecret };
|
|
5036
5062
|
saveGlobalConfig(config);
|
|
5037
5063
|
const state = randomBytes(16).toString("hex");
|
|
5038
5064
|
console.log(
|
|
@@ -5116,7 +5142,7 @@ function requireParsedArgs() {
|
|
|
5116
5142
|
return parsed;
|
|
5117
5143
|
}
|
|
5118
5144
|
function getOrInitRunList() {
|
|
5119
|
-
const config =
|
|
5145
|
+
const config = loadProjectConfig();
|
|
5120
5146
|
if (!config.run) config.run = [];
|
|
5121
5147
|
return { config, runList: config.run };
|
|
5122
5148
|
}
|
|
@@ -5149,12 +5175,12 @@ function add2() {
|
|
|
5149
5175
|
}
|
|
5150
5176
|
|
|
5151
5177
|
// src/commands/run/index.ts
|
|
5152
|
-
function
|
|
5178
|
+
function quoteIfNeeded2(arg) {
|
|
5153
5179
|
return arg.includes(" ") ? `"${arg}"` : arg;
|
|
5154
5180
|
}
|
|
5155
5181
|
function buildCommand(command, configArgs, extraArgs) {
|
|
5156
5182
|
const allArgs = [...configArgs, ...extraArgs];
|
|
5157
|
-
return [
|
|
5183
|
+
return [quoteIfNeeded2(command), ...allArgs.map(quoteIfNeeded2)].join(" ");
|
|
5158
5184
|
}
|
|
5159
5185
|
function printAvailableConfigs(configs) {
|
|
5160
5186
|
console.error("Available configurations:");
|
|
@@ -5184,14 +5210,14 @@ function onSpawnError(err) {
|
|
|
5184
5210
|
console.error(`Failed to execute command: ${err.message}`);
|
|
5185
5211
|
process.exit(1);
|
|
5186
5212
|
}
|
|
5187
|
-
function
|
|
5213
|
+
function spawnCommand2(fullCommand) {
|
|
5188
5214
|
const child = spawn4(fullCommand, [], { stdio: "inherit", shell: true });
|
|
5189
5215
|
child.on("close", (code) => process.exit(code ?? 0));
|
|
5190
5216
|
child.on("error", onSpawnError);
|
|
5191
5217
|
}
|
|
5192
5218
|
function run2(name, args) {
|
|
5193
5219
|
const runConfig = findRunConfig(name);
|
|
5194
|
-
|
|
5220
|
+
spawnCommand2(buildCommand(runConfig.command, runConfig.args ?? [], args));
|
|
5195
5221
|
}
|
|
5196
5222
|
|
|
5197
5223
|
// src/commands/statusLine.ts
|