@staff0rd/assist 0.318.4 → 0.318.5
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/dist/index.js +109 -119
- 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.318.
|
|
9
|
+
version: "0.318.5",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -3897,7 +3897,12 @@ var hooksSettings = {
|
|
|
3897
3897
|
UserPromptSubmit: on(RUNNING),
|
|
3898
3898
|
PreToolUse: on(RUNNING),
|
|
3899
3899
|
Stop: on(WAITING),
|
|
3900
|
-
Notification: on(WAITING)
|
|
3900
|
+
Notification: on(WAITING),
|
|
3901
|
+
/* why: a tool/plan approval prompt appears mid-turn, after PreToolUse has
|
|
3902
|
+
* already set running; PermissionRequest fires when the agent blocks on
|
|
3903
|
+
* that decision, so the card shows waiting rather than staying running while
|
|
3904
|
+
* it is genuinely awaiting the user (#449). */
|
|
3905
|
+
PermissionRequest: on(WAITING)
|
|
3901
3906
|
}
|
|
3902
3907
|
};
|
|
3903
3908
|
function ensureHooksSettings() {
|
|
@@ -4604,51 +4609,43 @@ Failed to launch Claude for ${context}: ${message}`)
|
|
|
4604
4609
|
}
|
|
4605
4610
|
}
|
|
4606
4611
|
|
|
4607
|
-
// src/
|
|
4608
|
-
import
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
itemId: z4.number().optional(),
|
|
4616
|
-
itemName: z4.string().optional(),
|
|
4617
|
-
phase: z4.number().optional(),
|
|
4618
|
-
phaseName: z4.string().optional(),
|
|
4619
|
-
totalPhases: z4.number().optional(),
|
|
4620
|
-
claudeSessionId: z4.string().optional(),
|
|
4621
|
-
startedAt: z4.number()
|
|
4622
|
-
});
|
|
4623
|
-
function activityPath(sessionId) {
|
|
4624
|
-
return join18(homedir7(), ".assist", "activity", `activity-${sessionId}.json`);
|
|
4625
|
-
}
|
|
4626
|
-
function emitActivity(activity2) {
|
|
4627
|
-
const sessionId = process.env.ASSIST_ACTIVITY_ID;
|
|
4628
|
-
if (!sessionId) return;
|
|
4629
|
-
const path57 = activityPath(sessionId);
|
|
4630
|
-
mkdirSync7(dirname14(path57), { recursive: true });
|
|
4631
|
-
writeFileSync17(path57, JSON.stringify({ ...activity2, startedAt: Date.now() }));
|
|
4612
|
+
// src/commands/sessions/daemon/connectToDaemon.ts
|
|
4613
|
+
import * as net from "net";
|
|
4614
|
+
function connectToDaemon() {
|
|
4615
|
+
return new Promise((resolve17, reject) => {
|
|
4616
|
+
const socket = net.connect(daemonPaths.socket);
|
|
4617
|
+
socket.once("connect", () => resolve17(socket));
|
|
4618
|
+
socket.once("error", reject);
|
|
4619
|
+
});
|
|
4632
4620
|
}
|
|
4633
|
-
function
|
|
4621
|
+
async function isDaemonRunning() {
|
|
4634
4622
|
try {
|
|
4635
|
-
|
|
4623
|
+
(await connectToDaemon()).destroy();
|
|
4624
|
+
return true;
|
|
4636
4625
|
} catch {
|
|
4637
|
-
return
|
|
4626
|
+
return false;
|
|
4638
4627
|
}
|
|
4639
4628
|
}
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4629
|
+
|
|
4630
|
+
// src/commands/sessions/daemon/sendToDaemon.ts
|
|
4631
|
+
async function sendToDaemon(message) {
|
|
4632
|
+
const socket = await connectToDaemon();
|
|
4633
|
+
const timer = setTimeout(() => socket.destroy(), 500);
|
|
4634
|
+
socket.on("error", () => {
|
|
4635
|
+
});
|
|
4636
|
+
socket.write(`${JSON.stringify(message)}
|
|
4637
|
+
`, () => {
|
|
4638
|
+
clearTimeout(timer);
|
|
4639
|
+
socket.end();
|
|
4640
|
+
});
|
|
4648
4641
|
}
|
|
4649
|
-
|
|
4642
|
+
|
|
4643
|
+
// src/commands/sessions/setSessionStatus.ts
|
|
4644
|
+
async function setSessionStatus(status2) {
|
|
4645
|
+
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
4646
|
+
if (!sessionId) return;
|
|
4650
4647
|
try {
|
|
4651
|
-
|
|
4648
|
+
await sendToDaemon({ type: "set-status", sessionId, status: status2 });
|
|
4652
4649
|
} catch {
|
|
4653
4650
|
}
|
|
4654
4651
|
}
|
|
@@ -4762,6 +4759,69 @@ function buildResumePrompt() {
|
|
|
4762
4759
|
return "A restart interrupted this conversation. Continue from where you left off.";
|
|
4763
4760
|
}
|
|
4764
4761
|
|
|
4762
|
+
// src/shared/emitActivity.ts
|
|
4763
|
+
import { mkdirSync as mkdirSync7, readFileSync as readFileSync14, rmSync, writeFileSync as writeFileSync17 } from "fs";
|
|
4764
|
+
import { homedir as homedir7 } from "os";
|
|
4765
|
+
import { dirname as dirname14, join as join18 } from "path";
|
|
4766
|
+
import { z as z4 } from "zod";
|
|
4767
|
+
var activitySchema = z4.object({
|
|
4768
|
+
kind: z4.enum(["command", "backlog"]),
|
|
4769
|
+
name: z4.string().optional(),
|
|
4770
|
+
itemId: z4.number().optional(),
|
|
4771
|
+
itemName: z4.string().optional(),
|
|
4772
|
+
phase: z4.number().optional(),
|
|
4773
|
+
phaseName: z4.string().optional(),
|
|
4774
|
+
totalPhases: z4.number().optional(),
|
|
4775
|
+
claudeSessionId: z4.string().optional(),
|
|
4776
|
+
startedAt: z4.number()
|
|
4777
|
+
});
|
|
4778
|
+
function activityPath(sessionId) {
|
|
4779
|
+
return join18(homedir7(), ".assist", "activity", `activity-${sessionId}.json`);
|
|
4780
|
+
}
|
|
4781
|
+
function emitActivity(activity2) {
|
|
4782
|
+
const sessionId = process.env.ASSIST_ACTIVITY_ID;
|
|
4783
|
+
if (!sessionId) return;
|
|
4784
|
+
const path57 = activityPath(sessionId);
|
|
4785
|
+
mkdirSync7(dirname14(path57), { recursive: true });
|
|
4786
|
+
writeFileSync17(path57, JSON.stringify({ ...activity2, startedAt: Date.now() }));
|
|
4787
|
+
}
|
|
4788
|
+
function readActivity(path57) {
|
|
4789
|
+
try {
|
|
4790
|
+
return JSON.parse(readFileSync14(path57, "utf8"));
|
|
4791
|
+
} catch {
|
|
4792
|
+
return void 0;
|
|
4793
|
+
}
|
|
4794
|
+
}
|
|
4795
|
+
function reconcileActivity(sessionId, activity2) {
|
|
4796
|
+
if (!activity2) {
|
|
4797
|
+
removeActivity(sessionId);
|
|
4798
|
+
return;
|
|
4799
|
+
}
|
|
4800
|
+
const path57 = activityPath(sessionId);
|
|
4801
|
+
mkdirSync7(dirname14(path57), { recursive: true });
|
|
4802
|
+
writeFileSync17(path57, JSON.stringify(activity2));
|
|
4803
|
+
}
|
|
4804
|
+
function removeActivity(sessionId) {
|
|
4805
|
+
try {
|
|
4806
|
+
rmSync(activityPath(sessionId));
|
|
4807
|
+
} catch {
|
|
4808
|
+
}
|
|
4809
|
+
}
|
|
4810
|
+
|
|
4811
|
+
// src/commands/backlog/reportPhaseActivity.ts
|
|
4812
|
+
function reportPhaseActivity(item, phaseNumber, totalPhases, phase, claudeSessionId) {
|
|
4813
|
+
const isReviewPhase = phaseNumber >= totalPhases;
|
|
4814
|
+
emitActivity({
|
|
4815
|
+
kind: "backlog",
|
|
4816
|
+
itemId: item.id,
|
|
4817
|
+
itemName: item.name,
|
|
4818
|
+
phase: phaseNumber,
|
|
4819
|
+
phaseName: isReviewPhase ? REVIEW_PHASE_NAME : phase.name,
|
|
4820
|
+
totalPhases,
|
|
4821
|
+
claudeSessionId
|
|
4822
|
+
});
|
|
4823
|
+
}
|
|
4824
|
+
|
|
4765
4825
|
// src/commands/backlog/resolvePhaseResult.ts
|
|
4766
4826
|
import { existsSync as existsSync22, unlinkSync as unlinkSync4 } from "fs";
|
|
4767
4827
|
import chalk40 from "chalk";
|
|
@@ -4875,16 +4935,7 @@ async function executePhase(item, phaseIndex, phases, spawnOptions, totalPhases
|
|
|
4875
4935
|
const resumeSessionId = spawnOptions?.resumeSessionId;
|
|
4876
4936
|
const claudeSessionId = resumeSessionId ?? randomUUID();
|
|
4877
4937
|
process.env.ASSIST_SESSION_ID ??= String(process.pid);
|
|
4878
|
-
|
|
4879
|
-
emitActivity({
|
|
4880
|
-
kind: "backlog",
|
|
4881
|
-
itemId: item.id,
|
|
4882
|
-
itemName: item.name,
|
|
4883
|
-
phase: phaseNumber,
|
|
4884
|
-
phaseName: isReviewPhase ? REVIEW_PHASE_NAME : phase.name,
|
|
4885
|
-
totalPhases,
|
|
4886
|
-
claudeSessionId
|
|
4887
|
-
});
|
|
4938
|
+
reportPhaseActivity(item, phaseNumber, totalPhases, phase, claudeSessionId);
|
|
4888
4939
|
const { child, done: done2 } = spawnClaude(
|
|
4889
4940
|
resumeSessionId ? buildResumePrompt() : buildPhasePrompt(item, phaseNumber, phase),
|
|
4890
4941
|
resumeSessionId ? spawnOptions : { ...spawnOptions, sessionId: claudeSessionId }
|
|
@@ -4896,6 +4947,7 @@ async function executePhase(item, phaseIndex, phases, spawnOptions, totalPhases
|
|
|
4896
4947
|
);
|
|
4897
4948
|
stopWatching();
|
|
4898
4949
|
if (!launched) return -1;
|
|
4950
|
+
void setSessionStatus("running");
|
|
4899
4951
|
return await resolvePhaseResult(phaseIndex, item.id);
|
|
4900
4952
|
}
|
|
4901
4953
|
|
|
@@ -5418,26 +5470,6 @@ import {
|
|
|
5418
5470
|
unlinkSync as unlinkSync5,
|
|
5419
5471
|
writeSync
|
|
5420
5472
|
} from "fs";
|
|
5421
|
-
|
|
5422
|
-
// src/commands/sessions/daemon/connectToDaemon.ts
|
|
5423
|
-
import * as net from "net";
|
|
5424
|
-
function connectToDaemon() {
|
|
5425
|
-
return new Promise((resolve17, reject) => {
|
|
5426
|
-
const socket = net.connect(daemonPaths.socket);
|
|
5427
|
-
socket.once("connect", () => resolve17(socket));
|
|
5428
|
-
socket.once("error", reject);
|
|
5429
|
-
});
|
|
5430
|
-
}
|
|
5431
|
-
async function isDaemonRunning() {
|
|
5432
|
-
try {
|
|
5433
|
-
(await connectToDaemon()).destroy();
|
|
5434
|
-
return true;
|
|
5435
|
-
} catch {
|
|
5436
|
-
return false;
|
|
5437
|
-
}
|
|
5438
|
-
}
|
|
5439
|
-
|
|
5440
|
-
// src/commands/sessions/daemon/ensureDaemonRunning.ts
|
|
5441
5473
|
var SPAWN_TIMEOUT_MS = 1e4;
|
|
5442
5474
|
var RETRY_DELAY_MS = 200;
|
|
5443
5475
|
var STALE_LOCK_MS = SPAWN_TIMEOUT_MS + 5e3;
|
|
@@ -20193,21 +20225,23 @@ function spawnRun(opts) {
|
|
|
20193
20225
|
}
|
|
20194
20226
|
|
|
20195
20227
|
// src/commands/sessions/daemon/createSession.ts
|
|
20196
|
-
function
|
|
20228
|
+
function sessionBase(id2, status2) {
|
|
20197
20229
|
const startedAt = Date.now();
|
|
20198
20230
|
return {
|
|
20199
20231
|
id: id2,
|
|
20200
|
-
status:
|
|
20232
|
+
status: status2,
|
|
20201
20233
|
startedAt,
|
|
20202
20234
|
runningMs: 0,
|
|
20203
|
-
|
|
20235
|
+
/* why: runningMs counts only running stretches, so a session that starts
|
|
20236
|
+
* waiting (idle, awaiting first input) has no open stretch to stamp. */
|
|
20237
|
+
runningSince: status2 === "running" ? startedAt : null,
|
|
20204
20238
|
scrollback: ""
|
|
20205
20239
|
};
|
|
20206
20240
|
}
|
|
20207
20241
|
function createSession(id2, prompt, cwd) {
|
|
20208
20242
|
const claudeSessionId = randomUUID4();
|
|
20209
20243
|
return {
|
|
20210
|
-
...
|
|
20244
|
+
...sessionBase(id2, prompt ? "running" : "waiting"),
|
|
20211
20245
|
name: prompt?.slice(0, 40) || `Session ${id2}`,
|
|
20212
20246
|
commandType: "claude",
|
|
20213
20247
|
pty: spawnClaude2({ prompt, cwd, sessionId: id2, claudeSessionId }),
|
|
@@ -20217,7 +20251,7 @@ function createSession(id2, prompt, cwd) {
|
|
|
20217
20251
|
}
|
|
20218
20252
|
function createRunSession(id2, runName, runArgs, cwd) {
|
|
20219
20253
|
return {
|
|
20220
|
-
...
|
|
20254
|
+
...sessionBase(id2, "running"),
|
|
20221
20255
|
name: `run: ${runName}`,
|
|
20222
20256
|
commandType: "run",
|
|
20223
20257
|
pty: spawnRun({ name: runName, args: runArgs, cwd }),
|
|
@@ -20536,26 +20570,6 @@ function refreshActivity(session) {
|
|
|
20536
20570
|
session.claudeSessionId = activity2.claudeSessionId;
|
|
20537
20571
|
}
|
|
20538
20572
|
|
|
20539
|
-
// src/commands/sessions/daemon/noteOutputForThinking.ts
|
|
20540
|
-
var ACTIVATE_MS = 500;
|
|
20541
|
-
var GAP_MS = 1e3;
|
|
20542
|
-
function noteOutputForThinking(session, onStatusChange) {
|
|
20543
|
-
if (session.status !== "waiting") {
|
|
20544
|
-
session.thinkingStreakStart = void 0;
|
|
20545
|
-
session.thinkingLastOutput = void 0;
|
|
20546
|
-
return;
|
|
20547
|
-
}
|
|
20548
|
-
const now = Date.now();
|
|
20549
|
-
const stale = session.thinkingStreakStart == null || session.thinkingLastOutput == null || now - session.thinkingLastOutput > GAP_MS;
|
|
20550
|
-
if (stale) session.thinkingStreakStart = now;
|
|
20551
|
-
session.thinkingLastOutput = now;
|
|
20552
|
-
if (now - (session.thinkingStreakStart ?? now) < ACTIVATE_MS) return;
|
|
20553
|
-
session.thinkingStreakStart = void 0;
|
|
20554
|
-
session.thinkingLastOutput = void 0;
|
|
20555
|
-
daemonLog(`session ${session.id} sustained output while waiting -> running`);
|
|
20556
|
-
onStatusChange(session, "running");
|
|
20557
|
-
}
|
|
20558
|
-
|
|
20559
20573
|
// src/commands/sessions/daemon/wirePtyEvents.ts
|
|
20560
20574
|
var MAX_SCROLLBACK = 256 * 1024;
|
|
20561
20575
|
function appendScrollback(session, data) {
|
|
@@ -20569,7 +20583,6 @@ function wirePtyEvents(session, clients, onStatusChange) {
|
|
|
20569
20583
|
session.pty.onData((data) => {
|
|
20570
20584
|
appendScrollback(session, data);
|
|
20571
20585
|
noteOutputForEscInterrupt(session, onStatusChange);
|
|
20572
|
-
noteOutputForThinking(session, onStatusChange);
|
|
20573
20586
|
broadcast(clients, { type: "output", sessionId: session.id, data });
|
|
20574
20587
|
});
|
|
20575
20588
|
session.pty.onExit(({ exitCode }) => {
|
|
@@ -21832,29 +21845,6 @@ function registerDaemon(program2) {
|
|
|
21832
21845
|
).action(restartDaemon);
|
|
21833
21846
|
}
|
|
21834
21847
|
|
|
21835
|
-
// src/commands/sessions/daemon/sendToDaemon.ts
|
|
21836
|
-
async function sendToDaemon(message) {
|
|
21837
|
-
const socket = await connectToDaemon();
|
|
21838
|
-
const timer = setTimeout(() => socket.destroy(), 500);
|
|
21839
|
-
socket.on("error", () => {
|
|
21840
|
-
});
|
|
21841
|
-
socket.write(`${JSON.stringify(message)}
|
|
21842
|
-
`, () => {
|
|
21843
|
-
clearTimeout(timer);
|
|
21844
|
-
socket.end();
|
|
21845
|
-
});
|
|
21846
|
-
}
|
|
21847
|
-
|
|
21848
|
-
// src/commands/sessions/setSessionStatus.ts
|
|
21849
|
-
async function setSessionStatus(status2) {
|
|
21850
|
-
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
21851
|
-
if (!sessionId) return;
|
|
21852
|
-
try {
|
|
21853
|
-
await sendToDaemon({ type: "set-status", sessionId, status: status2 });
|
|
21854
|
-
} catch {
|
|
21855
|
-
}
|
|
21856
|
-
}
|
|
21857
|
-
|
|
21858
21848
|
// src/commands/sessions/summarise/index.ts
|
|
21859
21849
|
import * as fs34 from "fs";
|
|
21860
21850
|
import chalk175 from "chalk";
|