@staff0rd/assist 0.383.0 → 0.384.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/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.383.0",
9
+ version: "0.384.1",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -513,7 +513,13 @@ var itemSubtasks = pgTable5(
513
513
  );
514
514
 
515
515
  // src/shared/db/phaseUsage.ts
516
- import { bigint as bigint2, integer as integer6, pgTable as pgTable6, primaryKey as primaryKey3 } from "drizzle-orm/pg-core";
516
+ import {
517
+ bigint as bigint2,
518
+ doublePrecision,
519
+ integer as integer6,
520
+ pgTable as pgTable6,
521
+ primaryKey as primaryKey3
522
+ } from "drizzle-orm/pg-core";
517
523
  var phaseUsage = pgTable6(
518
524
  "phase_usage",
519
525
  {
@@ -522,6 +528,7 @@ var phaseUsage = pgTable6(
522
528
  tokensUp: bigint2("tokens_up", { mode: "number" }).notNull().default(0),
523
529
  tokensDown: bigint2("tokens_down", { mode: "number" }).notNull().default(0),
524
530
  activeMs: bigint2("active_ms", { mode: "number" }).notNull().default(0),
531
+ peakContextPct: doublePrecision("peak_context_pct").notNull().default(0),
525
532
  lastTotalIn: bigint2("last_total_in", { mode: "number" }),
526
533
  lastTotalOut: bigint2("last_total_out", { mode: "number" })
527
534
  },
@@ -544,7 +551,7 @@ var phaseUsageMessages = pgTable7(
544
551
  import {
545
552
  bigint as bigint3,
546
553
  boolean as boolean2,
547
- doublePrecision,
554
+ doublePrecision as doublePrecision2,
548
555
  integer as integer8,
549
556
  pgTable as pgTable8,
550
557
  primaryKey as primaryKey5,
@@ -557,7 +564,7 @@ var usagePeaks = pgTable8(
557
564
  window: text7().$type().notNull(),
558
565
  resetsAt: bigint3("resets_at", { mode: "number" }).notNull(),
559
566
  segment: integer8().notNull().default(0),
560
- usedPercentage: doublePrecision("used_percentage").notNull(),
567
+ usedPercentage: doublePrecision2("used_percentage").notNull(),
561
568
  resetDetected: boolean2("reset_detected").notNull().default(false),
562
569
  tokensUp: bigint3("tokens_up", { mode: "number" }).notNull().default(0),
563
570
  tokensDown: bigint3("tokens_down", { mode: "number" }).notNull().default(0),
@@ -921,6 +928,7 @@ var SCHEMA = `
921
928
  tokens_up BIGINT NOT NULL DEFAULT 0,
922
929
  tokens_down BIGINT NOT NULL DEFAULT 0,
923
930
  active_ms BIGINT NOT NULL DEFAULT 0,
931
+ peak_context_pct DOUBLE PRECISION NOT NULL DEFAULT 0,
924
932
  last_total_in BIGINT,
925
933
  last_total_out BIGINT,
926
934
  PRIMARY KEY (item_id, phase_idx)
@@ -928,6 +936,7 @@ var SCHEMA = `
928
936
 
929
937
  ALTER TABLE phase_usage ADD COLUMN IF NOT EXISTS last_total_in BIGINT;
930
938
  ALTER TABLE phase_usage ADD COLUMN IF NOT EXISTS last_total_out BIGINT;
939
+ ALTER TABLE phase_usage ADD COLUMN IF NOT EXISTS peak_context_pct DOUBLE PRECISION NOT NULL DEFAULT 0;
931
940
 
932
941
  CREATE TABLE IF NOT EXISTS phase_usage_messages (
933
942
  item_id INTEGER NOT NULL REFERENCES items(id) ON DELETE CASCADE,
@@ -1002,7 +1011,7 @@ function createPool() {
1002
1011
  return pool;
1003
1012
  }
1004
1013
  async function initSchema(pool) {
1005
- await ensureSchema((sql13) => pool.query(sql13));
1014
+ await ensureSchema((sql14) => pool.query(sql14));
1006
1015
  const orm = makeOrmFromPool(pool);
1007
1016
  await seedNewsFeeds(orm);
1008
1017
  await runUsagePeakCleanup(orm);
@@ -4082,8 +4091,8 @@ async function buildDump(tables, copyOut) {
4082
4091
  // src/commands/backlog/dump/copyTableOut.ts
4083
4092
  import { to as copyTo } from "pg-copy-streams";
4084
4093
  async function copyTableOut(client, table) {
4085
- const sql13 = `COPY ${table.name} (${table.columns.join(", ")}) TO STDOUT`;
4086
- const stream = client.query(copyTo(sql13));
4094
+ const sql14 = `COPY ${table.name} (${table.columns.join(", ")}) TO STDOUT`;
4095
+ const stream = client.query(copyTo(sql14));
4087
4096
  const chunks = [];
4088
4097
  for await (const chunk of stream) {
4089
4098
  chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
@@ -4972,9 +4981,10 @@ function sumPhaseUsage(usage) {
4972
4981
  (total, u) => ({
4973
4982
  tokensUp: total.tokensUp + u.tokensUp,
4974
4983
  tokensDown: total.tokensDown + u.tokensDown,
4975
- activeMs: total.activeMs + u.activeMs
4984
+ activeMs: total.activeMs + u.activeMs,
4985
+ peakContextPct: Math.max(total.peakContextPct, u.peakContextPct)
4976
4986
  }),
4977
- { tokensUp: 0, tokensDown: 0, activeMs: 0 }
4987
+ { tokensUp: 0, tokensDown: 0, activeMs: 0, peakContextPct: 0 }
4978
4988
  );
4979
4989
  }
4980
4990
 
@@ -4984,7 +4994,8 @@ function rowToUsage(u) {
4984
4994
  phaseIdx: u.phaseIdx,
4985
4995
  tokensUp: u.tokensUp,
4986
4996
  tokensDown: u.tokensDown,
4987
- activeMs: u.activeMs
4997
+ activeMs: u.activeMs,
4998
+ peakContextPct: u.peakContextPct
4988
4999
  };
4989
5000
  }
4990
5001
  function attachUsage(item, rel, id) {
@@ -5104,12 +5115,14 @@ var phaseUsageSchema = z3.strictObject({
5104
5115
  phaseIdx: z3.number(),
5105
5116
  tokensUp: z3.number(),
5106
5117
  tokensDown: z3.number(),
5107
- activeMs: z3.number()
5118
+ activeMs: z3.number(),
5119
+ peakContextPct: z3.number()
5108
5120
  });
5109
5121
  var phaseUsageTotalSchema = z3.strictObject({
5110
5122
  tokensUp: z3.number(),
5111
5123
  tokensDown: z3.number(),
5112
- activeMs: z3.number()
5124
+ activeMs: z3.number(),
5125
+ peakContextPct: z3.number()
5113
5126
  });
5114
5127
  var subtaskStatusSchema = z3.enum(["todo", "in-progress", "done"]);
5115
5128
  var subtaskSchema = z3.strictObject({
@@ -6679,6 +6692,9 @@ function phaseUsageTotals(orm) {
6679
6692
  ),
6680
6693
  activeMs: sql6`sum(${phaseUsage.activeMs})::bigint`.as(
6681
6694
  "total_active_ms"
6695
+ ),
6696
+ peakContextPct: sql6`max(${phaseUsage.peakContextPct})`.as(
6697
+ "max_peak_context_pct"
6682
6698
  )
6683
6699
  }).from(phaseUsage).groupBy(phaseUsage.itemId).as("usage_totals");
6684
6700
  }
@@ -6697,7 +6713,8 @@ function rowToItemSummary(row) {
6697
6713
  usageTotal: row.tokensUp == null ? void 0 : {
6698
6714
  tokensUp: Number(row.tokensUp),
6699
6715
  tokensDown: Number(row.tokensDown),
6700
- activeMs: Number(row.activeMs)
6716
+ activeMs: Number(row.activeMs),
6717
+ peakContextPct: Number(row.peakContextPct ?? 0)
6701
6718
  }
6702
6719
  };
6703
6720
  }
@@ -6717,7 +6734,8 @@ async function loadItemSummaries(orm, origin) {
6717
6734
  incompleteSubtasks: incompleteCounts.count,
6718
6735
  tokensUp: usageTotals.tokensUp,
6719
6736
  tokensDown: usageTotals.tokensDown,
6720
- activeMs: usageTotals.activeMs
6737
+ activeMs: usageTotals.activeMs,
6738
+ peakContextPct: usageTotals.peakContextPct
6721
6739
  }).from(items).leftJoin(incompleteCounts, eq11(incompleteCounts.itemId, items.id)).leftJoin(usageTotals, eq11(usageTotals.itemId, items.id)).where(origin === void 0 ? void 0 : eq11(items.origin, origin)).orderBy(asc5(items.id));
6722
6740
  return rows.map(rowToItemSummary);
6723
6741
  }
@@ -8459,8 +8477,8 @@ async function readStdinBuffer() {
8459
8477
  import { finished } from "stream/promises";
8460
8478
  import { from as copyFrom } from "pg-copy-streams";
8461
8479
  async function copyTableIn(client, table, data) {
8462
- const sql13 = `COPY ${table.name} (${table.columns.join(", ")}) FROM STDIN`;
8463
- const stream = client.query(copyFrom(sql13));
8480
+ const sql14 = `COPY ${table.name} (${table.columns.join(", ")}) FROM STDIN`;
8481
+ const stream = client.query(copyFrom(sql14));
8464
8482
  stream.end(data);
8465
8483
  await finished(stream);
8466
8484
  }
@@ -20111,8 +20129,8 @@ function filterToSql(filter) {
20111
20129
  // src/commands/seq/fetchSeqData.ts
20112
20130
  function buildDataParams(filter, count8, from, to) {
20113
20131
  const sqlFilter = filterToSql(filter);
20114
- const sql13 = `select @Timestamp, @Level, @Exception, @Message from stream where ${sqlFilter} order by @Timestamp desc limit ${count8}`;
20115
- const params = new URLSearchParams({ q: sql13 });
20132
+ const sql14 = `select @Timestamp, @Level, @Exception, @Message from stream where ${sqlFilter} order by @Timestamp desc limit ${count8}`;
20133
+ const params = new URLSearchParams({ q: sql14 });
20116
20134
  if (from) params.set("rangeStartUtc", from);
20117
20135
  if (to) params.set("rangeEndUtc", to);
20118
20136
  return params;
@@ -20373,26 +20391,26 @@ import chalk187 from "chalk";
20373
20391
  // src/commands/sql/loadConnections.ts
20374
20392
  function loadConnections3() {
20375
20393
  const raw = loadGlobalConfigRaw();
20376
- const sql13 = raw.sql;
20377
- return sql13?.connections ?? [];
20394
+ const sql14 = raw.sql;
20395
+ return sql14?.connections ?? [];
20378
20396
  }
20379
20397
  function saveConnections3(connections) {
20380
20398
  const raw = loadGlobalConfigRaw();
20381
- const sql13 = raw.sql ?? {};
20382
- sql13.connections = connections;
20383
- raw.sql = sql13;
20399
+ const sql14 = raw.sql ?? {};
20400
+ sql14.connections = connections;
20401
+ raw.sql = sql14;
20384
20402
  saveGlobalConfig(raw);
20385
20403
  }
20386
20404
  function getDefaultConnection2() {
20387
20405
  const raw = loadGlobalConfigRaw();
20388
- const sql13 = raw.sql;
20389
- return sql13?.defaultConnection;
20406
+ const sql14 = raw.sql;
20407
+ return sql14?.defaultConnection;
20390
20408
  }
20391
20409
  function setDefaultConnection2(name) {
20392
20410
  const raw = loadGlobalConfigRaw();
20393
- const sql13 = raw.sql ?? {};
20394
- sql13.defaultConnection = name;
20395
- raw.sql = sql13;
20411
+ const sql14 = raw.sql ?? {};
20412
+ sql14.defaultConnection = name;
20413
+ raw.sql = sql14;
20396
20414
  saveGlobalConfig(raw);
20397
20415
  }
20398
20416
 
@@ -20542,11 +20560,11 @@ var MUTATION_PATTERN = new RegExp(
20542
20560
  `\\b(${MUTATION_KEYWORDS.join("|")})\\b`,
20543
20561
  "i"
20544
20562
  );
20545
- function stripComments(sql13) {
20546
- return sql13.replace(/\/\*[\s\S]*?\*\//g, " ").replace(/--[^\n]*/g, " ");
20563
+ function stripComments(sql14) {
20564
+ return sql14.replace(/\/\*[\s\S]*?\*\//g, " ").replace(/--[^\n]*/g, " ");
20547
20565
  }
20548
- function isMutation(sql13) {
20549
- const stripped = stripComments(sql13);
20566
+ function isMutation(sql14) {
20567
+ const stripped = stripComments(sql14);
20550
20568
  if (MUTATION_PATTERN.test(stripped)) return true;
20551
20569
  return /\bSELECT\b[\s\S]+\bINTO\s+\w/i.test(stripped);
20552
20570
  }
@@ -23046,8 +23064,19 @@ function makeStatusChangeHandler(dismiss, notify2, reuseForRun) {
23046
23064
  return (s, status2, exitCode) => applyStatusChange(s, status2, exitCode, dismiss, notify2, reuseForRun);
23047
23065
  }
23048
23066
 
23049
- // src/shared/db/recordPhaseTranscriptUsage.ts
23067
+ // src/shared/db/recordPhasePeakContext.ts
23050
23068
  import { sql as sql11 } from "drizzle-orm";
23069
+ async function recordPhasePeakContext(db, itemId2, phaseIdx, pct) {
23070
+ await db.insert(phaseUsage).values({ itemId: itemId2, phaseIdx, peakContextPct: pct }).onConflictDoUpdate({
23071
+ target: [phaseUsage.itemId, phaseUsage.phaseIdx],
23072
+ set: {
23073
+ peakContextPct: sql11`GREATEST(${phaseUsage.peakContextPct}, ${pct})`
23074
+ }
23075
+ });
23076
+ }
23077
+
23078
+ // src/shared/db/recordPhaseTranscriptUsage.ts
23079
+ import { sql as sql12 } from "drizzle-orm";
23051
23080
  async function recordPhaseTranscriptUsage(db, itemId2, phaseIdx, responses) {
23052
23081
  const byId = /* @__PURE__ */ new Map();
23053
23082
  for (const r of responses) byId.set(r.messageId, r);
@@ -23067,8 +23096,8 @@ async function recordPhaseTranscriptUsage(db, itemId2, phaseIdx, responses) {
23067
23096
  await tx.insert(phaseUsage).values({ itemId: itemId2, phaseIdx, tokensUp, tokensDown }).onConflictDoUpdate({
23068
23097
  target: [phaseUsage.itemId, phaseUsage.phaseIdx],
23069
23098
  set: {
23070
- tokensUp: sql11`${phaseUsage.tokensUp} + ${tokensUp}`,
23071
- tokensDown: sql11`${phaseUsage.tokensDown} + ${tokensDown}`
23099
+ tokensUp: sql12`${phaseUsage.tokensUp} + ${tokensUp}`,
23100
+ tokensDown: sql12`${phaseUsage.tokensDown} + ${tokensDown}`
23072
23101
  }
23073
23102
  });
23074
23103
  return { tokensUp, tokensDown };
@@ -23076,12 +23105,12 @@ async function recordPhaseTranscriptUsage(db, itemId2, phaseIdx, responses) {
23076
23105
  }
23077
23106
 
23078
23107
  // src/shared/db/recordWindowTokens.ts
23079
- import { and as and19, eq as eq37, sql as sql12 } from "drizzle-orm";
23108
+ import { and as and19, eq as eq37, sql as sql13 } from "drizzle-orm";
23080
23109
  async function recordWindowTokens(db, window, resetsAt, tokensUp, tokensDown) {
23081
23110
  if (tokensUp <= 0 && tokensDown <= 0) return;
23082
23111
  await db.update(usagePeaks).set({
23083
- tokensUp: sql12`${usagePeaks.tokensUp} + ${tokensUp}`,
23084
- tokensDown: sql12`${usagePeaks.tokensDown} + ${tokensDown}`
23112
+ tokensUp: sql13`${usagePeaks.tokensUp} + ${tokensUp}`,
23113
+ tokensDown: sql13`${usagePeaks.tokensDown} + ${tokensDown}`
23085
23114
  }).where(
23086
23115
  and19(
23087
23116
  eq37(usagePeaks.window, window),
@@ -23121,12 +23150,14 @@ async function readTranscriptUsage(transcriptPath) {
23121
23150
  }
23122
23151
 
23123
23152
  // src/commands/sessions/daemon/persistPhaseTokens.ts
23124
- async function persistPhaseTokens(itemId2, phaseIdx, transcriptPath, windows) {
23153
+ async function persistPhaseTokens(itemId2, phaseIdx, transcriptPath, usedPct, windows) {
23125
23154
  try {
23126
23155
  if (!process.env.ASSIST_DATABASE_URL && !loadConfig().database.url) return;
23156
+ const db = await getDb();
23157
+ if (usedPct !== void 0)
23158
+ await recordPhasePeakContext(db, itemId2, phaseIdx, usedPct);
23127
23159
  const responses = await readTranscriptUsage(transcriptPath);
23128
23160
  if (responses.length === 0) return;
23129
- const db = await getDb();
23130
23161
  const { tokensUp, tokensDown } = await recordPhaseTranscriptUsage(
23131
23162
  db,
23132
23163
  itemId2,
@@ -23152,6 +23183,7 @@ function recordSessionUsage(sessions, claudeSessionId, transcriptPath, usedPct,
23152
23183
  phase.itemId,
23153
23184
  phase.phaseIdx,
23154
23185
  transcriptPath,
23186
+ usedPct,
23155
23187
  windows
23156
23188
  );
23157
23189
  void flushPhaseActiveMs(session);
@@ -25259,8 +25291,12 @@ function processSessions(files) {
25259
25291
 
25260
25292
  // src/commands/sessions/registerSessions.ts
25261
25293
  function registerSessions(program2) {
25262
- const cmd = program2.command("sessions").description("Web dashboard for Claude Code sessions").option("--no-open", "Do not open a browser on startup").action((options2) => web({ port: "3100", open: options2.open }));
25263
- cmd.command("web").description("Start the sessions web dashboard").option("-p, --port <number>", "Port to listen on", "3100").option("--no-open", "Do not open a browser on startup").action(web);
25294
+ const cmd = program2.command("sessions").description("Web dashboard for Claude Code sessions").option("--no-open", "Do not open a browser on startup").action(
25295
+ (_options, command) => web({ port: "3100", open: command.optsWithGlobals().open })
25296
+ );
25297
+ cmd.command("web").description("Start the sessions web dashboard").option("-p, --port <number>", "Port to listen on", "3100").option("--no-open", "Do not open a browser on startup").action(
25298
+ (options2, command) => web({ ...options2, open: command.optsWithGlobals().open })
25299
+ );
25264
25300
  cmd.command("summarise").description("Generate one-line summaries for Claude sessions").option("-f, --force", "Re-generate all summaries, even existing ones").option("-n, --limit <count>", "Maximum number of sessions to summarise").action(summarise2);
25265
25301
  cmd.command("set-status <status>").description(
25266
25302
  "Report the current session's status to the sessions daemon (used by Claude Code hooks)"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.383.0",
3
+ "version": "0.384.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {