@tenderprompt/cli 0.1.8 → 0.1.10
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 +4 -0
- package/dist/index.js +324 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -157,6 +157,8 @@ tender app analytics export catalog artifact_123 --range 30d --json
|
|
|
157
157
|
tender app analytics export query artifact_123 --spec chart.json --format csv
|
|
158
158
|
|
|
159
159
|
tender app analytics suggestions artifact_123 --range 30d --json
|
|
160
|
+
|
|
161
|
+
tender app analytics charts templates --json
|
|
160
162
|
```
|
|
161
163
|
|
|
162
164
|
Safe write previews:
|
|
@@ -178,6 +180,8 @@ Agents should combine `capabilities --include-catalog` with local source-code
|
|
|
178
180
|
inspection. For example, inspect where the app calls
|
|
179
181
|
`__TP_ANALYTICS.invoke(...)`, propose a chart spec, validate it with
|
|
180
182
|
`analytics query`, and only then create a saved chart.
|
|
183
|
+
Use `charts templates --json` for reusable chart shapes; adapt any placeholders
|
|
184
|
+
to observed events, paths, or promoted property keys before querying or saving.
|
|
181
185
|
|
|
182
186
|
## Safety Model
|
|
183
187
|
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,38 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { spawn } from "node:child_process";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
3
4
|
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
4
5
|
import os from "node:os";
|
|
5
6
|
import path from "node:path";
|
|
6
7
|
import { fileURLToPath } from "node:url";
|
|
7
8
|
import { generateTenderAppEnvTypes, validateTenderApp, } from "@tenderprompt/tender-app-validator";
|
|
8
9
|
import { collectTenderAppFiles } from "./local-files.js";
|
|
10
|
+
const CLI_PACKAGE_NAME = "@tenderprompt/cli";
|
|
11
|
+
const UNKNOWN_CLI_VERSION = "0.0.0";
|
|
12
|
+
const RECOMMENDED_TENDER_PROMPT_SKILL = {
|
|
13
|
+
name: "tender-prompt",
|
|
14
|
+
version: "0.1.1",
|
|
15
|
+
source: "git@github.com:tenderprompt/skills.git",
|
|
16
|
+
path: "skills/tender-prompt/SKILL.md",
|
|
17
|
+
updateHint: "Refresh the tender-prompt skill from git@github.com:tenderprompt/skills.git when the local skill version is older.",
|
|
18
|
+
};
|
|
19
|
+
function readCliPackageVersion() {
|
|
20
|
+
try {
|
|
21
|
+
const packageJsonPath = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../package.json");
|
|
22
|
+
const parsed = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
23
|
+
if (typeof parsed === "object" &&
|
|
24
|
+
parsed !== null &&
|
|
25
|
+
"version" in parsed &&
|
|
26
|
+
typeof parsed.version === "string") {
|
|
27
|
+
return parsed.version;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return UNKNOWN_CLI_VERSION;
|
|
32
|
+
}
|
|
33
|
+
return UNKNOWN_CLI_VERSION;
|
|
34
|
+
}
|
|
35
|
+
const CLI_PACKAGE_VERSION = readCliPackageVersion();
|
|
9
36
|
class TenderCliUsageError extends Error {
|
|
10
37
|
constructor(message) {
|
|
11
38
|
super(message);
|
|
@@ -239,6 +266,7 @@ Commands:
|
|
|
239
266
|
tender app analytics suggestions <app-id> Generate starter chart suggestions
|
|
240
267
|
tender app analytics dashboards <app-id> List or create dashboards
|
|
241
268
|
tender app analytics export <kind> <app-id> Export catalog metadata or query rows
|
|
269
|
+
tender app analytics charts templates Print reusable chart spec templates
|
|
242
270
|
tender app analytics charts create <app-id> Create a saved chart
|
|
243
271
|
|
|
244
272
|
Examples:
|
|
@@ -250,6 +278,7 @@ Examples:
|
|
|
250
278
|
tender app analytics export query artifact_123 --spec chart.json --format csv
|
|
251
279
|
tender app analytics suggestions artifact_123 --range 2026-04-01..2026-04-30 --json
|
|
252
280
|
tender app analytics dashboards artifact_123 --create "Agent dashboard" --json
|
|
281
|
+
tender app analytics charts templates --json
|
|
253
282
|
tender app analytics charts create artifact_123 --dashboard analytics_dashboard_123 --title "Signup funnel" --spec funnel.json --json`;
|
|
254
283
|
}
|
|
255
284
|
function analyticsSummaryHelp() {
|
|
@@ -313,6 +342,16 @@ Examples:
|
|
|
313
342
|
tender app analytics dashboards artifact_123 --create "Agent dashboard" --dry-run --json
|
|
314
343
|
tender app analytics dashboards artifact_123 --create "Agent dashboard" --json`;
|
|
315
344
|
}
|
|
345
|
+
function analyticsChartsTemplatesHelp() {
|
|
346
|
+
return `Usage: tender app analytics charts templates [--json]
|
|
347
|
+
|
|
348
|
+
Print reusable chart spec templates for agents. Adapt templates to observed
|
|
349
|
+
events, paths, and property keys from analytics capabilities before querying or
|
|
350
|
+
saving.
|
|
351
|
+
|
|
352
|
+
Examples:
|
|
353
|
+
tender app analytics charts templates --json`;
|
|
354
|
+
}
|
|
316
355
|
function analyticsChartsCreateHelp() {
|
|
317
356
|
return `Usage: tender app analytics charts create <app-id> --dashboard <dashboard-id> --title <title> --spec <file|-> [--dry-run] [--base-url <url>] [--token <token>] [--profile <name>] [--json]
|
|
318
357
|
|
|
@@ -638,9 +677,15 @@ function tenderCliCapabilities() {
|
|
|
638
677
|
return {
|
|
639
678
|
ok: true,
|
|
640
679
|
surface: "tender_cli",
|
|
680
|
+
cli: {
|
|
681
|
+
name: CLI_PACKAGE_NAME,
|
|
682
|
+
version: CLI_PACKAGE_VERSION,
|
|
683
|
+
latestRunner: "npm exec --yes @tenderprompt/cli@latest --",
|
|
684
|
+
},
|
|
685
|
+
recommendedSkill: RECOMMENDED_TENDER_PROMPT_SKILL,
|
|
641
686
|
description: "Agent-safe Tender App source, lifecycle, analytics, and local scaffold controls.",
|
|
642
687
|
discovery: {
|
|
643
|
-
primary: "
|
|
688
|
+
primary: "npm exec --yes @tenderprompt/cli@latest -- capabilities --json",
|
|
644
689
|
layeredHelp: [
|
|
645
690
|
"tender --help",
|
|
646
691
|
"tender auth --help",
|
|
@@ -692,6 +737,7 @@ function tenderCliCapabilities() {
|
|
|
692
737
|
when: "When understanding app analytics or creating saved charts.",
|
|
693
738
|
commands: [
|
|
694
739
|
"tender app analytics capabilities <artifact-id> --include-catalog --range 30d --json",
|
|
740
|
+
"tender app analytics charts templates --json",
|
|
695
741
|
"tender app analytics query <artifact-id> --spec chart.json --json",
|
|
696
742
|
"tender app analytics export query <artifact-id> --spec chart.json --format csv",
|
|
697
743
|
"tender app analytics dashboards <artifact-id> --create \"Agent dashboard\" --dry-run --json",
|
|
@@ -749,6 +795,12 @@ function tenderCliCapabilities() {
|
|
|
749
795
|
requiresAuth: true,
|
|
750
796
|
writes: false,
|
|
751
797
|
},
|
|
798
|
+
{
|
|
799
|
+
command: "tender app analytics charts templates --json",
|
|
800
|
+
purpose: "Print reusable chart spec templates for agents to adapt to observed analytics data.",
|
|
801
|
+
requiresAuth: false,
|
|
802
|
+
writes: false,
|
|
803
|
+
},
|
|
752
804
|
],
|
|
753
805
|
security: [
|
|
754
806
|
"Prefer artifact-scoped device tokens.",
|
|
@@ -2522,6 +2574,21 @@ function parseAnalyticsDashboardsArgs(args) {
|
|
|
2522
2574
|
}
|
|
2523
2575
|
return { command: "app analytics dashboards", artifactId, name, dryRun, ...parsed };
|
|
2524
2576
|
}
|
|
2577
|
+
function parseAnalyticsChartsTemplatesArgs(args) {
|
|
2578
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
2579
|
+
return { command: "help", topic: "app analytics charts templates" };
|
|
2580
|
+
}
|
|
2581
|
+
let json = false;
|
|
2582
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
2583
|
+
const arg = args[index];
|
|
2584
|
+
if (arg === "--json") {
|
|
2585
|
+
json = true;
|
|
2586
|
+
continue;
|
|
2587
|
+
}
|
|
2588
|
+
throw new TenderCliUsageError(`Unknown analytics charts templates option: ${arg}`);
|
|
2589
|
+
}
|
|
2590
|
+
return { command: "app analytics charts templates", json };
|
|
2591
|
+
}
|
|
2525
2592
|
function parseAnalyticsExportCatalogArgs(args) {
|
|
2526
2593
|
if (args.includes("--help") || args.includes("-h")) {
|
|
2527
2594
|
return { command: "help", topic: "app analytics export catalog" };
|
|
@@ -2599,6 +2666,244 @@ function parseAnalyticsExportQueryArgs(args) {
|
|
|
2599
2666
|
...parsed,
|
|
2600
2667
|
};
|
|
2601
2668
|
}
|
|
2669
|
+
function analyticsChartTemplates() {
|
|
2670
|
+
return [
|
|
2671
|
+
{
|
|
2672
|
+
id: "daily_custom_events",
|
|
2673
|
+
title: "Daily custom events",
|
|
2674
|
+
visualization: "line",
|
|
2675
|
+
purpose: "Track app-owned business events over time.",
|
|
2676
|
+
usableAsIs: true,
|
|
2677
|
+
adaptWith: [
|
|
2678
|
+
"Use when the catalog has observed custom events.",
|
|
2679
|
+
"Switch the range preset to 7d or 90d when the user's question asks for that window.",
|
|
2680
|
+
],
|
|
2681
|
+
spec: {
|
|
2682
|
+
version: 1,
|
|
2683
|
+
dataset: "events",
|
|
2684
|
+
visualization: "line",
|
|
2685
|
+
metric: { name: "custom_event_count" },
|
|
2686
|
+
groupBy: [{ field: "day" }],
|
|
2687
|
+
filters: [],
|
|
2688
|
+
range: { preset: "30d" },
|
|
2689
|
+
sort: [{ field: "label", direction: "asc" }],
|
|
2690
|
+
limit: 30,
|
|
2691
|
+
},
|
|
2692
|
+
},
|
|
2693
|
+
{
|
|
2694
|
+
id: "top_custom_events",
|
|
2695
|
+
title: "Top custom events",
|
|
2696
|
+
visualization: "bar",
|
|
2697
|
+
purpose: "Show which app-owned events happen most often.",
|
|
2698
|
+
usableAsIs: true,
|
|
2699
|
+
adaptWith: [
|
|
2700
|
+
"Use this before proposing deeper charts so the agent can see the dominant event shape.",
|
|
2701
|
+
],
|
|
2702
|
+
spec: {
|
|
2703
|
+
version: 1,
|
|
2704
|
+
dataset: "events",
|
|
2705
|
+
visualization: "bar",
|
|
2706
|
+
metric: { name: "custom_event_count" },
|
|
2707
|
+
groupBy: [{ field: "event_name" }],
|
|
2708
|
+
filters: [],
|
|
2709
|
+
range: { preset: "30d" },
|
|
2710
|
+
sort: [{ field: "value", direction: "desc" }],
|
|
2711
|
+
limit: 10,
|
|
2712
|
+
},
|
|
2713
|
+
},
|
|
2714
|
+
{
|
|
2715
|
+
id: "top_request_paths",
|
|
2716
|
+
title: "Top request paths",
|
|
2717
|
+
visualization: "bar",
|
|
2718
|
+
purpose: "Find the generated app routes receiving the most traffic.",
|
|
2719
|
+
usableAsIs: true,
|
|
2720
|
+
adaptWith: [
|
|
2721
|
+
"Use only when the capabilities catalog reports request paths.",
|
|
2722
|
+
"Inspect the local source to understand what the busiest routes represent.",
|
|
2723
|
+
],
|
|
2724
|
+
spec: {
|
|
2725
|
+
version: 1,
|
|
2726
|
+
dataset: "events",
|
|
2727
|
+
visualization: "bar",
|
|
2728
|
+
metric: { name: "request_count" },
|
|
2729
|
+
groupBy: [{ field: "path" }],
|
|
2730
|
+
filters: [],
|
|
2731
|
+
range: { preset: "30d" },
|
|
2732
|
+
sort: [{ field: "value", direction: "desc" }],
|
|
2733
|
+
limit: 10,
|
|
2734
|
+
},
|
|
2735
|
+
},
|
|
2736
|
+
{
|
|
2737
|
+
id: "event_funnel_by_name",
|
|
2738
|
+
title: "Event funnel",
|
|
2739
|
+
visualization: "funnel",
|
|
2740
|
+
purpose: "Measure ordered conversion through observed custom event names.",
|
|
2741
|
+
usableAsIs: false,
|
|
2742
|
+
placeholders: {
|
|
2743
|
+
eventNames: ["<start_event>", "<middle_event>", "<conversion_event>"],
|
|
2744
|
+
},
|
|
2745
|
+
adaptWith: [
|
|
2746
|
+
"Replace placeholders with ordered event names from catalog classification or observed events.",
|
|
2747
|
+
"Use only event names observed for the selected app.",
|
|
2748
|
+
"Validate with analytics query before saving because funnel order changes the meaning.",
|
|
2749
|
+
],
|
|
2750
|
+
spec: {
|
|
2751
|
+
version: 1,
|
|
2752
|
+
dataset: "events",
|
|
2753
|
+
visualization: "funnel",
|
|
2754
|
+
metric: { name: "custom_event_count" },
|
|
2755
|
+
groupBy: [{ field: "event_name" }],
|
|
2756
|
+
filters: [
|
|
2757
|
+
{
|
|
2758
|
+
field: "event_name",
|
|
2759
|
+
op: "in",
|
|
2760
|
+
value: ["<start_event>", "<middle_event>", "<conversion_event>"],
|
|
2761
|
+
},
|
|
2762
|
+
],
|
|
2763
|
+
range: { preset: "30d" },
|
|
2764
|
+
sort: [{ field: "label", direction: "asc" }],
|
|
2765
|
+
limit: 3,
|
|
2766
|
+
},
|
|
2767
|
+
},
|
|
2768
|
+
{
|
|
2769
|
+
id: "request_path_funnel",
|
|
2770
|
+
title: "Request path funnel",
|
|
2771
|
+
visualization: "funnel",
|
|
2772
|
+
purpose: "Measure ordered conversion through observed request paths.",
|
|
2773
|
+
usableAsIs: false,
|
|
2774
|
+
placeholders: {
|
|
2775
|
+
paths: ["/<start_path>", "/<middle_path>", "/<conversion_path>"],
|
|
2776
|
+
},
|
|
2777
|
+
adaptWith: [
|
|
2778
|
+
"Use when catalog classification includes a path-based funnel or the source code shows ordered route milestones.",
|
|
2779
|
+
"Replace placeholders with exact observed paths from the selected app.",
|
|
2780
|
+
"Do not include repeated activity routes unless source context says they are milestones.",
|
|
2781
|
+
],
|
|
2782
|
+
spec: {
|
|
2783
|
+
version: 1,
|
|
2784
|
+
dataset: "events",
|
|
2785
|
+
visualization: "funnel",
|
|
2786
|
+
metric: { name: "request_count" },
|
|
2787
|
+
groupBy: [{ field: "path" }],
|
|
2788
|
+
filters: [
|
|
2789
|
+
{
|
|
2790
|
+
field: "path",
|
|
2791
|
+
op: "in",
|
|
2792
|
+
value: ["/<start_path>", "/<middle_path>", "/<conversion_path>"],
|
|
2793
|
+
},
|
|
2794
|
+
],
|
|
2795
|
+
range: { preset: "30d" },
|
|
2796
|
+
sort: [{ field: "label", direction: "asc" }],
|
|
2797
|
+
limit: 3,
|
|
2798
|
+
},
|
|
2799
|
+
},
|
|
2800
|
+
{
|
|
2801
|
+
id: "property_breakdown",
|
|
2802
|
+
title: "Property breakdown",
|
|
2803
|
+
visualization: "bar",
|
|
2804
|
+
purpose: "Compare a promoted dimension property observed in events.",
|
|
2805
|
+
usableAsIs: false,
|
|
2806
|
+
placeholders: {
|
|
2807
|
+
property: "<promoted_dimension_property>",
|
|
2808
|
+
},
|
|
2809
|
+
adaptWith: [
|
|
2810
|
+
"Use a property key promoted by capabilities chartSpec.groupBy, such as property:plan.",
|
|
2811
|
+
"Choose stable categorical properties with enough observations to compare.",
|
|
2812
|
+
],
|
|
2813
|
+
spec: {
|
|
2814
|
+
version: 1,
|
|
2815
|
+
dataset: "events",
|
|
2816
|
+
visualization: "bar",
|
|
2817
|
+
metric: { name: "custom_event_count" },
|
|
2818
|
+
groupBy: [{ field: "property:<promoted_dimension_property>" }],
|
|
2819
|
+
filters: [],
|
|
2820
|
+
range: { preset: "30d" },
|
|
2821
|
+
sort: [{ field: "value", direction: "desc" }],
|
|
2822
|
+
limit: 10,
|
|
2823
|
+
},
|
|
2824
|
+
},
|
|
2825
|
+
{
|
|
2826
|
+
id: "average_metric_property",
|
|
2827
|
+
title: "Average metric property",
|
|
2828
|
+
visualization: "line",
|
|
2829
|
+
purpose: "Track an observed numeric event property over time.",
|
|
2830
|
+
usableAsIs: false,
|
|
2831
|
+
placeholders: {
|
|
2832
|
+
metric: "avg:<promoted_metric_property>",
|
|
2833
|
+
},
|
|
2834
|
+
adaptWith: [
|
|
2835
|
+
"Use a numeric property key promoted by capabilities chartSpec.metrics.",
|
|
2836
|
+
"Prefer averages for scores, durations, quantities, or ordinal values.",
|
|
2837
|
+
],
|
|
2838
|
+
spec: {
|
|
2839
|
+
version: 1,
|
|
2840
|
+
dataset: "events",
|
|
2841
|
+
visualization: "line",
|
|
2842
|
+
metric: { name: "avg:<promoted_metric_property>" },
|
|
2843
|
+
groupBy: [{ field: "day" }],
|
|
2844
|
+
filters: [],
|
|
2845
|
+
range: { preset: "30d" },
|
|
2846
|
+
sort: [{ field: "label", direction: "asc" }],
|
|
2847
|
+
limit: 30,
|
|
2848
|
+
},
|
|
2849
|
+
},
|
|
2850
|
+
{
|
|
2851
|
+
id: "single_number_total",
|
|
2852
|
+
title: "Single number total",
|
|
2853
|
+
visualization: "number",
|
|
2854
|
+
purpose: "Show one headline count for a selected event or request segment.",
|
|
2855
|
+
usableAsIs: false,
|
|
2856
|
+
placeholders: {
|
|
2857
|
+
eventName: "<event_name>",
|
|
2858
|
+
},
|
|
2859
|
+
adaptWith: [
|
|
2860
|
+
"Use when a dashboard needs a compact KPI card.",
|
|
2861
|
+
"Replace the event filter with an observed conversion or outcome event.",
|
|
2862
|
+
],
|
|
2863
|
+
spec: {
|
|
2864
|
+
version: 1,
|
|
2865
|
+
dataset: "events",
|
|
2866
|
+
visualization: "number",
|
|
2867
|
+
metric: { name: "custom_event_count" },
|
|
2868
|
+
groupBy: [],
|
|
2869
|
+
filters: [{ field: "event_name", op: "=", value: "<event_name>" }],
|
|
2870
|
+
range: { preset: "30d" },
|
|
2871
|
+
sort: [],
|
|
2872
|
+
limit: 1,
|
|
2873
|
+
},
|
|
2874
|
+
},
|
|
2875
|
+
];
|
|
2876
|
+
}
|
|
2877
|
+
function runAnalyticsChartsTemplates(command, io) {
|
|
2878
|
+
const templates = analyticsChartTemplates();
|
|
2879
|
+
const payload = {
|
|
2880
|
+
ok: true,
|
|
2881
|
+
command: command.command,
|
|
2882
|
+
templates,
|
|
2883
|
+
next: [
|
|
2884
|
+
"Run tender app analytics capabilities <artifact-id> --include-catalog --range 30d --json.",
|
|
2885
|
+
"Choose a template and replace placeholders with observed events, paths, or promoted property keys.",
|
|
2886
|
+
"Validate with tender app analytics query <artifact-id> --spec chart.json --json.",
|
|
2887
|
+
"Preview saved writes with tender app analytics dashboards ... --dry-run and charts create ... --dry-run.",
|
|
2888
|
+
],
|
|
2889
|
+
};
|
|
2890
|
+
if (command.json) {
|
|
2891
|
+
io.stdout(JSON.stringify(payload, null, 2));
|
|
2892
|
+
}
|
|
2893
|
+
else {
|
|
2894
|
+
io.stdout([
|
|
2895
|
+
"Analytics chart templates",
|
|
2896
|
+
"",
|
|
2897
|
+
...templates.map((template) => {
|
|
2898
|
+
const marker = template.usableAsIs ? "usable as-is" : "adapt before use";
|
|
2899
|
+
return `- ${template.id}: ${template.title} (${marker})`;
|
|
2900
|
+
}),
|
|
2901
|
+
"",
|
|
2902
|
+
"Use --json to copy full chart specs.",
|
|
2903
|
+
].join("\n"));
|
|
2904
|
+
}
|
|
2905
|
+
return 0;
|
|
2906
|
+
}
|
|
2602
2907
|
function parseAnalyticsChartsCreateArgs(args) {
|
|
2603
2908
|
if (args.includes("--help") || args.includes("-h")) {
|
|
2604
2909
|
return { command: "help", topic: "app analytics charts create" };
|
|
@@ -2748,6 +3053,18 @@ function parseTenderArgs(args) {
|
|
|
2748
3053
|
resourceArgs[3] === "query") {
|
|
2749
3054
|
return parseAnalyticsExportQueryArgs(resourceArgs.slice(4));
|
|
2750
3055
|
}
|
|
3056
|
+
if (resourceArgs[1] === "analytics" &&
|
|
3057
|
+
resourceArgs[2] === "charts" &&
|
|
3058
|
+
resourceArgs[3] === "templates") {
|
|
3059
|
+
return parseAnalyticsChartsTemplatesArgs(resourceArgs.slice(4));
|
|
3060
|
+
}
|
|
3061
|
+
if (resourceArgs[1] === "analytics" &&
|
|
3062
|
+
resourceArgs[2] === "charts" &&
|
|
3063
|
+
(resourceArgs[3] === undefined ||
|
|
3064
|
+
resourceArgs[3] === "--help" ||
|
|
3065
|
+
resourceArgs[3] === "-h")) {
|
|
3066
|
+
return { command: "help", topic: "app analytics charts templates" };
|
|
3067
|
+
}
|
|
2751
3068
|
if (resourceArgs[1] === "analytics" &&
|
|
2752
3069
|
resourceArgs[2] === "charts" &&
|
|
2753
3070
|
resourceArgs[3] === "create") {
|
|
@@ -5470,6 +5787,9 @@ export async function runTenderCli(args, io = {
|
|
|
5470
5787
|
else if (command.topic === "app analytics export query") {
|
|
5471
5788
|
io.stdout(analyticsExportQueryHelp());
|
|
5472
5789
|
}
|
|
5790
|
+
else if (command.topic === "app analytics charts templates") {
|
|
5791
|
+
io.stdout(analyticsChartsTemplatesHelp());
|
|
5792
|
+
}
|
|
5473
5793
|
else if (command.topic === "app analytics charts create") {
|
|
5474
5794
|
io.stdout(analyticsChartsCreateHelp());
|
|
5475
5795
|
}
|
|
@@ -5568,6 +5888,9 @@ export async function runTenderCli(args, io = {
|
|
|
5568
5888
|
if (command.command === "app analytics export query") {
|
|
5569
5889
|
return await runAnalyticsExportQuery(command, io, runtime);
|
|
5570
5890
|
}
|
|
5891
|
+
if (command.command === "app analytics charts templates") {
|
|
5892
|
+
return runAnalyticsChartsTemplates(command, io);
|
|
5893
|
+
}
|
|
5571
5894
|
if (command.command === "app analytics charts create") {
|
|
5572
5895
|
return await runAnalyticsChartsCreate(command, io, runtime);
|
|
5573
5896
|
}
|