@staff0rd/assist 0.310.0 → 0.310.2
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 +230 -95
- package/dist/index.js +104 -52
- package/package.json +2 -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.310.
|
|
9
|
+
version: "0.310.2",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -43,6 +43,7 @@ var package_default = {
|
|
|
43
43
|
url: "https://github.com/staff0rd/assist"
|
|
44
44
|
},
|
|
45
45
|
dependencies: {
|
|
46
|
+
"@xterm/addon-webgl": "^0.19.0",
|
|
46
47
|
"better-sqlite3": "^12.8.0",
|
|
47
48
|
blessed: "^0.1.81",
|
|
48
49
|
"blessed-contrib": "^4.11.0",
|
|
@@ -1140,8 +1141,8 @@ var options = [
|
|
|
1140
1141
|
];
|
|
1141
1142
|
|
|
1142
1143
|
// src/commands/verify/init/getAvailableOptions/index.ts
|
|
1143
|
-
function resolveDescription(
|
|
1144
|
-
return typeof
|
|
1144
|
+
function resolveDescription(desc6, setup2) {
|
|
1145
|
+
return typeof desc6 === "function" ? desc6(setup2) : desc6;
|
|
1145
1146
|
}
|
|
1146
1147
|
function toVerifyOption(def, setup2) {
|
|
1147
1148
|
return {
|
|
@@ -3037,10 +3038,10 @@ function gitPullBacklog(dir) {
|
|
|
3037
3038
|
|
|
3038
3039
|
// src/shared/db/schema.ts
|
|
3039
3040
|
import {
|
|
3040
|
-
boolean,
|
|
3041
|
+
boolean as boolean2,
|
|
3041
3042
|
foreignKey,
|
|
3042
3043
|
index as index2,
|
|
3043
|
-
integer as
|
|
3044
|
+
integer as integer3,
|
|
3044
3045
|
pgTable as pgTable3,
|
|
3045
3046
|
primaryKey as primaryKey2,
|
|
3046
3047
|
text as text3
|
|
@@ -3064,60 +3065,66 @@ var handovers = pgTable(
|
|
|
3064
3065
|
// src/shared/db/usagePeaks.ts
|
|
3065
3066
|
import {
|
|
3066
3067
|
bigint,
|
|
3068
|
+
boolean,
|
|
3067
3069
|
doublePrecision,
|
|
3070
|
+
integer as integer2,
|
|
3068
3071
|
pgTable as pgTable2,
|
|
3069
3072
|
primaryKey,
|
|
3070
|
-
text as text2
|
|
3073
|
+
text as text2,
|
|
3074
|
+
timestamp as timestamp2
|
|
3071
3075
|
} from "drizzle-orm/pg-core";
|
|
3072
3076
|
var usagePeaks = pgTable2(
|
|
3073
3077
|
"usage_peaks",
|
|
3074
3078
|
{
|
|
3075
3079
|
window: text2().$type().notNull(),
|
|
3076
3080
|
resetsAt: bigint("resets_at", { mode: "number" }).notNull(),
|
|
3077
|
-
|
|
3081
|
+
segment: integer2().notNull().default(0),
|
|
3082
|
+
usedPercentage: doublePrecision("used_percentage").notNull(),
|
|
3083
|
+
resetDetected: boolean("reset_detected").notNull().default(false),
|
|
3084
|
+
createdAt: timestamp2("created_at", { withTimezone: true }).notNull().defaultNow()
|
|
3078
3085
|
},
|
|
3079
|
-
(t) => [primaryKey({ columns: [t.window, t.resetsAt] })]
|
|
3086
|
+
(t) => [primaryKey({ columns: [t.window, t.resetsAt, t.segment] })]
|
|
3080
3087
|
);
|
|
3081
3088
|
|
|
3082
3089
|
// src/shared/db/schema.ts
|
|
3083
3090
|
var items = pgTable3(
|
|
3084
3091
|
"items",
|
|
3085
3092
|
{
|
|
3086
|
-
id:
|
|
3093
|
+
id: integer3().generatedByDefaultAsIdentity().primaryKey(),
|
|
3087
3094
|
origin: text3().notNull(),
|
|
3088
3095
|
type: text3().notNull().default("story"),
|
|
3089
3096
|
name: text3().notNull(),
|
|
3090
3097
|
description: text3(),
|
|
3091
3098
|
acceptanceCriteria: text3("acceptance_criteria").notNull().default("[]"),
|
|
3092
3099
|
status: text3().notNull().default("todo"),
|
|
3093
|
-
currentPhase:
|
|
3094
|
-
starred:
|
|
3100
|
+
currentPhase: integer3("current_phase"),
|
|
3101
|
+
starred: boolean2().notNull().default(false)
|
|
3095
3102
|
},
|
|
3096
3103
|
(t) => [index2("items_origin_idx").on(t.origin)]
|
|
3097
3104
|
);
|
|
3098
3105
|
var comments = pgTable3("comments", {
|
|
3099
|
-
id:
|
|
3100
|
-
itemId:
|
|
3101
|
-
idx:
|
|
3106
|
+
id: integer3().generatedByDefaultAsIdentity().primaryKey(),
|
|
3107
|
+
itemId: integer3("item_id").notNull().references(() => items.id, { onDelete: "cascade" }),
|
|
3108
|
+
idx: integer3().notNull(),
|
|
3102
3109
|
text: text3().notNull(),
|
|
3103
|
-
phase:
|
|
3110
|
+
phase: integer3(),
|
|
3104
3111
|
timestamp: text3().notNull(),
|
|
3105
3112
|
type: text3().notNull().default("comment")
|
|
3106
3113
|
});
|
|
3107
3114
|
var links = pgTable3(
|
|
3108
3115
|
"links",
|
|
3109
3116
|
{
|
|
3110
|
-
itemId:
|
|
3117
|
+
itemId: integer3("item_id").notNull().references(() => items.id, { onDelete: "cascade" }),
|
|
3111
3118
|
type: text3().notNull(),
|
|
3112
|
-
targetId:
|
|
3119
|
+
targetId: integer3("target_id").notNull()
|
|
3113
3120
|
},
|
|
3114
3121
|
(t) => [primaryKey2({ columns: [t.itemId, t.type, t.targetId] })]
|
|
3115
3122
|
);
|
|
3116
3123
|
var planPhases = pgTable3(
|
|
3117
3124
|
"plan_phases",
|
|
3118
3125
|
{
|
|
3119
|
-
itemId:
|
|
3120
|
-
idx:
|
|
3126
|
+
itemId: integer3("item_id").notNull().references(() => items.id, { onDelete: "cascade" }),
|
|
3127
|
+
idx: integer3().notNull(),
|
|
3121
3128
|
name: text3().notNull(),
|
|
3122
3129
|
manualChecks: text3("manual_checks")
|
|
3123
3130
|
},
|
|
@@ -3126,9 +3133,9 @@ var planPhases = pgTable3(
|
|
|
3126
3133
|
var planTasks = pgTable3(
|
|
3127
3134
|
"plan_tasks",
|
|
3128
3135
|
{
|
|
3129
|
-
itemId:
|
|
3130
|
-
phaseIdx:
|
|
3131
|
-
idx:
|
|
3136
|
+
itemId: integer3("item_id").notNull(),
|
|
3137
|
+
phaseIdx: integer3("phase_idx").notNull(),
|
|
3138
|
+
idx: integer3().notNull(),
|
|
3132
3139
|
task: text3().notNull()
|
|
3133
3140
|
},
|
|
3134
3141
|
(t) => [
|
|
@@ -3144,7 +3151,7 @@ var metadata = pgTable3("metadata", {
|
|
|
3144
3151
|
value: text3().notNull()
|
|
3145
3152
|
});
|
|
3146
3153
|
var feeds = pgTable3("feeds", {
|
|
3147
|
-
id:
|
|
3154
|
+
id: integer3().generatedByDefaultAsIdentity().primaryKey(),
|
|
3148
3155
|
url: text3().notNull().unique()
|
|
3149
3156
|
});
|
|
3150
3157
|
var schema = {
|
|
@@ -3601,9 +3608,34 @@ var SCHEMA = `
|
|
|
3601
3608
|
CREATE TABLE IF NOT EXISTS usage_peaks (
|
|
3602
3609
|
"window" TEXT NOT NULL,
|
|
3603
3610
|
resets_at BIGINT NOT NULL,
|
|
3611
|
+
segment INTEGER NOT NULL DEFAULT 0,
|
|
3604
3612
|
used_percentage DOUBLE PRECISION NOT NULL,
|
|
3605
|
-
|
|
3613
|
+
reset_detected BOOLEAN NOT NULL DEFAULT false,
|
|
3614
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
3615
|
+
PRIMARY KEY ("window", resets_at, segment)
|
|
3606
3616
|
);
|
|
3617
|
+
|
|
3618
|
+
-- Backfill columns on databases created before reset/segment tracking existed.
|
|
3619
|
+
ALTER TABLE usage_peaks ADD COLUMN IF NOT EXISTS reset_detected BOOLEAN NOT NULL DEFAULT false;
|
|
3620
|
+
ALTER TABLE usage_peaks ADD COLUMN IF NOT EXISTS segment INTEGER NOT NULL DEFAULT 0;
|
|
3621
|
+
ALTER TABLE usage_peaks ADD COLUMN IF NOT EXISTS created_at TIMESTAMPTZ NOT NULL DEFAULT now();
|
|
3622
|
+
|
|
3623
|
+
-- Widen the primary key to include segment so a cycle can hold both its
|
|
3624
|
+
-- pre-reset peak and its post-reset continuation. Idempotent: only fires
|
|
3625
|
+
-- while the legacy two-column key is still in place.
|
|
3626
|
+
DO $$
|
|
3627
|
+
BEGIN
|
|
3628
|
+
IF EXISTS (
|
|
3629
|
+
SELECT 1 FROM pg_constraint
|
|
3630
|
+
WHERE conname = 'usage_peaks_pkey'
|
|
3631
|
+
AND conrelid = 'usage_peaks'::regclass
|
|
3632
|
+
AND array_length(conkey, 1) = 2
|
|
3633
|
+
) THEN
|
|
3634
|
+
ALTER TABLE usage_peaks DROP CONSTRAINT usage_peaks_pkey;
|
|
3635
|
+
ALTER TABLE usage_peaks ADD CONSTRAINT usage_peaks_pkey
|
|
3636
|
+
PRIMARY KEY ("window", resets_at, segment);
|
|
3637
|
+
END IF;
|
|
3638
|
+
END $$;
|
|
3607
3639
|
`;
|
|
3608
3640
|
async function ensureSchema(exec3) {
|
|
3609
3641
|
await exec3(SCHEMA);
|
|
@@ -5489,7 +5521,7 @@ async function listNewsItems(_req, res) {
|
|
|
5489
5521
|
// src/shared/db/listUsagePeaks.ts
|
|
5490
5522
|
import { desc } from "drizzle-orm";
|
|
5491
5523
|
async function listUsagePeaks(db) {
|
|
5492
|
-
return db.select().from(usagePeaks).orderBy(desc(usagePeaks.resetsAt), usagePeaks.window);
|
|
5524
|
+
return db.select().from(usagePeaks).orderBy(desc(usagePeaks.resetsAt), usagePeaks.window, usagePeaks.segment);
|
|
5493
5525
|
}
|
|
5494
5526
|
|
|
5495
5527
|
// src/commands/sessions/web/listUsageHistory.ts
|
|
@@ -7381,8 +7413,8 @@ function applyAcMutations(current, options2) {
|
|
|
7381
7413
|
// src/commands/backlog/update/buildUpdateValues.ts
|
|
7382
7414
|
import chalk81 from "chalk";
|
|
7383
7415
|
function buildUpdateValues(options2) {
|
|
7384
|
-
const { name, desc:
|
|
7385
|
-
if (!name && !
|
|
7416
|
+
const { name, desc: desc6, type, ac } = options2;
|
|
7417
|
+
if (!name && !desc6 && !type && !ac) {
|
|
7386
7418
|
console.log(chalk81.red("Nothing to update. Provide at least one flag."));
|
|
7387
7419
|
process.exitCode = 1;
|
|
7388
7420
|
return void 0;
|
|
@@ -7398,8 +7430,8 @@ function buildUpdateValues(options2) {
|
|
|
7398
7430
|
set.name = name;
|
|
7399
7431
|
fieldNames.push("name");
|
|
7400
7432
|
}
|
|
7401
|
-
if (
|
|
7402
|
-
set.description =
|
|
7433
|
+
if (desc6) {
|
|
7434
|
+
set.description = desc6;
|
|
7403
7435
|
fieldNames.push("description");
|
|
7404
7436
|
}
|
|
7405
7437
|
if (type) {
|
|
@@ -19147,8 +19179,8 @@ function buildOutputPath(outputDir, processName) {
|
|
|
19147
19179
|
if (!existsSync49(outputDir)) {
|
|
19148
19180
|
mkdirSync21(outputDir, { recursive: true });
|
|
19149
19181
|
}
|
|
19150
|
-
const
|
|
19151
|
-
return resolve14(outputDir, `${processName}-${
|
|
19182
|
+
const timestamp3 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
19183
|
+
return resolve14(outputDir, `${processName}-${timestamp3}.png`);
|
|
19152
19184
|
}
|
|
19153
19185
|
function runPowerShellScript(processName, outputPath) {
|
|
19154
19186
|
const scriptPath = join59(tmpdir7(), `assist-screenshot-${Date.now()}.ps1`);
|
|
@@ -19450,26 +19482,46 @@ function broadcastSessions(sessions, clients, windowsSessions = [], active) {
|
|
|
19450
19482
|
});
|
|
19451
19483
|
}
|
|
19452
19484
|
|
|
19485
|
+
// src/shared/db/recordWindowPeak.ts
|
|
19486
|
+
import { and as and13, desc as desc5, eq as eq31, sql as sql5 } from "drizzle-orm";
|
|
19487
|
+
var RESET_DROP_THRESHOLD = 1;
|
|
19488
|
+
async function recordWindowPeak(db, window, resetsAt, usedPercentage) {
|
|
19489
|
+
const [active] = await db.select().from(usagePeaks).where(
|
|
19490
|
+
and13(eq31(usagePeaks.window, window), eq31(usagePeaks.resetsAt, resetsAt))
|
|
19491
|
+
).orderBy(desc5(usagePeaks.segment)).limit(1);
|
|
19492
|
+
if (!active) {
|
|
19493
|
+
await db.insert(usagePeaks).values({ window, resetsAt, segment: 0, usedPercentage });
|
|
19494
|
+
return;
|
|
19495
|
+
}
|
|
19496
|
+
const matchActive = and13(
|
|
19497
|
+
eq31(usagePeaks.window, window),
|
|
19498
|
+
eq31(usagePeaks.resetsAt, resetsAt),
|
|
19499
|
+
eq31(usagePeaks.segment, active.segment)
|
|
19500
|
+
);
|
|
19501
|
+
if (usedPercentage < active.usedPercentage - RESET_DROP_THRESHOLD) {
|
|
19502
|
+
await db.update(usagePeaks).set({ resetDetected: true }).where(matchActive);
|
|
19503
|
+
await db.insert(usagePeaks).values({
|
|
19504
|
+
window,
|
|
19505
|
+
resetsAt,
|
|
19506
|
+
segment: active.segment + 1,
|
|
19507
|
+
usedPercentage
|
|
19508
|
+
});
|
|
19509
|
+
return;
|
|
19510
|
+
}
|
|
19511
|
+
await db.update(usagePeaks).set({
|
|
19512
|
+
usedPercentage: sql5`GREATEST(${usagePeaks.usedPercentage}, ${usedPercentage})`
|
|
19513
|
+
}).where(matchActive);
|
|
19514
|
+
}
|
|
19515
|
+
|
|
19453
19516
|
// src/shared/db/recordUsagePeak.ts
|
|
19454
|
-
import { sql as sql5 } from "drizzle-orm";
|
|
19455
19517
|
var WINDOWS = ["five_hour", "seven_day"];
|
|
19456
19518
|
async function recordUsagePeak(db, rateLimits) {
|
|
19457
|
-
const
|
|
19519
|
+
for (const window of WINDOWS) {
|
|
19458
19520
|
const w = rateLimits[window];
|
|
19459
|
-
if (!w
|
|
19460
|
-
|
|
19461
|
-
|
|
19462
|
-
|
|
19463
|
-
{ window, resetsAt: w.resets_at, usedPercentage: w.used_percentage }
|
|
19464
|
-
];
|
|
19465
|
-
});
|
|
19466
|
-
if (rows.length === 0) return;
|
|
19467
|
-
await db.insert(usagePeaks).values(rows).onConflictDoUpdate({
|
|
19468
|
-
target: [usagePeaks.window, usagePeaks.resetsAt],
|
|
19469
|
-
set: {
|
|
19470
|
-
usedPercentage: sql5`GREATEST(${usagePeaks.usedPercentage}, excluded.used_percentage)`
|
|
19471
|
-
}
|
|
19472
|
-
});
|
|
19521
|
+
if (!w || typeof w.resets_at !== "number" || typeof w.used_percentage !== "number")
|
|
19522
|
+
continue;
|
|
19523
|
+
await recordWindowPeak(db, window, w.resets_at, w.used_percentage);
|
|
19524
|
+
}
|
|
19473
19525
|
}
|
|
19474
19526
|
|
|
19475
19527
|
// src/commands/sessions/daemon/persistUsagePeak.ts
|
|
@@ -20722,7 +20774,7 @@ function backlogRunMarkers(text5) {
|
|
|
20722
20774
|
function extractSessionMeta(lines) {
|
|
20723
20775
|
let sessionId = "";
|
|
20724
20776
|
let cwd = "";
|
|
20725
|
-
let
|
|
20777
|
+
let timestamp3 = "";
|
|
20726
20778
|
let name = "";
|
|
20727
20779
|
let commandName = "";
|
|
20728
20780
|
let commandArgs = "";
|
|
@@ -20730,14 +20782,14 @@ function extractSessionMeta(lines) {
|
|
|
20730
20782
|
const entry = safeParse(line);
|
|
20731
20783
|
if (!entry) continue;
|
|
20732
20784
|
sessionId ||= strField(entry, "sessionId");
|
|
20733
|
-
|
|
20785
|
+
timestamp3 ||= strField(entry, "timestamp");
|
|
20734
20786
|
cwd ||= strField(entry, "cwd");
|
|
20735
20787
|
if (entry.type === "user" && !entry.isMeta) {
|
|
20736
20788
|
({ name, commandName, commandArgs } = parseFirstUserEntry(entry));
|
|
20737
20789
|
break;
|
|
20738
20790
|
}
|
|
20739
20791
|
}
|
|
20740
|
-
return { sessionId, cwd, timestamp:
|
|
20792
|
+
return { sessionId, cwd, timestamp: timestamp3, name, commandName, commandArgs };
|
|
20741
20793
|
}
|
|
20742
20794
|
function parseFirstUserEntry(entry) {
|
|
20743
20795
|
const raw = messageText(entry);
|
|
@@ -20778,13 +20830,13 @@ async function parseSessionFile(filePath, origin = "wsl") {
|
|
|
20778
20830
|
handle = await fs29.promises.open(filePath, "r");
|
|
20779
20831
|
const meta = extractSessionMeta(await readHeadLines(handle));
|
|
20780
20832
|
if (!meta.sessionId) return null;
|
|
20781
|
-
const
|
|
20833
|
+
const timestamp3 = meta.timestamp || (await fs29.promises.stat(filePath)).mtime.toISOString();
|
|
20782
20834
|
return {
|
|
20783
20835
|
sessionId: meta.sessionId,
|
|
20784
20836
|
name: meta.name || `Session ${meta.sessionId.slice(0, 8)}`,
|
|
20785
20837
|
project: deriveProject(meta.cwd, filePath, origin),
|
|
20786
20838
|
cwd: meta.cwd,
|
|
20787
|
-
timestamp:
|
|
20839
|
+
timestamp: timestamp3,
|
|
20788
20840
|
origin,
|
|
20789
20841
|
...deriveHistoryFields(meta.commandName, meta.commandArgs, meta.name)
|
|
20790
20842
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@staff0rd/assist",
|
|
3
|
-
"version": "0.310.
|
|
3
|
+
"version": "0.310.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"url": "https://github.com/staff0rd/assist"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
+
"@xterm/addon-webgl": "^0.19.0",
|
|
40
41
|
"better-sqlite3": "^12.8.0",
|
|
41
42
|
"blessed": "^0.1.81",
|
|
42
43
|
"blessed-contrib": "^4.11.0",
|