@staff0rd/assist 0.320.0 → 0.321.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/README.md CHANGED
@@ -247,7 +247,7 @@ The first backlog command in a repository that still has a local `.assist/backlo
247
247
  - `assist complexity <pattern>` - Analyze a file (all metrics if single match, maintainability if multiple)
248
248
  - `assist complexity cyclomatic [pattern]` - Calculate cyclomatic complexity per function
249
249
  - `assist complexity halstead [pattern]` - Calculate Halstead metrics per function
250
- - `assist complexity maintainability [pattern]` - Calculate maintainability index per file (`--ignore <glob>`, repeatable, excludes extra files on top of `complexity.ignore`)
250
+ - `assist complexity maintainability [pattern]` - Calculate maintainability index per file (`--ignore <glob>`, repeatable, excludes extra files on top of `complexity.ignore`). A file can declare its own threshold with a `// assist-maintainability-override: N` comment in its first ~10 lines (integer 0-100); that value replaces the global `--threshold` for that file only and the output annotates it with `(override: N)`
251
251
  - `assist complexity sloc [pattern]` - Count source lines of code per file
252
252
  - `assist transcript configure` - Configure transcript directories
253
253
  - `assist transcript format` - Convert VTT files to formatted markdown transcripts
package/claude/CLAUDE.md CHANGED
@@ -8,7 +8,7 @@ When renaming TypeScript files or symbols, use the refactor commands instead of
8
8
  - `assist refactor rename symbol <file> <oldName> <newName>` — rename a variable, function, class, or type across the project
9
9
  - `assist refactor extract <file> <functionName> <destination>` — extract a function and its private dependencies to a new file
10
10
  All default to dry-run; add `--apply` to execute.
11
- When using extract, name the destination file after the exported function (e.g. `updateWorkerCapacity.ts` for `updateWorkerCapacity`) to satisfy `useFilenamingConvention` lint rules.
11
+ When using extract, name the destination file after the exported function (e.g. `updateWorkerCapacity.ts` for `updateWorkerCapacity`) to satisfy the `oxlint-rules/filenameConvention.ts` lint rule.
12
12
 
13
13
  Do not modify `claude/settings.json` without asking the user first. Only read-only commands should be added to the allow list — write operations (add, remove, set, delete) must require confirmation.
14
14
 
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.320.0",
9
+ version: "0.321.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -9692,7 +9692,7 @@ import chalk95 from "chalk";
9692
9692
  function formatResultLine(entry, failing) {
9693
9693
  const { file, avgMaintainability, minMaintainability, override } = entry;
9694
9694
  const name = failing ? chalk95.red(file) : chalk95.white(file);
9695
- const suffix = failing && override !== void 0 ? chalk95.magenta(` (override threshold ${override})`) : "";
9695
+ const suffix = override !== void 0 ? chalk95.magenta(` (override: ${override})`) : "";
9696
9696
  return `${name} \u2192 avg: ${chalk95.cyan(avgMaintainability.toFixed(1))}, min: ${chalk95.yellow(minMaintainability.toFixed(1))}${suffix}`;
9697
9697
  }
9698
9698
 
@@ -9703,7 +9703,7 @@ function printMaintainabilityFailure(failingCount, threshold) {
9703
9703
  console.error(
9704
9704
  chalk96.red(
9705
9705
  `
9706
- Fail: ${failingCount} file(s) below threshold${thresholdLabel} (files marked "override threshold" were judged against their own marker). Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
9706
+ Fail: ${failingCount} file(s) below threshold${thresholdLabel} (files marked "(override: N)" were judged against their own marker). Maintainability index (0\u2013100) is derived from Halstead volume, cyclomatic complexity, and lines of code.
9707
9707
 
9708
9708
  \u26A0\uFE0F ${chalk96.bold("Diagnose and fix one file at a time")} \u2014 do not investigate or fix multiple files in parallel.
9709
9709
 
@@ -9730,6 +9730,11 @@ Analyzed ${results.length} files`));
9730
9730
  } else {
9731
9731
  for (const entry of failing) console.log(formatResultLine(entry, true));
9732
9732
  }
9733
+ const passingOverrides = results.filter(
9734
+ (r) => r.override !== void 0 && !failing.includes(r)
9735
+ );
9736
+ for (const entry of passingOverrides)
9737
+ console.log(formatResultLine(entry, false));
9733
9738
  console.log(chalk97.dim(`
9734
9739
  Analyzed ${results.length} files`));
9735
9740
  if (failing.length > 0) {
@@ -20073,6 +20078,13 @@ import { createInterface as createInterface5 } from "readline";
20073
20078
 
20074
20079
  // src/commands/sessions/daemon/loadPersistedSessions.ts
20075
20080
  import { z as z5 } from "zod";
20081
+
20082
+ // src/commands/sessions/daemon/daemonLog.ts
20083
+ function daemonLog(message) {
20084
+ console.log(`${(/* @__PURE__ */ new Date()).toISOString()} [${process.pid}] ${message}`);
20085
+ }
20086
+
20087
+ // src/commands/sessions/daemon/loadPersistedSessions.ts
20076
20088
  var SESSIONS_FILE = "sessions.json";
20077
20089
  var persistedSessionSchema = z5.object({
20078
20090
  name: z5.string(),
@@ -20098,8 +20110,19 @@ function savePersistedSessions(sessions) {
20098
20110
  saveJson(SESSIONS_FILE, sessions);
20099
20111
  }
20100
20112
  function persistLiveSessions(sessions) {
20101
- savePersistedSessions(
20102
- [...sessions.values()].filter((s) => s.pty && s.status !== "done").map(toPersistedSession)
20113
+ const live = [...sessions.values()].filter(
20114
+ (s) => s.pty && s.status !== "done"
20115
+ );
20116
+ savePersistedSessions(live.map(toPersistedSession));
20117
+ logPersist(live);
20118
+ }
20119
+ var lastPersistSignature = "";
20120
+ function logPersist(live) {
20121
+ const signature = live.map((s) => `${s.id}:${s.status}`).join(",");
20122
+ if (signature === lastPersistSignature) return;
20123
+ lastPersistSignature = signature;
20124
+ daemonLog(
20125
+ live.length > 0 ? `persisted ${live.length} session(s): ${live.map((s) => s.name).join(", ")}` : "persisted 0 sessions (sessions.json cleared)"
20103
20126
  );
20104
20127
  }
20105
20128
  function toPersistedSession(session) {
@@ -20173,11 +20196,6 @@ function createAutoExit(exit, graceMs = DEFAULT_GRACE_MS) {
20173
20196
  };
20174
20197
  }
20175
20198
 
20176
- // src/commands/sessions/daemon/daemonLog.ts
20177
- function daemonLog(message) {
20178
- console.log(`${(/* @__PURE__ */ new Date()).toISOString()} [${process.pid}] ${message}`);
20179
- }
20180
-
20181
20199
  // src/commands/sessions/daemon/loadActiveSelection.ts
20182
20200
  import { z as z6 } from "zod";
20183
20201
  var ACTIVE_FILE = "active.json";
@@ -20384,6 +20402,29 @@ function createAssistSession(id2, assistArgs, cwd) {
20384
20402
  };
20385
20403
  }
20386
20404
 
20405
+ // src/commands/sessions/daemon/dismissSession.ts
20406
+ function dismissSession(sessions, id2) {
20407
+ const s = sessions.get(id2);
20408
+ if (!s) return false;
20409
+ if (s.status !== "done") s.pty?.kill();
20410
+ s.activityWatcher?.close();
20411
+ removeActivity(s.id);
20412
+ if (s.activity?.itemId != null) releaseLock(s.activity.itemId);
20413
+ sessions.delete(id2);
20414
+ daemonLog(`session ${id2} dismissed (${s.name})`);
20415
+ return true;
20416
+ }
20417
+ function drainSessions(sessions, onDrained) {
20418
+ const names = [...sessions.values()].map((s) => s.name);
20419
+ const ids = [...sessions.keys()];
20420
+ for (const id2 of ids) dismissSession(sessions, id2);
20421
+ onDrained();
20422
+ daemonLog(
20423
+ ids.length > 0 ? `drained ${ids.length} session(s): ${names.join(", ")}` : "drained 0 sessions"
20424
+ );
20425
+ return ids.length;
20426
+ }
20427
+
20387
20428
  // src/commands/sessions/daemon/createSession.ts
20388
20429
  import { randomUUID as randomUUID4 } from "crypto";
20389
20430
 
@@ -20458,6 +20499,13 @@ function greetClient(client, sessions, windowsProxy) {
20458
20499
  void windowsProxy.discover();
20459
20500
  }
20460
20501
 
20502
+ // src/commands/sessions/daemon/logSpawnedSession.ts
20503
+ function logSpawnedSession(session) {
20504
+ daemonLog(
20505
+ `session ${session.id} spawned: ${session.name} [${session.commandType}] ${session.cwd ?? ""}`
20506
+ );
20507
+ }
20508
+
20461
20509
  // src/commands/sessions/daemon/setStatus.ts
20462
20510
  function setStatus2(session, newStatus) {
20463
20511
  const now = Date.now();
@@ -20821,6 +20869,7 @@ function retrySession(session, clients, onStatusChange) {
20821
20869
  session.pty = respawn();
20822
20870
  broadcast(clients, { type: "clear", sessionId: session.id });
20823
20871
  wirePtyEvents(session, clients, onStatusChange);
20872
+ daemonLog(`session ${session.id} retried: ${session.name}`);
20824
20873
  return true;
20825
20874
  }
20826
20875
  function respawnThunk(session) {
@@ -20850,6 +20899,7 @@ function reuseSessionForRun(session, itemId, clients, onStatusChange) {
20850
20899
 
20851
20900
  // src/commands/sessions/daemon/shutdownSessions.ts
20852
20901
  function shutdownSessions(sessions) {
20902
+ daemonLog(`shutting down: killing ${sessions.size} session(s)`);
20853
20903
  for (const session of sessions.values()) {
20854
20904
  if (session.status !== "done") session.pty?.kill();
20855
20905
  }
@@ -21400,6 +21450,7 @@ function setAutoRun(sessions, id2, enabled) {
21400
21450
  const s = sessions.get(id2);
21401
21451
  if (!s) return false;
21402
21452
  s.autoRun = enabled;
21453
+ daemonLog(`session ${id2} autorun ${enabled ? "on" : "off"}`);
21403
21454
  return true;
21404
21455
  }
21405
21456
  function setAutoAdvance(sessions, id2, enabled) {
@@ -21411,24 +21462,9 @@ function setAutoAdvance(sessions, id2, enabled) {
21411
21462
  if (enabled) clearPause(itemId);
21412
21463
  else requestPause(itemId);
21413
21464
  }
21465
+ daemonLog(`session ${id2} autoadvance ${enabled ? "on" : "off"}`);
21414
21466
  return true;
21415
21467
  }
21416
- function dismissSession(sessions, id2) {
21417
- const s = sessions.get(id2);
21418
- if (!s) return false;
21419
- if (s.status !== "done") s.pty?.kill();
21420
- s.activityWatcher?.close();
21421
- removeActivity(s.id);
21422
- if (s.activity?.itemId != null) releaseLock(s.activity.itemId);
21423
- sessions.delete(id2);
21424
- return true;
21425
- }
21426
- function drainSessions(sessions, onDrained) {
21427
- const ids = [...sessions.keys()];
21428
- for (const id2 of ids) dismissSession(sessions, id2);
21429
- onDrained();
21430
- return ids.length;
21431
- }
21432
21468
 
21433
21469
  // src/commands/sessions/daemon/SessionManager.ts
21434
21470
  var SessionManager = class {
@@ -21464,6 +21500,7 @@ var SessionManager = class {
21464
21500
  add(session) {
21465
21501
  this.wire(session);
21466
21502
  watchActivity(session, this.notify);
21503
+ logSpawnedSession(session);
21467
21504
  return session.id;
21468
21505
  }
21469
21506
  spawnWith = (create) => this.add(create(sessionLimits.nextId(this.sessions.size, this.idCounter)));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.320.0",
3
+ "version": "0.321.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {