@wervt/cli 0.2.7 → 0.2.9
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.mjs +68 -0
- package/package.json +1 -1
- package/skill/SKILL.md +2 -0
package/dist/index.mjs
CHANGED
|
@@ -695,6 +695,73 @@ const logs = defineCommand({
|
|
|
695
695
|
for (const entry of entries.reverse()) printLog(entry, Boolean(args.json));
|
|
696
696
|
}
|
|
697
697
|
});
|
|
698
|
+
const SPARKS = "▁▂▃▄▅▆▇█";
|
|
699
|
+
const stats = defineCommand({
|
|
700
|
+
meta: {
|
|
701
|
+
name: "stats",
|
|
702
|
+
description: "Show an app's visitors, page views and top pages (cookieless analytics)"
|
|
703
|
+
},
|
|
704
|
+
args: {
|
|
705
|
+
app: {
|
|
706
|
+
type: "positional",
|
|
707
|
+
required: true,
|
|
708
|
+
description: "App name"
|
|
709
|
+
},
|
|
710
|
+
range: {
|
|
711
|
+
type: "string",
|
|
712
|
+
default: "7d",
|
|
713
|
+
description: "24h, 7d, 30d or 90d"
|
|
714
|
+
},
|
|
715
|
+
path: {
|
|
716
|
+
type: "string",
|
|
717
|
+
description: "Only views of this path"
|
|
718
|
+
},
|
|
719
|
+
referrer: {
|
|
720
|
+
type: "string",
|
|
721
|
+
description: "Only visits from this referrer host ('' for direct)"
|
|
722
|
+
},
|
|
723
|
+
country: {
|
|
724
|
+
type: "string",
|
|
725
|
+
description: "Only visits from this country (ISO code, e.g. DE)"
|
|
726
|
+
},
|
|
727
|
+
json: {
|
|
728
|
+
type: "boolean",
|
|
729
|
+
description: "Print JSON"
|
|
730
|
+
},
|
|
731
|
+
...connection
|
|
732
|
+
},
|
|
733
|
+
async run({ args }) {
|
|
734
|
+
const params = new URLSearchParams({ range: args.range });
|
|
735
|
+
for (const key of [
|
|
736
|
+
"path",
|
|
737
|
+
"referrer",
|
|
738
|
+
"country"
|
|
739
|
+
]) if (args[key] !== void 0) params.set(key, args[key]);
|
|
740
|
+
const report = await (await api(`/v1/apps/${args.app}/analytics?${params.toString()}`, args)).json();
|
|
741
|
+
if (args.json) return console.log(JSON.stringify(report));
|
|
742
|
+
const { totals, series } = report;
|
|
743
|
+
const peak = Math.max(1, ...series.map((point) => point.views));
|
|
744
|
+
const spark = series.map((point) => point.views ? SPARKS[Math.min(7, Math.floor(point.views / peak * 7.99))] : " ").join("");
|
|
745
|
+
console.log(`${styleText("bold", String(totals.visitors))} visitors ${styleText("bold", String(totals.views))} page views` + (totals.users ? ` ${styleText("bold", String(totals.users))} signed-in users` : "") + styleText("dim", ` (last ${report.range}, visitors unique per day)`));
|
|
746
|
+
console.log(styleText("cyan", spark), styleText("dim", `per ${report.bucket}, peak ${peak}`));
|
|
747
|
+
const section = (title, rows, none) => {
|
|
748
|
+
if (!rows.length) return;
|
|
749
|
+
console.log(`\n${styleText("bold", title)}`);
|
|
750
|
+
const width = Math.max(...rows.map((row) => String(row.visitors).length));
|
|
751
|
+
for (const row of rows.slice(0, 5)) console.log(` ${String(row.visitors).padStart(width)} ${row.value || styleText("dim", none)}`);
|
|
752
|
+
};
|
|
753
|
+
section("Pages", report.top.path, "(none)");
|
|
754
|
+
section("Referrers", report.top.referrer, "direct");
|
|
755
|
+
section("Countries", report.top.country, "unknown");
|
|
756
|
+
section("Devices", report.top.device, "unknown");
|
|
757
|
+
section("Browsers", report.top.browser, "unknown");
|
|
758
|
+
if (report.events.length) {
|
|
759
|
+
console.log(`\n${styleText("bold", "Events")}`);
|
|
760
|
+
const width = Math.max(...report.events.map((event) => String(event.count).length));
|
|
761
|
+
for (const event of report.events.slice(0, 10)) console.log(` ${String(event.count).padStart(width)} ${event.name}${event.label ? styleText("dim", ` ${event.label}`) : ""}`);
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
});
|
|
698
765
|
const whoami = defineCommand({
|
|
699
766
|
meta: {
|
|
700
767
|
name: "whoami",
|
|
@@ -854,6 +921,7 @@ runMain(defineCommand({
|
|
|
854
921
|
env,
|
|
855
922
|
tokens,
|
|
856
923
|
tasks,
|
|
924
|
+
stats,
|
|
857
925
|
delete: remove,
|
|
858
926
|
login,
|
|
859
927
|
whoami,
|
package/package.json
CHANGED
package/skill/SKILL.md
CHANGED
|
@@ -49,6 +49,8 @@ existing app, work in its repository instead.
|
|
|
49
49
|
individual designs, Nuxt UI + the `nuxt-ui-mobile` skill for pure phone apps. Details in the
|
|
50
50
|
app's `AGENTS.md`.
|
|
51
51
|
- Users: wervt signs people in. Use `useWervtUser()`; never build login, passwords or OAuth.
|
|
52
|
+
- Browser agents: add a tool in `server/tools/` (`defineTool`) for each main thing a user does in
|
|
53
|
+
the app, so agents in the browser can do it too (WebMCP). Details in the app's `AGENTS.md`.
|
|
52
54
|
- After changing `server/db/schema.ts`: `pnpm db:generate`, and commit the migration.
|
|
53
55
|
- `pnpm dev` runs against a local wervt stack, which the user may not have. When it isn't running,
|
|
54
56
|
don't set one up: `pnpm build` plus `pnpm exec vp check --fix` are the checks, and the
|