@staff0rd/assist 0.515.0 → 0.516.1
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/commands/sessions/web/bundle.js +351 -351
- package/dist/index.js +118 -64
- 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.
|
|
9
|
+
version: "0.516.1",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -1964,9 +1964,6 @@ function stageAndCommit(files, message3) {
|
|
|
1964
1964
|
return commitStaged(message3);
|
|
1965
1965
|
}
|
|
1966
1966
|
|
|
1967
|
-
// src/commands/sessions/summarise/iterateUserMessages.ts
|
|
1968
|
-
import * as fs from "fs";
|
|
1969
|
-
|
|
1970
1967
|
// src/commands/sessions/summarise/parseUserLine.ts
|
|
1971
1968
|
function parseUserLine(line) {
|
|
1972
1969
|
let entry;
|
|
@@ -1992,21 +1989,27 @@ function parseUserLine(line) {
|
|
|
1992
1989
|
};
|
|
1993
1990
|
}
|
|
1994
1991
|
|
|
1995
|
-
// src/commands/sessions/summarise/
|
|
1996
|
-
|
|
1997
|
-
|
|
1992
|
+
// src/commands/sessions/summarise/readTranscriptHead.ts
|
|
1993
|
+
import * as fs from "fs";
|
|
1994
|
+
function readTranscriptHead(filePath, maxBytes = 65536) {
|
|
1998
1995
|
try {
|
|
1999
1996
|
const fd = fs.openSync(filePath, "r");
|
|
2000
1997
|
try {
|
|
2001
1998
|
const buf = Buffer.alloc(maxBytes);
|
|
2002
1999
|
const bytesRead = fs.readSync(fd, buf, 0, buf.length, 0);
|
|
2003
|
-
|
|
2000
|
+
return buf.toString("utf8", 0, bytesRead);
|
|
2004
2001
|
} finally {
|
|
2005
2002
|
fs.closeSync(fd);
|
|
2006
2003
|
}
|
|
2007
2004
|
} catch {
|
|
2008
|
-
return;
|
|
2005
|
+
return void 0;
|
|
2009
2006
|
}
|
|
2007
|
+
}
|
|
2008
|
+
|
|
2009
|
+
// src/commands/sessions/summarise/iterateUserMessages.ts
|
|
2010
|
+
function* iterateUserMessages(filePath, maxBytes = 65536) {
|
|
2011
|
+
const content = readTranscriptHead(filePath, maxBytes);
|
|
2012
|
+
if (content === void 0) return;
|
|
2010
2013
|
for (const line of content.split("\n")) {
|
|
2011
2014
|
if (!line) continue;
|
|
2012
2015
|
const entry = parseUserLine(line);
|
|
@@ -30329,9 +30332,17 @@ var ISSUE_KEY = /^[A-Z][A-Z0-9]+-\d+$/;
|
|
|
30329
30332
|
var HASH_NUMBER = /^#\d+$/;
|
|
30330
30333
|
var ASSIST_ITEM_ID = /^a[0-9a-f]{2,}$/;
|
|
30331
30334
|
function isReferenceOnlyPrompt(prompt) {
|
|
30332
|
-
const tokens = prompt
|
|
30335
|
+
const tokens = tokenise(prompt);
|
|
30333
30336
|
if (tokens.length === 0) return false;
|
|
30334
|
-
return tokens.some(isTrackerUrl) ||
|
|
30337
|
+
return tokens.some(isTrackerUrl) || isBareReferencePrompt(prompt);
|
|
30338
|
+
}
|
|
30339
|
+
function isBareReferencePrompt(prompt) {
|
|
30340
|
+
const tokens = tokenise(prompt);
|
|
30341
|
+
if (tokens.length === 0) return false;
|
|
30342
|
+
return tokens.every(isReference);
|
|
30343
|
+
}
|
|
30344
|
+
function tokenise(prompt) {
|
|
30345
|
+
return prompt.trim().split(/\s+/).filter(Boolean);
|
|
30335
30346
|
}
|
|
30336
30347
|
function isReference(token) {
|
|
30337
30348
|
return isTrackerUrl(token) || ISSUE_KEY.test(token) || HASH_NUMBER.test(token) || ASSIST_ITEM_ID.test(token);
|
|
@@ -30903,6 +30914,88 @@ async function reconcileTranscriptStatus(session, onStatusChange) {
|
|
|
30903
30914
|
onStatusChange(session, derived);
|
|
30904
30915
|
}
|
|
30905
30916
|
|
|
30917
|
+
// src/commands/sessions/shared/toolTarget.ts
|
|
30918
|
+
function toolTarget(input) {
|
|
30919
|
+
if (!input || typeof input !== "object") return "";
|
|
30920
|
+
const i = input;
|
|
30921
|
+
const str = (v) => typeof v === "string" ? v : "";
|
|
30922
|
+
const target = str(i.file_path) || str(i.path) || str(i.notebook_path) || str(i.command) || str(i.pattern) || str(i.url) || str(i.query) || str(i.description) || str(i.prompt);
|
|
30923
|
+
return target.replace(/\s+/g, " ").trim().slice(0, 120);
|
|
30924
|
+
}
|
|
30925
|
+
|
|
30926
|
+
// src/commands/sessions/shared/entryMessages.ts
|
|
30927
|
+
function entryMessages(entry) {
|
|
30928
|
+
const content = entry.message?.content;
|
|
30929
|
+
if (entry.type === "user") return userMessages(content);
|
|
30930
|
+
if (entry.type === "assistant") return assistantMessages(content);
|
|
30931
|
+
return [];
|
|
30932
|
+
}
|
|
30933
|
+
function userMessages(content) {
|
|
30934
|
+
if (typeof content === "string") return text16("user", cleanUserText(content));
|
|
30935
|
+
if (!Array.isArray(content)) return [];
|
|
30936
|
+
return content.filter((c) => c.type === "text").flatMap((c) => text16("user", cleanUserText(c.text ?? "")));
|
|
30937
|
+
}
|
|
30938
|
+
function assistantMessages(content) {
|
|
30939
|
+
if (typeof content === "string") return text16("assistant", content.trim());
|
|
30940
|
+
if (!Array.isArray(content)) return [];
|
|
30941
|
+
return content.flatMap((c) => assistantItem(c));
|
|
30942
|
+
}
|
|
30943
|
+
function assistantItem(c) {
|
|
30944
|
+
if (c.type === "text") return text16("assistant", (c.text ?? "").trim());
|
|
30945
|
+
if (c.type === "tool_use")
|
|
30946
|
+
return [
|
|
30947
|
+
{
|
|
30948
|
+
role: "tool",
|
|
30949
|
+
tool: typeof c.name === "string" ? c.name : "tool",
|
|
30950
|
+
target: toolTarget(c.input)
|
|
30951
|
+
}
|
|
30952
|
+
];
|
|
30953
|
+
return [];
|
|
30954
|
+
}
|
|
30955
|
+
function text16(role, value) {
|
|
30956
|
+
return value ? [{ role, text: value }] : [];
|
|
30957
|
+
}
|
|
30958
|
+
function cleanUserText(value) {
|
|
30959
|
+
return value.replace(/<command-[^>]*>[\s\S]*?<\/command-[^>]*>/g, "").replace(/<local-command-[^>]*>[\s\S]*?<\/local-command-[^>]*>/g, "").trim();
|
|
30960
|
+
}
|
|
30961
|
+
|
|
30962
|
+
// src/commands/sessions/summarise/extractContextAfterReference.ts
|
|
30963
|
+
var MIN_CONTEXT_CHARS = 120;
|
|
30964
|
+
var MAX_CONTEXT_CHARS = 800;
|
|
30965
|
+
function extractContextAfterReference(filePath) {
|
|
30966
|
+
const head = readTranscriptHead(filePath);
|
|
30967
|
+
if (head === void 0) return void 0;
|
|
30968
|
+
const parts = [];
|
|
30969
|
+
let length = 0;
|
|
30970
|
+
for (const text17 of conversationText(head)) {
|
|
30971
|
+
if (parts.length === 0 && isBareReferencePrompt(text17)) continue;
|
|
30972
|
+
parts.push(text17);
|
|
30973
|
+
length += text17.length;
|
|
30974
|
+
if (length >= MAX_CONTEXT_CHARS) break;
|
|
30975
|
+
}
|
|
30976
|
+
if (length < MIN_CONTEXT_CHARS) return void 0;
|
|
30977
|
+
return parts.join("\n").slice(0, MAX_CONTEXT_CHARS);
|
|
30978
|
+
}
|
|
30979
|
+
function* conversationText(head) {
|
|
30980
|
+
for (const line of head.split("\n")) {
|
|
30981
|
+
if (!line) continue;
|
|
30982
|
+
const entry = parseEntry(line);
|
|
30983
|
+
if (!entry || entry.isSidechain || entry.isMeta) continue;
|
|
30984
|
+
for (const message3 of entryMessages(entry)) {
|
|
30985
|
+
if (message3.role === "tool") continue;
|
|
30986
|
+
const text17 = message3.text.trim();
|
|
30987
|
+
if (text17) yield text17;
|
|
30988
|
+
}
|
|
30989
|
+
}
|
|
30990
|
+
}
|
|
30991
|
+
function parseEntry(line) {
|
|
30992
|
+
try {
|
|
30993
|
+
return JSON.parse(line);
|
|
30994
|
+
} catch {
|
|
30995
|
+
return void 0;
|
|
30996
|
+
}
|
|
30997
|
+
}
|
|
30998
|
+
|
|
30906
30999
|
// src/commands/sessions/summarise/extractFirstUserMessage.ts
|
|
30907
31000
|
function extractFirstUserMessage(filePath) {
|
|
30908
31001
|
for (const text17 of iterateUserMessages(filePath)) {
|
|
@@ -30918,17 +31011,25 @@ function truncate3(text17, maxChars = 500) {
|
|
|
30918
31011
|
|
|
30919
31012
|
// src/commands/sessions/daemon/startTranscriptTitleGeneration.ts
|
|
30920
31013
|
function startTranscriptTitleGeneration(session, notify2) {
|
|
30921
|
-
if (session.commandType !== "claude") return;
|
|
30922
31014
|
if (session.generatedTitle || session.titleGenerationStarted) return;
|
|
30923
|
-
|
|
31015
|
+
const source = titleSource(session);
|
|
31016
|
+
if (!source) return;
|
|
30924
31017
|
const filePath = transcriptPath(session);
|
|
30925
31018
|
if (!filePath) return;
|
|
30926
|
-
const
|
|
30927
|
-
if (!
|
|
31019
|
+
const context = source === "after-reference" ? extractContextAfterReference(filePath) : extractFirstUserMessage(filePath);
|
|
31020
|
+
if (!context) return;
|
|
30928
31021
|
daemonLog(
|
|
30929
|
-
`session ${session.id} deriving title from first transcript message`
|
|
31022
|
+
source === "after-reference" ? `session ${session.id} deriving title from transcript context after the reference` : `session ${session.id} deriving title from first transcript message`
|
|
30930
31023
|
);
|
|
30931
|
-
runSessionTitleGeneration(session,
|
|
31024
|
+
runSessionTitleGeneration(session, context, notify2);
|
|
31025
|
+
}
|
|
31026
|
+
function titleSource(session) {
|
|
31027
|
+
if (session.commandType === "claude")
|
|
31028
|
+
return session.initialPrompt?.trim() ? void 0 : "first-message";
|
|
31029
|
+
if (session.activity?.itemName) return void 0;
|
|
31030
|
+
const prompt = sessionTitlePrompt(session);
|
|
31031
|
+
if (!prompt || !isReferenceOnlyPrompt(prompt)) return void 0;
|
|
31032
|
+
return "after-reference";
|
|
30932
31033
|
}
|
|
30933
31034
|
function transcriptPath(session) {
|
|
30934
31035
|
if (session.transcriptPath) return session.transcriptPath;
|
|
@@ -33408,53 +33509,6 @@ function handleSetStatus(client, m, d) {
|
|
|
33408
33509
|
|
|
33409
33510
|
// src/commands/sessions/shared/parseTranscript.ts
|
|
33410
33511
|
import * as fs39 from "fs";
|
|
33411
|
-
|
|
33412
|
-
// src/commands/sessions/shared/toolTarget.ts
|
|
33413
|
-
function toolTarget(input) {
|
|
33414
|
-
if (!input || typeof input !== "object") return "";
|
|
33415
|
-
const i = input;
|
|
33416
|
-
const str = (v) => typeof v === "string" ? v : "";
|
|
33417
|
-
const target = str(i.file_path) || str(i.path) || str(i.notebook_path) || str(i.command) || str(i.pattern) || str(i.url) || str(i.query) || str(i.description) || str(i.prompt);
|
|
33418
|
-
return target.replace(/\s+/g, " ").trim().slice(0, 120);
|
|
33419
|
-
}
|
|
33420
|
-
|
|
33421
|
-
// src/commands/sessions/shared/entryMessages.ts
|
|
33422
|
-
function entryMessages(entry) {
|
|
33423
|
-
const content = entry.message?.content;
|
|
33424
|
-
if (entry.type === "user") return userMessages(content);
|
|
33425
|
-
if (entry.type === "assistant") return assistantMessages(content);
|
|
33426
|
-
return [];
|
|
33427
|
-
}
|
|
33428
|
-
function userMessages(content) {
|
|
33429
|
-
if (typeof content === "string") return text16("user", cleanUserText(content));
|
|
33430
|
-
if (!Array.isArray(content)) return [];
|
|
33431
|
-
return content.filter((c) => c.type === "text").flatMap((c) => text16("user", cleanUserText(c.text ?? "")));
|
|
33432
|
-
}
|
|
33433
|
-
function assistantMessages(content) {
|
|
33434
|
-
if (typeof content === "string") return text16("assistant", content.trim());
|
|
33435
|
-
if (!Array.isArray(content)) return [];
|
|
33436
|
-
return content.flatMap((c) => assistantItem(c));
|
|
33437
|
-
}
|
|
33438
|
-
function assistantItem(c) {
|
|
33439
|
-
if (c.type === "text") return text16("assistant", (c.text ?? "").trim());
|
|
33440
|
-
if (c.type === "tool_use")
|
|
33441
|
-
return [
|
|
33442
|
-
{
|
|
33443
|
-
role: "tool",
|
|
33444
|
-
tool: typeof c.name === "string" ? c.name : "tool",
|
|
33445
|
-
target: toolTarget(c.input)
|
|
33446
|
-
}
|
|
33447
|
-
];
|
|
33448
|
-
return [];
|
|
33449
|
-
}
|
|
33450
|
-
function text16(role, value) {
|
|
33451
|
-
return value ? [{ role, text: value }] : [];
|
|
33452
|
-
}
|
|
33453
|
-
function cleanUserText(value) {
|
|
33454
|
-
return value.replace(/<command-[^>]*>[\s\S]*?<\/command-[^>]*>/g, "").replace(/<local-command-[^>]*>[\s\S]*?<\/local-command-[^>]*>/g, "").trim();
|
|
33455
|
-
}
|
|
33456
|
-
|
|
33457
|
-
// src/commands/sessions/shared/parseTranscript.ts
|
|
33458
33512
|
async function parseTranscript(sessionId) {
|
|
33459
33513
|
const filePath = await findSessionJsonlPath(sessionId);
|
|
33460
33514
|
if (!filePath) return [];
|