@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 +1 -1
- package/claude/CLAUDE.md +1 -1
- package/dist/index.js +63 -26
- package/package.json +1 -1
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 `
|
|
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.
|
|
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 =
|
|
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
|
|
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
|
-
|
|
20102
|
-
|
|
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)));
|