@staff0rd/assist 0.299.0 → 0.300.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/commands/sessions/web/bundle.js +72 -71
- package/dist/index.js +285 -159
- 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.300.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -1074,8 +1074,8 @@ var options = [
|
|
|
1074
1074
|
];
|
|
1075
1075
|
|
|
1076
1076
|
// src/commands/verify/init/getAvailableOptions/index.ts
|
|
1077
|
-
function resolveDescription(
|
|
1078
|
-
return typeof
|
|
1077
|
+
function resolveDescription(desc5, setup2) {
|
|
1078
|
+
return typeof desc5 === "function" ? desc5(setup2) : desc5;
|
|
1079
1079
|
}
|
|
1080
1080
|
function toVerifyOption(def, setup2) {
|
|
1081
1081
|
return {
|
|
@@ -1665,8 +1665,8 @@ var MACHINE_DIRECTIVES = [
|
|
|
1665
1665
|
"v8 ignore",
|
|
1666
1666
|
"c8 ignore"
|
|
1667
1667
|
];
|
|
1668
|
-
function isCommentExempt(
|
|
1669
|
-
const lower =
|
|
1668
|
+
function isCommentExempt(text5, markers) {
|
|
1669
|
+
const lower = text5.toLowerCase();
|
|
1670
1670
|
if (MACHINE_DIRECTIVES.some((d) => lower.includes(d))) return true;
|
|
1671
1671
|
return markers.some((m) => lower.includes(m.toLowerCase()));
|
|
1672
1672
|
}
|
|
@@ -1709,8 +1709,8 @@ function parseDiffAddedLines(diff2) {
|
|
|
1709
1709
|
|
|
1710
1710
|
// src/commands/verify/commentPolicy/findAddedComments.ts
|
|
1711
1711
|
var SOURCE_EXTENSIONS = [".ts", ".tsx", ".cts", ".mts", ".js", ".jsx"];
|
|
1712
|
-
function toSingleLine(
|
|
1713
|
-
return
|
|
1712
|
+
function toSingleLine(text5) {
|
|
1713
|
+
return text5.replace(/\s+/g, " ").trim();
|
|
1714
1714
|
}
|
|
1715
1715
|
function shouldScan(file, ignoreGlobs) {
|
|
1716
1716
|
if (!SOURCE_EXTENSIONS.some((ext) => file.endsWith(ext))) return false;
|
|
@@ -1731,11 +1731,11 @@ function findAddedComments(options2) {
|
|
|
1731
1731
|
for (const [file, lines] of addedLines) {
|
|
1732
1732
|
if (!shouldScan(file, options2.ignoreGlobs)) continue;
|
|
1733
1733
|
const sourceFile = project.addSourceFileAtPath(file);
|
|
1734
|
-
for (const { pos, text:
|
|
1734
|
+
for (const { pos, text: text5 } of collectComments(sourceFile)) {
|
|
1735
1735
|
const { line } = sourceFile.getLineAndColumnAtPos(pos);
|
|
1736
1736
|
if (!lines.has(line)) continue;
|
|
1737
|
-
if (isCommentExempt(
|
|
1738
|
-
findings.push({ file, line, text: toSingleLine(
|
|
1737
|
+
if (isCommentExempt(text5, options2.markers)) continue;
|
|
1738
|
+
findings.push({ file, line, text: toSingleLine(text5) });
|
|
1739
1739
|
}
|
|
1740
1740
|
}
|
|
1741
1741
|
findings.sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);
|
|
@@ -1754,8 +1754,8 @@ function commentPolicy() {
|
|
|
1754
1754
|
process.exit(0);
|
|
1755
1755
|
}
|
|
1756
1756
|
console.log("Comments added on changed lines:\n");
|
|
1757
|
-
for (const { file, line, text:
|
|
1758
|
-
console.log(`${file}:${line} \u2192 ${
|
|
1757
|
+
for (const { file, line, text: text5 } of findings) {
|
|
1758
|
+
console.log(`${file}:${line} \u2192 ${text5}`);
|
|
1759
1759
|
}
|
|
1760
1760
|
console.log(`
|
|
1761
1761
|
Total: ${findings.length} comment(s)`);
|
|
@@ -2865,9 +2865,9 @@ import {
|
|
|
2865
2865
|
foreignKey,
|
|
2866
2866
|
index as index2,
|
|
2867
2867
|
integer as integer2,
|
|
2868
|
-
pgTable as
|
|
2869
|
-
primaryKey,
|
|
2870
|
-
text as
|
|
2868
|
+
pgTable as pgTable3,
|
|
2869
|
+
primaryKey as primaryKey2,
|
|
2870
|
+
text as text3
|
|
2871
2871
|
} from "drizzle-orm/pg-core";
|
|
2872
2872
|
|
|
2873
2873
|
// src/shared/db/handovers.ts
|
|
@@ -2885,73 +2885,91 @@ var handovers = pgTable(
|
|
|
2885
2885
|
(t) => [index("handovers_origin_idx").on(t.origin)]
|
|
2886
2886
|
);
|
|
2887
2887
|
|
|
2888
|
+
// src/shared/db/usagePeaks.ts
|
|
2889
|
+
import {
|
|
2890
|
+
bigint,
|
|
2891
|
+
doublePrecision,
|
|
2892
|
+
pgTable as pgTable2,
|
|
2893
|
+
primaryKey,
|
|
2894
|
+
text as text2
|
|
2895
|
+
} from "drizzle-orm/pg-core";
|
|
2896
|
+
var usagePeaks = pgTable2(
|
|
2897
|
+
"usage_peaks",
|
|
2898
|
+
{
|
|
2899
|
+
window: text2().$type().notNull(),
|
|
2900
|
+
resetsAt: bigint("resets_at", { mode: "number" }).notNull(),
|
|
2901
|
+
usedPercentage: doublePrecision("used_percentage").notNull()
|
|
2902
|
+
},
|
|
2903
|
+
(t) => [primaryKey({ columns: [t.window, t.resetsAt] })]
|
|
2904
|
+
);
|
|
2905
|
+
|
|
2888
2906
|
// src/shared/db/schema.ts
|
|
2889
|
-
var items =
|
|
2907
|
+
var items = pgTable3(
|
|
2890
2908
|
"items",
|
|
2891
2909
|
{
|
|
2892
2910
|
id: integer2().generatedByDefaultAsIdentity().primaryKey(),
|
|
2893
|
-
origin:
|
|
2894
|
-
type:
|
|
2895
|
-
name:
|
|
2896
|
-
description:
|
|
2897
|
-
acceptanceCriteria:
|
|
2898
|
-
status:
|
|
2911
|
+
origin: text3().notNull(),
|
|
2912
|
+
type: text3().notNull().default("story"),
|
|
2913
|
+
name: text3().notNull(),
|
|
2914
|
+
description: text3(),
|
|
2915
|
+
acceptanceCriteria: text3("acceptance_criteria").notNull().default("[]"),
|
|
2916
|
+
status: text3().notNull().default("todo"),
|
|
2899
2917
|
currentPhase: integer2("current_phase"),
|
|
2900
2918
|
starred: boolean().notNull().default(false)
|
|
2901
2919
|
},
|
|
2902
2920
|
(t) => [index2("items_origin_idx").on(t.origin)]
|
|
2903
2921
|
);
|
|
2904
|
-
var comments =
|
|
2922
|
+
var comments = pgTable3("comments", {
|
|
2905
2923
|
id: integer2().generatedByDefaultAsIdentity().primaryKey(),
|
|
2906
2924
|
itemId: integer2("item_id").notNull().references(() => items.id, { onDelete: "cascade" }),
|
|
2907
2925
|
idx: integer2().notNull(),
|
|
2908
|
-
text:
|
|
2926
|
+
text: text3().notNull(),
|
|
2909
2927
|
phase: integer2(),
|
|
2910
|
-
timestamp:
|
|
2911
|
-
type:
|
|
2928
|
+
timestamp: text3().notNull(),
|
|
2929
|
+
type: text3().notNull().default("comment")
|
|
2912
2930
|
});
|
|
2913
|
-
var links =
|
|
2931
|
+
var links = pgTable3(
|
|
2914
2932
|
"links",
|
|
2915
2933
|
{
|
|
2916
2934
|
itemId: integer2("item_id").notNull().references(() => items.id, { onDelete: "cascade" }),
|
|
2917
|
-
type:
|
|
2935
|
+
type: text3().notNull(),
|
|
2918
2936
|
targetId: integer2("target_id").notNull()
|
|
2919
2937
|
},
|
|
2920
|
-
(t) => [
|
|
2938
|
+
(t) => [primaryKey2({ columns: [t.itemId, t.type, t.targetId] })]
|
|
2921
2939
|
);
|
|
2922
|
-
var planPhases =
|
|
2940
|
+
var planPhases = pgTable3(
|
|
2923
2941
|
"plan_phases",
|
|
2924
2942
|
{
|
|
2925
2943
|
itemId: integer2("item_id").notNull().references(() => items.id, { onDelete: "cascade" }),
|
|
2926
2944
|
idx: integer2().notNull(),
|
|
2927
|
-
name:
|
|
2928
|
-
manualChecks:
|
|
2945
|
+
name: text3().notNull(),
|
|
2946
|
+
manualChecks: text3("manual_checks")
|
|
2929
2947
|
},
|
|
2930
|
-
(t) => [
|
|
2948
|
+
(t) => [primaryKey2({ columns: [t.itemId, t.idx] })]
|
|
2931
2949
|
);
|
|
2932
|
-
var planTasks =
|
|
2950
|
+
var planTasks = pgTable3(
|
|
2933
2951
|
"plan_tasks",
|
|
2934
2952
|
{
|
|
2935
2953
|
itemId: integer2("item_id").notNull(),
|
|
2936
2954
|
phaseIdx: integer2("phase_idx").notNull(),
|
|
2937
2955
|
idx: integer2().notNull(),
|
|
2938
|
-
task:
|
|
2956
|
+
task: text3().notNull()
|
|
2939
2957
|
},
|
|
2940
2958
|
(t) => [
|
|
2941
|
-
|
|
2959
|
+
primaryKey2({ columns: [t.itemId, t.phaseIdx, t.idx] }),
|
|
2942
2960
|
foreignKey({
|
|
2943
2961
|
columns: [t.itemId, t.phaseIdx],
|
|
2944
2962
|
foreignColumns: [planPhases.itemId, planPhases.idx]
|
|
2945
2963
|
}).onDelete("cascade")
|
|
2946
2964
|
]
|
|
2947
2965
|
);
|
|
2948
|
-
var metadata =
|
|
2949
|
-
key:
|
|
2950
|
-
value:
|
|
2966
|
+
var metadata = pgTable3("metadata", {
|
|
2967
|
+
key: text3().primaryKey(),
|
|
2968
|
+
value: text3().notNull()
|
|
2951
2969
|
});
|
|
2952
|
-
var feeds =
|
|
2970
|
+
var feeds = pgTable3("feeds", {
|
|
2953
2971
|
id: integer2().generatedByDefaultAsIdentity().primaryKey(),
|
|
2954
|
-
url:
|
|
2972
|
+
url: text3().notNull().unique()
|
|
2955
2973
|
});
|
|
2956
2974
|
var schema = {
|
|
2957
2975
|
items,
|
|
@@ -2961,7 +2979,8 @@ var schema = {
|
|
|
2961
2979
|
planTasks,
|
|
2962
2980
|
metadata,
|
|
2963
2981
|
feeds,
|
|
2964
|
-
handovers
|
|
2982
|
+
handovers,
|
|
2983
|
+
usagePeaks
|
|
2965
2984
|
};
|
|
2966
2985
|
|
|
2967
2986
|
// src/commands/backlog/itemColumns.ts
|
|
@@ -3402,6 +3421,13 @@ var SCHEMA = `
|
|
|
3402
3421
|
);
|
|
3403
3422
|
|
|
3404
3423
|
CREATE INDEX IF NOT EXISTS handovers_origin_idx ON handovers (origin);
|
|
3424
|
+
|
|
3425
|
+
CREATE TABLE IF NOT EXISTS usage_peaks (
|
|
3426
|
+
"window" TEXT NOT NULL,
|
|
3427
|
+
resets_at BIGINT NOT NULL,
|
|
3428
|
+
used_percentage DOUBLE PRECISION NOT NULL,
|
|
3429
|
+
PRIMARY KEY ("window", resets_at)
|
|
3430
|
+
);
|
|
3405
3431
|
`;
|
|
3406
3432
|
async function ensureSchema(exec3) {
|
|
3407
3433
|
await exec3(SCHEMA);
|
|
@@ -3449,7 +3475,7 @@ function getDb() {
|
|
|
3449
3475
|
);
|
|
3450
3476
|
});
|
|
3451
3477
|
_pool = pool;
|
|
3452
|
-
await ensureSchema((
|
|
3478
|
+
await ensureSchema((sql6) => pool.query(sql6));
|
|
3453
3479
|
_orm = makeOrmFromPool(pool);
|
|
3454
3480
|
await seedNewsFeeds(_orm);
|
|
3455
3481
|
return _orm;
|
|
@@ -4217,11 +4243,11 @@ import chalk37 from "chalk";
|
|
|
4217
4243
|
|
|
4218
4244
|
// src/commands/backlog/appendComment.ts
|
|
4219
4245
|
import { sql as sql2 } from "drizzle-orm";
|
|
4220
|
-
async function appendComment(orm, itemId,
|
|
4246
|
+
async function appendComment(orm, itemId, text5, opts = {}) {
|
|
4221
4247
|
await orm.insert(comments).values({
|
|
4222
4248
|
itemId,
|
|
4223
4249
|
idx: sql2`(SELECT COALESCE(MAX(${comments.idx}) + 1, 0) FROM ${comments} WHERE ${comments.itemId} = ${itemId})`,
|
|
4224
|
-
text:
|
|
4250
|
+
text: text5,
|
|
4225
4251
|
phase: opts.phase ?? null,
|
|
4226
4252
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4227
4253
|
type: opts.type ?? "comment"
|
|
@@ -5234,9 +5260,9 @@ function excerpt(xml, ...tags) {
|
|
|
5234
5260
|
for (const tag of tags) {
|
|
5235
5261
|
const raw = extractText(xml, tag);
|
|
5236
5262
|
if (!raw) continue;
|
|
5237
|
-
const
|
|
5238
|
-
if (
|
|
5239
|
-
return `${
|
|
5263
|
+
const text5 = stripHtml(raw);
|
|
5264
|
+
if (text5.length <= MAX_EXCERPT) return text5;
|
|
5265
|
+
return `${text5.slice(0, MAX_EXCERPT)}\u2026`;
|
|
5240
5266
|
}
|
|
5241
5267
|
return "";
|
|
5242
5268
|
}
|
|
@@ -5313,6 +5339,17 @@ async function listNewsItems(_req, res) {
|
|
|
5313
5339
|
respondJson(res, 200, cachedItems);
|
|
5314
5340
|
}
|
|
5315
5341
|
|
|
5342
|
+
// src/shared/db/listUsagePeaks.ts
|
|
5343
|
+
import { desc } from "drizzle-orm";
|
|
5344
|
+
async function listUsagePeaks(db) {
|
|
5345
|
+
return db.select().from(usagePeaks).orderBy(desc(usagePeaks.resetsAt), usagePeaks.window);
|
|
5346
|
+
}
|
|
5347
|
+
|
|
5348
|
+
// src/commands/sessions/web/listUsageHistory.ts
|
|
5349
|
+
async function listUsageHistory(_req, res) {
|
|
5350
|
+
respondJson(res, 200, await listUsagePeaks(await getDb()));
|
|
5351
|
+
}
|
|
5352
|
+
|
|
5316
5353
|
// src/commands/sessions/web/openInCode.ts
|
|
5317
5354
|
import { exec } from "child_process";
|
|
5318
5355
|
import { promisify as promisify2 } from "util";
|
|
@@ -5462,7 +5499,8 @@ var routes2 = {
|
|
|
5462
5499
|
"POST /api/restart": restartWeb,
|
|
5463
5500
|
"GET /api/github-url": githubUrl,
|
|
5464
5501
|
"GET /api/git-status": gitStatus,
|
|
5465
|
-
"GET /api/news/items": listNewsItems
|
|
5502
|
+
"GET /api/news/items": listNewsItems,
|
|
5503
|
+
"GET /api/usage/history": listUsageHistory
|
|
5466
5504
|
};
|
|
5467
5505
|
var handleRequest = createFallbackHandler(
|
|
5468
5506
|
routes2,
|
|
@@ -5877,10 +5915,10 @@ async function web2(options2) {
|
|
|
5877
5915
|
|
|
5878
5916
|
// src/commands/backlog/comment/index.ts
|
|
5879
5917
|
import chalk48 from "chalk";
|
|
5880
|
-
async function comment(id2,
|
|
5918
|
+
async function comment(id2, text5) {
|
|
5881
5919
|
const found = await findOneItem(id2);
|
|
5882
5920
|
if (!found) process.exit(1);
|
|
5883
|
-
await appendComment(found.orm, found.item.id,
|
|
5921
|
+
await appendComment(found.orm, found.item.id, text5);
|
|
5884
5922
|
console.log(chalk48.green(`Comment added to item #${id2}.`));
|
|
5885
5923
|
}
|
|
5886
5924
|
|
|
@@ -5993,8 +6031,8 @@ async function buildDump(copyOut) {
|
|
|
5993
6031
|
// src/commands/backlog/dump/copyTableOut.ts
|
|
5994
6032
|
import { to as copyTo } from "pg-copy-streams";
|
|
5995
6033
|
async function copyTableOut(client, table) {
|
|
5996
|
-
const
|
|
5997
|
-
const stream = client.query(copyTo(
|
|
6034
|
+
const sql6 = `COPY ${table.name} (${table.columns.join(", ")}) TO STDOUT`;
|
|
6035
|
+
const stream = client.query(copyTo(sql6));
|
|
5998
6036
|
const chunks = [];
|
|
5999
6037
|
for await (const chunk of stream) {
|
|
6000
6038
|
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
@@ -6050,9 +6088,9 @@ function readLine(dump, start3) {
|
|
|
6050
6088
|
return { text: dump.subarray(start3, eol).toString("utf8"), next: eol + 1 };
|
|
6051
6089
|
}
|
|
6052
6090
|
function parseHeader(dump) {
|
|
6053
|
-
const { text:
|
|
6091
|
+
const { text: text5, next: next3 } = readLine(dump, 0);
|
|
6054
6092
|
try {
|
|
6055
|
-
return { header: JSON.parse(
|
|
6093
|
+
return { header: JSON.parse(text5), bodyStart: next3 };
|
|
6056
6094
|
} catch {
|
|
6057
6095
|
return invalid("header is not valid JSON.");
|
|
6058
6096
|
}
|
|
@@ -6061,9 +6099,9 @@ function parseSections(dump, bodyStart) {
|
|
|
6061
6099
|
const sections = /* @__PURE__ */ new Map();
|
|
6062
6100
|
let cursor = bodyStart;
|
|
6063
6101
|
while (cursor < dump.length) {
|
|
6064
|
-
const { text:
|
|
6065
|
-
const match =
|
|
6066
|
-
if (!match) invalid(`malformed table marker "${
|
|
6102
|
+
const { text: text5, next: next3 } = readLine(dump, cursor);
|
|
6103
|
+
const match = text5.match(/^@table (\S+) (\d+)$/);
|
|
6104
|
+
if (!match) invalid(`malformed table marker "${text5}".`);
|
|
6067
6105
|
const [, name, bytes] = match;
|
|
6068
6106
|
const end = next3 + Number(bytes);
|
|
6069
6107
|
if (end > dump.length) invalid(`section "${name}" overruns the dump.`);
|
|
@@ -6144,8 +6182,8 @@ async function readStdinBuffer() {
|
|
|
6144
6182
|
import { finished } from "stream/promises";
|
|
6145
6183
|
import { from as copyFrom } from "pg-copy-streams";
|
|
6146
6184
|
async function copyTableIn(client, table, data) {
|
|
6147
|
-
const
|
|
6148
|
-
const stream = client.query(copyFrom(
|
|
6185
|
+
const sql6 = `COPY ${table.name} (${table.columns.join(", ")}) FROM STDIN`;
|
|
6186
|
+
const stream = client.query(copyFrom(sql6));
|
|
6149
6187
|
stream.end(data);
|
|
6150
6188
|
await finished(stream);
|
|
6151
6189
|
}
|
|
@@ -6314,9 +6352,9 @@ import chalk56 from "chalk";
|
|
|
6314
6352
|
import { count, eq as eq17 } from "drizzle-orm";
|
|
6315
6353
|
|
|
6316
6354
|
// src/commands/backlog/shiftPhasesUp.ts
|
|
6317
|
-
import { and as and3, desc, eq as eq16, gte } from "drizzle-orm";
|
|
6355
|
+
import { and as and3, desc as desc2, eq as eq16, gte } from "drizzle-orm";
|
|
6318
6356
|
async function shiftPhasesUp(db, itemId, fromIdx) {
|
|
6319
|
-
const toShift = await db.select({ idx: planPhases.idx }).from(planPhases).where(and3(eq16(planPhases.itemId, itemId), gte(planPhases.idx, fromIdx))).orderBy(
|
|
6357
|
+
const toShift = await db.select({ idx: planPhases.idx }).from(planPhases).where(and3(eq16(planPhases.itemId, itemId), gte(planPhases.idx, fromIdx))).orderBy(desc2(planPhases.idx));
|
|
6320
6358
|
for (const p of toShift) {
|
|
6321
6359
|
await db.update(planTasks).set({ phaseIdx: p.idx + 1 }).where(and3(eq16(planTasks.itemId, itemId), eq16(planTasks.phaseIdx, p.idx)));
|
|
6322
6360
|
await db.update(planPhases).set({ idx: p.idx + 1 }).where(and3(eq16(planPhases.itemId, itemId), eq16(planPhases.idx, p.idx)));
|
|
@@ -7191,8 +7229,8 @@ function applyAcMutations(current, options2) {
|
|
|
7191
7229
|
// src/commands/backlog/update/buildUpdateValues.ts
|
|
7192
7230
|
import chalk78 from "chalk";
|
|
7193
7231
|
function buildUpdateValues(options2) {
|
|
7194
|
-
const { name, desc:
|
|
7195
|
-
if (!name && !
|
|
7232
|
+
const { name, desc: desc5, type, ac } = options2;
|
|
7233
|
+
if (!name && !desc5 && !type && !ac) {
|
|
7196
7234
|
console.log(chalk78.red("Nothing to update. Provide at least one flag."));
|
|
7197
7235
|
process.exitCode = 1;
|
|
7198
7236
|
return void 0;
|
|
@@ -7208,8 +7246,8 @@ function buildUpdateValues(options2) {
|
|
|
7208
7246
|
set.name = name;
|
|
7209
7247
|
fieldNames.push("name");
|
|
7210
7248
|
}
|
|
7211
|
-
if (
|
|
7212
|
-
set.description =
|
|
7249
|
+
if (desc5) {
|
|
7250
|
+
set.description = desc5;
|
|
7213
7251
|
fieldNames.push("description");
|
|
7214
7252
|
}
|
|
7215
7253
|
if (type) {
|
|
@@ -8325,8 +8363,8 @@ function formatHuman(cli, commands) {
|
|
|
8325
8363
|
`];
|
|
8326
8364
|
for (const cmd of sorted) {
|
|
8327
8365
|
const full = `${cli} ${cmd.path.join(" ")}`;
|
|
8328
|
-
const
|
|
8329
|
-
lines.push(`${prefix(classifyVerb(cmd.path))}${
|
|
8366
|
+
const text5 = cmd.description ? `${full} \u2014 ${cmd.description}` : full;
|
|
8367
|
+
lines.push(`${prefix(classifyVerb(cmd.path))}${text5}`);
|
|
8330
8368
|
}
|
|
8331
8369
|
return lines.join("\n");
|
|
8332
8370
|
}
|
|
@@ -10722,13 +10760,13 @@ async function load(options2 = {}) {
|
|
|
10722
10760
|
}
|
|
10723
10761
|
|
|
10724
10762
|
// src/commands/handover/listPendingHandovers.ts
|
|
10725
|
-
import { and as and11, desc as
|
|
10763
|
+
import { and as and11, desc as desc3, eq as eq30, isNull as isNull2 } from "drizzle-orm";
|
|
10726
10764
|
async function listPendingHandovers(orm, origin) {
|
|
10727
10765
|
return orm.select({
|
|
10728
10766
|
id: handovers.id,
|
|
10729
10767
|
summary: handovers.summary,
|
|
10730
10768
|
createdAt: handovers.createdAt
|
|
10731
|
-
}).from(handovers).where(and11(eq30(handovers.origin, origin), isNull2(handovers.recalledAt))).orderBy(
|
|
10769
|
+
}).from(handovers).where(and11(eq30(handovers.origin, origin), isNull2(handovers.recalledAt))).orderBy(desc3(handovers.createdAt), desc3(handovers.id));
|
|
10732
10770
|
}
|
|
10733
10771
|
|
|
10734
10772
|
// src/commands/handover/printPendingHandovers.ts
|
|
@@ -10741,7 +10779,7 @@ async function printPendingHandovers() {
|
|
|
10741
10779
|
}
|
|
10742
10780
|
|
|
10743
10781
|
// src/commands/handover/recallHandover.ts
|
|
10744
|
-
import { and as and12, desc as
|
|
10782
|
+
import { and as and12, desc as desc4, eq as eq31, isNull as isNull3 } from "drizzle-orm";
|
|
10745
10783
|
async function recallHandover(orm, origin, id2) {
|
|
10746
10784
|
const [row] = await orm.select().from(handovers).where(
|
|
10747
10785
|
and12(
|
|
@@ -10749,7 +10787,7 @@ async function recallHandover(orm, origin, id2) {
|
|
|
10749
10787
|
isNull3(handovers.recalledAt),
|
|
10750
10788
|
...id2 === void 0 ? [] : [eq31(handovers.id, id2)]
|
|
10751
10789
|
)
|
|
10752
|
-
).orderBy(
|
|
10790
|
+
).orderBy(desc4(handovers.createdAt), desc4(handovers.id)).limit(1);
|
|
10753
10791
|
if (!row) return void 0;
|
|
10754
10792
|
await orm.update(handovers).set({ recalledAt: /* @__PURE__ */ new Date() }).where(eq31(handovers.id, row.id));
|
|
10755
10793
|
return row.content;
|
|
@@ -10805,9 +10843,9 @@ import chalk115 from "chalk";
|
|
|
10805
10843
|
|
|
10806
10844
|
// src/commands/jira/adfToText.ts
|
|
10807
10845
|
function renderInline(node) {
|
|
10808
|
-
const
|
|
10809
|
-
if (node.marks?.some((m) => m.type === "code")) return `\`${
|
|
10810
|
-
return
|
|
10846
|
+
const text5 = node.text ?? "";
|
|
10847
|
+
if (node.marks?.some((m) => m.type === "code")) return `\`${text5}\``;
|
|
10848
|
+
return text5;
|
|
10811
10849
|
}
|
|
10812
10850
|
function renderChildren(node, indent2) {
|
|
10813
10851
|
return renderNodes(node.content ?? [], indent2);
|
|
@@ -10849,8 +10887,8 @@ function isListNode(node) {
|
|
|
10849
10887
|
function renderListChild(child, indent2, pad, marker, isFirst) {
|
|
10850
10888
|
if (isListNode(child)) return renderNodes([child], indent2 + 1);
|
|
10851
10889
|
if (child.type !== "paragraph") return renderNode(child, indent2);
|
|
10852
|
-
const
|
|
10853
|
-
return isFirst ? `${pad}${marker} ${
|
|
10890
|
+
const text5 = renderChildren(child, indent2);
|
|
10891
|
+
return isFirst ? `${pad}${marker} ${text5}` : `${pad} ${text5}`;
|
|
10854
10892
|
}
|
|
10855
10893
|
function renderListItem(node, indent2, marker) {
|
|
10856
10894
|
const pad = " ".repeat(indent2);
|
|
@@ -11540,8 +11578,8 @@ function isWallOfText(lines) {
|
|
|
11540
11578
|
if (lines.some(isListLine)) {
|
|
11541
11579
|
return false;
|
|
11542
11580
|
}
|
|
11543
|
-
const
|
|
11544
|
-
return
|
|
11581
|
+
const text5 = lines.join(" ").trim();
|
|
11582
|
+
return text5.length > MAX_PARAGRAPH_CHARS || countSentences(text5) > MAX_PARAGRAPH_SENTENCES;
|
|
11545
11583
|
}
|
|
11546
11584
|
function validatePrContent(title, body) {
|
|
11547
11585
|
if (title.toLowerCase().includes("claude")) {
|
|
@@ -13202,9 +13240,9 @@ function resolveImports(target, dependencies, sourceFile, statements = []) {
|
|
|
13202
13240
|
function extractTexts(target, allFunctions, statements) {
|
|
13203
13241
|
const stmtTexts = statements.map((v) => v.getFullText().trim());
|
|
13204
13242
|
const fnTexts = allFunctions.map((fn) => {
|
|
13205
|
-
const
|
|
13206
|
-
if (fn === target && !
|
|
13207
|
-
return
|
|
13243
|
+
const text5 = fn.getFullText().trim();
|
|
13244
|
+
if (fn === target && !text5.startsWith("export ")) return `export ${text5}`;
|
|
13245
|
+
return text5;
|
|
13208
13246
|
});
|
|
13209
13247
|
return [...stmtTexts, ...fnTexts];
|
|
13210
13248
|
}
|
|
@@ -15040,9 +15078,9 @@ var MultiSpinner = class {
|
|
|
15040
15078
|
elapsedPrefix: prefix2
|
|
15041
15079
|
});
|
|
15042
15080
|
}
|
|
15043
|
-
failRemaining(
|
|
15081
|
+
failRemaining(text5) {
|
|
15044
15082
|
for (const entry of this.entries) {
|
|
15045
|
-
if (entry.state === "running") this.resolve(entry, "failed",
|
|
15083
|
+
if (entry.state === "running") this.resolve(entry, "failed", text5);
|
|
15046
15084
|
}
|
|
15047
15085
|
}
|
|
15048
15086
|
add(entry) {
|
|
@@ -15055,14 +15093,14 @@ var MultiSpinner = class {
|
|
|
15055
15093
|
set text(value) {
|
|
15056
15094
|
entry.text = value;
|
|
15057
15095
|
},
|
|
15058
|
-
succeed: (
|
|
15059
|
-
fail: (
|
|
15096
|
+
succeed: (text5) => this.resolve(entry, "succeeded", text5),
|
|
15097
|
+
fail: (text5) => this.resolve(entry, "failed", text5)
|
|
15060
15098
|
};
|
|
15061
15099
|
}
|
|
15062
|
-
resolve(entry, state,
|
|
15100
|
+
resolve(entry, state, text5) {
|
|
15063
15101
|
if (entry.state !== "running") return;
|
|
15064
15102
|
entry.state = state;
|
|
15065
|
-
if (
|
|
15103
|
+
if (text5 !== void 0) entry.text = text5;
|
|
15066
15104
|
entry.elapsedStart = void 0;
|
|
15067
15105
|
this.render();
|
|
15068
15106
|
this.maybeFinish();
|
|
@@ -15137,12 +15175,12 @@ function skippedCodexResult(outputPath) {
|
|
|
15137
15175
|
// src/commands/review/formatReviewerFailure.ts
|
|
15138
15176
|
var FAST_FAIL_MS = 1e3;
|
|
15139
15177
|
var STDOUT_TAIL_LINES = 20;
|
|
15140
|
-
function indent(
|
|
15141
|
-
return
|
|
15178
|
+
function indent(text5) {
|
|
15179
|
+
return text5.split(/\r?\n/).map((line) => ` ${line}`);
|
|
15142
15180
|
}
|
|
15143
|
-
function tailLines(
|
|
15144
|
-
const lines =
|
|
15145
|
-
return lines.length <= maxLines ?
|
|
15181
|
+
function tailLines(text5, maxLines) {
|
|
15182
|
+
const lines = text5.split(/\r?\n/);
|
|
15183
|
+
return lines.length <= maxLines ? text5 : lines.slice(-maxLines).join("\n");
|
|
15146
15184
|
}
|
|
15147
15185
|
function isFastFail(input) {
|
|
15148
15186
|
return input.exitCode !== 0 && input.elapsedMs !== void 0 && input.elapsedMs < FAST_FAIL_MS;
|
|
@@ -16062,8 +16100,8 @@ function filterToSql(filter) {
|
|
|
16062
16100
|
// src/commands/seq/fetchSeqData.ts
|
|
16063
16101
|
function buildDataParams(filter, count6, from, to) {
|
|
16064
16102
|
const sqlFilter = filterToSql(filter);
|
|
16065
|
-
const
|
|
16066
|
-
const params = new URLSearchParams({ q:
|
|
16103
|
+
const sql6 = `select @Timestamp, @Level, @Exception, @Message from stream where ${sqlFilter} order by @Timestamp desc limit ${count6}`;
|
|
16104
|
+
const params = new URLSearchParams({ q: sql6 });
|
|
16067
16105
|
if (from) params.set("rangeStartUtc", from);
|
|
16068
16106
|
if (to) params.set("rangeEndUtc", to);
|
|
16069
16107
|
return params;
|
|
@@ -16323,26 +16361,26 @@ import chalk159 from "chalk";
|
|
|
16323
16361
|
// src/commands/sql/loadConnections.ts
|
|
16324
16362
|
function loadConnections3() {
|
|
16325
16363
|
const raw = loadGlobalConfigRaw();
|
|
16326
|
-
const
|
|
16327
|
-
return
|
|
16364
|
+
const sql6 = raw.sql;
|
|
16365
|
+
return sql6?.connections ?? [];
|
|
16328
16366
|
}
|
|
16329
16367
|
function saveConnections3(connections) {
|
|
16330
16368
|
const raw = loadGlobalConfigRaw();
|
|
16331
|
-
const
|
|
16332
|
-
|
|
16333
|
-
raw.sql =
|
|
16369
|
+
const sql6 = raw.sql ?? {};
|
|
16370
|
+
sql6.connections = connections;
|
|
16371
|
+
raw.sql = sql6;
|
|
16334
16372
|
saveGlobalConfig(raw);
|
|
16335
16373
|
}
|
|
16336
16374
|
function getDefaultConnection2() {
|
|
16337
16375
|
const raw = loadGlobalConfigRaw();
|
|
16338
|
-
const
|
|
16339
|
-
return
|
|
16376
|
+
const sql6 = raw.sql;
|
|
16377
|
+
return sql6?.defaultConnection;
|
|
16340
16378
|
}
|
|
16341
16379
|
function setDefaultConnection2(name) {
|
|
16342
16380
|
const raw = loadGlobalConfigRaw();
|
|
16343
|
-
const
|
|
16344
|
-
|
|
16345
|
-
raw.sql =
|
|
16381
|
+
const sql6 = raw.sql ?? {};
|
|
16382
|
+
sql6.defaultConnection = name;
|
|
16383
|
+
raw.sql = sql6;
|
|
16346
16384
|
saveGlobalConfig(raw);
|
|
16347
16385
|
}
|
|
16348
16386
|
|
|
@@ -16478,11 +16516,11 @@ var MUTATION_PATTERN = new RegExp(
|
|
|
16478
16516
|
`\\b(${MUTATION_KEYWORDS.join("|")})\\b`,
|
|
16479
16517
|
"i"
|
|
16480
16518
|
);
|
|
16481
|
-
function stripComments(
|
|
16482
|
-
return
|
|
16519
|
+
function stripComments(sql6) {
|
|
16520
|
+
return sql6.replace(/\/\*[\s\S]*?\*\//g, " ").replace(/--[^\n]*/g, " ");
|
|
16483
16521
|
}
|
|
16484
|
-
function isMutation(
|
|
16485
|
-
const stripped = stripComments(
|
|
16522
|
+
function isMutation(sql6) {
|
|
16523
|
+
const stripped = stripComments(sql6);
|
|
16486
16524
|
if (MUTATION_PATTERN.test(stripped)) return true;
|
|
16487
16525
|
return /\bSELECT\b[\s\S]+\bINTO\s+\w/i.test(stripped);
|
|
16488
16526
|
}
|
|
@@ -16778,8 +16816,8 @@ import { existsSync as existsSync38, mkdirSync as mkdirSync14, readFileSync as r
|
|
|
16778
16816
|
import { basename as basename9, dirname as dirname21, join as join41 } from "path";
|
|
16779
16817
|
|
|
16780
16818
|
// src/commands/transcript/cleanText.ts
|
|
16781
|
-
function cleanText(
|
|
16782
|
-
const words =
|
|
16819
|
+
function cleanText(text5) {
|
|
16820
|
+
const words = text5.split(/\s+/);
|
|
16783
16821
|
const cleaned = [];
|
|
16784
16822
|
for (let i = 0; i < words.length; i++) {
|
|
16785
16823
|
let isRepeat = false;
|
|
@@ -16799,8 +16837,8 @@ function cleanText(text4) {
|
|
|
16799
16837
|
}
|
|
16800
16838
|
|
|
16801
16839
|
// src/commands/transcript/format/processVttFile/parseVtt/deduplicateCues/removeSubstringDuplicates.ts
|
|
16802
|
-
function normalizeText(
|
|
16803
|
-
return
|
|
16840
|
+
function normalizeText(text5) {
|
|
16841
|
+
return text5.toLowerCase().trim();
|
|
16804
16842
|
}
|
|
16805
16843
|
function checkSubstringRelation(textI, textJ) {
|
|
16806
16844
|
if (textI.includes(textJ) && textI.length > textJ.length)
|
|
@@ -16929,13 +16967,13 @@ function parseTimestampLine(line) {
|
|
|
16929
16967
|
return { startMs: parseTimestamp(startStr), endMs: parseTimestamp(endStr) };
|
|
16930
16968
|
}
|
|
16931
16969
|
function buildCue(startMs, endMs, fullText) {
|
|
16932
|
-
const { speaker, text:
|
|
16933
|
-
return
|
|
16970
|
+
const { speaker, text: text5 } = extractSpeaker(fullText);
|
|
16971
|
+
return text5 ? { startMs, endMs, speaker, text: text5 } : null;
|
|
16934
16972
|
}
|
|
16935
16973
|
function parseCueLine(lines, i) {
|
|
16936
16974
|
const { startMs, endMs } = parseTimestampLine(lines[i]);
|
|
16937
|
-
const { text:
|
|
16938
|
-
return { cue: buildCue(startMs, endMs,
|
|
16975
|
+
const { text: text5, nextIndex: nextIndex2 } = collectTextLines(lines, i + 1);
|
|
16976
|
+
return { cue: buildCue(startMs, endMs, text5), nextIndex: nextIndex2 };
|
|
16939
16977
|
}
|
|
16940
16978
|
function isCueSeparator(line) {
|
|
16941
16979
|
return line.trim().includes("-->");
|
|
@@ -17604,8 +17642,8 @@ async function exchangeToken(params) {
|
|
|
17604
17642
|
body: body.toString()
|
|
17605
17643
|
});
|
|
17606
17644
|
if (!response.ok) {
|
|
17607
|
-
const
|
|
17608
|
-
throw new Error(`Token exchange failed (${response.status}): ${
|
|
17645
|
+
const text5 = await response.text();
|
|
17646
|
+
throw new Error(`Token exchange failed (${response.status}): ${text5}`);
|
|
17609
17647
|
}
|
|
17610
17648
|
return response.json();
|
|
17611
17649
|
}
|
|
@@ -18517,6 +18555,7 @@ function toSessionInfo({
|
|
|
18517
18555
|
assistArgs,
|
|
18518
18556
|
cwd,
|
|
18519
18557
|
restored,
|
|
18558
|
+
error,
|
|
18520
18559
|
activity: activity2,
|
|
18521
18560
|
autoRun,
|
|
18522
18561
|
autoAdvance
|
|
@@ -18532,6 +18571,7 @@ function toSessionInfo({
|
|
|
18532
18571
|
assistArgs,
|
|
18533
18572
|
cwd,
|
|
18534
18573
|
restored,
|
|
18574
|
+
error,
|
|
18535
18575
|
activity: activity2,
|
|
18536
18576
|
autoRun,
|
|
18537
18577
|
autoAdvance
|
|
@@ -18549,12 +18589,50 @@ function broadcastSessions(sessions, clients, windowsSessions = [], active) {
|
|
|
18549
18589
|
});
|
|
18550
18590
|
}
|
|
18551
18591
|
|
|
18592
|
+
// src/shared/db/recordUsagePeak.ts
|
|
18593
|
+
import { sql as sql5 } from "drizzle-orm";
|
|
18594
|
+
var WINDOWS = ["five_hour", "seven_day"];
|
|
18595
|
+
async function recordUsagePeak(db, rateLimits) {
|
|
18596
|
+
const rows = WINDOWS.flatMap((window) => {
|
|
18597
|
+
const w = rateLimits[window];
|
|
18598
|
+
if (!w) return [];
|
|
18599
|
+
if (typeof w.resets_at !== "number" || typeof w.used_percentage !== "number")
|
|
18600
|
+
return [];
|
|
18601
|
+
return [
|
|
18602
|
+
{ window, resetsAt: w.resets_at, usedPercentage: w.used_percentage }
|
|
18603
|
+
];
|
|
18604
|
+
});
|
|
18605
|
+
if (rows.length === 0) return;
|
|
18606
|
+
await db.insert(usagePeaks).values(rows).onConflictDoUpdate({
|
|
18607
|
+
target: [usagePeaks.window, usagePeaks.resetsAt],
|
|
18608
|
+
set: {
|
|
18609
|
+
usedPercentage: sql5`GREATEST(${usagePeaks.usedPercentage}, excluded.used_percentage)`
|
|
18610
|
+
}
|
|
18611
|
+
});
|
|
18612
|
+
}
|
|
18613
|
+
|
|
18614
|
+
// src/commands/sessions/daemon/persistUsagePeak.ts
|
|
18615
|
+
async function persistUsagePeak(rateLimits) {
|
|
18616
|
+
try {
|
|
18617
|
+
if (!process.env.ASSIST_DATABASE_URL && !loadConfig().database.url) return;
|
|
18618
|
+
await recordUsagePeak(await getDb(), rateLimits);
|
|
18619
|
+
} catch (error) {
|
|
18620
|
+
daemonLog(`usage-peak persist failed: ${String(error)}`);
|
|
18621
|
+
}
|
|
18622
|
+
}
|
|
18623
|
+
|
|
18552
18624
|
// src/commands/sessions/daemon/ClientHub.ts
|
|
18553
18625
|
var ClientHub = class extends Set {
|
|
18626
|
+
// why: the daemon injects a best-effort persister; left undefined elsewhere so `new ClientHub()` works and broadcasting never depends on it.
|
|
18627
|
+
constructor(persistPeak) {
|
|
18628
|
+
super();
|
|
18629
|
+
this.persistPeak = persistPeak;
|
|
18630
|
+
}
|
|
18554
18631
|
latestLimits;
|
|
18555
18632
|
updateLimits(rateLimits) {
|
|
18556
18633
|
this.latestLimits = rateLimits;
|
|
18557
18634
|
broadcast(this, { type: "limits", rateLimits });
|
|
18635
|
+
this.persistPeak?.(rateLimits);
|
|
18558
18636
|
}
|
|
18559
18637
|
greet(client) {
|
|
18560
18638
|
if (this.latestLimits) {
|
|
@@ -18722,12 +18800,6 @@ function makeStatusChangeHandler(dismiss, notify2, reuseForRun) {
|
|
|
18722
18800
|
return (s, status2, exitCode) => applyStatusChange(s, status2, exitCode, dismiss, notify2, reuseForRun);
|
|
18723
18801
|
}
|
|
18724
18802
|
|
|
18725
|
-
// src/commands/sessions/daemon/backlogRunArgs.ts
|
|
18726
|
-
function backlogRunArgs(persisted) {
|
|
18727
|
-
const args = ["assist", ...persisted.assistArgs];
|
|
18728
|
-
return persisted.claudeSessionId ? [...args, "--resume-session", persisted.claudeSessionId] : args;
|
|
18729
|
-
}
|
|
18730
|
-
|
|
18731
18803
|
// src/commands/sessions/daemon/restoreBase.ts
|
|
18732
18804
|
function restoreBase(id2, persisted) {
|
|
18733
18805
|
return {
|
|
@@ -18742,6 +18814,26 @@ function restoreBase(id2, persisted) {
|
|
|
18742
18814
|
};
|
|
18743
18815
|
}
|
|
18744
18816
|
|
|
18817
|
+
// src/commands/sessions/daemon/errorSession.ts
|
|
18818
|
+
function errorSession(id2, persisted, error) {
|
|
18819
|
+
return {
|
|
18820
|
+
...restoreBase(id2, persisted),
|
|
18821
|
+
status: "error",
|
|
18822
|
+
startedAt: persisted.startedAt,
|
|
18823
|
+
pty: null,
|
|
18824
|
+
runName: persisted.runName,
|
|
18825
|
+
runArgs: persisted.runArgs,
|
|
18826
|
+
error,
|
|
18827
|
+
restored: false
|
|
18828
|
+
};
|
|
18829
|
+
}
|
|
18830
|
+
|
|
18831
|
+
// src/commands/sessions/daemon/backlogRunArgs.ts
|
|
18832
|
+
function backlogRunArgs(persisted) {
|
|
18833
|
+
const args = ["assist", ...persisted.assistArgs];
|
|
18834
|
+
return persisted.claudeSessionId ? [...args, "--resume-session", persisted.claudeSessionId] : args;
|
|
18835
|
+
}
|
|
18836
|
+
|
|
18745
18837
|
// src/commands/sessions/daemon/runningSession.ts
|
|
18746
18838
|
function runningSession(base, persisted, pty2) {
|
|
18747
18839
|
return {
|
|
@@ -18769,6 +18861,13 @@ function restoreSession(id2, persisted) {
|
|
|
18769
18861
|
});
|
|
18770
18862
|
return runningSession(base, persisted, pty2);
|
|
18771
18863
|
}
|
|
18864
|
+
if (persisted.commandType === "claude") {
|
|
18865
|
+
return errorSession(
|
|
18866
|
+
id2,
|
|
18867
|
+
persisted,
|
|
18868
|
+
"no claude session id was recorded before the daemon stopped, so the conversation cannot be resumed"
|
|
18869
|
+
);
|
|
18870
|
+
}
|
|
18772
18871
|
return {
|
|
18773
18872
|
...base,
|
|
18774
18873
|
status: "done",
|
|
@@ -18783,6 +18882,28 @@ function isBacklogRun(persisted) {
|
|
|
18783
18882
|
return persisted.commandType === "assist" && persisted.assistArgs?.[0] === "backlog" && persisted.assistArgs?.[1] === "run";
|
|
18784
18883
|
}
|
|
18785
18884
|
|
|
18885
|
+
// src/commands/sessions/daemon/restoreOne.ts
|
|
18886
|
+
function restoreOne(persisted, spawn12, sessions) {
|
|
18887
|
+
try {
|
|
18888
|
+
const id2 = spawn12((sid) => restoreSession(sid, persisted));
|
|
18889
|
+
logUnresumable(persisted.name, id2, sessions.get(id2));
|
|
18890
|
+
} catch (error) {
|
|
18891
|
+
const reason = logRestoreError(persisted.name, error);
|
|
18892
|
+
spawn12((id2) => errorSession(id2, persisted, reason));
|
|
18893
|
+
}
|
|
18894
|
+
}
|
|
18895
|
+
function logUnresumable(name, id2, session) {
|
|
18896
|
+
if (session?.status === "error")
|
|
18897
|
+
daemonLog(
|
|
18898
|
+
`could not resume restored session "${name}" (id ${id2}): ${session.error}`
|
|
18899
|
+
);
|
|
18900
|
+
}
|
|
18901
|
+
function logRestoreError(name, error) {
|
|
18902
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
18903
|
+
daemonLog(`failed to restore session "${name}": ${reason}`);
|
|
18904
|
+
return reason;
|
|
18905
|
+
}
|
|
18906
|
+
|
|
18786
18907
|
// src/commands/sessions/daemon/resumeSession.ts
|
|
18787
18908
|
function resumeSession(id2, sessionId, cwd, name) {
|
|
18788
18909
|
return {
|
|
@@ -18874,7 +18995,14 @@ function wirePtyEvents(session, clients, onStatusChange) {
|
|
|
18874
18995
|
session.pty.onExit(({ exitCode }) => {
|
|
18875
18996
|
clearIdle(session);
|
|
18876
18997
|
refreshActivity(session);
|
|
18877
|
-
|
|
18998
|
+
const failedResume = session.restored === true && exitCode !== 0 && session.scrollback.length === 0;
|
|
18999
|
+
if (failedResume) {
|
|
19000
|
+
session.error = `resume process exited with code ${exitCode} before producing any output`;
|
|
19001
|
+
daemonLog(
|
|
19002
|
+
`could not resume restored session "${session.name}" (id ${session.id}): ${session.error}`
|
|
19003
|
+
);
|
|
19004
|
+
}
|
|
19005
|
+
onStatusChange(session, failedResume ? "error" : "done", exitCode);
|
|
18878
19006
|
});
|
|
18879
19007
|
scheduleIdle(session, () => onStatusChange(session, "waiting"));
|
|
18880
19008
|
}
|
|
@@ -19488,8 +19616,8 @@ function deriveSessionType(commandName, name) {
|
|
|
19488
19616
|
}
|
|
19489
19617
|
|
|
19490
19618
|
// src/commands/sessions/shared/backlogRunMarkers.ts
|
|
19491
|
-
function backlogRunMarkers(
|
|
19492
|
-
const match =
|
|
19619
|
+
function backlogRunMarkers(text5) {
|
|
19620
|
+
const match = text5.match(/backlog item #(\d+):[ \t]*([^\n]*)/);
|
|
19493
19621
|
if (!match) return { commandName: "", commandArgs: "" };
|
|
19494
19622
|
const title = match[2].trim();
|
|
19495
19623
|
return {
|
|
@@ -19543,11 +19671,11 @@ function messageText(entry) {
|
|
|
19543
19671
|
const content = msg?.content;
|
|
19544
19672
|
return typeof content === "string" ? content : Array.isArray(content) ? content.find((c) => c.type === "text")?.text ?? "" : "";
|
|
19545
19673
|
}
|
|
19546
|
-
function stripMarkers(
|
|
19547
|
-
return
|
|
19674
|
+
function stripMarkers(text5) {
|
|
19675
|
+
return text5.replace(/<command-[^>]*>[^<]*<\/command-[^>]*>/g, "").trim().slice(0, 80);
|
|
19548
19676
|
}
|
|
19549
|
-
function matchMarker(
|
|
19550
|
-
const match =
|
|
19677
|
+
function matchMarker(text5, tag) {
|
|
19678
|
+
const match = text5.match(new RegExp(`<${tag}>([\\s\\S]*?)</${tag}>`));
|
|
19551
19679
|
return match ? match[1].trim() : "";
|
|
19552
19680
|
}
|
|
19553
19681
|
|
|
@@ -19757,7 +19885,7 @@ var SessionManager = class {
|
|
|
19757
19885
|
sessions = /* @__PURE__ */ new Map();
|
|
19758
19886
|
// why: dispatch calls active.set() on card click; broadcasts include active.toJSON()
|
|
19759
19887
|
active = new ActiveSelection(() => this.notify());
|
|
19760
|
-
clients = new ClientHub();
|
|
19888
|
+
clients = new ClientHub(persistUsagePeak);
|
|
19761
19889
|
nextId = 1;
|
|
19762
19890
|
shuttingDown = false;
|
|
19763
19891
|
// why: dispatch calls windowsProxy.route() to forward windows-origin sessions
|
|
@@ -19778,7 +19906,7 @@ var SessionManager = class {
|
|
|
19778
19906
|
}
|
|
19779
19907
|
restore() {
|
|
19780
19908
|
return loadPersistedSessions().map((persisted) => {
|
|
19781
|
-
this.spawnWith
|
|
19909
|
+
restoreOne(persisted, this.spawnWith, this.sessions);
|
|
19782
19910
|
return persisted.name;
|
|
19783
19911
|
});
|
|
19784
19912
|
}
|
|
@@ -19788,9 +19916,7 @@ var SessionManager = class {
|
|
|
19788
19916
|
watchActivity(session, this.notify);
|
|
19789
19917
|
return session.id;
|
|
19790
19918
|
}
|
|
19791
|
-
spawnWith(create)
|
|
19792
|
-
return this.add(create(String(this.nextId++)));
|
|
19793
|
-
}
|
|
19919
|
+
spawnWith = (create) => this.add(create(String(this.nextId++)));
|
|
19794
19920
|
spawn(prompt, cwd) {
|
|
19795
19921
|
return this.spawnWith((id2) => createSession(id2, prompt, cwd));
|
|
19796
19922
|
}
|
|
@@ -19871,17 +19997,17 @@ function entryMessages(entry) {
|
|
|
19871
19997
|
return [];
|
|
19872
19998
|
}
|
|
19873
19999
|
function userMessages(content) {
|
|
19874
|
-
if (typeof content === "string") return
|
|
20000
|
+
if (typeof content === "string") return text4("user", cleanUserText(content));
|
|
19875
20001
|
if (!Array.isArray(content)) return [];
|
|
19876
|
-
return content.filter((c) => c.type === "text").flatMap((c) =>
|
|
20002
|
+
return content.filter((c) => c.type === "text").flatMap((c) => text4("user", cleanUserText(c.text ?? "")));
|
|
19877
20003
|
}
|
|
19878
20004
|
function assistantMessages(content) {
|
|
19879
|
-
if (typeof content === "string") return
|
|
20005
|
+
if (typeof content === "string") return text4("assistant", content.trim());
|
|
19880
20006
|
if (!Array.isArray(content)) return [];
|
|
19881
20007
|
return content.flatMap((c) => assistantItem(c));
|
|
19882
20008
|
}
|
|
19883
20009
|
function assistantItem(c) {
|
|
19884
|
-
if (c.type === "text") return
|
|
20010
|
+
if (c.type === "text") return text4("assistant", (c.text ?? "").trim());
|
|
19885
20011
|
if (c.type === "tool_use")
|
|
19886
20012
|
return [
|
|
19887
20013
|
{
|
|
@@ -19892,7 +20018,7 @@ function assistantItem(c) {
|
|
|
19892
20018
|
];
|
|
19893
20019
|
return [];
|
|
19894
20020
|
}
|
|
19895
|
-
function
|
|
20021
|
+
function text4(role, value) {
|
|
19896
20022
|
return value ? [{ role, text: value }] : [];
|
|
19897
20023
|
}
|
|
19898
20024
|
function cleanUserText(value) {
|
|
@@ -20223,16 +20349,16 @@ function parseUserLine(line) {
|
|
|
20223
20349
|
if (entry.type !== "user") return void 0;
|
|
20224
20350
|
const msg = entry.message;
|
|
20225
20351
|
const c = msg?.content;
|
|
20226
|
-
let
|
|
20352
|
+
let text5;
|
|
20227
20353
|
if (typeof c === "string") {
|
|
20228
|
-
|
|
20354
|
+
text5 = c;
|
|
20229
20355
|
} else if (Array.isArray(c)) {
|
|
20230
20356
|
const collected = c.filter((b) => b.type === "text").map((b) => b.text ?? "").join("\n");
|
|
20231
|
-
|
|
20357
|
+
text5 = collected || void 0;
|
|
20232
20358
|
}
|
|
20233
|
-
if (!
|
|
20359
|
+
if (!text5) return void 0;
|
|
20234
20360
|
return {
|
|
20235
|
-
text:
|
|
20361
|
+
text: text5,
|
|
20236
20362
|
entrypoint: typeof entry.entrypoint === "string" ? entry.entrypoint : void 0
|
|
20237
20363
|
};
|
|
20238
20364
|
}
|
|
@@ -20261,13 +20387,13 @@ function* iterateUserMessages(filePath, maxBytes = 65536) {
|
|
|
20261
20387
|
|
|
20262
20388
|
// src/commands/sessions/summarise/extractFirstUserMessage.ts
|
|
20263
20389
|
function extractFirstUserMessage(filePath) {
|
|
20264
|
-
for (const
|
|
20265
|
-
return truncate3(
|
|
20390
|
+
for (const text5 of iterateUserMessages(filePath)) {
|
|
20391
|
+
return truncate3(text5);
|
|
20266
20392
|
}
|
|
20267
20393
|
return void 0;
|
|
20268
20394
|
}
|
|
20269
|
-
function truncate3(
|
|
20270
|
-
const trimmed =
|
|
20395
|
+
function truncate3(text5, maxChars = 500) {
|
|
20396
|
+
const trimmed = text5.trim();
|
|
20271
20397
|
if (trimmed.length <= maxChars) return trimmed;
|
|
20272
20398
|
return `${trimmed.slice(0, maxChars)}\u2026`;
|
|
20273
20399
|
}
|
|
@@ -20275,28 +20401,28 @@ function truncate3(text4, maxChars = 500) {
|
|
|
20275
20401
|
// src/commands/sessions/summarise/scanSessionBacklogRefs.ts
|
|
20276
20402
|
function scanSessionBacklogRefs(filePath) {
|
|
20277
20403
|
const ids = /* @__PURE__ */ new Set();
|
|
20278
|
-
for (const
|
|
20279
|
-
for (const id2 of extractBacklogIds(
|
|
20404
|
+
for (const text5 of iterateUserMessages(filePath, Number.MAX_SAFE_INTEGER)) {
|
|
20405
|
+
for (const id2 of extractBacklogIds(text5)) {
|
|
20280
20406
|
ids.add(id2);
|
|
20281
20407
|
}
|
|
20282
20408
|
}
|
|
20283
20409
|
return [...ids].sort((a, b) => a - b);
|
|
20284
20410
|
}
|
|
20285
|
-
function extractBacklogIds(
|
|
20411
|
+
function extractBacklogIds(text5) {
|
|
20286
20412
|
const ids = [];
|
|
20287
|
-
for (const m of
|
|
20413
|
+
for (const m of text5.matchAll(/backlog\s+run\s+(\d+)/gi)) {
|
|
20288
20414
|
ids.push(Number.parseInt(m[1], 10));
|
|
20289
20415
|
}
|
|
20290
|
-
for (const m of
|
|
20416
|
+
for (const m of text5.matchAll(/backlog\s+(?:item\s+)?#(\d+)/gi)) {
|
|
20291
20417
|
ids.push(Number.parseInt(m[1], 10));
|
|
20292
20418
|
}
|
|
20293
|
-
for (const m of
|
|
20419
|
+
for (const m of text5.matchAll(/backlog\s+phase-done\s+(\d+)/gi)) {
|
|
20294
20420
|
ids.push(Number.parseInt(m[1], 10));
|
|
20295
20421
|
}
|
|
20296
|
-
for (const m of
|
|
20422
|
+
for (const m of text5.matchAll(/backlog\s+comment\s+(\d+)/gi)) {
|
|
20297
20423
|
ids.push(Number.parseInt(m[1], 10));
|
|
20298
20424
|
}
|
|
20299
|
-
for (const m of
|
|
20425
|
+
for (const m of text5.matchAll(/(?:^|[\s(])#(\d{1,4})(?=[\s).,;:!?]|$)/gm)) {
|
|
20300
20426
|
ids.push(Number.parseInt(m[1], 10));
|
|
20301
20427
|
}
|
|
20302
20428
|
return ids;
|