@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/README.md +2 -0
- package/dist/commands/backlog/web/bundle.js +26 -26
- package/dist/index.js +91 -7
- 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.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
|
|
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 =
|
|
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
|
|
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
|
|
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(
|
|
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
|