@staff0rd/assist 0.64.2 → 0.66.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.
Files changed (3) hide show
  1. package/README.md +3 -2
  2. package/dist/index.js +106 -63
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -7,6 +7,7 @@ You can install `assist` globally using npm:
7
7
 
8
8
  ```bash
9
9
  npm install -g @staff0rd/assist
10
+ assist sync
10
11
  ```
11
12
 
12
13
  ## Local Development
@@ -61,11 +62,11 @@ After installation, the `assist` command will be available globally.
61
62
  - `assist backlog done <id>` - Set a backlog item to done
62
63
  - `assist roam auth` - Authenticate with Roam via OAuth (opens browser, saves tokens to ~/.assist.yml)
63
64
  - `assist run <name>` - Run a configured command from assist.yml
64
- - `assist run add` - Add a new run configuration to assist.yml
65
+ - `assist run add` - Add a new run configuration to assist.yml and create a Claude command file
65
66
  - `assist config set <key> <value>` - Set a config value (e.g. commit.push true)
66
67
  - `assist config get <key>` - Get a config value
67
68
  - `assist config list` - List all config values
68
- - `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)
69
70
  - `assist verify init` - Add verify scripts to a project
70
71
  - `assist verify hardcoded-colors` - Check for hardcoded hex colors in src/
71
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.64.2",
9
+ version: "0.66.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -1333,10 +1333,6 @@ Total: ${lines.length} hardcoded color(s)`);
1333
1333
  }
1334
1334
  }
1335
1335
 
1336
- // src/commands/verify/run/index.ts
1337
- import { spawn } from "child_process";
1338
- import * as path13 from "path";
1339
-
1340
1336
  // src/commands/verify/run/createTimerCallback/printTaskStatuses.ts
1341
1337
  function formatDuration(ms) {
1342
1338
  if (ms < 1e3) {
@@ -1379,41 +1375,87 @@ function initTaskStatuses(scripts) {
1379
1375
  return scripts.map((script) => ({ script, startTime: Date.now() }));
1380
1376
  }
1381
1377
 
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
- };
1378
+ // src/commands/verify/run/resolveEntries.ts
1379
+ import * as path13 from "path";
1380
+ function quoteIfNeeded(arg) {
1381
+ return arg.includes(" ") ? `"${arg}"` : arg;
1382
+ }
1383
+ function buildFullCommand(command, args) {
1384
+ return [quoteIfNeeded(command), ...(args ?? []).map(quoteIfNeeded)].join(" ");
1385
+ }
1386
+ function getRunEntries() {
1387
+ const { run: run3 } = loadConfig();
1388
+ if (!run3) return [];
1389
+ return run3.filter((r) => r.name.startsWith("verify:")).map((r) => ({
1390
+ name: r.name,
1391
+ fullCommand: buildFullCommand(r.command, r.args)
1392
+ }));
1393
+ }
1394
+ function getPackageJsonEntries() {
1395
+ const result = findPackageJsonWithVerifyScripts(process.cwd());
1396
+ if (!result) return [];
1397
+ const cwd = path13.dirname(result.packageJsonPath);
1398
+ return result.verifyScripts.map((script) => ({
1399
+ name: script,
1400
+ fullCommand: `npm run ${script}`,
1401
+ cwd
1402
+ }));
1403
+ }
1404
+ function resolveEntries() {
1405
+ return [...getRunEntries(), ...getPackageJsonEntries()];
1406
+ }
1407
+
1408
+ // src/commands/verify/run/spawnCommand.ts
1409
+ import { spawn } from "child_process";
1410
+ var isClaudeCode = !!process.env.CLAUDECODE;
1411
+ function spawnCommand(fullCommand, cwd) {
1412
+ return spawn(fullCommand, [], {
1413
+ stdio: isClaudeCode ? "pipe" : "inherit",
1414
+ shell: true,
1415
+ cwd: cwd ?? process.cwd()
1416
+ });
1417
+ }
1418
+ function collectOutput(child) {
1419
+ if (!isClaudeCode) return [];
1420
+ const chunks = [];
1421
+ child.stdout?.on("data", (data) => chunks.push(data));
1422
+ child.stderr?.on("data", (data) => chunks.push(data));
1423
+ return chunks;
1392
1424
  }
1393
- function runScript(script, cwd, onComplete) {
1425
+ function flushIfFailed(exitCode, chunks) {
1426
+ if (exitCode !== 0 && chunks.length > 0) {
1427
+ process.stdout.write(Buffer.concat(chunks));
1428
+ }
1429
+ }
1430
+
1431
+ // src/commands/verify/run/index.ts
1432
+ function runEntry(entry, onComplete) {
1394
1433
  return new Promise((resolve3) => {
1395
- spawnScript(script, cwd).on(
1396
- "close",
1397
- onScriptClose(script, onComplete, resolve3)
1398
- );
1434
+ const child = spawnCommand(entry.fullCommand, entry.cwd);
1435
+ const chunks = collectOutput(child);
1436
+ child.on("close", (code) => {
1437
+ const exitCode = code ?? 1;
1438
+ flushIfFailed(exitCode, chunks);
1439
+ onComplete?.(exitCode);
1440
+ resolve3({ script: entry.name, code: exitCode });
1441
+ });
1399
1442
  });
1400
1443
  }
1401
- function runAllScripts(verifyScripts, packageDir, timer) {
1402
- const taskStatuses = initTaskStatuses(verifyScripts);
1444
+ function runAllEntries(entries, timer) {
1445
+ const taskStatuses = initTaskStatuses(entries.map((e) => e.name));
1403
1446
  return Promise.all(
1404
- verifyScripts.map(
1405
- (script, index) => runScript(
1406
- script,
1407
- packageDir,
1447
+ entries.map(
1448
+ (entry, index) => runEntry(
1449
+ entry,
1408
1450
  timer ? createTimerCallback(taskStatuses, index) : void 0
1409
1451
  )
1410
1452
  )
1411
1453
  );
1412
1454
  }
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}`);
1455
+ function printEntryList(entries) {
1456
+ console.log(`Running ${entries.length} verify command(s) in parallel:`);
1457
+ for (const entry of entries) {
1458
+ console.log(` - ${entry.name}`);
1417
1459
  }
1418
1460
  }
1419
1461
  function exitIfFailed(failed) {
@@ -1424,32 +1466,17 @@ function exitIfFailed(failed) {
1424
1466
  function handleResults(results, totalCount) {
1425
1467
  exitIfFailed(results.filter((r) => r.code !== 0));
1426
1468
  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);
1469
+ All ${totalCount} verify command(s) passed`);
1448
1470
  }
1449
1471
  async function run(options2 = {}) {
1450
- const found = resolveVerifyScripts();
1451
- if (!found) return;
1452
- await executeVerifyScripts(found, options2.timer ?? false);
1472
+ const allEntries = resolveEntries();
1473
+ if (allEntries.length === 0) {
1474
+ console.log("No verify commands found");
1475
+ return;
1476
+ }
1477
+ printEntryList(allEntries);
1478
+ const results = await runAllEntries(allEntries, options2.timer ?? false);
1479
+ handleResults(results, allEntries.length);
1453
1480
  }
1454
1481
 
1455
1482
  // src/commands/new/registerNew/initGit.ts
@@ -3125,7 +3152,7 @@ import { join as join14 } from "path";
3125
3152
  import { stringify } from "yaml";
3126
3153
 
3127
3154
  // src/lib/isClaudeCode.ts
3128
- function isClaudeCode() {
3155
+ function isClaudeCode2() {
3129
3156
  return process.env.CLAUDECODE !== void 0;
3130
3157
  }
3131
3158
 
@@ -3224,7 +3251,7 @@ function formatForHuman(comment) {
3224
3251
 
3225
3252
  // src/commands/prs/listComments/index.ts
3226
3253
  function formatComment(comment) {
3227
- return isClaudeCode() ? JSON.stringify(comment) : formatForHuman(comment);
3254
+ return isClaudeCode2() ? JSON.stringify(comment) : formatForHuman(comment);
3228
3255
  }
3229
3256
  function printComments(comments) {
3230
3257
  if (comments.length === 0) {
@@ -3623,7 +3650,7 @@ function getViolations(pattern2, options2 = {}, maxLines = DEFAULT_MAX_LINES) {
3623
3650
  }
3624
3651
 
3625
3652
  // src/commands/refactor/check/index.ts
3626
- function runScript2(script, cwd) {
3653
+ function runScript(script, cwd) {
3627
3654
  return new Promise((resolve3) => {
3628
3655
  const child = spawn3("npm", ["run", script], {
3629
3656
  stdio: "pipe",
@@ -3657,7 +3684,7 @@ async function runVerifyQuietly() {
3657
3684
  if (!result) return true;
3658
3685
  const packageDir = path17.dirname(result.packageJsonPath);
3659
3686
  const results = await Promise.all(
3660
- result.verifyScripts.map((script) => runScript2(script, packageDir))
3687
+ result.verifyScripts.map((script) => runScript(script, packageDir))
3661
3688
  );
3662
3689
  const failed = results.filter((r) => r.code !== 0);
3663
3690
  if (failed.length > 0) {
@@ -4857,7 +4884,7 @@ function registerTranscript(program2) {
4857
4884
 
4858
4885
  // src/commands/registerVerify.ts
4859
4886
  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));
4887
+ 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
4888
  verifyCommand.command("init").description("Add verify scripts to a project").action(init2);
4862
4889
  verifyCommand.command("hardcoded-colors").description("Check for hardcoded hex colors in src/").action(hardcodedColors);
4863
4890
  }
@@ -5072,6 +5099,8 @@ function registerRoam(program2) {
5072
5099
  import { spawn as spawn4 } from "child_process";
5073
5100
 
5074
5101
  // src/commands/run/add.ts
5102
+ import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync17 } from "fs";
5103
+ import { join as join21 } from "path";
5075
5104
  function findAddIndex() {
5076
5105
  const addIndex = process.argv.indexOf("add");
5077
5106
  if (addIndex === -1 || addIndex + 2 >= process.argv.length) return -1;
@@ -5124,21 +5153,35 @@ function saveNewRunConfig(name, command, args) {
5124
5153
  runList.push(buildRunEntry(name, command, args));
5125
5154
  saveConfig(config);
5126
5155
  }
5156
+ function createCommandFile(name) {
5157
+ const dir = join21(".claude", "commands");
5158
+ mkdirSync7(dir, { recursive: true });
5159
+ const content = `---
5160
+ description: Run ${name}
5161
+ ---
5162
+
5163
+ Run \`assist run ${name} $ARGUMENTS 2>&1\`.
5164
+ `;
5165
+ const filePath = join21(dir, `${name}.md`);
5166
+ writeFileSync17(filePath, content);
5167
+ console.log(`Created command file: ${filePath}`);
5168
+ }
5127
5169
  function add2() {
5128
5170
  const { name, command, args } = requireParsedArgs();
5129
5171
  saveNewRunConfig(name, command, args);
5172
+ createCommandFile(name);
5130
5173
  console.log(
5131
5174
  `Added run configuration: ${name} -> ${formatDisplay(command, args)}`
5132
5175
  );
5133
5176
  }
5134
5177
 
5135
5178
  // src/commands/run/index.ts
5136
- function quoteIfNeeded(arg) {
5179
+ function quoteIfNeeded2(arg) {
5137
5180
  return arg.includes(" ") ? `"${arg}"` : arg;
5138
5181
  }
5139
5182
  function buildCommand(command, configArgs, extraArgs) {
5140
5183
  const allArgs = [...configArgs, ...extraArgs];
5141
- return [quoteIfNeeded(command), ...allArgs.map(quoteIfNeeded)].join(" ");
5184
+ return [quoteIfNeeded2(command), ...allArgs.map(quoteIfNeeded2)].join(" ");
5142
5185
  }
5143
5186
  function printAvailableConfigs(configs) {
5144
5187
  console.error("Available configurations:");
@@ -5168,14 +5211,14 @@ function onSpawnError(err) {
5168
5211
  console.error(`Failed to execute command: ${err.message}`);
5169
5212
  process.exit(1);
5170
5213
  }
5171
- function spawnCommand(fullCommand) {
5214
+ function spawnCommand2(fullCommand) {
5172
5215
  const child = spawn4(fullCommand, [], { stdio: "inherit", shell: true });
5173
5216
  child.on("close", (code) => process.exit(code ?? 0));
5174
5217
  child.on("error", onSpawnError);
5175
5218
  }
5176
5219
  function run2(name, args) {
5177
5220
  const runConfig = findRunConfig(name);
5178
- spawnCommand(buildCommand(runConfig.command, runConfig.args ?? [], args));
5221
+ spawnCommand2(buildCommand(runConfig.command, runConfig.args ?? [], args));
5179
5222
  }
5180
5223
 
5181
5224
  // src/commands/statusLine.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.64.2",
3
+ "version": "0.66.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {