@staff0rd/assist 0.514.2 → 0.516.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/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.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -107,6 +107,7 @@ var package_default = {
|
|
|
107
107
|
jscpd: "^4.0.5",
|
|
108
108
|
jsdom: "^29.1.1",
|
|
109
109
|
knip: "^5.71.0",
|
|
110
|
+
"monaco-editor": "^0.56.0",
|
|
110
111
|
oxfmt: "^0.54.0",
|
|
111
112
|
oxlint: "^1.69.0",
|
|
112
113
|
react: "^19.2.4",
|
|
@@ -1963,9 +1964,6 @@ function stageAndCommit(files, message3) {
|
|
|
1963
1964
|
return commitStaged(message3);
|
|
1964
1965
|
}
|
|
1965
1966
|
|
|
1966
|
-
// src/commands/sessions/summarise/iterateUserMessages.ts
|
|
1967
|
-
import * as fs from "fs";
|
|
1968
|
-
|
|
1969
1967
|
// src/commands/sessions/summarise/parseUserLine.ts
|
|
1970
1968
|
function parseUserLine(line) {
|
|
1971
1969
|
let entry;
|
|
@@ -1991,21 +1989,27 @@ function parseUserLine(line) {
|
|
|
1991
1989
|
};
|
|
1992
1990
|
}
|
|
1993
1991
|
|
|
1994
|
-
// src/commands/sessions/summarise/
|
|
1995
|
-
|
|
1996
|
-
|
|
1992
|
+
// src/commands/sessions/summarise/readTranscriptHead.ts
|
|
1993
|
+
import * as fs from "fs";
|
|
1994
|
+
function readTranscriptHead(filePath, maxBytes = 65536) {
|
|
1997
1995
|
try {
|
|
1998
1996
|
const fd = fs.openSync(filePath, "r");
|
|
1999
1997
|
try {
|
|
2000
1998
|
const buf = Buffer.alloc(maxBytes);
|
|
2001
1999
|
const bytesRead = fs.readSync(fd, buf, 0, buf.length, 0);
|
|
2002
|
-
|
|
2000
|
+
return buf.toString("utf8", 0, bytesRead);
|
|
2003
2001
|
} finally {
|
|
2004
2002
|
fs.closeSync(fd);
|
|
2005
2003
|
}
|
|
2006
2004
|
} catch {
|
|
2007
|
-
return;
|
|
2005
|
+
return void 0;
|
|
2008
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;
|
|
2009
2013
|
for (const line of content.split("\n")) {
|
|
2010
2014
|
if (!line) continue;
|
|
2011
2015
|
const entry = parseUserLine(line);
|
|
@@ -12081,6 +12085,19 @@ var routes2 = {
|
|
|
12081
12085
|
"commands/sessions/web/bundle.css",
|
|
12082
12086
|
"text/css"
|
|
12083
12087
|
),
|
|
12088
|
+
"GET /monaco.js": createBundleHandler(
|
|
12089
|
+
import.meta.url,
|
|
12090
|
+
"commands/sessions/web/monaco.js"
|
|
12091
|
+
),
|
|
12092
|
+
"GET /monaco.worker.js": createBundleHandler(
|
|
12093
|
+
import.meta.url,
|
|
12094
|
+
"commands/sessions/web/monaco.worker.js"
|
|
12095
|
+
),
|
|
12096
|
+
"GET /monaco.css": createBundleHandler(
|
|
12097
|
+
import.meta.url,
|
|
12098
|
+
"commands/sessions/web/monaco.css",
|
|
12099
|
+
"text/css"
|
|
12100
|
+
),
|
|
12084
12101
|
"GET /api/items": listItems,
|
|
12085
12102
|
"GET /api/backlog/summary": getBacklogSummary,
|
|
12086
12103
|
"POST /api/open-in-code": openInCode,
|
|
@@ -30315,9 +30332,17 @@ var ISSUE_KEY = /^[A-Z][A-Z0-9]+-\d+$/;
|
|
|
30315
30332
|
var HASH_NUMBER = /^#\d+$/;
|
|
30316
30333
|
var ASSIST_ITEM_ID = /^a[0-9a-f]{2,}$/;
|
|
30317
30334
|
function isReferenceOnlyPrompt(prompt) {
|
|
30318
|
-
const tokens = prompt
|
|
30335
|
+
const tokens = tokenise(prompt);
|
|
30336
|
+
if (tokens.length === 0) return false;
|
|
30337
|
+
return tokens.some(isTrackerUrl) || isBareReferencePrompt(prompt);
|
|
30338
|
+
}
|
|
30339
|
+
function isBareReferencePrompt(prompt) {
|
|
30340
|
+
const tokens = tokenise(prompt);
|
|
30319
30341
|
if (tokens.length === 0) return false;
|
|
30320
|
-
return tokens.
|
|
30342
|
+
return tokens.every(isReference);
|
|
30343
|
+
}
|
|
30344
|
+
function tokenise(prompt) {
|
|
30345
|
+
return prompt.trim().split(/\s+/).filter(Boolean);
|
|
30321
30346
|
}
|
|
30322
30347
|
function isReference(token) {
|
|
30323
30348
|
return isTrackerUrl(token) || ISSUE_KEY.test(token) || HASH_NUMBER.test(token) || ASSIST_ITEM_ID.test(token);
|
|
@@ -30889,6 +30914,88 @@ async function reconcileTranscriptStatus(session, onStatusChange) {
|
|
|
30889
30914
|
onStatusChange(session, derived);
|
|
30890
30915
|
}
|
|
30891
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
|
+
|
|
30892
30999
|
// src/commands/sessions/summarise/extractFirstUserMessage.ts
|
|
30893
31000
|
function extractFirstUserMessage(filePath) {
|
|
30894
31001
|
for (const text17 of iterateUserMessages(filePath)) {
|
|
@@ -30904,17 +31011,25 @@ function truncate3(text17, maxChars = 500) {
|
|
|
30904
31011
|
|
|
30905
31012
|
// src/commands/sessions/daemon/startTranscriptTitleGeneration.ts
|
|
30906
31013
|
function startTranscriptTitleGeneration(session, notify2) {
|
|
30907
|
-
if (session.commandType !== "claude") return;
|
|
30908
31014
|
if (session.generatedTitle || session.titleGenerationStarted) return;
|
|
30909
|
-
|
|
31015
|
+
const source = titleSource(session);
|
|
31016
|
+
if (!source) return;
|
|
30910
31017
|
const filePath = transcriptPath(session);
|
|
30911
31018
|
if (!filePath) return;
|
|
30912
|
-
const
|
|
30913
|
-
if (!
|
|
31019
|
+
const context = source === "after-reference" ? extractContextAfterReference(filePath) : extractFirstUserMessage(filePath);
|
|
31020
|
+
if (!context) return;
|
|
30914
31021
|
daemonLog(
|
|
30915
|
-
`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`
|
|
30916
31023
|
);
|
|
30917
|
-
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";
|
|
30918
31033
|
}
|
|
30919
31034
|
function transcriptPath(session) {
|
|
30920
31035
|
if (session.transcriptPath) return session.transcriptPath;
|
|
@@ -33394,53 +33509,6 @@ function handleSetStatus(client, m, d) {
|
|
|
33394
33509
|
|
|
33395
33510
|
// src/commands/sessions/shared/parseTranscript.ts
|
|
33396
33511
|
import * as fs39 from "fs";
|
|
33397
|
-
|
|
33398
|
-
// src/commands/sessions/shared/toolTarget.ts
|
|
33399
|
-
function toolTarget(input) {
|
|
33400
|
-
if (!input || typeof input !== "object") return "";
|
|
33401
|
-
const i = input;
|
|
33402
|
-
const str = (v) => typeof v === "string" ? v : "";
|
|
33403
|
-
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);
|
|
33404
|
-
return target.replace(/\s+/g, " ").trim().slice(0, 120);
|
|
33405
|
-
}
|
|
33406
|
-
|
|
33407
|
-
// src/commands/sessions/shared/entryMessages.ts
|
|
33408
|
-
function entryMessages(entry) {
|
|
33409
|
-
const content = entry.message?.content;
|
|
33410
|
-
if (entry.type === "user") return userMessages(content);
|
|
33411
|
-
if (entry.type === "assistant") return assistantMessages(content);
|
|
33412
|
-
return [];
|
|
33413
|
-
}
|
|
33414
|
-
function userMessages(content) {
|
|
33415
|
-
if (typeof content === "string") return text16("user", cleanUserText(content));
|
|
33416
|
-
if (!Array.isArray(content)) return [];
|
|
33417
|
-
return content.filter((c) => c.type === "text").flatMap((c) => text16("user", cleanUserText(c.text ?? "")));
|
|
33418
|
-
}
|
|
33419
|
-
function assistantMessages(content) {
|
|
33420
|
-
if (typeof content === "string") return text16("assistant", content.trim());
|
|
33421
|
-
if (!Array.isArray(content)) return [];
|
|
33422
|
-
return content.flatMap((c) => assistantItem(c));
|
|
33423
|
-
}
|
|
33424
|
-
function assistantItem(c) {
|
|
33425
|
-
if (c.type === "text") return text16("assistant", (c.text ?? "").trim());
|
|
33426
|
-
if (c.type === "tool_use")
|
|
33427
|
-
return [
|
|
33428
|
-
{
|
|
33429
|
-
role: "tool",
|
|
33430
|
-
tool: typeof c.name === "string" ? c.name : "tool",
|
|
33431
|
-
target: toolTarget(c.input)
|
|
33432
|
-
}
|
|
33433
|
-
];
|
|
33434
|
-
return [];
|
|
33435
|
-
}
|
|
33436
|
-
function text16(role, value) {
|
|
33437
|
-
return value ? [{ role, text: value }] : [];
|
|
33438
|
-
}
|
|
33439
|
-
function cleanUserText(value) {
|
|
33440
|
-
return value.replace(/<command-[^>]*>[\s\S]*?<\/command-[^>]*>/g, "").replace(/<local-command-[^>]*>[\s\S]*?<\/local-command-[^>]*>/g, "").trim();
|
|
33441
|
-
}
|
|
33442
|
-
|
|
33443
|
-
// src/commands/sessions/shared/parseTranscript.ts
|
|
33444
33512
|
async function parseTranscript(sessionId) {
|
|
33445
33513
|
const filePath = await findSessionJsonlPath(sessionId);
|
|
33446
33514
|
if (!filePath) return [];
|
|
@@ -33966,6 +34034,13 @@ import chalk213 from "chalk";
|
|
|
33966
34034
|
// src/shared/rateLimitLevel.ts
|
|
33967
34035
|
var FIVE_HOUR_SECONDS = 5 * 3600;
|
|
33968
34036
|
var SEVEN_DAY_SECONDS = 7 * 86400;
|
|
34037
|
+
function rateLimitElapsedFraction(resetsAt, windowSeconds, now) {
|
|
34038
|
+
if (resetsAt == null) return void 0;
|
|
34039
|
+
const timeRemaining = Math.max(0, resetsAt - now);
|
|
34040
|
+
const elapsed = Math.max(0, windowSeconds - timeRemaining) / windowSeconds;
|
|
34041
|
+
if (elapsed < 0.05) return void 0;
|
|
34042
|
+
return elapsed;
|
|
34043
|
+
}
|
|
33969
34044
|
function formatRateLimitTimeLeft(resetsAt, now) {
|
|
33970
34045
|
const seconds = Math.max(0, resetsAt - now);
|
|
33971
34046
|
const days = Math.floor(seconds / 86400);
|
|
@@ -33976,10 +34051,8 @@ function formatRateLimitTimeLeft(resetsAt, now) {
|
|
|
33976
34051
|
return `${minutes}m`;
|
|
33977
34052
|
}
|
|
33978
34053
|
function projectUsage(pct, resetsAt, windowSeconds, now) {
|
|
33979
|
-
|
|
33980
|
-
|
|
33981
|
-
const elapsed = Math.max(0, windowSeconds - timeRemaining) / windowSeconds;
|
|
33982
|
-
if (elapsed < 0.05) return void 0;
|
|
34054
|
+
const elapsed = rateLimitElapsedFraction(resetsAt, windowSeconds, now);
|
|
34055
|
+
if (elapsed == null) return void 0;
|
|
33983
34056
|
return pct / elapsed;
|
|
33984
34057
|
}
|
|
33985
34058
|
function rateLimitLevel(pct, resetsAt, windowSeconds, now) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@staff0rd/assist",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.516.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -101,6 +101,7 @@
|
|
|
101
101
|
"jscpd": "^4.0.5",
|
|
102
102
|
"jsdom": "^29.1.1",
|
|
103
103
|
"knip": "^5.71.0",
|
|
104
|
+
"monaco-editor": "^0.56.0",
|
|
104
105
|
"oxfmt": "^0.54.0",
|
|
105
106
|
"oxlint": "^1.69.0",
|
|
106
107
|
"react": "^19.2.4",
|