@staff0rd/assist 0.195.1 → 0.195.2

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 (2) hide show
  1. package/dist/index.js +263 -270
  2. package/package.json +1 -1
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.195.1",
9
+ version: "0.195.2",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -92,7 +92,7 @@ var package_default = {
92
92
  };
93
93
 
94
94
  // src/commands/backlog/next.ts
95
- import chalk9 from "chalk";
95
+ import chalk8 from "chalk";
96
96
  import enquirer2 from "enquirer";
97
97
 
98
98
  // src/shared/exitOnCancel.ts
@@ -768,7 +768,7 @@ function findUnblockedTodos(items) {
768
768
  }
769
769
 
770
770
  // src/commands/backlog/run.ts
771
- import chalk8 from "chalk";
771
+ import chalk7 from "chalk";
772
772
 
773
773
  // src/commands/backlog/buildCommentLines.ts
774
774
  function buildCommentLines(comments2) {
@@ -887,7 +887,7 @@ function buildReviewPhase() {
887
887
  }
888
888
 
889
889
  // src/commands/backlog/executePhase.ts
890
- import chalk6 from "chalk";
890
+ import chalk5 from "chalk";
891
891
 
892
892
  // src/commands/backlog/resolvePhaseResult.ts
893
893
  import { existsSync as existsSync6, unlinkSync as unlinkSync2 } from "fs";
@@ -973,220 +973,8 @@ Phase ${phaseNumber} completed.`));
973
973
 
974
974
  // src/commands/backlog/spawnClaude.ts
975
975
  import { spawn } from "child_process";
976
-
977
- // src/shared/loadConfig.ts
978
- import { existsSync as existsSync8, writeFileSync as writeFileSync5 } from "fs";
979
- import { homedir } from "os";
980
- import { dirname, join as join7 } from "path";
981
- import chalk5 from "chalk";
982
- import { stringify as stringifyYaml } from "yaml";
983
-
984
- // src/shared/loadRawYaml.ts
985
- import { existsSync as existsSync7, readFileSync as readFileSync6 } from "fs";
986
- import { parse as parseYaml2 } from "yaml";
987
- function loadRawYaml(path52) {
988
- if (!existsSync7(path52)) return {};
989
- try {
990
- const content = readFileSync6(path52, "utf-8");
991
- return parseYaml2(content) || {};
992
- } catch {
993
- return {};
994
- }
995
- }
996
-
997
- // src/shared/types.ts
998
- import { z as z2 } from "zod";
999
- var runParamSchema = z2.strictObject({
1000
- name: z2.string(),
1001
- required: z2.boolean().optional(),
1002
- default: z2.string().optional(),
1003
- description: z2.string().optional()
1004
- });
1005
- var runConfigSchema = z2.strictObject({
1006
- name: z2.string(),
1007
- command: z2.string(),
1008
- args: z2.array(z2.string()).optional(),
1009
- params: z2.array(runParamSchema).optional(),
1010
- env: z2.record(z2.string(), z2.string()).optional(),
1011
- filter: z2.string().optional(),
1012
- pre: z2.array(z2.string()).optional(),
1013
- cwd: z2.string().optional()
1014
- });
1015
- var runLinkSchema = z2.strictObject({
1016
- link: z2.string(),
1017
- prefix: z2.string()
1018
- });
1019
- var transcriptConfigSchema = z2.strictObject({
1020
- vttDir: z2.string(),
1021
- transcriptsDir: z2.string(),
1022
- summaryDir: z2.string()
1023
- });
1024
- var DEFAULT_WAKE_WORDS = ["computer"];
1025
- var DEFAULT_MODELS_DIR = "~/.assist/voice/models";
1026
- var assistConfigSchema = z2.strictObject({
1027
- commit: z2.strictObject({
1028
- conventional: z2.boolean().default(false),
1029
- pull: z2.boolean().default(false),
1030
- push: z2.boolean().default(false)
1031
- }).default({ conventional: false, pull: false, push: false }),
1032
- devlog: z2.strictObject({
1033
- name: z2.string().optional(),
1034
- ignore: z2.array(z2.string()).optional(),
1035
- skip: z2.record(z2.string(), z2.array(z2.string())).optional()
1036
- }).optional(),
1037
- notify: z2.strictObject({
1038
- enabled: z2.boolean().default(true)
1039
- }).default({ enabled: true }),
1040
- complexity: z2.strictObject({
1041
- ignore: z2.array(z2.string()).default(["**/*test.ts*"])
1042
- }).default({ ignore: ["**/*test.ts*"] }),
1043
- hardcodedColors: z2.strictObject({
1044
- ignore: z2.array(z2.string()).default([])
1045
- }).optional(),
1046
- restructure: z2.strictObject({
1047
- ignore: z2.array(z2.string()).default([])
1048
- }).optional(),
1049
- jira: z2.strictObject({
1050
- acField: z2.string().default("customfield_11937")
1051
- }).optional(),
1052
- roam: z2.strictObject({
1053
- clientId: z2.string(),
1054
- clientSecret: z2.string(),
1055
- accessToken: z2.string().optional(),
1056
- refreshToken: z2.string().optional(),
1057
- tokenExpiresAt: z2.number().optional()
1058
- }).optional(),
1059
- run: z2.array(z2.union([runConfigSchema, runLinkSchema])).optional(),
1060
- transcript: transcriptConfigSchema.optional(),
1061
- cliReadVerbs: z2.record(z2.string(), z2.array(z2.string())).optional(),
1062
- news: z2.strictObject({
1063
- feeds: z2.array(z2.string()).default([])
1064
- }).default({ feeds: [] }),
1065
- dotnet: z2.strictObject({
1066
- inspect: z2.strictObject({
1067
- suppress: z2.array(z2.string()).default([])
1068
- }).default({ suppress: [] })
1069
- }).optional(),
1070
- ravendb: z2.strictObject({
1071
- connections: z2.array(
1072
- z2.strictObject({
1073
- name: z2.string(),
1074
- url: z2.string(),
1075
- database: z2.string(),
1076
- apiKeyRef: z2.string()
1077
- })
1078
- ).default([]),
1079
- defaultConnection: z2.string().optional()
1080
- }).optional(),
1081
- seq: z2.strictObject({
1082
- connections: z2.array(
1083
- z2.strictObject({
1084
- name: z2.string(),
1085
- url: z2.string(),
1086
- apiToken: z2.string()
1087
- })
1088
- ).default([]),
1089
- defaultConnection: z2.string().optional()
1090
- }).optional(),
1091
- screenshot: z2.strictObject({
1092
- outputDir: z2.string().default("./screenshots")
1093
- }).default({ outputDir: "./screenshots" }),
1094
- backlog: z2.strictObject({
1095
- autoCommit: z2.boolean().default(false)
1096
- }).default({ autoCommit: false }),
1097
- deny: z2.array(
1098
- z2.strictObject({
1099
- pattern: z2.string(),
1100
- message: z2.string()
1101
- })
1102
- ).optional(),
1103
- sync: z2.strictObject({
1104
- autoConfirm: z2.boolean().default(false)
1105
- }).default({ autoConfirm: false }),
1106
- caveman: z2.boolean().default(true),
1107
- voice: z2.strictObject({
1108
- wakeWords: z2.array(z2.string()).default(DEFAULT_WAKE_WORDS),
1109
- mic: z2.string().optional(),
1110
- cwd: z2.string().optional(),
1111
- modelsDir: z2.string().default(DEFAULT_MODELS_DIR),
1112
- lockDir: z2.string().optional(),
1113
- submitWindows: z2.array(z2.string()).optional(),
1114
- models: z2.strictObject({
1115
- vad: z2.string().optional(),
1116
- smartTurn: z2.string().optional()
1117
- }).default({})
1118
- }).default({
1119
- wakeWords: DEFAULT_WAKE_WORDS,
1120
- modelsDir: DEFAULT_MODELS_DIR,
1121
- models: {}
1122
- })
1123
- });
1124
- function isRunLink(entry) {
1125
- return "link" in entry;
1126
- }
1127
-
1128
- // src/shared/loadConfig.ts
1129
- function findConfigUp(startDir) {
1130
- let current = startDir;
1131
- while (current !== dirname(current)) {
1132
- const claudePath = join7(current, ".claude", "assist.yml");
1133
- if (existsSync8(claudePath)) return claudePath;
1134
- const rootPath = join7(current, "assist.yml");
1135
- if (existsSync8(rootPath)) return rootPath;
1136
- current = dirname(current);
1137
- }
1138
- return null;
1139
- }
1140
- function getConfigPath() {
1141
- const found = findConfigUp(process.cwd());
1142
- if (found) return found;
1143
- return join7(process.cwd(), "assist.yml");
1144
- }
1145
- function getGlobalConfigPath() {
1146
- return join7(homedir(), ".assist.yml");
1147
- }
1148
- function getConfigDir() {
1149
- return dirname(getConfigPath());
1150
- }
1151
- function loadConfig() {
1152
- const globalRaw = loadRawYaml(getGlobalConfigPath());
1153
- const projectRaw = loadRawYaml(getConfigPath());
1154
- const merged = { ...globalRaw, ...projectRaw };
1155
- return assistConfigSchema.parse(merged);
1156
- }
1157
- function loadProjectConfig() {
1158
- return loadRawYaml(getConfigPath());
1159
- }
1160
- function loadGlobalConfigRaw() {
1161
- return loadRawYaml(getGlobalConfigPath());
1162
- }
1163
- function saveGlobalConfig(config) {
1164
- writeFileSync5(getGlobalConfigPath(), stringifyYaml(config, { lineWidth: 0 }));
1165
- }
1166
- function saveConfig(config) {
1167
- const configPath = getConfigPath();
1168
- writeFileSync5(configPath, stringifyYaml(config, { lineWidth: 0 }));
1169
- }
1170
- function getTranscriptConfig() {
1171
- const config = loadConfig();
1172
- if (!config.transcript) {
1173
- console.error(
1174
- chalk5.red(
1175
- "Transcript directories not configured. Run 'assist transcript configure' first."
1176
- )
1177
- );
1178
- process.exit(1);
1179
- }
1180
- return config.transcript;
1181
- }
1182
-
1183
- // src/commands/backlog/spawnClaude.ts
1184
976
  function spawnClaude(prompt, options2 = {}) {
1185
- const config = loadConfig();
1186
- const finalPrompt = config.caveman ? `/caveman:caveman
1187
-
1188
- ${prompt}` : prompt;
1189
- const args = [finalPrompt];
977
+ const args = [prompt];
1190
978
  if (options2.allowEdits) {
1191
979
  args.push("--permission-mode", "acceptEdits");
1192
980
  }
@@ -1201,11 +989,11 @@ ${prompt}` : prompt;
1201
989
  }
1202
990
 
1203
991
  // src/commands/backlog/watchForMarker.ts
1204
- import { existsSync as existsSync9, unwatchFile, watchFile } from "fs";
992
+ import { existsSync as existsSync7, unwatchFile, watchFile } from "fs";
1205
993
  function watchForMarker(child) {
1206
994
  const statusPath = getSignalPath();
1207
995
  watchFile(statusPath, { interval: 1e3 }, () => {
1208
- if (!existsSync9(statusPath)) return;
996
+ if (!existsSync7(statusPath)) return;
1209
997
  const signal = readSignal();
1210
998
  if (signal) {
1211
999
  unwatchFile(statusPath);
@@ -1222,7 +1010,7 @@ async function executePhase(item, phaseIndex, phases, spawnOptions) {
1222
1010
  const phase = phases[phaseIndex];
1223
1011
  const phaseNumber = phaseIndex + 1;
1224
1012
  console.log(
1225
- chalk6.bold(
1013
+ chalk5.bold(
1226
1014
  `
1227
1015
  --- Phase ${phaseNumber}/${phases.length}: ${phase.name} ---
1228
1016
  `
@@ -1240,7 +1028,7 @@ async function executePhase(item, phaseIndex, phases, spawnOptions) {
1240
1028
  }
1241
1029
 
1242
1030
  // src/commands/backlog/prepareRun.ts
1243
- import chalk7 from "chalk";
1031
+ import chalk6 from "chalk";
1244
1032
 
1245
1033
  // src/commands/backlog/resolvePlan.ts
1246
1034
  function resolvePlan(item) {
@@ -1263,13 +1051,13 @@ function prepareRun(id) {
1263
1051
  const plan2 = resolvePlan(item);
1264
1052
  const startPhase = (item.currentPhase ?? 1) - 1;
1265
1053
  if (item.status === "done") {
1266
- console.log(chalk7.green(`Already done: #${id}: ${item.name}`));
1054
+ console.log(chalk6.green(`Already done: #${id}: ${item.name}`));
1267
1055
  return void 0;
1268
1056
  }
1269
1057
  if (startPhase > plan2.length) {
1270
1058
  setStatus(id, "done");
1271
1059
  console.log(
1272
- chalk7.green(`All phases already complete for #${id}: ${item.name}`)
1060
+ chalk6.green(`All phases already complete for #${id}: ${item.name}`)
1273
1061
  );
1274
1062
  return void 0;
1275
1063
  }
@@ -1294,13 +1082,13 @@ async function run(id, spawnOptions) {
1294
1082
  }
1295
1083
  }
1296
1084
  function logProgress(id, name, startPhase, total) {
1297
- console.log(chalk8.bold(`Running plan for #${id}: ${name}`));
1085
+ console.log(chalk7.bold(`Running plan for #${id}: ${name}`));
1298
1086
  if (startPhase > 0) {
1299
1087
  const phaseNumber = startPhase + 1;
1300
- console.log(chalk8.dim(`Resuming from phase ${phaseNumber}/${total}
1088
+ console.log(chalk7.dim(`Resuming from phase ${phaseNumber}/${total}
1301
1089
  `));
1302
1090
  } else {
1303
- console.log(chalk8.dim(`${total} phase(s)
1091
+ console.log(chalk7.dim(`${total} phase(s)
1304
1092
  `));
1305
1093
  }
1306
1094
  }
@@ -1333,7 +1121,7 @@ async function runReview(item, plan2, spawnOptions) {
1333
1121
  // src/commands/backlog/next.ts
1334
1122
  function toChoice(item, items) {
1335
1123
  const name = `${typeLabel(item.type)} #${item.id}: ${item.name}`;
1336
- return isBlocked(item, items) ? { name, disabled: chalk9.red("[blocked]") } : { name };
1124
+ return isBlocked(item, items) ? { name, disabled: chalk8.red("[blocked]") } : { name };
1337
1125
  }
1338
1126
  async function selectItem(todo, items) {
1339
1127
  const { selected } = await exitOnCancel(
@@ -1350,7 +1138,7 @@ async function pickItem(items, firstPick = false) {
1350
1138
  const resumable = findResumable(items);
1351
1139
  if (resumable) {
1352
1140
  console.log(
1353
- chalk9.bold(
1141
+ chalk8.bold(
1354
1142
  `Resuming in-progress item #${resumable.id}: ${resumable.name}`
1355
1143
  )
1356
1144
  );
@@ -1360,7 +1148,7 @@ async function pickItem(items, firstPick = false) {
1360
1148
  if (!unblocked) return void 0;
1361
1149
  if (firstPick && unblocked.length === 1) {
1362
1150
  const item = unblocked[0];
1363
- console.log(chalk9.bold(`Auto-selecting item #${item.id}: ${item.name}`));
1151
+ console.log(chalk8.bold(`Auto-selecting item #${item.id}: ${item.name}`));
1364
1152
  return String(item.id);
1365
1153
  }
1366
1154
  const todo = items.filter((i) => i.status === "todo");
@@ -1378,7 +1166,7 @@ async function next(options2) {
1378
1166
  }
1379
1167
 
1380
1168
  // src/commands/backlog/phaseDone.ts
1381
- import chalk10 from "chalk";
1169
+ import chalk9 from "chalk";
1382
1170
 
1383
1171
  // src/commands/backlog/addComment.ts
1384
1172
  function addComment(item, text, phase) {
@@ -1413,7 +1201,7 @@ function phaseDone(id, phase, summary) {
1413
1201
  });
1414
1202
  const result = loadAndFindItem(id);
1415
1203
  if (result?.item.status === "done") {
1416
- console.log(chalk10.dim(`Item #${id} already done, skipping phase advance.`));
1204
+ console.log(chalk9.dim(`Item #${id} already done, skipping phase advance.`));
1417
1205
  return;
1418
1206
  }
1419
1207
  if (result) {
@@ -1422,24 +1210,24 @@ function phaseDone(id, phase, summary) {
1422
1210
  }
1423
1211
  setCurrentPhase(id, phaseNumber + 1);
1424
1212
  console.log(
1425
- chalk10.green(`Phase ${phaseNumber} of item #${id} marked as complete.`)
1213
+ chalk9.green(`Phase ${phaseNumber} of item #${id} marked as complete.`)
1426
1214
  );
1427
1215
  }
1428
1216
 
1429
1217
  // src/commands/backlog/plan.ts
1430
- import chalk11 from "chalk";
1218
+ import chalk10 from "chalk";
1431
1219
  function plan(id) {
1432
1220
  const result = loadAndFindItem(id);
1433
1221
  if (!result) return;
1434
1222
  const { item } = result;
1435
1223
  if (!item.plan || item.plan.length === 0) {
1436
- console.log(chalk11.dim("No plan defined for this item."));
1224
+ console.log(chalk10.dim("No plan defined for this item."));
1437
1225
  return;
1438
1226
  }
1439
- console.log(chalk11.bold(item.name));
1227
+ console.log(chalk10.bold(item.name));
1440
1228
  console.log();
1441
1229
  for (const [i, phase] of item.plan.entries()) {
1442
- console.log(`${chalk11.bold(`Phase ${i + 1}:`)} ${phase.name}`);
1230
+ console.log(`${chalk10.bold(`Phase ${i + 1}:`)} ${phase.name}`);
1443
1231
  for (const task of phase.tasks) {
1444
1232
  console.log(` - ${task.task}`);
1445
1233
  }
@@ -1448,35 +1236,35 @@ function plan(id) {
1448
1236
  }
1449
1237
 
1450
1238
  // src/commands/backlog/show/index.ts
1451
- import chalk15 from "chalk";
1239
+ import chalk14 from "chalk";
1452
1240
 
1453
1241
  // src/commands/backlog/formatComment.ts
1454
- import chalk12 from "chalk";
1242
+ import chalk11 from "chalk";
1455
1243
  function formatComment(entry) {
1456
- const id = entry.id !== void 0 ? chalk12.dim(`#${entry.id} `) : "";
1457
- const tag = entry.type === "summary" ? chalk12.magenta("[summary]") : chalk12.cyan("[comment]");
1458
- const phase = entry.phase !== void 0 ? chalk12.dim(` (phase ${entry.phase})`) : "";
1459
- const time = chalk12.dim(entry.timestamp);
1244
+ const id = entry.id !== void 0 ? chalk11.dim(`#${entry.id} `) : "";
1245
+ const tag = entry.type === "summary" ? chalk11.magenta("[summary]") : chalk11.cyan("[comment]");
1246
+ const phase = entry.phase !== void 0 ? chalk11.dim(` (phase ${entry.phase})`) : "";
1247
+ const time = chalk11.dim(entry.timestamp);
1460
1248
  return `${id}${tag}${phase} ${time}
1461
1249
  ${entry.text}`;
1462
1250
  }
1463
1251
 
1464
1252
  // src/commands/backlog/show/printLinks.ts
1465
- import chalk13 from "chalk";
1253
+ import chalk12 from "chalk";
1466
1254
  function printLinks(item, items) {
1467
1255
  const links = item.links ?? [];
1468
1256
  if (links.length === 0) return;
1469
- console.log(chalk13.bold("Links"));
1257
+ console.log(chalk12.bold("Links"));
1470
1258
  for (const link3 of links) {
1471
1259
  const target = items.find((i) => i.id === link3.targetId);
1472
- const typeLabel2 = link3.type === "depends-on" ? chalk13.red("depends-on") : chalk13.blue("relates-to");
1260
+ const typeLabel2 = link3.type === "depends-on" ? chalk12.red("depends-on") : chalk12.blue("relates-to");
1473
1261
  if (target) {
1474
1262
  console.log(
1475
- ` ${typeLabel2} #${target.id} ${target.name} ${chalk13.dim(`(${target.status})`)}`
1263
+ ` ${typeLabel2} #${target.id} ${target.name} ${chalk12.dim(`(${target.status})`)}`
1476
1264
  );
1477
1265
  } else {
1478
1266
  console.log(
1479
- ` ${typeLabel2} #${link3.targetId} ${chalk13.dim("(not found)")}`
1267
+ ` ${typeLabel2} #${link3.targetId} ${chalk12.dim("(not found)")}`
1480
1268
  );
1481
1269
  }
1482
1270
  }
@@ -1484,15 +1272,15 @@ function printLinks(item, items) {
1484
1272
  }
1485
1273
 
1486
1274
  // src/commands/backlog/show/printPhaseTasks.ts
1487
- import chalk14 from "chalk";
1275
+ import chalk13 from "chalk";
1488
1276
  function printPhaseTasks(phase) {
1489
1277
  for (const task of phase.tasks) {
1490
1278
  console.log(` - ${task.task}`);
1491
1279
  }
1492
1280
  if (phase.manualChecks && phase.manualChecks.length > 0) {
1493
- console.log(` ${chalk14.dim("Manual checks:")}`);
1281
+ console.log(` ${chalk13.dim("Manual checks:")}`);
1494
1282
  for (const check2 of phase.manualChecks) {
1495
- console.log(` ${chalk14.dim(`- ${check2}`)}`);
1283
+ console.log(` ${chalk13.dim(`- ${check2}`)}`);
1496
1284
  }
1497
1285
  }
1498
1286
  }
@@ -1500,7 +1288,7 @@ function printPhaseTasks(phase) {
1500
1288
  // src/commands/backlog/show/index.ts
1501
1289
  function printPlan(item) {
1502
1290
  if (!item.plan || item.plan.length === 0) return;
1503
- console.log(chalk15.bold("Plan"));
1291
+ console.log(chalk14.bold("Plan"));
1504
1292
  for (const [i, phase] of item.plan.entries()) {
1505
1293
  const isCurrent = item.currentPhase === i + 1;
1506
1294
  printPhase(phase, i, isCurrent);
@@ -1509,8 +1297,8 @@ function printPlan(item) {
1509
1297
  }
1510
1298
  function phaseHeader(index, name, isCurrent) {
1511
1299
  const phaseNumber = index + 1;
1512
- const marker = isCurrent ? chalk15.green("\u25B6 ") : " ";
1513
- const label2 = isCurrent ? chalk15.green.bold(`Phase ${phaseNumber}: ${name}`) : `${chalk15.bold(`Phase ${phaseNumber}:`)} ${name}`;
1300
+ const marker = isCurrent ? chalk14.green("\u25B6 ") : " ";
1301
+ const label2 = isCurrent ? chalk14.green.bold(`Phase ${phaseNumber}: ${name}`) : `${chalk14.bold(`Phase ${phaseNumber}:`)} ${name}`;
1514
1302
  return `${marker}${label2}`;
1515
1303
  }
1516
1304
  function printPhase(phase, index, isCurrent) {
@@ -1518,15 +1306,15 @@ function printPhase(phase, index, isCurrent) {
1518
1306
  printPhaseTasks(phase);
1519
1307
  }
1520
1308
  function printHeader(item) {
1521
- console.log(chalk15.bold(`#${item.id} ${item.name}`));
1309
+ console.log(chalk14.bold(`#${item.id} ${item.name}`));
1522
1310
  console.log(
1523
- `${chalk15.dim("Type:")} ${item.type} ${chalk15.dim("Status:")} ${item.status}`
1311
+ `${chalk14.dim("Type:")} ${item.type} ${chalk14.dim("Status:")} ${item.status}`
1524
1312
  );
1525
1313
  console.log();
1526
1314
  }
1527
1315
  function printAcceptanceCriteria(criteria) {
1528
1316
  if (criteria.length === 0) return;
1529
- console.log(chalk15.bold("Acceptance Criteria"));
1317
+ console.log(chalk14.bold("Acceptance Criteria"));
1530
1318
  for (const [i, ac] of criteria.entries()) {
1531
1319
  console.log(` ${i + 1}. ${ac}`);
1532
1320
  }
@@ -1538,7 +1326,7 @@ function show(id) {
1538
1326
  const { item, items } = result;
1539
1327
  printHeader(item);
1540
1328
  if (item.description) {
1541
- console.log(chalk15.bold("Description"));
1329
+ console.log(chalk14.bold("Description"));
1542
1330
  console.log(item.description);
1543
1331
  console.log();
1544
1332
  }
@@ -1550,7 +1338,7 @@ function show(id) {
1550
1338
  function printComments(item) {
1551
1339
  const entries = item.comments ?? [];
1552
1340
  if (entries.length === 0) return;
1553
- console.log(chalk15.bold("Comments"));
1341
+ console.log(chalk14.bold("Comments"));
1554
1342
  for (const entry of entries) {
1555
1343
  console.log(` ${formatComment(entry)}`);
1556
1344
  }
@@ -1559,23 +1347,23 @@ function printComments(item) {
1559
1347
 
1560
1348
  // src/shared/web.ts
1561
1349
  import { exec } from "child_process";
1562
- import { readFileSync as readFileSync7 } from "fs";
1350
+ import { readFileSync as readFileSync6 } from "fs";
1563
1351
  import {
1564
1352
  createServer
1565
1353
  } from "http";
1566
- import { dirname as dirname2, join as join8 } from "path";
1354
+ import { dirname, join as join7 } from "path";
1567
1355
  import { fileURLToPath } from "url";
1568
- import chalk16 from "chalk";
1356
+ import chalk15 from "chalk";
1569
1357
  function respondJson(res, status2, data) {
1570
1358
  res.writeHead(status2, { "Content-Type": "application/json" });
1571
1359
  res.end(JSON.stringify(data));
1572
1360
  }
1573
1361
  function createBundleHandler(importMetaUrl, bundlePath) {
1574
- const dir = dirname2(fileURLToPath(importMetaUrl));
1362
+ const dir = dirname(fileURLToPath(importMetaUrl));
1575
1363
  let cache;
1576
1364
  return (_req, res) => {
1577
1365
  if (!cache) {
1578
- cache = readFileSync7(join8(dir, bundlePath), "utf-8");
1366
+ cache = readFileSync6(join7(dir, bundlePath), "utf-8");
1579
1367
  }
1580
1368
  res.writeHead(200, { "Content-Type": "application/javascript" });
1581
1369
  res.end(cache);
@@ -1609,8 +1397,8 @@ function startWebServer(label2, port, handler) {
1609
1397
  handler(req, res, port);
1610
1398
  });
1611
1399
  server.listen(port, () => {
1612
- console.log(chalk16.green(`${label2}: ${url}`));
1613
- console.log(chalk16.dim("Press Ctrl+C to stop"));
1400
+ console.log(chalk15.green(`${label2}: ${url}`));
1401
+ console.log(chalk15.dim("Press Ctrl+C to stop"));
1614
1402
  exec(`open ${url}`);
1615
1403
  });
1616
1404
  return server;
@@ -1825,7 +1613,7 @@ async function web(options2) {
1825
1613
  }
1826
1614
 
1827
1615
  // src/commands/backlog/launchMode.ts
1828
- import chalk17 from "chalk";
1616
+ import chalk16 from "chalk";
1829
1617
  async function launchMode(slashCommand) {
1830
1618
  process.env.ASSIST_SESSION_ID = String(process.pid);
1831
1619
  const { child, done: done2 } = spawnClaude(`/${slashCommand}`, { allowEdits: true });
@@ -1835,13 +1623,13 @@ async function launchMode(slashCommand) {
1835
1623
  const signal = readSignal();
1836
1624
  cleanupSignal();
1837
1625
  if (signal?.event === "next") {
1838
- console.log(chalk17.bold("\nChaining into assist next...\n"));
1626
+ console.log(chalk16.bold("\nChaining into assist next...\n"));
1839
1627
  await next({ allowEdits: true });
1840
1628
  }
1841
1629
  }
1842
1630
 
1843
1631
  // src/commands/backlog/refine.ts
1844
- import chalk18 from "chalk";
1632
+ import chalk17 from "chalk";
1845
1633
  import enquirer3 from "enquirer";
1846
1634
  async function pickItemForRefine() {
1847
1635
  const items = loadBacklog();
@@ -1849,12 +1637,12 @@ async function pickItemForRefine() {
1849
1637
  (i) => i.status === "todo" || i.status === "in-progress"
1850
1638
  );
1851
1639
  if (active.length === 0) {
1852
- console.log(chalk18.yellow("No active backlog items to refine."));
1640
+ console.log(chalk17.yellow("No active backlog items to refine."));
1853
1641
  return void 0;
1854
1642
  }
1855
1643
  if (active.length === 1) {
1856
1644
  const item = active[0];
1857
- console.log(chalk18.bold(`Auto-selecting item #${item.id}: ${item.name}`));
1645
+ console.log(chalk17.bold(`Auto-selecting item #${item.id}: ${item.name}`));
1858
1646
  return String(item.id);
1859
1647
  }
1860
1648
  const { selected } = await exitOnCancel(
@@ -1878,6 +1666,211 @@ async function refine(id) {
1878
1666
  // src/commands/commit.ts
1879
1667
  import { execSync } from "child_process";
1880
1668
 
1669
+ // src/shared/loadConfig.ts
1670
+ import { existsSync as existsSync9, writeFileSync as writeFileSync5 } from "fs";
1671
+ import { homedir } from "os";
1672
+ import { dirname as dirname2, join as join8 } from "path";
1673
+ import chalk18 from "chalk";
1674
+ import { stringify as stringifyYaml } from "yaml";
1675
+
1676
+ // src/shared/loadRawYaml.ts
1677
+ import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
1678
+ import { parse as parseYaml2 } from "yaml";
1679
+ function loadRawYaml(path52) {
1680
+ if (!existsSync8(path52)) return {};
1681
+ try {
1682
+ const content = readFileSync7(path52, "utf-8");
1683
+ return parseYaml2(content) || {};
1684
+ } catch {
1685
+ return {};
1686
+ }
1687
+ }
1688
+
1689
+ // src/shared/types.ts
1690
+ import { z as z2 } from "zod";
1691
+ var runParamSchema = z2.strictObject({
1692
+ name: z2.string(),
1693
+ required: z2.boolean().optional(),
1694
+ default: z2.string().optional(),
1695
+ description: z2.string().optional()
1696
+ });
1697
+ var runConfigSchema = z2.strictObject({
1698
+ name: z2.string(),
1699
+ command: z2.string(),
1700
+ args: z2.array(z2.string()).optional(),
1701
+ params: z2.array(runParamSchema).optional(),
1702
+ env: z2.record(z2.string(), z2.string()).optional(),
1703
+ filter: z2.string().optional(),
1704
+ pre: z2.array(z2.string()).optional(),
1705
+ cwd: z2.string().optional()
1706
+ });
1707
+ var runLinkSchema = z2.strictObject({
1708
+ link: z2.string(),
1709
+ prefix: z2.string()
1710
+ });
1711
+ var transcriptConfigSchema = z2.strictObject({
1712
+ vttDir: z2.string(),
1713
+ transcriptsDir: z2.string(),
1714
+ summaryDir: z2.string()
1715
+ });
1716
+ var DEFAULT_WAKE_WORDS = ["computer"];
1717
+ var DEFAULT_MODELS_DIR = "~/.assist/voice/models";
1718
+ var assistConfigSchema = z2.strictObject({
1719
+ commit: z2.strictObject({
1720
+ conventional: z2.boolean().default(false),
1721
+ pull: z2.boolean().default(false),
1722
+ push: z2.boolean().default(false)
1723
+ }).default({ conventional: false, pull: false, push: false }),
1724
+ devlog: z2.strictObject({
1725
+ name: z2.string().optional(),
1726
+ ignore: z2.array(z2.string()).optional(),
1727
+ skip: z2.record(z2.string(), z2.array(z2.string())).optional()
1728
+ }).optional(),
1729
+ notify: z2.strictObject({
1730
+ enabled: z2.boolean().default(true)
1731
+ }).default({ enabled: true }),
1732
+ complexity: z2.strictObject({
1733
+ ignore: z2.array(z2.string()).default(["**/*test.ts*"])
1734
+ }).default({ ignore: ["**/*test.ts*"] }),
1735
+ hardcodedColors: z2.strictObject({
1736
+ ignore: z2.array(z2.string()).default([])
1737
+ }).optional(),
1738
+ restructure: z2.strictObject({
1739
+ ignore: z2.array(z2.string()).default([])
1740
+ }).optional(),
1741
+ jira: z2.strictObject({
1742
+ acField: z2.string().default("customfield_11937")
1743
+ }).optional(),
1744
+ roam: z2.strictObject({
1745
+ clientId: z2.string(),
1746
+ clientSecret: z2.string(),
1747
+ accessToken: z2.string().optional(),
1748
+ refreshToken: z2.string().optional(),
1749
+ tokenExpiresAt: z2.number().optional()
1750
+ }).optional(),
1751
+ run: z2.array(z2.union([runConfigSchema, runLinkSchema])).optional(),
1752
+ transcript: transcriptConfigSchema.optional(),
1753
+ cliReadVerbs: z2.record(z2.string(), z2.array(z2.string())).optional(),
1754
+ news: z2.strictObject({
1755
+ feeds: z2.array(z2.string()).default([])
1756
+ }).default({ feeds: [] }),
1757
+ dotnet: z2.strictObject({
1758
+ inspect: z2.strictObject({
1759
+ suppress: z2.array(z2.string()).default([])
1760
+ }).default({ suppress: [] })
1761
+ }).optional(),
1762
+ ravendb: z2.strictObject({
1763
+ connections: z2.array(
1764
+ z2.strictObject({
1765
+ name: z2.string(),
1766
+ url: z2.string(),
1767
+ database: z2.string(),
1768
+ apiKeyRef: z2.string()
1769
+ })
1770
+ ).default([]),
1771
+ defaultConnection: z2.string().optional()
1772
+ }).optional(),
1773
+ seq: z2.strictObject({
1774
+ connections: z2.array(
1775
+ z2.strictObject({
1776
+ name: z2.string(),
1777
+ url: z2.string(),
1778
+ apiToken: z2.string()
1779
+ })
1780
+ ).default([]),
1781
+ defaultConnection: z2.string().optional()
1782
+ }).optional(),
1783
+ screenshot: z2.strictObject({
1784
+ outputDir: z2.string().default("./screenshots")
1785
+ }).default({ outputDir: "./screenshots" }),
1786
+ backlog: z2.strictObject({
1787
+ autoCommit: z2.boolean().default(false)
1788
+ }).default({ autoCommit: false }),
1789
+ deny: z2.array(
1790
+ z2.strictObject({
1791
+ pattern: z2.string(),
1792
+ message: z2.string()
1793
+ })
1794
+ ).optional(),
1795
+ sync: z2.strictObject({
1796
+ autoConfirm: z2.boolean().default(false)
1797
+ }).default({ autoConfirm: false }),
1798
+ voice: z2.strictObject({
1799
+ wakeWords: z2.array(z2.string()).default(DEFAULT_WAKE_WORDS),
1800
+ mic: z2.string().optional(),
1801
+ cwd: z2.string().optional(),
1802
+ modelsDir: z2.string().default(DEFAULT_MODELS_DIR),
1803
+ lockDir: z2.string().optional(),
1804
+ submitWindows: z2.array(z2.string()).optional(),
1805
+ models: z2.strictObject({
1806
+ vad: z2.string().optional(),
1807
+ smartTurn: z2.string().optional()
1808
+ }).default({})
1809
+ }).default({
1810
+ wakeWords: DEFAULT_WAKE_WORDS,
1811
+ modelsDir: DEFAULT_MODELS_DIR,
1812
+ models: {}
1813
+ })
1814
+ });
1815
+ function isRunLink(entry) {
1816
+ return "link" in entry;
1817
+ }
1818
+
1819
+ // src/shared/loadConfig.ts
1820
+ function findConfigUp(startDir) {
1821
+ let current = startDir;
1822
+ while (current !== dirname2(current)) {
1823
+ const claudePath = join8(current, ".claude", "assist.yml");
1824
+ if (existsSync9(claudePath)) return claudePath;
1825
+ const rootPath = join8(current, "assist.yml");
1826
+ if (existsSync9(rootPath)) return rootPath;
1827
+ current = dirname2(current);
1828
+ }
1829
+ return null;
1830
+ }
1831
+ function getConfigPath() {
1832
+ const found = findConfigUp(process.cwd());
1833
+ if (found) return found;
1834
+ return join8(process.cwd(), "assist.yml");
1835
+ }
1836
+ function getGlobalConfigPath() {
1837
+ return join8(homedir(), ".assist.yml");
1838
+ }
1839
+ function getConfigDir() {
1840
+ return dirname2(getConfigPath());
1841
+ }
1842
+ function loadConfig() {
1843
+ const globalRaw = loadRawYaml(getGlobalConfigPath());
1844
+ const projectRaw = loadRawYaml(getConfigPath());
1845
+ const merged = { ...globalRaw, ...projectRaw };
1846
+ return assistConfigSchema.parse(merged);
1847
+ }
1848
+ function loadProjectConfig() {
1849
+ return loadRawYaml(getConfigPath());
1850
+ }
1851
+ function loadGlobalConfigRaw() {
1852
+ return loadRawYaml(getGlobalConfigPath());
1853
+ }
1854
+ function saveGlobalConfig(config) {
1855
+ writeFileSync5(getGlobalConfigPath(), stringifyYaml(config, { lineWidth: 0 }));
1856
+ }
1857
+ function saveConfig(config) {
1858
+ const configPath = getConfigPath();
1859
+ writeFileSync5(configPath, stringifyYaml(config, { lineWidth: 0 }));
1860
+ }
1861
+ function getTranscriptConfig() {
1862
+ const config = loadConfig();
1863
+ if (!config.transcript) {
1864
+ console.error(
1865
+ chalk18.red(
1866
+ "Transcript directories not configured. Run 'assist transcript configure' first."
1867
+ )
1868
+ );
1869
+ process.exit(1);
1870
+ }
1871
+ return config.transcript;
1872
+ }
1873
+
1881
1874
  // src/shared/shellQuote.ts
1882
1875
  function shellQuote(arg) {
1883
1876
  if (/[^a-zA-Z0-9_./:=@%^+,-]/.test(arg)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.195.1",
3
+ "version": "0.195.2",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {