@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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/dist/index.js +112 -86
  3. 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:* scripts from package.json in parallel
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.65.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 loadGlobalConfig() {
151
- const raw = loadRawConfig(getGlobalConfigPath());
152
- return assistConfigSchema.parse(raw);
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 result.data;
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/index.ts
1383
- function spawnScript(script, cwd) {
1384
- return spawn("npm", ["run", script], { stdio: "inherit", shell: true, cwd });
1385
- }
1386
- function onScriptClose(script, onComplete, resolve3) {
1387
- return (code) => {
1388
- const exitCode = code ?? 1;
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 runScript(script, cwd, onComplete) {
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
- spawnScript(script, cwd).on(
1396
- "close",
1397
- onScriptClose(script, onComplete, resolve3)
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 runAllScripts(verifyScripts, packageDir, timer) {
1402
- const taskStatuses = initTaskStatuses(verifyScripts);
1442
+ function runAllEntries(entries, timer) {
1443
+ const taskStatuses = initTaskStatuses(entries.map((e) => e.name));
1403
1444
  return Promise.all(
1404
- verifyScripts.map(
1405
- (script, index) => runScript(
1406
- script,
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 printScriptList(scripts) {
1414
- console.log(`Running ${scripts.length} verify script(s) in parallel:`);
1415
- for (const script of scripts) {
1416
- console.log(` - ${script}`);
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 script(s) passed`);
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 found = resolveVerifyScripts();
1451
- if (!found) return;
1452
- await executeVerifyScripts(found, options2.timer ?? false);
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 = loadConfig();
2921
- const skipDays = config.devlog?.skip?.days ?? [];
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
- config.devlog = {
2929
- ...config.devlog,
2930
- skip: {
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 isClaudeCode() {
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 isClaudeCode() ? JSON.stringify(comment) : formatForHuman(comment);
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 runScript2(script, cwd) {
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) => runScript2(script, packageDir))
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 = loadConfig();
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:* scripts from package.json in parallel").option("--timer", "Show timing information for each task as they complete").action((options2) => run(options2));
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 = loadGlobalConfig();
5034
- const { clientId, clientSecret } = await promptCredentials(config.roam);
5035
- config.roam = { ...config.roam, clientId, clientSecret };
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 = loadConfig();
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 quoteIfNeeded(arg) {
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 [quoteIfNeeded(command), ...allArgs.map(quoteIfNeeded)].join(" ");
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 spawnCommand(fullCommand) {
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
- spawnCommand(buildCommand(runConfig.command, runConfig.args ?? [], args));
5220
+ spawnCommand2(buildCommand(runConfig.command, runConfig.args ?? [], args));
5195
5221
  }
5196
5222
 
5197
5223
  // src/commands/statusLine.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.65.0",
3
+ "version": "0.66.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {