@staff0rd/assist 0.194.0 → 0.195.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.194.0",
9
+ version: "0.195.1",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -1674,6 +1674,48 @@ async function parseItemBody(req) {
1674
1674
  async function parseStatusBody(req) {
1675
1675
  return JSON.parse(await readBody(req));
1676
1676
  }
1677
+ async function parseRewindBody(req) {
1678
+ return JSON.parse(await readBody(req));
1679
+ }
1680
+
1681
+ // src/commands/backlog/web/rewindItemPhase.ts
1682
+ async function rewindItemPhase(req, res, id) {
1683
+ const { phase, reason } = await parseRewindBody(req);
1684
+ const items = loadBacklog();
1685
+ const item = items.find((i) => i.id === id);
1686
+ if (!item) {
1687
+ respondJson(res, 404, { error: "Not found" });
1688
+ return;
1689
+ }
1690
+ const error = validateRewind(item, phase);
1691
+ if (error) {
1692
+ respondJson(res, 400, { error });
1693
+ return;
1694
+ }
1695
+ const phaseName = item.plan?.[phase - 1].name;
1696
+ addComment(
1697
+ item,
1698
+ `Rewound to phase ${phase} (${phaseName}): ${reason}`,
1699
+ phase
1700
+ );
1701
+ item.currentPhase = phase;
1702
+ item.status = "in-progress";
1703
+ saveBacklog(items);
1704
+ respondJson(res, 200, item);
1705
+ }
1706
+ function validateRewind(item, phase) {
1707
+ if (!item.plan || item.plan.length === 0) {
1708
+ return "Item has no plan phases.";
1709
+ }
1710
+ if (phase < 1 || phase > item.plan.length) {
1711
+ return `Phase ${phase} does not exist. Valid range: 1\u2013${item.plan.length}.`;
1712
+ }
1713
+ const currentPhase = item.currentPhase ?? 1;
1714
+ if (phase >= currentPhase) {
1715
+ return `Phase ${phase} is not earlier than the current phase (${currentPhase}).`;
1716
+ }
1717
+ return void 0;
1718
+ }
1677
1719
 
1678
1720
  // src/commands/backlog/web/shared.ts
1679
1721
  function listItems(req, res) {
@@ -1755,6 +1797,11 @@ var itemRoutes = {
1755
1797
  DELETE: (_req, res, id) => deleteItem2(res, id)
1756
1798
  };
1757
1799
  async function handleItemRoute(req, res, pathname) {
1800
+ const rewindMatch = pathname.match(/^\/api\/items\/(\d+)\/rewind$/);
1801
+ if (rewindMatch && req.method === "POST") {
1802
+ await rewindItemPhase(req, res, Number.parseInt(rewindMatch[1], 10));
1803
+ return true;
1804
+ }
1758
1805
  const match = pathname.match(/^\/api\/items\/(\d+)$/);
1759
1806
  if (!match) return false;
1760
1807
  const handler = itemRoutes[req.method ?? "GET"];
@@ -4403,7 +4450,7 @@ function registerLinkCommands(cmd) {
4403
4450
 
4404
4451
  // src/commands/backlog/rewindPhase.ts
4405
4452
  import chalk53 from "chalk";
4406
- function validateRewind(item, phaseNumber) {
4453
+ function validateRewind2(item, phaseNumber) {
4407
4454
  if (!item.plan || item.plan.length === 0) {
4408
4455
  return `Item #${item.id} has no plan phases.`;
4409
4456
  }
@@ -4422,7 +4469,7 @@ function rewindPhase(id, phase, opts) {
4422
4469
  const result = loadAndFindItem(id);
4423
4470
  if (!result) return;
4424
4471
  const { item } = result;
4425
- const error = validateRewind(item, phaseNumber);
4472
+ const error = validateRewind2(item, phaseNumber);
4426
4473
  if (error) {
4427
4474
  console.log(chalk53.red(error));
4428
4475
  process.exitCode = 1;
@@ -10556,10 +10603,12 @@ function filterToSql(filter) {
10556
10603
  }
10557
10604
 
10558
10605
  // src/commands/seq/fetchSeqData.ts
10559
- async function fetchSeqData(conn, filter, count, from) {
10606
+ async function fetchSeqData(conn, filter, count, from, to) {
10560
10607
  const sqlFilter = filterToSql(filter);
10561
10608
  const sql = `select @Timestamp, @Level, @Exception, @Message from stream where ${sqlFilter} order by @Timestamp desc limit ${count}`;
10562
- const params = new URLSearchParams({ q: sql, fromDateUtc: from });
10609
+ const params = new URLSearchParams({ q: sql });
10610
+ if (from) params.set("fromDateUtc", from);
10611
+ if (to) params.set("toDateUtc", to);
10563
10612
  const response = await fetchSeq(conn, "/api/data", params);
10564
10613
  const data = await response.json();
10565
10614
  return mapDataToEvents(data);
@@ -10665,6 +10714,32 @@ function formatEvent(event) {
10665
10714
  return lines.join("\n");
10666
10715
  }
10667
10716
 
10717
+ // src/commands/seq/parseRelativeTime.ts
10718
+ var relativePattern = /^(\d+)([smhdw])$/;
10719
+ var unitMs = {
10720
+ s: 1e3,
10721
+ m: 6e4,
10722
+ h: 36e5,
10723
+ d: 864e5,
10724
+ w: 6048e5
10725
+ };
10726
+ function parseRelativeTime(value, now = /* @__PURE__ */ new Date()) {
10727
+ const match = relativePattern.exec(value);
10728
+ if (!match) return value;
10729
+ const [, amount, unit] = match;
10730
+ return new Date(now.getTime() - Number(amount) * unitMs[unit]).toISOString();
10731
+ }
10732
+
10733
+ // src/commands/seq/rejectTimestampFilter.ts
10734
+ var timestampPattern = /@Timestamp/i;
10735
+ function rejectTimestampFilter(filter) {
10736
+ if (timestampPattern.test(filter)) {
10737
+ throw new Error(
10738
+ "Timestamp expressions are not supported in the filter string. Use --from and --to options instead."
10739
+ );
10740
+ }
10741
+ }
10742
+
10668
10743
  // src/commands/seq/resolveConnection.ts
10669
10744
  import chalk127 from "chalk";
10670
10745
  function resolveConnection2(name) {
@@ -10686,9 +10761,12 @@ function resolveConnection2(name) {
10686
10761
 
10687
10762
  // src/commands/seq/seqQuery.ts
10688
10763
  async function seqQuery(filter, options2) {
10764
+ rejectTimestampFilter(filter);
10689
10765
  const conn = resolveConnection2(options2.connection);
10690
10766
  const count = Number.parseInt(options2.count ?? "1000", 10);
10691
- const events = options2.from ? await fetchSeqData(conn, filter, count, options2.from) : await fetchSeqEvents(
10767
+ const from = options2.from ? parseRelativeTime(options2.from) : void 0;
10768
+ const to = options2.to ? parseRelativeTime(options2.to) : void 0;
10769
+ const events = from || to ? await fetchSeqData(conn, filter, count, from, to) : await fetchSeqEvents(
10692
10770
  conn,
10693
10771
  new URLSearchParams({ filter, count: String(count) })
10694
10772
  );
@@ -10735,7 +10813,13 @@ function registerSeq(program2) {
10735
10813
  auth2.command("list").description("List configured connections").action(() => seqAuth.list());
10736
10814
  auth2.command("remove <name>").description("Remove a configured connection").action((name) => seqAuth.remove(name));
10737
10815
  cmd.command("set-connection <name>").description("Set the default Seq connection").action((name) => seqSetConnection(name));
10738
- cmd.command("query <filter>").description("Query Seq events with a filter expression").option("-c, --connection <name>", "Connection to use").option("-n, --count <n>", "Number of events to fetch", "50").option("--from <date>", "Start date (UTC) for the query window").option("--json", "Output raw JSON").action((filter, options2) => seqQuery(filter, options2));
10816
+ cmd.command("query <filter>").description("Query Seq events with a filter expression").option("-c, --connection <name>", "Connection to use").option("-n, --count <n>", "Number of events to fetch", "50").option(
10817
+ "--from <date>",
10818
+ "Start of query window (UTC date or relative e.g. 5m, 1h, 2d)"
10819
+ ).option(
10820
+ "--to <date>",
10821
+ "End of query window (UTC date or relative e.g. 5m, 1h, 2d)"
10822
+ ).option("--json", "Output raw JSON").action((filter, options2) => seqQuery(filter, options2));
10739
10823
  }
10740
10824
 
10741
10825
  // src/commands/transcript/shared.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.194.0",
3
+ "version": "0.195.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {