@tenderprompt/cli 0.1.2 → 0.1.4
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 +22 -17
- package/dist/index.js +1264 -234
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
|
4
4
|
import os from "node:os";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
|
-
import { validateTenderApp, } from "@tenderprompt/tender-app-validator";
|
|
7
|
+
import { generateTenderAppEnvTypes, validateTenderApp, } from "@tenderprompt/tender-app-validator";
|
|
8
8
|
import { collectTenderAppFiles } from "./local-files.js";
|
|
9
9
|
class TenderCliUsageError extends Error {
|
|
10
10
|
constructor(message) {
|
|
@@ -23,58 +23,73 @@ Commands:
|
|
|
23
23
|
tender auth login --device
|
|
24
24
|
Authorize this machine with a browser-approved device flow
|
|
25
25
|
tender auth status Show whether a Tender API token is available
|
|
26
|
-
tender
|
|
27
|
-
tender
|
|
28
|
-
Create a new
|
|
29
|
-
tender
|
|
30
|
-
Update
|
|
31
|
-
tender
|
|
26
|
+
tender app list List Tender App records visible to the current token
|
|
27
|
+
tender app create --name <name>
|
|
28
|
+
Create a new Tender App in the current account
|
|
29
|
+
tender app update <app-id> --name <name>
|
|
30
|
+
Update app metadata
|
|
31
|
+
tender app init <app-id>
|
|
32
32
|
Bootstrap a checkout for local agent work
|
|
33
|
-
tender
|
|
34
|
-
Validate the server-side
|
|
35
|
-
tender
|
|
36
|
-
Build the current
|
|
37
|
-
tender
|
|
33
|
+
tender app validate <app-id>
|
|
34
|
+
Validate the server-side app workspace
|
|
35
|
+
tender app build <app-id>
|
|
36
|
+
Build the current app workspace
|
|
37
|
+
tender app preview <app-id>
|
|
38
38
|
Rebuild the preview from the current workspace
|
|
39
|
-
tender
|
|
39
|
+
tender app preview status <app-id>
|
|
40
40
|
Show the latest or commit-pinned preview job
|
|
41
|
-
tender
|
|
41
|
+
tender app preview watch <app-id>
|
|
42
42
|
Stream or print lifecycle events for a preview job
|
|
43
|
-
tender
|
|
43
|
+
tender app publish <app-id>
|
|
44
44
|
Publish after explicit confirmation
|
|
45
|
-
tender
|
|
45
|
+
tender app publish status <app-id>
|
|
46
46
|
Show publish job status by job id
|
|
47
|
-
tender
|
|
47
|
+
tender app publish watch <app-id>
|
|
48
48
|
Stream or print lifecycle events for a publish job
|
|
49
|
-
tender
|
|
49
|
+
tender app analytics summary <app-id>
|
|
50
|
+
Read artifact analytics totals and trend points
|
|
51
|
+
tender app analytics query <app-id> --spec <file|->
|
|
52
|
+
Run a server-validated chart spec
|
|
53
|
+
tender app analytics suggestions <app-id>
|
|
54
|
+
Generate useful starter chart suggestions
|
|
55
|
+
tender app context fetch <app-id>
|
|
50
56
|
Fetch managed agent context into a checkout
|
|
51
|
-
tender
|
|
57
|
+
tender app context status <app-id>
|
|
52
58
|
Report whether managed context is stale
|
|
53
|
-
tender
|
|
59
|
+
tender app context refresh <app-id>
|
|
54
60
|
Refresh managed context files
|
|
55
|
-
tender
|
|
56
|
-
Configure a checkout to push to the
|
|
57
|
-
tender
|
|
61
|
+
tender app git setup <app-id>
|
|
62
|
+
Configure a checkout to push to the app remote
|
|
63
|
+
tender app doctor Validate a local Tender App checkout
|
|
64
|
+
tender app generate-env-types
|
|
65
|
+
Regenerate src/env.d.ts from app.json and bindings
|
|
66
|
+
|
|
67
|
+
Compatibility:
|
|
68
|
+
tender artifacts ... Legacy alias for Tender App commands
|
|
58
69
|
|
|
59
70
|
Examples:
|
|
60
71
|
tender auth login --device --profile edit-preview --artifact artifact_123 --ttl 7d
|
|
61
72
|
tender auth status --json
|
|
62
|
-
tender
|
|
63
|
-
tender
|
|
64
|
-
tender
|
|
65
|
-
tender
|
|
66
|
-
tender
|
|
67
|
-
tender
|
|
68
|
-
tender
|
|
69
|
-
tender
|
|
70
|
-
tender
|
|
71
|
-
tender
|
|
72
|
-
tender
|
|
73
|
-
tender
|
|
74
|
-
tender
|
|
75
|
-
tender
|
|
76
|
-
tender
|
|
77
|
-
tender
|
|
73
|
+
tender app list --json
|
|
74
|
+
tender app create --name "Exit Intent Widget" --json
|
|
75
|
+
tender app update artifact_123 --name "Sale Widget" --json
|
|
76
|
+
tender app init artifact_123 --dir ./widget --json
|
|
77
|
+
tender app validate artifact_123 --json
|
|
78
|
+
tender app build artifact_123 --commit $(git rev-parse HEAD) --json
|
|
79
|
+
tender app preview artifact_123 --commit $(git rev-parse HEAD) --stream --json
|
|
80
|
+
tender app preview status artifact_123 --commit $(git rev-parse HEAD) --json
|
|
81
|
+
tender app preview watch artifact_123 --job job_123 --stream --json
|
|
82
|
+
tender app publish artifact_123 --commit $(git rev-parse HEAD) --confirm publish --stream --json
|
|
83
|
+
tender app analytics summary artifact_123 --range 30d --json
|
|
84
|
+
tender app analytics query artifact_123 --spec chart.json --json
|
|
85
|
+
tender app analytics suggestions artifact_123 --range 30d --json
|
|
86
|
+
tender app context fetch artifact_123 --dir ./widget --dry-run --json
|
|
87
|
+
tender app context status artifact_123 --dir ./widget --json
|
|
88
|
+
tender app context refresh artifact_123 --dir ./widget --dry-run --json
|
|
89
|
+
tender app git setup artifact_123 --dir ./widget --json
|
|
90
|
+
tender app doctor --dir ./widget
|
|
91
|
+
tender app generate-env-types --dir ./widget --json
|
|
92
|
+
tender app doctor --dir ./widget --json`;
|
|
78
93
|
}
|
|
79
94
|
function authHelp() {
|
|
80
95
|
return `Usage: tender auth <command> [options]
|
|
@@ -117,68 +132,187 @@ Examples:
|
|
|
117
132
|
tender auth status
|
|
118
133
|
tender auth status --profile publish --json`;
|
|
119
134
|
}
|
|
120
|
-
function
|
|
121
|
-
return `Usage: tender
|
|
135
|
+
function appHelp() {
|
|
136
|
+
return `Usage: tender app <command> [options]
|
|
122
137
|
|
|
123
138
|
Commands:
|
|
124
|
-
tender
|
|
125
|
-
tender
|
|
126
|
-
Create a new
|
|
127
|
-
tender
|
|
128
|
-
Update
|
|
129
|
-
tender
|
|
139
|
+
tender app list List Tender App records visible to the current token
|
|
140
|
+
tender app create --name <name>
|
|
141
|
+
Create a new Tender App in the current account
|
|
142
|
+
tender app update <app-id> --name <name>
|
|
143
|
+
Update app metadata
|
|
144
|
+
tender app init <app-id>
|
|
130
145
|
Bootstrap context files and the tender Git remote
|
|
131
|
-
tender
|
|
132
|
-
Validate the server-side
|
|
133
|
-
tender
|
|
134
|
-
Build the current
|
|
135
|
-
tender
|
|
146
|
+
tender app validate <app-id>
|
|
147
|
+
Validate the server-side app workspace
|
|
148
|
+
tender app build <app-id>
|
|
149
|
+
Build the current app workspace
|
|
150
|
+
tender app preview <app-id>
|
|
136
151
|
Rebuild the preview and optionally stream lifecycle events
|
|
137
|
-
tender
|
|
152
|
+
tender app preview status <app-id>
|
|
138
153
|
Show preview job status by latest, commit, or job id
|
|
139
|
-
tender
|
|
154
|
+
tender app preview watch <app-id>
|
|
140
155
|
Replay lifecycle events by latest, commit, or job id
|
|
141
|
-
tender
|
|
156
|
+
tender app publish <app-id>
|
|
142
157
|
Publish after dry-run or explicit confirmation
|
|
143
|
-
tender
|
|
158
|
+
tender app publish status <app-id>
|
|
144
159
|
Show publish job status by job id
|
|
145
|
-
tender
|
|
160
|
+
tender app publish watch <app-id>
|
|
146
161
|
Replay lifecycle events for a publish job id
|
|
147
|
-
tender
|
|
162
|
+
tender app analytics summary <app-id>
|
|
163
|
+
Read artifact analytics totals and trend points
|
|
164
|
+
tender app analytics query <app-id> --spec <file|->
|
|
165
|
+
Run a server-validated chart spec
|
|
166
|
+
tender app analytics suggestions <app-id>
|
|
167
|
+
Generate useful starter chart suggestions
|
|
168
|
+
tender app analytics dashboards <app-id>
|
|
169
|
+
List or create saved dashboards
|
|
170
|
+
tender app analytics charts create <app-id>
|
|
171
|
+
Create a saved chart from a chart spec
|
|
172
|
+
tender app context fetch <app-id>
|
|
148
173
|
Fetch AGENTS.md, skills, and Tender App scaffold files
|
|
149
|
-
tender
|
|
174
|
+
tender app context status <app-id>
|
|
150
175
|
Show managed context freshness for a checkout
|
|
151
|
-
tender
|
|
176
|
+
tender app context refresh <app-id>
|
|
152
177
|
Refresh managed context files in a checkout
|
|
153
|
-
tender
|
|
178
|
+
tender app git setup <app-id>
|
|
154
179
|
Configure the tender Git remote and credential helper
|
|
155
|
-
tender
|
|
156
|
-
tender
|
|
180
|
+
tender app doctor Validate local context, TypeScript scaffold, and Tender App rules
|
|
181
|
+
tender app generate-env-types
|
|
182
|
+
Regenerate src/env.d.ts from app.json and bindings
|
|
183
|
+
tender app git remote <app-id>
|
|
157
184
|
Show Tender-hosted Git remote metadata
|
|
158
185
|
|
|
159
186
|
Examples:
|
|
160
|
-
tender
|
|
161
|
-
tender
|
|
162
|
-
tender
|
|
163
|
-
tender
|
|
164
|
-
tender
|
|
165
|
-
tender
|
|
166
|
-
tender
|
|
167
|
-
tender
|
|
168
|
-
tender
|
|
169
|
-
tender
|
|
170
|
-
tender
|
|
171
|
-
tender
|
|
172
|
-
tender
|
|
173
|
-
tender
|
|
174
|
-
tender
|
|
175
|
-
tender
|
|
176
|
-
tender
|
|
177
|
-
tender
|
|
178
|
-
tender
|
|
187
|
+
tender app list --json
|
|
188
|
+
tender app create --name "Exit Intent Widget" --json
|
|
189
|
+
tender app update artifact_123 --name "Sale Widget" --json
|
|
190
|
+
tender app init artifact_123 --dir ./widget --json
|
|
191
|
+
tender app validate artifact_123 --json
|
|
192
|
+
tender app build artifact_123 --commit $(git rev-parse HEAD) --json
|
|
193
|
+
tender app preview artifact_123 --commit $(git rev-parse HEAD) --stream --json
|
|
194
|
+
tender app preview status artifact_123 --commit $(git rev-parse HEAD) --json
|
|
195
|
+
tender app preview watch artifact_123 --job job_123 --stream --json
|
|
196
|
+
tender app publish artifact_123 --dry-run --json
|
|
197
|
+
tender app publish status artifact_123 --job job_123 --json
|
|
198
|
+
tender app publish watch artifact_123 --job job_123 --stream --json
|
|
199
|
+
tender app analytics summary artifact_123 --range 30d --json
|
|
200
|
+
tender app analytics query artifact_123 --spec chart.json --json
|
|
201
|
+
tender app analytics suggestions artifact_123 --range 30d --json
|
|
202
|
+
tender app analytics dashboards artifact_123 --json
|
|
203
|
+
tender app analytics dashboards artifact_123 --create "Agent dashboard" --json
|
|
204
|
+
tender app analytics charts create artifact_123 --dashboard analytics_dashboard_123 --title "Signup funnel" --spec funnel.json --json
|
|
205
|
+
tender app context fetch artifact_123 --dir ./widget --dry-run --json
|
|
206
|
+
tender app context status artifact_123 --dir ./widget --json
|
|
207
|
+
tender app context refresh artifact_123 --dir ./widget --dry-run --json
|
|
208
|
+
tender app git setup artifact_123 --dir ./widget --json
|
|
209
|
+
tender app doctor --dir ./widget
|
|
210
|
+
tender app generate-env-types --dir ./widget --json
|
|
211
|
+
tender app doctor --json
|
|
212
|
+
tender app git remote artifact_123 --ttl 7d --json`;
|
|
213
|
+
}
|
|
214
|
+
function artifactsHelp() {
|
|
215
|
+
return `${appHelp()}
|
|
216
|
+
|
|
217
|
+
Legacy alias:
|
|
218
|
+
tender artifacts ... continues to work for existing automation. Prefer tender app ... for new workflows.`;
|
|
219
|
+
}
|
|
220
|
+
function analyticsHelp() {
|
|
221
|
+
return `Usage: tender app analytics <command> <app-id> [options]
|
|
222
|
+
|
|
223
|
+
Start here for agents:
|
|
224
|
+
tender app analytics capabilities <app-id> --include-catalog --range 30d --json
|
|
225
|
+
|
|
226
|
+
Commands:
|
|
227
|
+
tender app analytics summary <app-id> Read totals and trend points
|
|
228
|
+
tender app analytics query <app-id> Run one chart spec
|
|
229
|
+
tender app analytics capabilities <app-id> Describe agent-safe analytics capabilities
|
|
230
|
+
tender app analytics suggestions <app-id> Generate starter chart suggestions
|
|
231
|
+
tender app analytics dashboards <app-id> List or create dashboards
|
|
232
|
+
tender app analytics export <kind> <app-id> Export catalog metadata or query rows
|
|
233
|
+
tender app analytics charts create <app-id> Create a saved chart
|
|
234
|
+
|
|
235
|
+
Examples:
|
|
236
|
+
tender app analytics summary artifact_123 --range 30d --json
|
|
237
|
+
tender app analytics capabilities artifact_123 --include-catalog --json
|
|
238
|
+
tender app analytics query artifact_123 --spec chart.json --json
|
|
239
|
+
tender app analytics query artifact_123 --spec - --json < chart.json
|
|
240
|
+
tender app analytics export catalog artifact_123 --range 30d --json
|
|
241
|
+
tender app analytics export query artifact_123 --spec chart.json --format csv
|
|
242
|
+
tender app analytics suggestions artifact_123 --range 2026-04-01..2026-04-30 --json
|
|
243
|
+
tender app analytics dashboards artifact_123 --create "Agent dashboard" --json
|
|
244
|
+
tender app analytics charts create artifact_123 --dashboard analytics_dashboard_123 --title "Signup funnel" --spec funnel.json --json`;
|
|
245
|
+
}
|
|
246
|
+
function analyticsSummaryHelp() {
|
|
247
|
+
return `Usage: tender app analytics summary <app-id> [--range <7d|30d|90d|YYYY-MM-DD..YYYY-MM-DD>] [--base-url <url>] [--token <token>] [--profile <name>] [--json]
|
|
248
|
+
|
|
249
|
+
Examples:
|
|
250
|
+
tender app analytics summary artifact_123 --range 30d --json
|
|
251
|
+
tender app analytics summary artifact_123 --range 2026-04-01..2026-04-30 --json`;
|
|
252
|
+
}
|
|
253
|
+
function analyticsQueryHelp() {
|
|
254
|
+
return `Usage: tender app analytics query <app-id> --spec <file|-> [--base-url <url>] [--token <token>] [--profile <name>] [--json]
|
|
255
|
+
|
|
256
|
+
Examples:
|
|
257
|
+
tender app analytics query artifact_123 --spec chart.json --json
|
|
258
|
+
tender app analytics query artifact_123 --spec - --json < chart.json`;
|
|
259
|
+
}
|
|
260
|
+
function analyticsCapabilitiesHelp() {
|
|
261
|
+
return `Usage: tender app analytics capabilities <app-id> [--include-catalog] [--range <7d|30d|90d|YYYY-MM-DD..YYYY-MM-DD>] [--base-url <url>] [--token <token>] [--profile <name>] [--json]
|
|
262
|
+
|
|
263
|
+
Use this as the self-documenting entrypoint for coding agents. With --include-catalog,
|
|
264
|
+
the response includes observed events, paths, rough property types, current saved
|
|
265
|
+
dashboards, supported chart spec shapes, retention limits, and safe next commands.
|
|
266
|
+
|
|
267
|
+
Examples:
|
|
268
|
+
tender app analytics capabilities artifact_123 --json
|
|
269
|
+
tender app analytics capabilities artifact_123 --include-catalog --range 30d --json`;
|
|
270
|
+
}
|
|
271
|
+
function analyticsExportHelp() {
|
|
272
|
+
return `Usage: tender app analytics export <catalog|query> <app-id> [options]
|
|
273
|
+
|
|
274
|
+
Examples:
|
|
275
|
+
tender app analytics export catalog artifact_123 --range 30d --json
|
|
276
|
+
tender app analytics export query artifact_123 --spec chart.json --format json
|
|
277
|
+
tender app analytics export query artifact_123 --spec chart.json --format csv`;
|
|
278
|
+
}
|
|
279
|
+
function analyticsExportCatalogHelp() {
|
|
280
|
+
return `Usage: tender app analytics export catalog <app-id> [--range <7d|30d|90d|YYYY-MM-DD..YYYY-MM-DD>] [--format json] [--base-url <url>] [--token <token>] [--profile <name>] [--json]
|
|
281
|
+
|
|
282
|
+
Examples:
|
|
283
|
+
tender app analytics export catalog artifact_123 --range 30d --json`;
|
|
284
|
+
}
|
|
285
|
+
function analyticsExportQueryHelp() {
|
|
286
|
+
return `Usage: tender app analytics export query <app-id> --spec <file|-> [--format <json|csv>] [--base-url <url>] [--token <token>] [--profile <name>] [--json]
|
|
287
|
+
|
|
288
|
+
Examples:
|
|
289
|
+
tender app analytics export query artifact_123 --spec chart.json --format json
|
|
290
|
+
tender app analytics export query artifact_123 --spec chart.json --format csv
|
|
291
|
+
tender app analytics export query artifact_123 --spec - --format csv < chart.json`;
|
|
292
|
+
}
|
|
293
|
+
function analyticsSuggestionsHelp() {
|
|
294
|
+
return `Usage: tender app analytics suggestions <app-id> [--range <7d|30d|90d|YYYY-MM-DD..YYYY-MM-DD>] [--base-url <url>] [--token <token>] [--profile <name>] [--json]
|
|
295
|
+
|
|
296
|
+
Examples:
|
|
297
|
+
tender app analytics suggestions artifact_123 --range 30d --json`;
|
|
298
|
+
}
|
|
299
|
+
function analyticsDashboardsHelp() {
|
|
300
|
+
return `Usage: tender app analytics dashboards <app-id> [--create <name>] [--dry-run] [--base-url <url>] [--token <token>] [--profile <name>] [--json]
|
|
301
|
+
|
|
302
|
+
Examples:
|
|
303
|
+
tender app analytics dashboards artifact_123 --json
|
|
304
|
+
tender app analytics dashboards artifact_123 --create "Agent dashboard" --dry-run --json
|
|
305
|
+
tender app analytics dashboards artifact_123 --create "Agent dashboard" --json`;
|
|
306
|
+
}
|
|
307
|
+
function analyticsChartsCreateHelp() {
|
|
308
|
+
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]
|
|
309
|
+
|
|
310
|
+
Examples:
|
|
311
|
+
tender app analytics charts create artifact_123 --dashboard analytics_dashboard_123 --title "Signup funnel" --spec funnel.json --dry-run --json
|
|
312
|
+
tender app analytics charts create artifact_123 --dashboard analytics_dashboard_123 --title "Signup funnel" --spec funnel.json --json`;
|
|
179
313
|
}
|
|
180
314
|
function artifactsListHelp() {
|
|
181
|
-
return `Usage: tender
|
|
315
|
+
return `Usage: tender app list [--base-url <url>] [--token <token>] [--profile <name>] [--json]
|
|
182
316
|
|
|
183
317
|
Options:
|
|
184
318
|
--base-url <url> Tender base URL. Defaults to TENDER_BASE_URL, saved profile base URL, or https://app.tenderprompt.com.
|
|
@@ -187,15 +321,15 @@ Options:
|
|
|
187
321
|
--json Emit stable JSON for coding agents.
|
|
188
322
|
|
|
189
323
|
Examples:
|
|
190
|
-
tender
|
|
191
|
-
tender
|
|
192
|
-
TENDER_API_TOKEN=tpat_... tender
|
|
324
|
+
tender app list --json
|
|
325
|
+
tender app list --profile account --json
|
|
326
|
+
TENDER_API_TOKEN=tpat_... tender app list --base-url https://app.tenderprompt.com --json`;
|
|
193
327
|
}
|
|
194
328
|
function artifactsCreateHelp() {
|
|
195
|
-
return `Usage: tender
|
|
329
|
+
return `Usage: tender app create --name <name> [--target-pack <id>] [--target-pack-version <version>] [--base-url <url>] [--token <token>] [--profile <name>] [--json]
|
|
196
330
|
|
|
197
331
|
Options:
|
|
198
|
-
--name <name>
|
|
332
|
+
--name <name> App name.
|
|
199
333
|
--target-pack <id> Target pack id. Defaults to the API default.
|
|
200
334
|
--target-pack-version <value> Target pack version. Defaults to the API default.
|
|
201
335
|
--base-url <url> Tender base URL. Defaults to TENDER_BASE_URL, saved profile base URL, or https://app.tenderprompt.com.
|
|
@@ -204,24 +338,24 @@ Options:
|
|
|
204
338
|
--json Emit stable JSON for coding agents.
|
|
205
339
|
|
|
206
340
|
Examples:
|
|
207
|
-
tender
|
|
208
|
-
tender
|
|
341
|
+
tender app create --name "Exit Intent Widget" --json
|
|
342
|
+
tender app create --name "Exit Intent Widget" --profile account --json`;
|
|
209
343
|
}
|
|
210
344
|
function artifactsUpdateHelp() {
|
|
211
|
-
return `Usage: tender
|
|
345
|
+
return `Usage: tender app update <app-id> --name <name> [--base-url <url>] [--token <token>] [--profile <name>] [--json]
|
|
212
346
|
|
|
213
347
|
Options:
|
|
214
|
-
--name <name> New
|
|
348
|
+
--name <name> New app name.
|
|
215
349
|
--base-url <url> Tender base URL. Defaults to TENDER_BASE_URL, saved profile base URL, or https://app.tenderprompt.com.
|
|
216
350
|
--token <token> Tender API token. Defaults to TENDER_API_TOKEN or the saved profile token.
|
|
217
351
|
--profile <name> Local config profile name. Defaults to the saved default profile.
|
|
218
352
|
--json Emit stable JSON for coding agents.
|
|
219
353
|
|
|
220
354
|
Examples:
|
|
221
|
-
tender
|
|
355
|
+
tender app update artifact_123 --name "Sale Widget" --json`;
|
|
222
356
|
}
|
|
223
357
|
function artifactsInitHelp() {
|
|
224
|
-
return `Usage: tender
|
|
358
|
+
return `Usage: tender app init <app-id> [--dir <path>] [--remote <name>] [--base-url <url>] [--token <token>] [--profile <name>] [--ttl <7d|14d|30d>] [--dry-run] [--force] [--json]
|
|
225
359
|
|
|
226
360
|
Options:
|
|
227
361
|
--dir <path> Local checkout directory to create/update. Defaults to current directory.
|
|
@@ -235,12 +369,12 @@ Options:
|
|
|
235
369
|
--json Emit stable JSON for coding agents.
|
|
236
370
|
|
|
237
371
|
Examples:
|
|
238
|
-
tender
|
|
239
|
-
tender
|
|
240
|
-
tender
|
|
372
|
+
tender app init artifact_123 --dir ./widget --dry-run --json
|
|
373
|
+
tender app init artifact_123 --dir ./widget --json
|
|
374
|
+
tender app init artifact_123 --dir ./widget --force --json`;
|
|
241
375
|
}
|
|
242
376
|
function artifactsContextFetchHelp() {
|
|
243
|
-
return `Usage: tender
|
|
377
|
+
return `Usage: tender app context fetch <app-id> [--dir <path>] [--base-url <url>] [--token <token>] [--profile <name>] [--dry-run] [--force] [--json]
|
|
244
378
|
|
|
245
379
|
Options:
|
|
246
380
|
--dir <path> Local checkout to update. Defaults to current directory.
|
|
@@ -252,12 +386,12 @@ Options:
|
|
|
252
386
|
--json Emit stable JSON for coding agents.
|
|
253
387
|
|
|
254
388
|
Examples:
|
|
255
|
-
tender
|
|
256
|
-
tender
|
|
257
|
-
tender
|
|
389
|
+
tender app context fetch artifact_123 --dir ./widget --dry-run --json
|
|
390
|
+
tender app context fetch artifact_123 --dir ./widget --force
|
|
391
|
+
tender app context fetch artifact_123 --profile agent --json`;
|
|
258
392
|
}
|
|
259
393
|
function artifactsContextStatusHelp() {
|
|
260
|
-
return `Usage: tender
|
|
394
|
+
return `Usage: tender app context status <app-id> [--dir <path>] [--base-url <url>] [--token <token>] [--profile <name>] [--json]
|
|
261
395
|
|
|
262
396
|
Options:
|
|
263
397
|
--dir <path> Local checkout to inspect. Defaults to current directory.
|
|
@@ -267,10 +401,10 @@ Options:
|
|
|
267
401
|
--json Emit stable JSON for coding agents.
|
|
268
402
|
|
|
269
403
|
Examples:
|
|
270
|
-
tender
|
|
404
|
+
tender app context status artifact_123 --dir ./widget --json`;
|
|
271
405
|
}
|
|
272
406
|
function artifactsContextRefreshHelp() {
|
|
273
|
-
return `Usage: tender
|
|
407
|
+
return `Usage: tender app context refresh <app-id> [--dir <path>] [--base-url <url>] [--token <token>] [--profile <name>] [--dry-run] [--force] [--json]
|
|
274
408
|
|
|
275
409
|
Options:
|
|
276
410
|
--dir <path> Local checkout to update. Defaults to current directory.
|
|
@@ -282,22 +416,33 @@ Options:
|
|
|
282
416
|
--json Emit stable JSON for coding agents.
|
|
283
417
|
|
|
284
418
|
Examples:
|
|
285
|
-
tender
|
|
286
|
-
tender
|
|
419
|
+
tender app context refresh artifact_123 --dir ./widget --dry-run --json
|
|
420
|
+
tender app context refresh artifact_123 --dir ./widget --force`;
|
|
287
421
|
}
|
|
288
422
|
function doctorHelp() {
|
|
289
|
-
return `Usage: tender
|
|
423
|
+
return `Usage: tender app doctor [--dir <path>] [--json]
|
|
290
424
|
|
|
291
425
|
Options:
|
|
292
426
|
--dir <path> Local Tender App checkout to inspect. Defaults to current directory.
|
|
293
427
|
--json Emit stable JSON for coding agents.
|
|
294
428
|
|
|
295
429
|
Examples:
|
|
296
|
-
tender
|
|
297
|
-
tender
|
|
430
|
+
tender app doctor --dir ./widget
|
|
431
|
+
tender app doctor --dir ./widget --json`;
|
|
432
|
+
}
|
|
433
|
+
function generateEnvTypesHelp() {
|
|
434
|
+
return `Usage: tender app generate-env-types [--dir <path>] [--json]
|
|
435
|
+
|
|
436
|
+
Options:
|
|
437
|
+
--dir <path> Local Tender App checkout to update. Defaults to current directory.
|
|
438
|
+
--json Emit stable JSON for coding agents.
|
|
439
|
+
|
|
440
|
+
Examples:
|
|
441
|
+
tender app generate-env-types --dir ./widget
|
|
442
|
+
tender app generate-env-types --dir ./widget --json`;
|
|
298
443
|
}
|
|
299
444
|
function gitRemoteHelp() {
|
|
300
|
-
return `Usage: tender
|
|
445
|
+
return `Usage: tender app git remote <app-id> [--base-url <url>] [--token <token>] [--profile <name>] [--ttl <7d|14d|30d>] [--json]
|
|
301
446
|
|
|
302
447
|
Options:
|
|
303
448
|
--base-url <url> Tender base URL. Defaults to TENDER_BASE_URL, saved profile base URL, or https://app.tenderprompt.com.
|
|
@@ -307,12 +452,12 @@ Options:
|
|
|
307
452
|
--json Emit stable JSON for coding agents.
|
|
308
453
|
|
|
309
454
|
Examples:
|
|
310
|
-
tender
|
|
311
|
-
tender
|
|
312
|
-
TENDER_API_TOKEN=tp_... tender
|
|
455
|
+
tender app git remote artifact_123 --ttl 7d --json
|
|
456
|
+
tender app git remote artifact_123 --profile publish --ttl 7d --json
|
|
457
|
+
TENDER_API_TOKEN=tp_... tender app git remote artifact_123 --base-url https://app.tenderprompt.com --json`;
|
|
313
458
|
}
|
|
314
459
|
function gitSetupHelp() {
|
|
315
|
-
return `Usage: tender
|
|
460
|
+
return `Usage: tender app git setup <app-id> [--dir <path>] [--remote <name>] [--base-url <url>] [--token <token>] [--profile <name>] [--ttl <7d|14d|30d>] [--dry-run] [--json]
|
|
316
461
|
|
|
317
462
|
Options:
|
|
318
463
|
--dir <path> Local Git checkout to configure. Defaults to current directory.
|
|
@@ -325,26 +470,26 @@ Options:
|
|
|
325
470
|
--json Emit stable JSON for coding agents.
|
|
326
471
|
|
|
327
472
|
Examples:
|
|
328
|
-
tender
|
|
329
|
-
tender
|
|
330
|
-
tender
|
|
473
|
+
tender app git setup artifact_123 --dir ./widget --json
|
|
474
|
+
tender app git setup artifact_123 --dir ./widget --remote tender --ttl 7d
|
|
475
|
+
tender app git setup artifact_123 --dir ./widget --dry-run --json`;
|
|
331
476
|
}
|
|
332
477
|
function gitCredentialHelp() {
|
|
333
|
-
return `Usage: tender
|
|
478
|
+
return `Usage: tender app git credential <app-id> [get|store|erase] [--base-url <url>] [--token <token>] [--profile <name>] [--ttl <7d|14d|30d>] [--remote-url <url>]
|
|
334
479
|
|
|
335
480
|
This command is intended for Git's credential.helper protocol. It prints a
|
|
336
481
|
Tender API-token username/password pair only for matching get requests. Do not
|
|
337
482
|
run it manually unless you are debugging Git credential-helper behavior.
|
|
338
483
|
|
|
339
484
|
Examples:
|
|
340
|
-
tender
|
|
341
|
-
tender
|
|
485
|
+
tender app git credential artifact_123 get
|
|
486
|
+
tender app git credential artifact_123 get --remote-url https://app.tenderprompt.com/git/artifacts/artifact_123.git`;
|
|
342
487
|
}
|
|
343
488
|
function previewRebuildHelp() {
|
|
344
|
-
return `Usage: tender
|
|
489
|
+
return `Usage: tender app preview rebuild <app-id> [--commit <sha>] [--base-url <url>] [--token <token>] [--profile <name>] [--stream] [--json]
|
|
345
490
|
|
|
346
491
|
Options:
|
|
347
|
-
--commit <sha> Rebuild preview only if the
|
|
492
|
+
--commit <sha> Rebuild preview only if the app workspace is at this Git commit.
|
|
348
493
|
--base-url <url> Tender base URL. Defaults to TENDER_BASE_URL, saved profile base URL, or https://app.tenderprompt.com.
|
|
349
494
|
--token <token> Tender API token. Defaults to TENDER_API_TOKEN or the saved profile token.
|
|
350
495
|
--profile <name> Local config profile name. Defaults to the saved default profile.
|
|
@@ -352,11 +497,11 @@ Options:
|
|
|
352
497
|
--json Emit stable JSON for coding agents.
|
|
353
498
|
|
|
354
499
|
Examples:
|
|
355
|
-
tender
|
|
356
|
-
tender
|
|
500
|
+
tender app preview rebuild artifact_123 --commit $(git rev-parse HEAD) --stream --json
|
|
501
|
+
tender app preview rebuild artifact_123 --json`;
|
|
357
502
|
}
|
|
358
503
|
function validateHelp() {
|
|
359
|
-
return `Usage: tender
|
|
504
|
+
return `Usage: tender app validate <app-id> [--base-url <url>] [--token <token>] [--profile <name>] [--stream] [--json]
|
|
360
505
|
|
|
361
506
|
Options:
|
|
362
507
|
--base-url <url> Tender base URL. Defaults to TENDER_BASE_URL, saved profile base URL, or https://app.tenderprompt.com.
|
|
@@ -366,14 +511,14 @@ Options:
|
|
|
366
511
|
--json Emit stable JSON for coding agents.
|
|
367
512
|
|
|
368
513
|
Examples:
|
|
369
|
-
tender
|
|
370
|
-
tender
|
|
514
|
+
tender app validate artifact_123 --json
|
|
515
|
+
tender app validate artifact_123 --stream --json`;
|
|
371
516
|
}
|
|
372
517
|
function buildHelp() {
|
|
373
|
-
return `Usage: tender
|
|
518
|
+
return `Usage: tender app build <app-id> [--commit <sha>] [--base-url <url>] [--token <token>] [--profile <name>] [--stream] [--json]
|
|
374
519
|
|
|
375
520
|
Options:
|
|
376
|
-
--commit <sha> Build only if the
|
|
521
|
+
--commit <sha> Build only if the app workspace is at this Git commit.
|
|
377
522
|
--base-url <url> Tender base URL. Defaults to TENDER_BASE_URL, saved profile base URL, or https://app.tenderprompt.com.
|
|
378
523
|
--token <token> Tender API token. Defaults to TENDER_API_TOKEN or the saved profile token.
|
|
379
524
|
--profile <name> Local config profile name. Defaults to the saved default profile.
|
|
@@ -381,11 +526,11 @@ Options:
|
|
|
381
526
|
--json Emit stable JSON for coding agents.
|
|
382
527
|
|
|
383
528
|
Examples:
|
|
384
|
-
tender
|
|
385
|
-
tender
|
|
529
|
+
tender app build artifact_123 --commit $(git rev-parse HEAD) --json
|
|
530
|
+
tender app build artifact_123 --stream --json`;
|
|
386
531
|
}
|
|
387
532
|
function previewStatusHelp() {
|
|
388
|
-
return `Usage: tender
|
|
533
|
+
return `Usage: tender app preview status <app-id> [--commit <sha> | --job <job-id>] [--base-url <url>] [--token <token>] [--profile <name>] [--json]
|
|
389
534
|
|
|
390
535
|
Options:
|
|
391
536
|
--commit <sha> Show the latest preview job for one artifact Git commit.
|
|
@@ -396,11 +541,11 @@ Options:
|
|
|
396
541
|
--json Emit stable JSON for coding agents.
|
|
397
542
|
|
|
398
543
|
Examples:
|
|
399
|
-
tender
|
|
400
|
-
tender
|
|
544
|
+
tender app preview status artifact_123 --commit $(git rev-parse HEAD) --json
|
|
545
|
+
tender app preview status artifact_123 --job job_123 --json`;
|
|
401
546
|
}
|
|
402
547
|
function previewWatchHelp() {
|
|
403
|
-
return `Usage: tender
|
|
548
|
+
return `Usage: tender app preview watch <app-id> [--commit <sha> | --job <job-id>] [--base-url <url>] [--token <token>] [--profile <name>] [--stream] [--json]
|
|
404
549
|
|
|
405
550
|
Options:
|
|
406
551
|
--commit <sha> Watch the latest preview job for one artifact Git commit.
|
|
@@ -412,16 +557,16 @@ Options:
|
|
|
412
557
|
--json Emit lifecycle events as JSON lines.
|
|
413
558
|
|
|
414
559
|
Examples:
|
|
415
|
-
tender
|
|
416
|
-
tender
|
|
560
|
+
tender app preview watch artifact_123 --commit $(git rev-parse HEAD) --stream --json
|
|
561
|
+
tender app preview watch artifact_123 --job job_123 --stream --json`;
|
|
417
562
|
}
|
|
418
563
|
function publishHelp() {
|
|
419
|
-
return `Usage: tender
|
|
564
|
+
return `Usage: tender app publish <app-id> (--dry-run | --confirm publish) [--commit <sha>] [--message <text>] [--base-url <url>] [--token <token>] [--profile <name>] [--stream] [--json]
|
|
420
565
|
|
|
421
566
|
Options:
|
|
422
567
|
--dry-run Show the publish request without calling the API.
|
|
423
568
|
--confirm publish Required to call the production-facing publish API.
|
|
424
|
-
--commit <sha> Publish only if the
|
|
569
|
+
--commit <sha> Publish only if the app workspace is at this Git commit.
|
|
425
570
|
--message <text> Human audit message returned in CLI output.
|
|
426
571
|
--base-url <url> Tender base URL. Defaults to TENDER_BASE_URL, saved profile base URL, or https://app.tenderprompt.com.
|
|
427
572
|
--token <token> Tender API token. Defaults to TENDER_API_TOKEN or the saved profile token.
|
|
@@ -430,11 +575,11 @@ Options:
|
|
|
430
575
|
--json Emit stable JSON for coding agents.
|
|
431
576
|
|
|
432
577
|
Examples:
|
|
433
|
-
tender
|
|
434
|
-
tender
|
|
578
|
+
tender app publish artifact_123 --dry-run --json
|
|
579
|
+
tender app publish artifact_123 --commit $(git rev-parse HEAD) --confirm publish --stream --json`;
|
|
435
580
|
}
|
|
436
581
|
function publishStatusHelp() {
|
|
437
|
-
return `Usage: tender
|
|
582
|
+
return `Usage: tender app publish status <app-id> --job <job-id> [--base-url <url>] [--token <token>] [--profile <name>] [--json]
|
|
438
583
|
|
|
439
584
|
Options:
|
|
440
585
|
--job <job-id> Show one publish lifecycle job directly.
|
|
@@ -444,10 +589,10 @@ Options:
|
|
|
444
589
|
--json Emit stable JSON for coding agents.
|
|
445
590
|
|
|
446
591
|
Examples:
|
|
447
|
-
tender
|
|
592
|
+
tender app publish status artifact_123 --job job_123 --json`;
|
|
448
593
|
}
|
|
449
594
|
function publishWatchHelp() {
|
|
450
|
-
return `Usage: tender
|
|
595
|
+
return `Usage: tender app publish watch <app-id> --job <job-id> [--base-url <url>] [--token <token>] [--profile <name>] [--stream] [--json]
|
|
451
596
|
|
|
452
597
|
Options:
|
|
453
598
|
--job <job-id> Watch one publish lifecycle job directly.
|
|
@@ -458,7 +603,7 @@ Options:
|
|
|
458
603
|
--json Emit lifecycle events as JSON lines.
|
|
459
604
|
|
|
460
605
|
Examples:
|
|
461
|
-
tender
|
|
606
|
+
tender app publish watch artifact_123 --job job_123 --stream --json`;
|
|
462
607
|
}
|
|
463
608
|
function normalizeBaseUrl(value) {
|
|
464
609
|
return (value ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
@@ -605,7 +750,7 @@ function parseGitRemoteArgs(args) {
|
|
|
605
750
|
}
|
|
606
751
|
const artifactId = args[0];
|
|
607
752
|
if (!artifactId || artifactId.startsWith("-")) {
|
|
608
|
-
throw new TenderCliUsageError("
|
|
753
|
+
throw new TenderCliUsageError("app id is required. Example: tender app git remote <app-id> --json");
|
|
609
754
|
}
|
|
610
755
|
let baseUrl = null;
|
|
611
756
|
let flagToken = null;
|
|
@@ -665,7 +810,7 @@ function parseGitSetupArgs(args) {
|
|
|
665
810
|
}
|
|
666
811
|
const artifactId = args[0];
|
|
667
812
|
if (!artifactId || artifactId.startsWith("-")) {
|
|
668
|
-
throw new TenderCliUsageError("
|
|
813
|
+
throw new TenderCliUsageError("app id is required. Example: tender app git setup <app-id> --dir ./widget --json");
|
|
669
814
|
}
|
|
670
815
|
let dir = ".";
|
|
671
816
|
let remoteName = "tender";
|
|
@@ -758,7 +903,7 @@ function parseGitCredentialArgs(args) {
|
|
|
758
903
|
}
|
|
759
904
|
const artifactId = args[0];
|
|
760
905
|
if (!artifactId || artifactId.startsWith("-")) {
|
|
761
|
-
throw new TenderCliUsageError("
|
|
906
|
+
throw new TenderCliUsageError("app id is required. Example: tender app git credential <app-id> get");
|
|
762
907
|
}
|
|
763
908
|
const parsedOperation = parseGitCredentialOperation(args[1]);
|
|
764
909
|
let operation = parsedOperation.operation;
|
|
@@ -832,7 +977,7 @@ function parseValidateArgs(args) {
|
|
|
832
977
|
}
|
|
833
978
|
const artifactId = args[0];
|
|
834
979
|
if (!artifactId || artifactId.startsWith("-")) {
|
|
835
|
-
throw new TenderCliUsageError("
|
|
980
|
+
throw new TenderCliUsageError("app id is required. Example: tender app validate <app-id> --json");
|
|
836
981
|
}
|
|
837
982
|
let baseUrl = null;
|
|
838
983
|
let flagToken = null;
|
|
@@ -882,7 +1027,7 @@ function parseBuildArgs(args) {
|
|
|
882
1027
|
}
|
|
883
1028
|
const artifactId = args[0];
|
|
884
1029
|
if (!artifactId || artifactId.startsWith("-")) {
|
|
885
|
-
throw new TenderCliUsageError("
|
|
1030
|
+
throw new TenderCliUsageError("app id is required. Example: tender app build <app-id> --json");
|
|
886
1031
|
}
|
|
887
1032
|
let baseUrl = null;
|
|
888
1033
|
let flagToken = null;
|
|
@@ -943,7 +1088,7 @@ function parsePreviewRebuildArgs(args) {
|
|
|
943
1088
|
}
|
|
944
1089
|
const artifactId = args[0];
|
|
945
1090
|
if (!artifactId || artifactId.startsWith("-")) {
|
|
946
|
-
throw new TenderCliUsageError("
|
|
1091
|
+
throw new TenderCliUsageError("app id is required. Example: tender app preview rebuild <app-id> --stream --json");
|
|
947
1092
|
}
|
|
948
1093
|
let baseUrl = null;
|
|
949
1094
|
let flagToken = null;
|
|
@@ -1070,7 +1215,7 @@ function parsePreviewStatusArgs(args) {
|
|
|
1070
1215
|
}
|
|
1071
1216
|
const artifactId = args[0];
|
|
1072
1217
|
if (!artifactId || artifactId.startsWith("-")) {
|
|
1073
|
-
throw new TenderCliUsageError("
|
|
1218
|
+
throw new TenderCliUsageError("app id is required. Example: tender app preview status <app-id> --commit <sha> --json");
|
|
1074
1219
|
}
|
|
1075
1220
|
const options = readPreviewLookupOptions({
|
|
1076
1221
|
args,
|
|
@@ -1078,7 +1223,7 @@ function parsePreviewStatusArgs(args) {
|
|
|
1078
1223
|
commandName: "preview status",
|
|
1079
1224
|
});
|
|
1080
1225
|
if (options.stream) {
|
|
1081
|
-
throw new TenderCliUsageError("preview status does not support --stream. Use tender
|
|
1226
|
+
throw new TenderCliUsageError("preview status does not support --stream. Use tender app preview watch.");
|
|
1082
1227
|
}
|
|
1083
1228
|
return {
|
|
1084
1229
|
command: "artifacts preview status",
|
|
@@ -1097,7 +1242,7 @@ function parsePreviewWatchArgs(args) {
|
|
|
1097
1242
|
}
|
|
1098
1243
|
const artifactId = args[0];
|
|
1099
1244
|
if (!artifactId || artifactId.startsWith("-")) {
|
|
1100
|
-
throw new TenderCliUsageError("
|
|
1245
|
+
throw new TenderCliUsageError("app id is required. Example: tender app preview watch <app-id> --job <job-id> --stream --json");
|
|
1101
1246
|
}
|
|
1102
1247
|
const options = readPreviewLookupOptions({
|
|
1103
1248
|
args,
|
|
@@ -1122,7 +1267,7 @@ function parsePublishArgs(args) {
|
|
|
1122
1267
|
}
|
|
1123
1268
|
const artifactId = args[0];
|
|
1124
1269
|
if (!artifactId || artifactId.startsWith("-")) {
|
|
1125
|
-
throw new TenderCliUsageError("
|
|
1270
|
+
throw new TenderCliUsageError("app id is required. Example: tender app publish <app-id> --dry-run --json");
|
|
1126
1271
|
}
|
|
1127
1272
|
let baseUrl = null;
|
|
1128
1273
|
let flagToken = null;
|
|
@@ -1269,7 +1414,7 @@ function parsePublishStatusArgs(args) {
|
|
|
1269
1414
|
}
|
|
1270
1415
|
const artifactId = args[0];
|
|
1271
1416
|
if (!artifactId || artifactId.startsWith("-")) {
|
|
1272
|
-
throw new TenderCliUsageError("
|
|
1417
|
+
throw new TenderCliUsageError("app id is required. Example: tender app publish status <app-id> --job <job-id> --json");
|
|
1273
1418
|
}
|
|
1274
1419
|
const options = readPublishJobLookupOptions({
|
|
1275
1420
|
args,
|
|
@@ -1277,7 +1422,7 @@ function parsePublishStatusArgs(args) {
|
|
|
1277
1422
|
commandName: "publish status",
|
|
1278
1423
|
});
|
|
1279
1424
|
if (options.stream) {
|
|
1280
|
-
throw new TenderCliUsageError("publish status does not support --stream. Use tender
|
|
1425
|
+
throw new TenderCliUsageError("publish status does not support --stream. Use tender app publish watch.");
|
|
1281
1426
|
}
|
|
1282
1427
|
return {
|
|
1283
1428
|
command: "artifacts publish status",
|
|
@@ -1295,7 +1440,7 @@ function parsePublishWatchArgs(args) {
|
|
|
1295
1440
|
}
|
|
1296
1441
|
const artifactId = args[0];
|
|
1297
1442
|
if (!artifactId || artifactId.startsWith("-")) {
|
|
1298
|
-
throw new TenderCliUsageError("
|
|
1443
|
+
throw new TenderCliUsageError("app id is required. Example: tender app publish watch <app-id> --job <job-id> --stream --json");
|
|
1299
1444
|
}
|
|
1300
1445
|
const options = readPublishJobLookupOptions({
|
|
1301
1446
|
args,
|
|
@@ -1342,7 +1487,7 @@ function parseArtifactsListArgs(args) {
|
|
|
1342
1487
|
index += 1;
|
|
1343
1488
|
continue;
|
|
1344
1489
|
}
|
|
1345
|
-
throw new TenderCliUsageError(`Unknown
|
|
1490
|
+
throw new TenderCliUsageError(`Unknown app list option: ${arg}`);
|
|
1346
1491
|
}
|
|
1347
1492
|
return {
|
|
1348
1493
|
command: "artifacts list",
|
|
@@ -1372,7 +1517,7 @@ function parseArtifactsCreateArgs(args) {
|
|
|
1372
1517
|
if (arg === "--name") {
|
|
1373
1518
|
const value = args[index + 1];
|
|
1374
1519
|
if (!value || value.startsWith("-")) {
|
|
1375
|
-
throw new TenderCliUsageError("--name requires an
|
|
1520
|
+
throw new TenderCliUsageError("--name requires an app name.");
|
|
1376
1521
|
}
|
|
1377
1522
|
name = value;
|
|
1378
1523
|
index += 1;
|
|
@@ -1411,10 +1556,10 @@ function parseArtifactsCreateArgs(args) {
|
|
|
1411
1556
|
index += 1;
|
|
1412
1557
|
continue;
|
|
1413
1558
|
}
|
|
1414
|
-
throw new TenderCliUsageError(`Unknown
|
|
1559
|
+
throw new TenderCliUsageError(`Unknown app create option: ${arg}`);
|
|
1415
1560
|
}
|
|
1416
1561
|
if (!name.trim()) {
|
|
1417
|
-
throw new TenderCliUsageError("--name is required. Example: tender
|
|
1562
|
+
throw new TenderCliUsageError("--name is required. Example: tender app create --name \"Exit Intent Widget\" --json");
|
|
1418
1563
|
}
|
|
1419
1564
|
return {
|
|
1420
1565
|
command: "artifacts create",
|
|
@@ -1433,7 +1578,7 @@ function parseArtifactsUpdateArgs(args) {
|
|
|
1433
1578
|
}
|
|
1434
1579
|
const artifactId = args[0];
|
|
1435
1580
|
if (!artifactId || artifactId.startsWith("-")) {
|
|
1436
|
-
throw new TenderCliUsageError("
|
|
1581
|
+
throw new TenderCliUsageError("app id is required. Example: tender app update <app-id> --name \"Sale Widget\" --json");
|
|
1437
1582
|
}
|
|
1438
1583
|
let name = "";
|
|
1439
1584
|
let baseUrl = null;
|
|
@@ -1449,7 +1594,7 @@ function parseArtifactsUpdateArgs(args) {
|
|
|
1449
1594
|
if (arg === "--name") {
|
|
1450
1595
|
const value = args[index + 1];
|
|
1451
1596
|
if (!value || value.startsWith("-")) {
|
|
1452
|
-
throw new TenderCliUsageError("--name requires an
|
|
1597
|
+
throw new TenderCliUsageError("--name requires an app name.");
|
|
1453
1598
|
}
|
|
1454
1599
|
name = value;
|
|
1455
1600
|
index += 1;
|
|
@@ -1470,10 +1615,10 @@ function parseArtifactsUpdateArgs(args) {
|
|
|
1470
1615
|
index += 1;
|
|
1471
1616
|
continue;
|
|
1472
1617
|
}
|
|
1473
|
-
throw new TenderCliUsageError(`Unknown
|
|
1618
|
+
throw new TenderCliUsageError(`Unknown app update option: ${arg}`);
|
|
1474
1619
|
}
|
|
1475
1620
|
if (!name.trim()) {
|
|
1476
|
-
throw new TenderCliUsageError("--name is required. Example: tender
|
|
1621
|
+
throw new TenderCliUsageError("--name is required. Example: tender app update artifact_123 --name \"Sale Widget\" --json");
|
|
1477
1622
|
}
|
|
1478
1623
|
return {
|
|
1479
1624
|
command: "artifacts update",
|
|
@@ -1491,7 +1636,7 @@ function parseArtifactsInitArgs(args) {
|
|
|
1491
1636
|
}
|
|
1492
1637
|
const artifactId = args[0];
|
|
1493
1638
|
if (!artifactId || artifactId.startsWith("-")) {
|
|
1494
|
-
throw new TenderCliUsageError("
|
|
1639
|
+
throw new TenderCliUsageError("app id is required. Example: tender app init <app-id> --dir ./widget --json");
|
|
1495
1640
|
}
|
|
1496
1641
|
let dir = ".";
|
|
1497
1642
|
let remoteName = "tender";
|
|
@@ -1550,7 +1695,7 @@ function parseArtifactsInitArgs(args) {
|
|
|
1550
1695
|
index += 1;
|
|
1551
1696
|
continue;
|
|
1552
1697
|
}
|
|
1553
|
-
throw new TenderCliUsageError(`Unknown
|
|
1698
|
+
throw new TenderCliUsageError(`Unknown app init option: ${arg}`);
|
|
1554
1699
|
}
|
|
1555
1700
|
return {
|
|
1556
1701
|
command: "artifacts init",
|
|
@@ -1572,7 +1717,7 @@ function parseContextFetchArgs(args) {
|
|
|
1572
1717
|
}
|
|
1573
1718
|
const artifactId = args[0];
|
|
1574
1719
|
if (!artifactId || artifactId.startsWith("-")) {
|
|
1575
|
-
throw new TenderCliUsageError("
|
|
1720
|
+
throw new TenderCliUsageError("app id is required. Example: tender app context fetch <app-id> --dir ./widget --json");
|
|
1576
1721
|
}
|
|
1577
1722
|
let dir = ".";
|
|
1578
1723
|
let baseUrl = null;
|
|
@@ -1639,7 +1784,7 @@ function parseContextStatusArgs(args) {
|
|
|
1639
1784
|
}
|
|
1640
1785
|
const artifactId = args[0];
|
|
1641
1786
|
if (!artifactId || artifactId.startsWith("-")) {
|
|
1642
|
-
throw new TenderCliUsageError("
|
|
1787
|
+
throw new TenderCliUsageError("app id is required. Example: tender app context status <app-id> --dir ./widget --json");
|
|
1643
1788
|
}
|
|
1644
1789
|
let dir = ".";
|
|
1645
1790
|
let baseUrl = null;
|
|
@@ -1694,7 +1839,7 @@ function parseContextRefreshArgs(args) {
|
|
|
1694
1839
|
}
|
|
1695
1840
|
const artifactId = args[0];
|
|
1696
1841
|
if (!artifactId || artifactId.startsWith("-")) {
|
|
1697
|
-
throw new TenderCliUsageError("
|
|
1842
|
+
throw new TenderCliUsageError("app id is required. Example: tender app context refresh <app-id> --dir ./widget --dry-run --json");
|
|
1698
1843
|
}
|
|
1699
1844
|
let dir = ".";
|
|
1700
1845
|
let baseUrl = null;
|
|
@@ -1873,6 +2018,343 @@ function parseAuthStatusArgs(args) {
|
|
|
1873
2018
|
json,
|
|
1874
2019
|
};
|
|
1875
2020
|
}
|
|
2021
|
+
function parseGenerateEnvTypesArgs(args) {
|
|
2022
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
2023
|
+
return { command: "help", topic: "artifacts generate-env-types" };
|
|
2024
|
+
}
|
|
2025
|
+
let dir = ".";
|
|
2026
|
+
let json = false;
|
|
2027
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
2028
|
+
const arg = args[index];
|
|
2029
|
+
if (arg === "--json") {
|
|
2030
|
+
json = true;
|
|
2031
|
+
continue;
|
|
2032
|
+
}
|
|
2033
|
+
if (arg === "--dir") {
|
|
2034
|
+
const value = args[index + 1];
|
|
2035
|
+
if (!value) {
|
|
2036
|
+
throw new TenderCliUsageError("--dir requires a path.");
|
|
2037
|
+
}
|
|
2038
|
+
dir = value;
|
|
2039
|
+
index += 1;
|
|
2040
|
+
continue;
|
|
2041
|
+
}
|
|
2042
|
+
throw new TenderCliUsageError(`Unknown generate-env-types option: ${arg}`);
|
|
2043
|
+
}
|
|
2044
|
+
return {
|
|
2045
|
+
command: "artifacts generate-env-types",
|
|
2046
|
+
dir,
|
|
2047
|
+
json,
|
|
2048
|
+
};
|
|
2049
|
+
}
|
|
2050
|
+
function parseAnalyticsRange(value) {
|
|
2051
|
+
if (!value || value.startsWith("-")) {
|
|
2052
|
+
throw new TenderCliUsageError("--range requires 7d, 30d, 90d, or YYYY-MM-DD..YYYY-MM-DD.");
|
|
2053
|
+
}
|
|
2054
|
+
if (value === "7d" || value === "30d" || value === "90d") {
|
|
2055
|
+
return value;
|
|
2056
|
+
}
|
|
2057
|
+
if (/^\d{4}-\d{2}-\d{2}\.\.\d{4}-\d{2}-\d{2}$/.test(value)) {
|
|
2058
|
+
return value;
|
|
2059
|
+
}
|
|
2060
|
+
throw new TenderCliUsageError("--range must be 7d, 30d, 90d, or YYYY-MM-DD..YYYY-MM-DD.");
|
|
2061
|
+
}
|
|
2062
|
+
function parseSpecPath(value) {
|
|
2063
|
+
if (!value || (value !== "-" && value.startsWith("-"))) {
|
|
2064
|
+
throw new TenderCliUsageError("--spec requires a JSON file path or - for stdin.");
|
|
2065
|
+
}
|
|
2066
|
+
return value;
|
|
2067
|
+
}
|
|
2068
|
+
function parseRequiredFlagValue(value, flag) {
|
|
2069
|
+
if (!value || value.startsWith("-")) {
|
|
2070
|
+
throw new TenderCliUsageError(`${flag} requires a value.`);
|
|
2071
|
+
}
|
|
2072
|
+
return value;
|
|
2073
|
+
}
|
|
2074
|
+
function parseAnalyticsCommonArgs(args, startIndex) {
|
|
2075
|
+
let baseUrl = null;
|
|
2076
|
+
let flagToken = null;
|
|
2077
|
+
let profileName = null;
|
|
2078
|
+
let json = false;
|
|
2079
|
+
const remaining = [];
|
|
2080
|
+
for (let index = startIndex; index < args.length; index += 1) {
|
|
2081
|
+
const arg = args[index];
|
|
2082
|
+
if (arg === "--json") {
|
|
2083
|
+
json = true;
|
|
2084
|
+
continue;
|
|
2085
|
+
}
|
|
2086
|
+
if (arg === "--base-url") {
|
|
2087
|
+
baseUrl = parseBaseUrlFlag(args, index);
|
|
2088
|
+
index += 1;
|
|
2089
|
+
continue;
|
|
2090
|
+
}
|
|
2091
|
+
if (arg === "--token") {
|
|
2092
|
+
flagToken = parseTokenFlag(args, index);
|
|
2093
|
+
index += 1;
|
|
2094
|
+
continue;
|
|
2095
|
+
}
|
|
2096
|
+
if (arg === "--profile") {
|
|
2097
|
+
profileName = parseProfileName(args[index + 1], "--profile");
|
|
2098
|
+
index += 1;
|
|
2099
|
+
continue;
|
|
2100
|
+
}
|
|
2101
|
+
remaining.push(arg);
|
|
2102
|
+
}
|
|
2103
|
+
return { baseUrl, flagToken, profileName, json, remaining };
|
|
2104
|
+
}
|
|
2105
|
+
function parseAnalyticsSummaryArgs(args) {
|
|
2106
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
2107
|
+
return { command: "help", topic: "artifacts analytics summary" };
|
|
2108
|
+
}
|
|
2109
|
+
const artifactId = args[0];
|
|
2110
|
+
if (!artifactId || artifactId.startsWith("-")) {
|
|
2111
|
+
throw new TenderCliUsageError("app id is required. Example: tender app analytics summary <app-id> --range 30d --json");
|
|
2112
|
+
}
|
|
2113
|
+
const parsed = parseAnalyticsCommonArgs(args, 1);
|
|
2114
|
+
let range = "7d";
|
|
2115
|
+
for (let index = 0; index < parsed.remaining.length; index += 1) {
|
|
2116
|
+
const arg = parsed.remaining[index];
|
|
2117
|
+
if (arg === "--range") {
|
|
2118
|
+
range = parseAnalyticsRange(parsed.remaining[index + 1]);
|
|
2119
|
+
index += 1;
|
|
2120
|
+
continue;
|
|
2121
|
+
}
|
|
2122
|
+
throw new TenderCliUsageError(`Unknown analytics summary option: ${arg}`);
|
|
2123
|
+
}
|
|
2124
|
+
return { command: "artifacts analytics summary", artifactId, range, ...parsed };
|
|
2125
|
+
}
|
|
2126
|
+
function parseAnalyticsQueryArgs(args) {
|
|
2127
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
2128
|
+
return { command: "help", topic: "artifacts analytics query" };
|
|
2129
|
+
}
|
|
2130
|
+
const artifactId = args[0];
|
|
2131
|
+
if (!artifactId || artifactId.startsWith("-")) {
|
|
2132
|
+
throw new TenderCliUsageError("app id is required. Example: tender app analytics query <app-id> --spec chart.json --json");
|
|
2133
|
+
}
|
|
2134
|
+
const parsed = parseAnalyticsCommonArgs(args, 1);
|
|
2135
|
+
let specPath = null;
|
|
2136
|
+
for (let index = 0; index < parsed.remaining.length; index += 1) {
|
|
2137
|
+
const arg = parsed.remaining[index];
|
|
2138
|
+
if (arg === "--spec") {
|
|
2139
|
+
specPath = parseSpecPath(parsed.remaining[index + 1]);
|
|
2140
|
+
index += 1;
|
|
2141
|
+
continue;
|
|
2142
|
+
}
|
|
2143
|
+
throw new TenderCliUsageError(`Unknown analytics query option: ${arg}`);
|
|
2144
|
+
}
|
|
2145
|
+
if (!specPath) {
|
|
2146
|
+
throw new TenderCliUsageError("--spec is required. Example: tender app analytics query artifact_123 --spec chart.json --json");
|
|
2147
|
+
}
|
|
2148
|
+
return { command: "artifacts analytics query", artifactId, specPath, ...parsed };
|
|
2149
|
+
}
|
|
2150
|
+
function parseAnalyticsCapabilitiesArgs(args) {
|
|
2151
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
2152
|
+
return { command: "help", topic: "artifacts analytics capabilities" };
|
|
2153
|
+
}
|
|
2154
|
+
const artifactId = args[0];
|
|
2155
|
+
if (!artifactId || artifactId.startsWith("-")) {
|
|
2156
|
+
throw new TenderCliUsageError("app id is required. Example: tender app analytics capabilities <app-id> --include-catalog --json");
|
|
2157
|
+
}
|
|
2158
|
+
const parsed = parseAnalyticsCommonArgs(args, 1);
|
|
2159
|
+
let range = "7d";
|
|
2160
|
+
let includeCatalog = false;
|
|
2161
|
+
for (let index = 0; index < parsed.remaining.length; index += 1) {
|
|
2162
|
+
const arg = parsed.remaining[index];
|
|
2163
|
+
if (arg === "--include-catalog") {
|
|
2164
|
+
includeCatalog = true;
|
|
2165
|
+
continue;
|
|
2166
|
+
}
|
|
2167
|
+
if (arg === "--range") {
|
|
2168
|
+
range = parseAnalyticsRange(parsed.remaining[index + 1]);
|
|
2169
|
+
index += 1;
|
|
2170
|
+
continue;
|
|
2171
|
+
}
|
|
2172
|
+
throw new TenderCliUsageError(`Unknown analytics capabilities option: ${arg}`);
|
|
2173
|
+
}
|
|
2174
|
+
return {
|
|
2175
|
+
command: "artifacts analytics capabilities",
|
|
2176
|
+
artifactId,
|
|
2177
|
+
includeCatalog,
|
|
2178
|
+
range,
|
|
2179
|
+
...parsed,
|
|
2180
|
+
};
|
|
2181
|
+
}
|
|
2182
|
+
function parseAnalyticsSuggestionsArgs(args) {
|
|
2183
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
2184
|
+
return { command: "help", topic: "artifacts analytics suggestions" };
|
|
2185
|
+
}
|
|
2186
|
+
const artifactId = args[0];
|
|
2187
|
+
if (!artifactId || artifactId.startsWith("-")) {
|
|
2188
|
+
throw new TenderCliUsageError("app id is required. Example: tender app analytics suggestions <app-id> --range 30d --json");
|
|
2189
|
+
}
|
|
2190
|
+
const parsed = parseAnalyticsCommonArgs(args, 1);
|
|
2191
|
+
let range = "7d";
|
|
2192
|
+
for (let index = 0; index < parsed.remaining.length; index += 1) {
|
|
2193
|
+
const arg = parsed.remaining[index];
|
|
2194
|
+
if (arg === "--range") {
|
|
2195
|
+
range = parseAnalyticsRange(parsed.remaining[index + 1]);
|
|
2196
|
+
index += 1;
|
|
2197
|
+
continue;
|
|
2198
|
+
}
|
|
2199
|
+
throw new TenderCliUsageError(`Unknown analytics suggestions option: ${arg}`);
|
|
2200
|
+
}
|
|
2201
|
+
return { command: "artifacts analytics suggestions", artifactId, range, ...parsed };
|
|
2202
|
+
}
|
|
2203
|
+
function parseAnalyticsDashboardsArgs(args) {
|
|
2204
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
2205
|
+
return { command: "help", topic: "artifacts analytics dashboards" };
|
|
2206
|
+
}
|
|
2207
|
+
const artifactId = args[0];
|
|
2208
|
+
if (!artifactId || artifactId.startsWith("-")) {
|
|
2209
|
+
throw new TenderCliUsageError("app id is required. Example: tender app analytics dashboards <app-id> --json");
|
|
2210
|
+
}
|
|
2211
|
+
const parsed = parseAnalyticsCommonArgs(args, 1);
|
|
2212
|
+
let name = null;
|
|
2213
|
+
let dryRun = false;
|
|
2214
|
+
for (let index = 0; index < parsed.remaining.length; index += 1) {
|
|
2215
|
+
const arg = parsed.remaining[index];
|
|
2216
|
+
if (arg === "--create") {
|
|
2217
|
+
name = parseRequiredFlagValue(parsed.remaining[index + 1], "--create");
|
|
2218
|
+
index += 1;
|
|
2219
|
+
continue;
|
|
2220
|
+
}
|
|
2221
|
+
if (arg === "--dry-run") {
|
|
2222
|
+
dryRun = true;
|
|
2223
|
+
continue;
|
|
2224
|
+
}
|
|
2225
|
+
throw new TenderCliUsageError(`Unknown analytics dashboards option: ${arg}`);
|
|
2226
|
+
}
|
|
2227
|
+
if (dryRun && !name) {
|
|
2228
|
+
throw new TenderCliUsageError("--dry-run is only valid with --create. Example: tender app analytics dashboards artifact_123 --create \"Agent dashboard\" --dry-run --json");
|
|
2229
|
+
}
|
|
2230
|
+
return { command: "artifacts analytics dashboards", artifactId, name, dryRun, ...parsed };
|
|
2231
|
+
}
|
|
2232
|
+
function parseAnalyticsExportCatalogArgs(args) {
|
|
2233
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
2234
|
+
return { command: "help", topic: "artifacts analytics export catalog" };
|
|
2235
|
+
}
|
|
2236
|
+
const artifactId = args[0];
|
|
2237
|
+
if (!artifactId || artifactId.startsWith("-")) {
|
|
2238
|
+
throw new TenderCliUsageError("app id is required. Example: tender app analytics export catalog <app-id> --range 30d --json");
|
|
2239
|
+
}
|
|
2240
|
+
const parsed = parseAnalyticsCommonArgs(args, 1);
|
|
2241
|
+
let range = "7d";
|
|
2242
|
+
let format = "json";
|
|
2243
|
+
for (let index = 0; index < parsed.remaining.length; index += 1) {
|
|
2244
|
+
const arg = parsed.remaining[index];
|
|
2245
|
+
if (arg === "--range") {
|
|
2246
|
+
range = parseAnalyticsRange(parsed.remaining[index + 1]);
|
|
2247
|
+
index += 1;
|
|
2248
|
+
continue;
|
|
2249
|
+
}
|
|
2250
|
+
if (arg === "--format") {
|
|
2251
|
+
const value = parseRequiredFlagValue(parsed.remaining[index + 1], "--format");
|
|
2252
|
+
if (value !== "json") {
|
|
2253
|
+
throw new TenderCliUsageError("--format for export catalog must be json.");
|
|
2254
|
+
}
|
|
2255
|
+
format = value;
|
|
2256
|
+
index += 1;
|
|
2257
|
+
continue;
|
|
2258
|
+
}
|
|
2259
|
+
throw new TenderCliUsageError(`Unknown analytics export catalog option: ${arg}`);
|
|
2260
|
+
}
|
|
2261
|
+
return {
|
|
2262
|
+
command: "artifacts analytics export catalog",
|
|
2263
|
+
artifactId,
|
|
2264
|
+
format,
|
|
2265
|
+
range,
|
|
2266
|
+
...parsed,
|
|
2267
|
+
};
|
|
2268
|
+
}
|
|
2269
|
+
function parseAnalyticsExportQueryArgs(args) {
|
|
2270
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
2271
|
+
return { command: "help", topic: "artifacts analytics export query" };
|
|
2272
|
+
}
|
|
2273
|
+
const artifactId = args[0];
|
|
2274
|
+
if (!artifactId || artifactId.startsWith("-")) {
|
|
2275
|
+
throw new TenderCliUsageError("app id is required. Example: tender app analytics export query <app-id> --spec chart.json --format csv");
|
|
2276
|
+
}
|
|
2277
|
+
const parsed = parseAnalyticsCommonArgs(args, 1);
|
|
2278
|
+
let specPath = null;
|
|
2279
|
+
let format = "json";
|
|
2280
|
+
for (let index = 0; index < parsed.remaining.length; index += 1) {
|
|
2281
|
+
const arg = parsed.remaining[index];
|
|
2282
|
+
if (arg === "--spec") {
|
|
2283
|
+
specPath = parseSpecPath(parsed.remaining[index + 1]);
|
|
2284
|
+
index += 1;
|
|
2285
|
+
continue;
|
|
2286
|
+
}
|
|
2287
|
+
if (arg === "--format") {
|
|
2288
|
+
const value = parseRequiredFlagValue(parsed.remaining[index + 1], "--format");
|
|
2289
|
+
if (value !== "json" && value !== "csv") {
|
|
2290
|
+
throw new TenderCliUsageError("--format must be json or csv.");
|
|
2291
|
+
}
|
|
2292
|
+
format = value;
|
|
2293
|
+
index += 1;
|
|
2294
|
+
continue;
|
|
2295
|
+
}
|
|
2296
|
+
throw new TenderCliUsageError(`Unknown analytics export query option: ${arg}`);
|
|
2297
|
+
}
|
|
2298
|
+
if (!specPath) {
|
|
2299
|
+
throw new TenderCliUsageError("--spec is required. Example: tender app analytics export query artifact_123 --spec chart.json --format csv");
|
|
2300
|
+
}
|
|
2301
|
+
return {
|
|
2302
|
+
command: "artifacts analytics export query",
|
|
2303
|
+
artifactId,
|
|
2304
|
+
specPath,
|
|
2305
|
+
format,
|
|
2306
|
+
...parsed,
|
|
2307
|
+
};
|
|
2308
|
+
}
|
|
2309
|
+
function parseAnalyticsChartsCreateArgs(args) {
|
|
2310
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
2311
|
+
return { command: "help", topic: "artifacts analytics charts create" };
|
|
2312
|
+
}
|
|
2313
|
+
const artifactId = args[0];
|
|
2314
|
+
if (!artifactId || artifactId.startsWith("-")) {
|
|
2315
|
+
throw new TenderCliUsageError("app id is required. Example: tender app analytics charts create <app-id> --dashboard <dashboard-id> --title <title> --spec chart.json --json");
|
|
2316
|
+
}
|
|
2317
|
+
const parsed = parseAnalyticsCommonArgs(args, 1);
|
|
2318
|
+
let dashboardId = null;
|
|
2319
|
+
let title = null;
|
|
2320
|
+
let specPath = null;
|
|
2321
|
+
let dryRun = false;
|
|
2322
|
+
for (let index = 0; index < parsed.remaining.length; index += 1) {
|
|
2323
|
+
const arg = parsed.remaining[index];
|
|
2324
|
+
if (arg === "--dashboard") {
|
|
2325
|
+
dashboardId = parseRequiredFlagValue(parsed.remaining[index + 1], "--dashboard");
|
|
2326
|
+
index += 1;
|
|
2327
|
+
continue;
|
|
2328
|
+
}
|
|
2329
|
+
if (arg === "--title") {
|
|
2330
|
+
title = parseRequiredFlagValue(parsed.remaining[index + 1], "--title");
|
|
2331
|
+
index += 1;
|
|
2332
|
+
continue;
|
|
2333
|
+
}
|
|
2334
|
+
if (arg === "--spec") {
|
|
2335
|
+
specPath = parseSpecPath(parsed.remaining[index + 1]);
|
|
2336
|
+
index += 1;
|
|
2337
|
+
continue;
|
|
2338
|
+
}
|
|
2339
|
+
if (arg === "--dry-run") {
|
|
2340
|
+
dryRun = true;
|
|
2341
|
+
continue;
|
|
2342
|
+
}
|
|
2343
|
+
throw new TenderCliUsageError(`Unknown analytics charts create option: ${arg}`);
|
|
2344
|
+
}
|
|
2345
|
+
if (!dashboardId || !title || !specPath) {
|
|
2346
|
+
throw new TenderCliUsageError("--dashboard, --title, and --spec are required. Example: tender app analytics charts create artifact_123 --dashboard analytics_dashboard_123 --title \"Signup funnel\" --spec chart.json --json");
|
|
2347
|
+
}
|
|
2348
|
+
return {
|
|
2349
|
+
command: "artifacts analytics charts create",
|
|
2350
|
+
artifactId,
|
|
2351
|
+
dashboardId,
|
|
2352
|
+
title,
|
|
2353
|
+
specPath,
|
|
2354
|
+
dryRun,
|
|
2355
|
+
...parsed,
|
|
2356
|
+
};
|
|
2357
|
+
}
|
|
1876
2358
|
function parseTenderArgs(args) {
|
|
1877
2359
|
if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
|
|
1878
2360
|
return { command: "help", topic: "root" };
|
|
@@ -1889,81 +2371,141 @@ function parseTenderArgs(args) {
|
|
|
1889
2371
|
}
|
|
1890
2372
|
throw new TenderCliUsageError(`Unknown auth command: ${args[1]}`);
|
|
1891
2373
|
}
|
|
1892
|
-
if (args[0]
|
|
2374
|
+
if (args[0] === "apps") {
|
|
2375
|
+
throw new TenderCliUsageError("Unknown command: apps. Use `tender app ...` for Tender App workflows.");
|
|
2376
|
+
}
|
|
2377
|
+
if (args[0] !== "artifacts" && args[0] !== "app") {
|
|
1893
2378
|
throw new TenderCliUsageError(`Unknown command: ${args[0]}`);
|
|
1894
2379
|
}
|
|
1895
|
-
|
|
2380
|
+
const resourceArgs = normalizeAppArgs(args);
|
|
2381
|
+
const resourceName = args[0] === "app" ? "app" : "artifacts";
|
|
2382
|
+
if (resourceArgs[1] === undefined ||
|
|
2383
|
+
resourceArgs[1] === "--help" ||
|
|
2384
|
+
resourceArgs[1] === "-h") {
|
|
1896
2385
|
return { command: "help", topic: "artifacts" };
|
|
1897
2386
|
}
|
|
1898
|
-
if (
|
|
1899
|
-
if (
|
|
1900
|
-
return parseArtifactsListArgs(
|
|
2387
|
+
if (resourceArgs[1] !== "doctor") {
|
|
2388
|
+
if (resourceArgs[1] === "list") {
|
|
2389
|
+
return parseArtifactsListArgs(resourceArgs.slice(2));
|
|
2390
|
+
}
|
|
2391
|
+
if (resourceArgs[1] === "create") {
|
|
2392
|
+
return parseArtifactsCreateArgs(resourceArgs.slice(2));
|
|
2393
|
+
}
|
|
2394
|
+
if (resourceArgs[1] === "update") {
|
|
2395
|
+
return parseArtifactsUpdateArgs(resourceArgs.slice(2));
|
|
2396
|
+
}
|
|
2397
|
+
if (resourceArgs[1] === "init") {
|
|
2398
|
+
return parseArtifactsInitArgs(resourceArgs.slice(2));
|
|
1901
2399
|
}
|
|
1902
|
-
if (
|
|
1903
|
-
return
|
|
2400
|
+
if (resourceArgs[1] === "context" && resourceArgs[2] === "fetch") {
|
|
2401
|
+
return parseContextFetchArgs(resourceArgs.slice(3));
|
|
1904
2402
|
}
|
|
1905
|
-
if (
|
|
1906
|
-
return
|
|
2403
|
+
if (resourceArgs[1] === "context" && resourceArgs[2] === "status") {
|
|
2404
|
+
return parseContextStatusArgs(resourceArgs.slice(3));
|
|
1907
2405
|
}
|
|
1908
|
-
if (
|
|
1909
|
-
return
|
|
2406
|
+
if (resourceArgs[1] === "context" && resourceArgs[2] === "refresh") {
|
|
2407
|
+
return parseContextRefreshArgs(resourceArgs.slice(3));
|
|
1910
2408
|
}
|
|
1911
|
-
if (
|
|
1912
|
-
|
|
2409
|
+
if (resourceArgs[1] === "analytics" &&
|
|
2410
|
+
(resourceArgs[2] === undefined ||
|
|
2411
|
+
resourceArgs[2] === "--help" ||
|
|
2412
|
+
resourceArgs[2] === "-h")) {
|
|
2413
|
+
return { command: "help", topic: "artifacts analytics" };
|
|
1913
2414
|
}
|
|
1914
|
-
if (
|
|
1915
|
-
return
|
|
2415
|
+
if (resourceArgs[1] === "analytics" && resourceArgs[2] === "summary") {
|
|
2416
|
+
return parseAnalyticsSummaryArgs(resourceArgs.slice(3));
|
|
1916
2417
|
}
|
|
1917
|
-
if (
|
|
1918
|
-
return
|
|
2418
|
+
if (resourceArgs[1] === "analytics" && resourceArgs[2] === "query") {
|
|
2419
|
+
return parseAnalyticsQueryArgs(resourceArgs.slice(3));
|
|
1919
2420
|
}
|
|
1920
|
-
if (
|
|
1921
|
-
(
|
|
2421
|
+
if (resourceArgs[1] === "analytics" && resourceArgs[2] === "capabilities") {
|
|
2422
|
+
return parseAnalyticsCapabilitiesArgs(resourceArgs.slice(3));
|
|
2423
|
+
}
|
|
2424
|
+
if (resourceArgs[1] === "analytics" && resourceArgs[2] === "suggestions") {
|
|
2425
|
+
return parseAnalyticsSuggestionsArgs(resourceArgs.slice(3));
|
|
2426
|
+
}
|
|
2427
|
+
if (resourceArgs[1] === "analytics" && resourceArgs[2] === "dashboards") {
|
|
2428
|
+
return parseAnalyticsDashboardsArgs(resourceArgs.slice(3));
|
|
2429
|
+
}
|
|
2430
|
+
if (resourceArgs[1] === "analytics" &&
|
|
2431
|
+
resourceArgs[2] === "export" &&
|
|
2432
|
+
(resourceArgs[3] === undefined ||
|
|
2433
|
+
resourceArgs[3] === "--help" ||
|
|
2434
|
+
resourceArgs[3] === "-h")) {
|
|
2435
|
+
return { command: "help", topic: "artifacts analytics export" };
|
|
2436
|
+
}
|
|
2437
|
+
if (resourceArgs[1] === "analytics" &&
|
|
2438
|
+
resourceArgs[2] === "export" &&
|
|
2439
|
+
resourceArgs[3] === "catalog") {
|
|
2440
|
+
return parseAnalyticsExportCatalogArgs(resourceArgs.slice(4));
|
|
2441
|
+
}
|
|
2442
|
+
if (resourceArgs[1] === "analytics" &&
|
|
2443
|
+
resourceArgs[2] === "export" &&
|
|
2444
|
+
resourceArgs[3] === "query") {
|
|
2445
|
+
return parseAnalyticsExportQueryArgs(resourceArgs.slice(4));
|
|
2446
|
+
}
|
|
2447
|
+
if (resourceArgs[1] === "analytics" &&
|
|
2448
|
+
resourceArgs[2] === "charts" &&
|
|
2449
|
+
resourceArgs[3] === "create") {
|
|
2450
|
+
return parseAnalyticsChartsCreateArgs(resourceArgs.slice(4));
|
|
2451
|
+
}
|
|
2452
|
+
if (resourceArgs[1] === "context" &&
|
|
2453
|
+
(resourceArgs[2] === undefined ||
|
|
2454
|
+
resourceArgs[2] === "--help" ||
|
|
2455
|
+
resourceArgs[2] === "-h")) {
|
|
1922
2456
|
return { command: "help", topic: "artifacts" };
|
|
1923
2457
|
}
|
|
1924
|
-
if (
|
|
1925
|
-
return parseGitRemoteArgs(
|
|
2458
|
+
if (resourceArgs[1] === "git" && resourceArgs[2] === "remote") {
|
|
2459
|
+
return parseGitRemoteArgs(resourceArgs.slice(3));
|
|
1926
2460
|
}
|
|
1927
|
-
if (
|
|
1928
|
-
return parseGitSetupArgs(
|
|
2461
|
+
if (resourceArgs[1] === "git" && resourceArgs[2] === "setup") {
|
|
2462
|
+
return parseGitSetupArgs(resourceArgs.slice(3));
|
|
1929
2463
|
}
|
|
1930
|
-
if (
|
|
1931
|
-
return parseGitCredentialArgs(
|
|
2464
|
+
if (resourceArgs[1] === "git" && resourceArgs[2] === "credential") {
|
|
2465
|
+
return parseGitCredentialArgs(resourceArgs.slice(3));
|
|
1932
2466
|
}
|
|
1933
|
-
if (
|
|
1934
|
-
return
|
|
2467
|
+
if (resourceArgs[1] === "generate-env-types") {
|
|
2468
|
+
return parseGenerateEnvTypesArgs(resourceArgs.slice(2));
|
|
1935
2469
|
}
|
|
1936
|
-
if (
|
|
1937
|
-
return
|
|
2470
|
+
if (resourceArgs[1] === "validate") {
|
|
2471
|
+
return parseValidateArgs(resourceArgs.slice(2));
|
|
1938
2472
|
}
|
|
1939
|
-
if (
|
|
1940
|
-
return
|
|
2473
|
+
if (resourceArgs[1] === "build") {
|
|
2474
|
+
return parseBuildArgs(resourceArgs.slice(2));
|
|
1941
2475
|
}
|
|
1942
|
-
if (
|
|
1943
|
-
return
|
|
2476
|
+
if (resourceArgs[1] === "preview" && resourceArgs[2] === "rebuild") {
|
|
2477
|
+
return parsePreviewRebuildArgs(resourceArgs.slice(3));
|
|
1944
2478
|
}
|
|
1945
|
-
if (
|
|
1946
|
-
return
|
|
2479
|
+
if (resourceArgs[1] === "preview" && resourceArgs[2] === "status") {
|
|
2480
|
+
return parsePreviewStatusArgs(resourceArgs.slice(3));
|
|
1947
2481
|
}
|
|
1948
|
-
if (
|
|
1949
|
-
(
|
|
2482
|
+
if (resourceArgs[1] === "preview" && resourceArgs[2] === "watch") {
|
|
2483
|
+
return parsePreviewWatchArgs(resourceArgs.slice(3));
|
|
2484
|
+
}
|
|
2485
|
+
if (resourceArgs[1] === "preview" &&
|
|
2486
|
+
(resourceArgs[2] === undefined ||
|
|
2487
|
+
resourceArgs[2] === "--help" ||
|
|
2488
|
+
resourceArgs[2] === "-h")) {
|
|
1950
2489
|
return { command: "help", topic: "artifacts" };
|
|
1951
2490
|
}
|
|
1952
|
-
if (
|
|
1953
|
-
return parsePublishStatusArgs(
|
|
2491
|
+
if (resourceArgs[1] === "publish" && resourceArgs[2] === "status") {
|
|
2492
|
+
return parsePublishStatusArgs(resourceArgs.slice(3));
|
|
1954
2493
|
}
|
|
1955
|
-
if (
|
|
1956
|
-
return parsePublishWatchArgs(
|
|
2494
|
+
if (resourceArgs[1] === "publish" && resourceArgs[2] === "watch") {
|
|
2495
|
+
return parsePublishWatchArgs(resourceArgs.slice(3));
|
|
1957
2496
|
}
|
|
1958
|
-
if (
|
|
1959
|
-
return parsePublishArgs(
|
|
2497
|
+
if (resourceArgs[1] === "publish") {
|
|
2498
|
+
return parsePublishArgs(resourceArgs.slice(2));
|
|
1960
2499
|
}
|
|
1961
|
-
if (
|
|
2500
|
+
if (resourceArgs[1] === "git" &&
|
|
2501
|
+
(resourceArgs[2] === undefined ||
|
|
2502
|
+
resourceArgs[2] === "--help" ||
|
|
2503
|
+
resourceArgs[2] === "-h")) {
|
|
1962
2504
|
return { command: "help", topic: "artifacts" };
|
|
1963
2505
|
}
|
|
1964
|
-
throw new TenderCliUsageError(`Unknown
|
|
2506
|
+
throw new TenderCliUsageError(`Unknown ${resourceName} command: ${resourceArgs[1]}`);
|
|
1965
2507
|
}
|
|
1966
|
-
const rest =
|
|
2508
|
+
const rest = resourceArgs.slice(2);
|
|
1967
2509
|
if (rest.includes("--help") || rest.includes("-h")) {
|
|
1968
2510
|
return { command: "help", topic: "artifacts doctor" };
|
|
1969
2511
|
}
|
|
@@ -1992,11 +2534,26 @@ function parseTenderArgs(args) {
|
|
|
1992
2534
|
json,
|
|
1993
2535
|
};
|
|
1994
2536
|
}
|
|
2537
|
+
function normalizeAppArgs(args) {
|
|
2538
|
+
if (args[0] !== "app") {
|
|
2539
|
+
return args;
|
|
2540
|
+
}
|
|
2541
|
+
if (args[1] === "preview" &&
|
|
2542
|
+
args[2] &&
|
|
2543
|
+
args[2] !== "rebuild" &&
|
|
2544
|
+
args[2] !== "status" &&
|
|
2545
|
+
args[2] !== "watch" &&
|
|
2546
|
+
args[2] !== "--help" &&
|
|
2547
|
+
args[2] !== "-h") {
|
|
2548
|
+
return ["artifacts", "preview", "rebuild", ...args.slice(2)];
|
|
2549
|
+
}
|
|
2550
|
+
return ["artifacts", ...args.slice(1)];
|
|
2551
|
+
}
|
|
1995
2552
|
function formatDoctorHuman(result) {
|
|
1996
2553
|
if (result.diagnostics.length === 0) {
|
|
1997
2554
|
return result.ok
|
|
1998
|
-
? "Tender
|
|
1999
|
-
: "Tender
|
|
2555
|
+
? "Tender app doctor passed."
|
|
2556
|
+
: "Tender app doctor failed.";
|
|
2000
2557
|
}
|
|
2001
2558
|
return result.diagnostics
|
|
2002
2559
|
.map((diagnostic) => {
|
|
@@ -2039,6 +2596,69 @@ async function runDoctor(command, io) {
|
|
|
2039
2596
|
}
|
|
2040
2597
|
return result.ok ? 0 : 1;
|
|
2041
2598
|
}
|
|
2599
|
+
function formatEnvTypesGenerationFailure(result) {
|
|
2600
|
+
if (result.ok || result.diagnostics.length === 0) {
|
|
2601
|
+
return "Could not generate src/env.d.ts.";
|
|
2602
|
+
}
|
|
2603
|
+
return formatDoctorHuman({
|
|
2604
|
+
ok: false,
|
|
2605
|
+
diagnostics: result.diagnostics,
|
|
2606
|
+
});
|
|
2607
|
+
}
|
|
2608
|
+
async function runGenerateEnvTypes(command, io) {
|
|
2609
|
+
const root = path.resolve(command.dir);
|
|
2610
|
+
const files = await collectTenderAppFiles({ root, current: root });
|
|
2611
|
+
const result = generateTenderAppEnvTypes({
|
|
2612
|
+
files,
|
|
2613
|
+
mode: "local",
|
|
2614
|
+
});
|
|
2615
|
+
if (!result.ok) {
|
|
2616
|
+
if (command.json) {
|
|
2617
|
+
io.stdout(JSON.stringify({
|
|
2618
|
+
ok: false,
|
|
2619
|
+
command: command.command,
|
|
2620
|
+
dir: root,
|
|
2621
|
+
path: result.path,
|
|
2622
|
+
diagnostics: result.diagnostics,
|
|
2623
|
+
}, null, 2));
|
|
2624
|
+
}
|
|
2625
|
+
else {
|
|
2626
|
+
io.stdout(formatEnvTypesGenerationFailure(result));
|
|
2627
|
+
}
|
|
2628
|
+
return 1;
|
|
2629
|
+
}
|
|
2630
|
+
const absolutePath = path.join(root, result.path);
|
|
2631
|
+
const previous = await readFile(absolutePath, "utf8").catch((error) => {
|
|
2632
|
+
if (error &&
|
|
2633
|
+
typeof error === "object" &&
|
|
2634
|
+
error.code === "ENOENT") {
|
|
2635
|
+
return null;
|
|
2636
|
+
}
|
|
2637
|
+
throw error;
|
|
2638
|
+
});
|
|
2639
|
+
const changed = previous !== result.content;
|
|
2640
|
+
await mkdir(path.dirname(absolutePath), { recursive: true });
|
|
2641
|
+
await writeFile(absolutePath, result.content);
|
|
2642
|
+
if (command.json) {
|
|
2643
|
+
io.stdout(JSON.stringify({
|
|
2644
|
+
ok: true,
|
|
2645
|
+
command: command.command,
|
|
2646
|
+
dir: root,
|
|
2647
|
+
path: result.path,
|
|
2648
|
+
absolutePath,
|
|
2649
|
+
changed,
|
|
2650
|
+
bytes: Buffer.byteLength(result.content),
|
|
2651
|
+
diagnostics: result.diagnostics,
|
|
2652
|
+
}, null, 2));
|
|
2653
|
+
}
|
|
2654
|
+
else {
|
|
2655
|
+
io.stdout([
|
|
2656
|
+
`generated: ${path.join(command.dir, result.path)}`,
|
|
2657
|
+
`changed: ${changed ? "yes" : "no"}`,
|
|
2658
|
+
].join("\n"));
|
|
2659
|
+
}
|
|
2660
|
+
return 0;
|
|
2661
|
+
}
|
|
2042
2662
|
async function parseJsonResponse(response) {
|
|
2043
2663
|
return (await response.json().catch(() => null));
|
|
2044
2664
|
}
|
|
@@ -2076,6 +2696,119 @@ function parseSseLifecycleBlock(block) {
|
|
|
2076
2696
|
return { raw: dataLines.join("\n") };
|
|
2077
2697
|
}
|
|
2078
2698
|
}
|
|
2699
|
+
function appendAnalyticsRange(params, range) {
|
|
2700
|
+
if (range === "7d" || range === "30d" || range === "90d") {
|
|
2701
|
+
params.set("rangePreset", range);
|
|
2702
|
+
return;
|
|
2703
|
+
}
|
|
2704
|
+
const [startDate, endDate] = range.split("..");
|
|
2705
|
+
if (startDate && endDate) {
|
|
2706
|
+
params.set("startDate", startDate);
|
|
2707
|
+
params.set("endDate", endDate);
|
|
2708
|
+
}
|
|
2709
|
+
}
|
|
2710
|
+
async function readAnalyticsSpec(input) {
|
|
2711
|
+
const raw = input.specPath === "-"
|
|
2712
|
+
? input.stdin
|
|
2713
|
+
: await readFile(path.resolve(input.specPath), "utf8");
|
|
2714
|
+
if (!raw) {
|
|
2715
|
+
throw new TenderCliUsageError("--spec - requires JSON on stdin.");
|
|
2716
|
+
}
|
|
2717
|
+
try {
|
|
2718
|
+
return JSON.parse(raw);
|
|
2719
|
+
}
|
|
2720
|
+
catch {
|
|
2721
|
+
throw new TenderCliUsageError("--spec must contain valid JSON.");
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2724
|
+
async function requestAnalyticsApi(input) {
|
|
2725
|
+
const params = new URLSearchParams();
|
|
2726
|
+
if (input.range) {
|
|
2727
|
+
appendAnalyticsRange(params, input.range);
|
|
2728
|
+
}
|
|
2729
|
+
if (input.includeCatalog) {
|
|
2730
|
+
params.set("includeCatalog", "1");
|
|
2731
|
+
}
|
|
2732
|
+
const suffix = input.analyticsPath ? `/${input.analyticsPath}` : "";
|
|
2733
|
+
const query = params.size > 0 ? `?${params.toString()}` : "";
|
|
2734
|
+
const response = await input.fetcher(`${input.baseUrl}/api/v1/artifacts/${encodeURIComponent(input.artifactId)}/analytics${suffix}${query}`, {
|
|
2735
|
+
method: input.method,
|
|
2736
|
+
headers: {
|
|
2737
|
+
authorization: `Bearer ${input.token}`,
|
|
2738
|
+
accept: "application/json",
|
|
2739
|
+
...(input.body === undefined ? {} : { "content-type": "application/json" }),
|
|
2740
|
+
},
|
|
2741
|
+
body: input.body === undefined ? undefined : JSON.stringify(input.body),
|
|
2742
|
+
});
|
|
2743
|
+
const payload = await parseJsonResponse(response);
|
|
2744
|
+
if (!response.ok || !payload?.ok) {
|
|
2745
|
+
const reasonCode = (typeof payload?.reasonCode === "string" && payload.reasonCode) ||
|
|
2746
|
+
`http_${response.status}`;
|
|
2747
|
+
const message = (typeof payload?.message === "string" && payload.message) ||
|
|
2748
|
+
(typeof payload?.reasonCode === "string" && payload.reasonCode) ||
|
|
2749
|
+
`Analytics request failed with HTTP ${response.status}.`;
|
|
2750
|
+
throw new Error([
|
|
2751
|
+
message,
|
|
2752
|
+
`Scope: artifact ${input.artifactId}, analytics/${input.analyticsPath || "summary"}.`,
|
|
2753
|
+
`Reason: ${reasonCode}.`,
|
|
2754
|
+
`Example: ${analyticsCorrectedExample(input.artifactId, input.analyticsPath)}.`,
|
|
2755
|
+
].join("\n"));
|
|
2756
|
+
}
|
|
2757
|
+
return payload;
|
|
2758
|
+
}
|
|
2759
|
+
function analyticsCorrectedExample(artifactId, analyticsPath) {
|
|
2760
|
+
if (analyticsPath === "capabilities") {
|
|
2761
|
+
return `tender app analytics capabilities ${artifactId} --include-catalog --range 30d --json`;
|
|
2762
|
+
}
|
|
2763
|
+
if (analyticsPath === "query") {
|
|
2764
|
+
return `tender app analytics query ${artifactId} --spec chart.json --json`;
|
|
2765
|
+
}
|
|
2766
|
+
if (analyticsPath === "suggestions") {
|
|
2767
|
+
return `tender app analytics suggestions ${artifactId} --range 30d --json`;
|
|
2768
|
+
}
|
|
2769
|
+
if (analyticsPath === "dashboards") {
|
|
2770
|
+
return `tender app analytics dashboards ${artifactId} --json`;
|
|
2771
|
+
}
|
|
2772
|
+
if (analyticsPath === "charts") {
|
|
2773
|
+
return `tender app analytics charts create ${artifactId} --dashboard analytics_dashboard_123 --title "Signup funnel" --spec chart.json --json`;
|
|
2774
|
+
}
|
|
2775
|
+
return `tender app analytics summary ${artifactId} --range 30d --json`;
|
|
2776
|
+
}
|
|
2777
|
+
function printAnalyticsPayload(command, io, payload, fallbackLines) {
|
|
2778
|
+
if (command.json) {
|
|
2779
|
+
io.stdout(JSON.stringify(payload, null, 2));
|
|
2780
|
+
}
|
|
2781
|
+
else {
|
|
2782
|
+
io.stdout(fallbackLines.join("\n"));
|
|
2783
|
+
}
|
|
2784
|
+
}
|
|
2785
|
+
function csvCell(value) {
|
|
2786
|
+
if (value === null || value === undefined) {
|
|
2787
|
+
return "";
|
|
2788
|
+
}
|
|
2789
|
+
const json = JSON.stringify(value);
|
|
2790
|
+
const text = typeof value === "string" ? value : typeof json === "string" ? json : String(value);
|
|
2791
|
+
if (/[",\n\r]/.test(text)) {
|
|
2792
|
+
return `"${text.replaceAll("\"", "\"\"")}"`;
|
|
2793
|
+
}
|
|
2794
|
+
return text;
|
|
2795
|
+
}
|
|
2796
|
+
function rowsToCsv(rows) {
|
|
2797
|
+
const records = rows.filter((row) => Boolean(row) && typeof row === "object" && !Array.isArray(row));
|
|
2798
|
+
const headers = Array.from(records.reduce((set, row) => {
|
|
2799
|
+
for (const key of Object.keys(row)) {
|
|
2800
|
+
set.add(key);
|
|
2801
|
+
}
|
|
2802
|
+
return set;
|
|
2803
|
+
}, new Set()));
|
|
2804
|
+
if (headers.length === 0) {
|
|
2805
|
+
return "";
|
|
2806
|
+
}
|
|
2807
|
+
return [
|
|
2808
|
+
headers.map(csvCell).join(","),
|
|
2809
|
+
...records.map((row) => headers.map((header) => csvCell(row[header])).join(",")),
|
|
2810
|
+
].join("\n");
|
|
2811
|
+
}
|
|
2079
2812
|
function findSseBlockSeparator(buffer) {
|
|
2080
2813
|
const unixIndex = buffer.indexOf("\n\n");
|
|
2081
2814
|
const windowsIndex = buffer.indexOf("\r\n\r\n");
|
|
@@ -2377,7 +3110,7 @@ async function runAuthStatus(command, io, runtime) {
|
|
|
2377
3110
|
`base_url: ${profile.baseUrl}`,
|
|
2378
3111
|
`token_prefix: ${profile.tokenPrefix ?? "(unknown)"}`,
|
|
2379
3112
|
`tenant_id: ${profile.tenantId ?? "(unknown)"}`,
|
|
2380
|
-
`
|
|
3113
|
+
`app_id: ${profile.artifactId ?? "(account)"}`,
|
|
2381
3114
|
`permissions: ${(profile.permissions ?? []).join(" ") || "(unknown)"}`,
|
|
2382
3115
|
`expires_at: ${formatExpiry(profile.expiresAt) ?? "(unknown)"}`,
|
|
2383
3116
|
].join("\n"));
|
|
@@ -2502,7 +3235,7 @@ async function runAuthLogin(command, io, runtime) {
|
|
|
2502
3235
|
"authenticated: true",
|
|
2503
3236
|
`profile: ${command.saveProfile}`,
|
|
2504
3237
|
`tenant_id: ${result.tenantId ?? "(unknown)"}`,
|
|
2505
|
-
`
|
|
3238
|
+
`app_id: ${result.artifactId ?? "(account)"}`,
|
|
2506
3239
|
`permissions: ${result.permissions.join(" ") || "(unknown)"}`,
|
|
2507
3240
|
`expires_at: ${result.expiresAt ?? "(unknown)"}`,
|
|
2508
3241
|
].join("\n"));
|
|
@@ -2706,7 +3439,7 @@ async function runArtifactsList(command, io, runtime) {
|
|
|
2706
3439
|
io.stdout(JSON.stringify(result, null, 2));
|
|
2707
3440
|
}
|
|
2708
3441
|
else if (payload.artifacts.length === 0) {
|
|
2709
|
-
io.stdout("No
|
|
3442
|
+
io.stdout("No Tender App records found.");
|
|
2710
3443
|
}
|
|
2711
3444
|
else {
|
|
2712
3445
|
io.stdout(payload.artifacts
|
|
@@ -2758,10 +3491,11 @@ async function runArtifactsCreate(command, io, runtime) {
|
|
|
2758
3491
|
authSource: credentials.source,
|
|
2759
3492
|
profile: credentials.profileName,
|
|
2760
3493
|
tenantId: payload.tenantId ?? null,
|
|
3494
|
+
appId: payload.artifact.artifactId,
|
|
2761
3495
|
artifact: payload.artifact,
|
|
2762
3496
|
next: {
|
|
2763
|
-
contextFetch: `tender
|
|
2764
|
-
gitSetup: `tender
|
|
3497
|
+
contextFetch: `tender app context fetch ${payload.artifact.artifactId} --dir .`,
|
|
3498
|
+
gitSetup: `tender app git setup ${payload.artifact.artifactId} --dir .`,
|
|
2765
3499
|
},
|
|
2766
3500
|
};
|
|
2767
3501
|
if (command.json) {
|
|
@@ -2769,7 +3503,7 @@ async function runArtifactsCreate(command, io, runtime) {
|
|
|
2769
3503
|
}
|
|
2770
3504
|
else {
|
|
2771
3505
|
io.stdout([
|
|
2772
|
-
`
|
|
3506
|
+
`app_id: ${payload.artifact.artifactId}`,
|
|
2773
3507
|
`name: ${payload.artifact.name}`,
|
|
2774
3508
|
`preview_url: ${payload.artifact.previewUrl ?? ""}`,
|
|
2775
3509
|
`next: ${result.next.contextFetch}`,
|
|
@@ -2806,6 +3540,7 @@ async function runArtifactsUpdate(command, io, runtime) {
|
|
|
2806
3540
|
authSource: credentials.source,
|
|
2807
3541
|
profile: credentials.profileName,
|
|
2808
3542
|
tenantId: payload.tenantId ?? null,
|
|
3543
|
+
appId: payload.artifact.artifactId,
|
|
2809
3544
|
artifact: payload.artifact,
|
|
2810
3545
|
};
|
|
2811
3546
|
if (command.json) {
|
|
@@ -2813,7 +3548,7 @@ async function runArtifactsUpdate(command, io, runtime) {
|
|
|
2813
3548
|
}
|
|
2814
3549
|
else {
|
|
2815
3550
|
io.stdout([
|
|
2816
|
-
`
|
|
3551
|
+
`app_id: ${payload.artifact.artifactId}`,
|
|
2817
3552
|
`name: ${payload.artifact.name}`,
|
|
2818
3553
|
].join("\n"));
|
|
2819
3554
|
}
|
|
@@ -2903,6 +3638,8 @@ function createGitSetupCommandPlan(input) {
|
|
|
2903
3638
|
input.credentialHelper,
|
|
2904
3639
|
],
|
|
2905
3640
|
["git", "config", "--local", "credential.useHttpPath", "true"],
|
|
3641
|
+
["git", "config", "--local", "pack.window", "0"],
|
|
3642
|
+
["git", "config", "--local", "pack.depth", "0"],
|
|
2906
3643
|
];
|
|
2907
3644
|
}
|
|
2908
3645
|
async function applyGitSetup(input) {
|
|
@@ -2958,6 +3695,16 @@ async function applyGitSetup(input) {
|
|
|
2958
3695
|
cwd: input.root,
|
|
2959
3696
|
args: ["config", "--local", "credential.useHttpPath", "true"],
|
|
2960
3697
|
});
|
|
3698
|
+
await runGitCommand({
|
|
3699
|
+
runtime: input.runtime,
|
|
3700
|
+
cwd: input.root,
|
|
3701
|
+
args: ["config", "--local", "pack.window", "0"],
|
|
3702
|
+
});
|
|
3703
|
+
await runGitCommand({
|
|
3704
|
+
runtime: input.runtime,
|
|
3705
|
+
cwd: input.root,
|
|
3706
|
+
args: ["config", "--local", "pack.depth", "0"],
|
|
3707
|
+
});
|
|
2961
3708
|
}
|
|
2962
3709
|
async function maybeCheckoutInitialArtifactSource(input) {
|
|
2963
3710
|
const localHead = await runGitCommand({
|
|
@@ -3508,6 +4255,7 @@ async function runArtifactsInit(command, io, runtime) {
|
|
|
3508
4255
|
ok: true,
|
|
3509
4256
|
command: command.command,
|
|
3510
4257
|
artifactId: command.artifactId,
|
|
4258
|
+
appId: command.artifactId,
|
|
3511
4259
|
revision: context.revision,
|
|
3512
4260
|
dir: root,
|
|
3513
4261
|
remoteName: command.remoteName,
|
|
@@ -3545,7 +4293,7 @@ async function runArtifactsInit(command, io, runtime) {
|
|
|
3545
4293
|
}
|
|
3546
4294
|
else {
|
|
3547
4295
|
io.stdout([
|
|
3548
|
-
`
|
|
4296
|
+
`app_id: ${command.artifactId}`,
|
|
3549
4297
|
`context_revision: ${context.revision}`,
|
|
3550
4298
|
`dir: ${root}`,
|
|
3551
4299
|
`remote: ${command.remoteName}`,
|
|
@@ -3608,6 +4356,7 @@ async function postLifecycle(input) {
|
|
|
3608
4356
|
authSource: credentials.source,
|
|
3609
4357
|
profile: credentials.profileName,
|
|
3610
4358
|
artifactId: input.command.artifactId,
|
|
4359
|
+
appId: input.command.artifactId,
|
|
3611
4360
|
operation: payload.operation ?? input.operation,
|
|
3612
4361
|
job: payload.job ?? null,
|
|
3613
4362
|
result: payload.result ?? null,
|
|
@@ -3617,7 +4366,7 @@ async function postLifecycle(input) {
|
|
|
3617
4366
|
}
|
|
3618
4367
|
else {
|
|
3619
4368
|
input.io.stdout([
|
|
3620
|
-
`
|
|
4369
|
+
`app_id: ${input.command.artifactId}`,
|
|
3621
4370
|
`operation: ${result.operation}`,
|
|
3622
4371
|
"status: completed",
|
|
3623
4372
|
].join("\n"));
|
|
@@ -3731,7 +4480,7 @@ async function runPreviewStatus(command, io, runtime) {
|
|
|
3731
4480
|
}
|
|
3732
4481
|
else {
|
|
3733
4482
|
io.stdout([
|
|
3734
|
-
`
|
|
4483
|
+
`app_id: ${command.artifactId}`,
|
|
3735
4484
|
`job_id: ${job.jobId}`,
|
|
3736
4485
|
`status: ${result.status ?? "unknown"}`,
|
|
3737
4486
|
...(result.previewUrl ? [`preview_url: ${result.previewUrl}`] : []),
|
|
@@ -3801,6 +4550,7 @@ async function runPublish(command, io, runtime) {
|
|
|
3801
4550
|
ok: true,
|
|
3802
4551
|
command: command.command,
|
|
3803
4552
|
artifactId: command.artifactId,
|
|
4553
|
+
appId: command.artifactId,
|
|
3804
4554
|
commitSha: command.commitSha,
|
|
3805
4555
|
dryRun: true,
|
|
3806
4556
|
confirmed: false,
|
|
@@ -3820,7 +4570,7 @@ async function runPublish(command, io, runtime) {
|
|
|
3820
4570
|
}
|
|
3821
4571
|
else {
|
|
3822
4572
|
io.stdout([
|
|
3823
|
-
`
|
|
4573
|
+
`app_id: ${command.artifactId}`,
|
|
3824
4574
|
"dry_run: true",
|
|
3825
4575
|
"next: rerun with --confirm publish to publish.",
|
|
3826
4576
|
].join("\n"));
|
|
@@ -3880,7 +4630,7 @@ async function runPublishStatus(command, io, runtime) {
|
|
|
3880
4630
|
}
|
|
3881
4631
|
else {
|
|
3882
4632
|
io.stdout([
|
|
3883
|
-
`
|
|
4633
|
+
`app_id: ${command.artifactId}`,
|
|
3884
4634
|
`job_id: ${job.jobId}`,
|
|
3885
4635
|
`status: ${result.status ?? "unknown"}`,
|
|
3886
4636
|
...(result.publishedUrl
|
|
@@ -3995,6 +4745,226 @@ async function runGitRemote(command, io, runtime) {
|
|
|
3995
4745
|
}
|
|
3996
4746
|
return 0;
|
|
3997
4747
|
}
|
|
4748
|
+
async function resolveAnalyticsCredentials(command, runtime) {
|
|
4749
|
+
return await resolveApiCredentials({
|
|
4750
|
+
baseUrl: command.baseUrl,
|
|
4751
|
+
flagToken: command.flagToken,
|
|
4752
|
+
profileName: command.profileName,
|
|
4753
|
+
env: runtime.env ?? process.env,
|
|
4754
|
+
});
|
|
4755
|
+
}
|
|
4756
|
+
async function runAnalyticsSummary(command, io, runtime) {
|
|
4757
|
+
const credentials = await resolveAnalyticsCredentials(command, runtime);
|
|
4758
|
+
const payload = await requestAnalyticsApi({
|
|
4759
|
+
artifactId: command.artifactId,
|
|
4760
|
+
analyticsPath: "",
|
|
4761
|
+
method: "GET",
|
|
4762
|
+
baseUrl: credentials.baseUrl,
|
|
4763
|
+
token: credentials.token,
|
|
4764
|
+
fetcher: runtime.fetcher ?? fetch,
|
|
4765
|
+
range: command.range,
|
|
4766
|
+
});
|
|
4767
|
+
const points = Array.isArray(payload.points) ? payload.points : [];
|
|
4768
|
+
printAnalyticsPayload(command, io, payload, [
|
|
4769
|
+
`app_id: ${command.artifactId}`,
|
|
4770
|
+
`source: ${String(payload.source ?? "unknown")}`,
|
|
4771
|
+
`points: ${points.length}`,
|
|
4772
|
+
]);
|
|
4773
|
+
return 0;
|
|
4774
|
+
}
|
|
4775
|
+
async function runAnalyticsQuery(command, io, runtime) {
|
|
4776
|
+
const credentials = await resolveAnalyticsCredentials(command, runtime);
|
|
4777
|
+
const spec = await readAnalyticsSpec({
|
|
4778
|
+
specPath: command.specPath,
|
|
4779
|
+
stdin: runtime.stdin,
|
|
4780
|
+
});
|
|
4781
|
+
const payload = await requestAnalyticsApi({
|
|
4782
|
+
artifactId: command.artifactId,
|
|
4783
|
+
analyticsPath: "query",
|
|
4784
|
+
method: "POST",
|
|
4785
|
+
baseUrl: credentials.baseUrl,
|
|
4786
|
+
token: credentials.token,
|
|
4787
|
+
fetcher: runtime.fetcher ?? fetch,
|
|
4788
|
+
body: { spec },
|
|
4789
|
+
});
|
|
4790
|
+
const rows = Array.isArray(payload.rows) ? payload.rows : [];
|
|
4791
|
+
printAnalyticsPayload(command, io, payload, [
|
|
4792
|
+
`app_id: ${command.artifactId}`,
|
|
4793
|
+
`source: ${String(payload.source ?? "unknown")}`,
|
|
4794
|
+
`rows: ${rows.length}`,
|
|
4795
|
+
]);
|
|
4796
|
+
return 0;
|
|
4797
|
+
}
|
|
4798
|
+
async function runAnalyticsCapabilities(command, io, runtime) {
|
|
4799
|
+
const credentials = await resolveAnalyticsCredentials(command, runtime);
|
|
4800
|
+
const payload = await requestAnalyticsApi({
|
|
4801
|
+
artifactId: command.artifactId,
|
|
4802
|
+
analyticsPath: "capabilities",
|
|
4803
|
+
method: "GET",
|
|
4804
|
+
baseUrl: credentials.baseUrl,
|
|
4805
|
+
token: credentials.token,
|
|
4806
|
+
fetcher: runtime.fetcher ?? fetch,
|
|
4807
|
+
range: command.range,
|
|
4808
|
+
includeCatalog: command.includeCatalog,
|
|
4809
|
+
});
|
|
4810
|
+
const commands = Array.isArray(payload.commands) ? payload.commands : [];
|
|
4811
|
+
const catalog = payload.catalog && typeof payload.catalog === "object"
|
|
4812
|
+
? payload.catalog
|
|
4813
|
+
: null;
|
|
4814
|
+
const observedEvents = Array.isArray(catalog?.observedEvents)
|
|
4815
|
+
? catalog.observedEvents
|
|
4816
|
+
: [];
|
|
4817
|
+
printAnalyticsPayload(command, io, payload, [
|
|
4818
|
+
`app_id: ${command.artifactId}`,
|
|
4819
|
+
`commands: ${commands.length}`,
|
|
4820
|
+
`catalog_events: ${observedEvents.length}`,
|
|
4821
|
+
]);
|
|
4822
|
+
return 0;
|
|
4823
|
+
}
|
|
4824
|
+
async function runAnalyticsSuggestions(command, io, runtime) {
|
|
4825
|
+
const credentials = await resolveAnalyticsCredentials(command, runtime);
|
|
4826
|
+
const payload = await requestAnalyticsApi({
|
|
4827
|
+
artifactId: command.artifactId,
|
|
4828
|
+
analyticsPath: "suggestions",
|
|
4829
|
+
method: "POST",
|
|
4830
|
+
baseUrl: credentials.baseUrl,
|
|
4831
|
+
token: credentials.token,
|
|
4832
|
+
fetcher: runtime.fetcher ?? fetch,
|
|
4833
|
+
range: command.range,
|
|
4834
|
+
body: {},
|
|
4835
|
+
});
|
|
4836
|
+
const suggestions = Array.isArray(payload.suggestions) ? payload.suggestions : [];
|
|
4837
|
+
printAnalyticsPayload(command, io, payload, [
|
|
4838
|
+
`app_id: ${command.artifactId}`,
|
|
4839
|
+
`suggestions: ${suggestions.length}`,
|
|
4840
|
+
]);
|
|
4841
|
+
return 0;
|
|
4842
|
+
}
|
|
4843
|
+
async function runAnalyticsDashboards(command, io, runtime) {
|
|
4844
|
+
if (command.name && command.dryRun) {
|
|
4845
|
+
const payload = {
|
|
4846
|
+
ok: true,
|
|
4847
|
+
dryRun: true,
|
|
4848
|
+
artifactId: command.artifactId,
|
|
4849
|
+
request: {
|
|
4850
|
+
name: command.name,
|
|
4851
|
+
},
|
|
4852
|
+
};
|
|
4853
|
+
printAnalyticsPayload(command, io, payload, [
|
|
4854
|
+
`app_id: ${command.artifactId}`,
|
|
4855
|
+
`name: ${command.name}`,
|
|
4856
|
+
"dry_run: true",
|
|
4857
|
+
]);
|
|
4858
|
+
return 0;
|
|
4859
|
+
}
|
|
4860
|
+
const credentials = await resolveAnalyticsCredentials(command, runtime);
|
|
4861
|
+
const payload = await requestAnalyticsApi({
|
|
4862
|
+
artifactId: command.artifactId,
|
|
4863
|
+
analyticsPath: "dashboards",
|
|
4864
|
+
method: command.name ? "POST" : "GET",
|
|
4865
|
+
baseUrl: credentials.baseUrl,
|
|
4866
|
+
token: credentials.token,
|
|
4867
|
+
fetcher: runtime.fetcher ?? fetch,
|
|
4868
|
+
body: command.name ? { name: command.name } : undefined,
|
|
4869
|
+
});
|
|
4870
|
+
const dashboards = Array.isArray(payload.dashboards) ? payload.dashboards : [];
|
|
4871
|
+
printAnalyticsPayload(command, io, payload, [
|
|
4872
|
+
`app_id: ${command.artifactId}`,
|
|
4873
|
+
command.name
|
|
4874
|
+
? `dashboard_id: ${String(payload.dashboard?.id ?? "")}`
|
|
4875
|
+
: `dashboards: ${dashboards.length}`,
|
|
4876
|
+
]);
|
|
4877
|
+
return 0;
|
|
4878
|
+
}
|
|
4879
|
+
async function runAnalyticsExportCatalog(command, io, runtime) {
|
|
4880
|
+
const credentials = await resolveAnalyticsCredentials(command, runtime);
|
|
4881
|
+
const payload = await requestAnalyticsApi({
|
|
4882
|
+
artifactId: command.artifactId,
|
|
4883
|
+
analyticsPath: "capabilities",
|
|
4884
|
+
method: "GET",
|
|
4885
|
+
baseUrl: credentials.baseUrl,
|
|
4886
|
+
token: credentials.token,
|
|
4887
|
+
fetcher: runtime.fetcher ?? fetch,
|
|
4888
|
+
range: command.range,
|
|
4889
|
+
includeCatalog: true,
|
|
4890
|
+
});
|
|
4891
|
+
const catalog = payload.catalog && typeof payload.catalog === "object"
|
|
4892
|
+
? payload.catalog
|
|
4893
|
+
: null;
|
|
4894
|
+
const exportPayload = {
|
|
4895
|
+
ok: true,
|
|
4896
|
+
artifactId: command.artifactId,
|
|
4897
|
+
format: command.format,
|
|
4898
|
+
catalog,
|
|
4899
|
+
};
|
|
4900
|
+
io.stdout(JSON.stringify(exportPayload, null, 2));
|
|
4901
|
+
return 0;
|
|
4902
|
+
}
|
|
4903
|
+
async function runAnalyticsExportQuery(command, io, runtime) {
|
|
4904
|
+
const credentials = await resolveAnalyticsCredentials(command, runtime);
|
|
4905
|
+
const spec = await readAnalyticsSpec({
|
|
4906
|
+
specPath: command.specPath,
|
|
4907
|
+
stdin: runtime.stdin,
|
|
4908
|
+
});
|
|
4909
|
+
const payload = await requestAnalyticsApi({
|
|
4910
|
+
artifactId: command.artifactId,
|
|
4911
|
+
analyticsPath: "query",
|
|
4912
|
+
method: "POST",
|
|
4913
|
+
baseUrl: credentials.baseUrl,
|
|
4914
|
+
token: credentials.token,
|
|
4915
|
+
fetcher: runtime.fetcher ?? fetch,
|
|
4916
|
+
body: { spec },
|
|
4917
|
+
});
|
|
4918
|
+
const rows = Array.isArray(payload.rows) ? payload.rows : [];
|
|
4919
|
+
if (command.format === "csv") {
|
|
4920
|
+
io.stdout(rowsToCsv(rows));
|
|
4921
|
+
return 0;
|
|
4922
|
+
}
|
|
4923
|
+
io.stdout(JSON.stringify(payload, null, 2));
|
|
4924
|
+
return 0;
|
|
4925
|
+
}
|
|
4926
|
+
async function runAnalyticsChartsCreate(command, io, runtime) {
|
|
4927
|
+
const spec = await readAnalyticsSpec({
|
|
4928
|
+
specPath: command.specPath,
|
|
4929
|
+
stdin: runtime.stdin,
|
|
4930
|
+
});
|
|
4931
|
+
const body = {
|
|
4932
|
+
dashboardId: command.dashboardId,
|
|
4933
|
+
title: command.title,
|
|
4934
|
+
spec,
|
|
4935
|
+
layout: {},
|
|
4936
|
+
};
|
|
4937
|
+
if (command.dryRun) {
|
|
4938
|
+
const payload = {
|
|
4939
|
+
ok: true,
|
|
4940
|
+
dryRun: true,
|
|
4941
|
+
artifactId: command.artifactId,
|
|
4942
|
+
request: body,
|
|
4943
|
+
};
|
|
4944
|
+
printAnalyticsPayload(command, io, payload, [
|
|
4945
|
+
`app_id: ${command.artifactId}`,
|
|
4946
|
+
`dashboard_id: ${command.dashboardId}`,
|
|
4947
|
+
`title: ${command.title}`,
|
|
4948
|
+
"dry_run: true",
|
|
4949
|
+
]);
|
|
4950
|
+
return 0;
|
|
4951
|
+
}
|
|
4952
|
+
const credentials = await resolveAnalyticsCredentials(command, runtime);
|
|
4953
|
+
const payload = await requestAnalyticsApi({
|
|
4954
|
+
artifactId: command.artifactId,
|
|
4955
|
+
analyticsPath: "charts",
|
|
4956
|
+
method: "POST",
|
|
4957
|
+
baseUrl: credentials.baseUrl,
|
|
4958
|
+
token: credentials.token,
|
|
4959
|
+
fetcher: runtime.fetcher ?? fetch,
|
|
4960
|
+
body,
|
|
4961
|
+
});
|
|
4962
|
+
printAnalyticsPayload(command, io, payload, [
|
|
4963
|
+
`app_id: ${command.artifactId}`,
|
|
4964
|
+
`chart_id: ${String(payload.chart?.id ?? "")}`,
|
|
4965
|
+
]);
|
|
4966
|
+
return 0;
|
|
4967
|
+
}
|
|
3998
4968
|
export async function runTenderCli(args, io = {
|
|
3999
4969
|
stdout: (message) => console.log(message),
|
|
4000
4970
|
stderr: (message) => console.error(message),
|
|
@@ -4023,6 +4993,9 @@ export async function runTenderCli(args, io = {
|
|
|
4023
4993
|
else if (command.topic === "artifacts doctor") {
|
|
4024
4994
|
io.stdout(doctorHelp());
|
|
4025
4995
|
}
|
|
4996
|
+
else if (command.topic === "artifacts generate-env-types") {
|
|
4997
|
+
io.stdout(generateEnvTypesHelp());
|
|
4998
|
+
}
|
|
4026
4999
|
else if (command.topic === "artifacts list") {
|
|
4027
5000
|
io.stdout(artifactsListHelp());
|
|
4028
5001
|
}
|
|
@@ -4068,6 +5041,36 @@ export async function runTenderCli(args, io = {
|
|
|
4068
5041
|
else if (command.topic === "artifacts publish watch") {
|
|
4069
5042
|
io.stdout(publishWatchHelp());
|
|
4070
5043
|
}
|
|
5044
|
+
else if (command.topic === "artifacts analytics") {
|
|
5045
|
+
io.stdout(analyticsHelp());
|
|
5046
|
+
}
|
|
5047
|
+
else if (command.topic === "artifacts analytics summary") {
|
|
5048
|
+
io.stdout(analyticsSummaryHelp());
|
|
5049
|
+
}
|
|
5050
|
+
else if (command.topic === "artifacts analytics query") {
|
|
5051
|
+
io.stdout(analyticsQueryHelp());
|
|
5052
|
+
}
|
|
5053
|
+
else if (command.topic === "artifacts analytics capabilities") {
|
|
5054
|
+
io.stdout(analyticsCapabilitiesHelp());
|
|
5055
|
+
}
|
|
5056
|
+
else if (command.topic === "artifacts analytics suggestions") {
|
|
5057
|
+
io.stdout(analyticsSuggestionsHelp());
|
|
5058
|
+
}
|
|
5059
|
+
else if (command.topic === "artifacts analytics dashboards") {
|
|
5060
|
+
io.stdout(analyticsDashboardsHelp());
|
|
5061
|
+
}
|
|
5062
|
+
else if (command.topic === "artifacts analytics export") {
|
|
5063
|
+
io.stdout(analyticsExportHelp());
|
|
5064
|
+
}
|
|
5065
|
+
else if (command.topic === "artifacts analytics export catalog") {
|
|
5066
|
+
io.stdout(analyticsExportCatalogHelp());
|
|
5067
|
+
}
|
|
5068
|
+
else if (command.topic === "artifacts analytics export query") {
|
|
5069
|
+
io.stdout(analyticsExportQueryHelp());
|
|
5070
|
+
}
|
|
5071
|
+
else if (command.topic === "artifacts analytics charts create") {
|
|
5072
|
+
io.stdout(analyticsChartsCreateHelp());
|
|
5073
|
+
}
|
|
4071
5074
|
else if (command.topic === "artifacts") {
|
|
4072
5075
|
io.stdout(artifactsHelp());
|
|
4073
5076
|
}
|
|
@@ -4094,6 +5097,9 @@ export async function runTenderCli(args, io = {
|
|
|
4094
5097
|
if (command.command === "artifacts init") {
|
|
4095
5098
|
return await runArtifactsInit(command, io, runtime);
|
|
4096
5099
|
}
|
|
5100
|
+
if (command.command === "artifacts generate-env-types") {
|
|
5101
|
+
return await runGenerateEnvTypes(command, io);
|
|
5102
|
+
}
|
|
4097
5103
|
if (command.command === "artifacts context fetch") {
|
|
4098
5104
|
return await runContextFetch(command, io, runtime);
|
|
4099
5105
|
}
|
|
@@ -4133,6 +5139,30 @@ export async function runTenderCli(args, io = {
|
|
|
4133
5139
|
if (command.command === "artifacts publish watch") {
|
|
4134
5140
|
return await runPublishWatch(command, io, runtime);
|
|
4135
5141
|
}
|
|
5142
|
+
if (command.command === "artifacts analytics summary") {
|
|
5143
|
+
return await runAnalyticsSummary(command, io, runtime);
|
|
5144
|
+
}
|
|
5145
|
+
if (command.command === "artifacts analytics query") {
|
|
5146
|
+
return await runAnalyticsQuery(command, io, runtime);
|
|
5147
|
+
}
|
|
5148
|
+
if (command.command === "artifacts analytics capabilities") {
|
|
5149
|
+
return await runAnalyticsCapabilities(command, io, runtime);
|
|
5150
|
+
}
|
|
5151
|
+
if (command.command === "artifacts analytics suggestions") {
|
|
5152
|
+
return await runAnalyticsSuggestions(command, io, runtime);
|
|
5153
|
+
}
|
|
5154
|
+
if (command.command === "artifacts analytics dashboards") {
|
|
5155
|
+
return await runAnalyticsDashboards(command, io, runtime);
|
|
5156
|
+
}
|
|
5157
|
+
if (command.command === "artifacts analytics export catalog") {
|
|
5158
|
+
return await runAnalyticsExportCatalog(command, io, runtime);
|
|
5159
|
+
}
|
|
5160
|
+
if (command.command === "artifacts analytics export query") {
|
|
5161
|
+
return await runAnalyticsExportQuery(command, io, runtime);
|
|
5162
|
+
}
|
|
5163
|
+
if (command.command === "artifacts analytics charts create") {
|
|
5164
|
+
return await runAnalyticsChartsCreate(command, io, runtime);
|
|
5165
|
+
}
|
|
4136
5166
|
if (command.command === "artifacts git remote") {
|
|
4137
5167
|
return await runGitRemote(command, io, runtime);
|
|
4138
5168
|
}
|
|
@@ -4146,9 +5176,9 @@ export async function runTenderCli(args, io = {
|
|
|
4146
5176
|
}
|
|
4147
5177
|
const currentFile = fileURLToPath(import.meta.url);
|
|
4148
5178
|
function shouldReadEntrypointStdin(args) {
|
|
4149
|
-
return (args[0] === "artifacts" &&
|
|
4150
|
-
args[1] === "git" &&
|
|
4151
|
-
|
|
5179
|
+
return ((args[0] === "artifacts" || args[0] === "app") &&
|
|
5180
|
+
((args[1] === "git" && args[2] === "credential") ||
|
|
5181
|
+
(args[1] === "analytics" && args.includes("--spec") && args.includes("-"))));
|
|
4152
5182
|
}
|
|
4153
5183
|
async function readEntrypointStdin() {
|
|
4154
5184
|
if (process.stdin.isTTY) {
|