terse-cli 0.1.36 → 0.1.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +9 -9
- package/dist/api.js.map +1 -1
- package/dist/assertProjectRoot.d.ts +1 -1
- package/dist/assertProjectRoot.d.ts.map +1 -1
- package/dist/assertProjectRoot.js +5 -4
- package/dist/assertProjectRoot.js.map +1 -1
- package/dist/cliError.d.ts +22 -0
- package/dist/cliError.d.ts.map +1 -0
- package/dist/cliError.js +67 -0
- package/dist/cliError.js.map +1 -0
- package/dist/cliHelpers.d.ts +20 -0
- package/dist/cliHelpers.d.ts.map +1 -0
- package/dist/cliHelpers.js +69 -0
- package/dist/cliHelpers.js.map +1 -0
- package/dist/commands/attach.d.ts +2 -1
- package/dist/commands/attach.d.ts.map +1 -1
- package/dist/commands/attach.js +7 -5
- package/dist/commands/attach.js.map +1 -1
- package/dist/commands/auth.d.ts +2 -1
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +20 -1
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +14 -14
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/generate.d.ts +1 -5
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +13 -16
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/history.d.ts +1 -1
- package/dist/commands/history.d.ts.map +1 -1
- package/dist/commands/history.js +4 -3
- package/dist/commands/history.js.map +1 -1
- package/dist/commands/improvements.d.ts +4 -0
- package/dist/commands/improvements.d.ts.map +1 -0
- package/dist/commands/improvements.js +246 -0
- package/dist/commands/improvements.js.map +1 -0
- package/dist/commands/init.d.ts +2 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +11 -10
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/integrate.d.ts +32 -2
- package/dist/commands/integrate.d.ts.map +1 -1
- package/dist/commands/integrate.js +228 -5
- package/dist/commands/integrate.js.map +1 -1
- package/dist/commands/replay.d.ts.map +1 -1
- package/dist/commands/replay.js +5 -6
- package/dist/commands/replay.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +14 -17
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/test.d.ts +47 -0
- package/dist/commands/test.d.ts.map +1 -1
- package/dist/commands/test.js +214 -58
- package/dist/commands/test.js.map +1 -1
- package/dist/index.js +183 -14
- package/dist/index.js.map +1 -1
- package/dist/jsonOutput.d.ts +19 -0
- package/dist/jsonOutput.d.ts.map +1 -0
- package/dist/jsonOutput.js +25 -0
- package/dist/jsonOutput.js.map +1 -0
- package/dist/loadJob.d.ts +2 -1
- package/dist/loadJob.d.ts.map +1 -1
- package/dist/loadJob.js +16 -13
- package/dist/loadJob.js.map +1 -1
- package/dist/nonInteractive.d.ts +18 -0
- package/dist/nonInteractive.d.ts.map +1 -0
- package/dist/nonInteractive.js +57 -0
- package/dist/nonInteractive.js.map +1 -0
- package/dist/projectConfig.d.ts.map +1 -1
- package/dist/projectConfig.js +17 -10
- package/dist/projectConfig.js.map +1 -1
- package/dist/providers/python/PythonProvider.d.ts.map +1 -1
- package/dist/providers/python/PythonProvider.js +24 -14
- package/dist/providers/python/PythonProvider.js.map +1 -1
- package/dist/providers/resolveProvider.d.ts.map +1 -1
- package/dist/providers/resolveProvider.js +7 -9
- package/dist/providers/resolveProvider.js.map +1 -1
- package/dist/providers/shared/entryFileGuidance.d.ts.map +1 -1
- package/dist/providers/shared/entryFileGuidance.js +7 -12
- package/dist/providers/shared/entryFileGuidance.js.map +1 -1
- package/dist/providers/typescript/TypeScriptProvider.d.ts.map +1 -1
- package/dist/providers/typescript/TypeScriptProvider.js +30 -27
- package/dist/providers/typescript/TypeScriptProvider.js.map +1 -1
- package/dist/replay.d.ts +3 -0
- package/dist/replay.d.ts.map +1 -0
- package/dist/replay.js +20 -0
- package/dist/replay.js.map +1 -0
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +12 -36
- package/dist/run.js.map +1 -1
- package/dist/sampleEventCache.d.ts +9 -0
- package/dist/sampleEventCache.d.ts.map +1 -0
- package/dist/sampleEventCache.js +47 -0
- package/dist/sampleEventCache.js.map +1 -0
- package/dist/sampleEventId.d.ts +13 -0
- package/dist/sampleEventId.d.ts.map +1 -0
- package/dist/sampleEventId.js +20 -0
- package/dist/sampleEventId.js.map +1 -0
- package/dist/shared/ToolDisplayUtils.js +1 -1
- package/dist/shared/ToolDisplayUtils.js.map +1 -1
- package/dist/urls.d.ts +3 -0
- package/dist/urls.d.ts.map +1 -0
- package/dist/urls.js +27 -0
- package/dist/urls.js.map +1 -0
- package/package.json +3 -3
- package/dist/commands/deployTheme.d.ts +0 -28
- package/dist/commands/deployTheme.d.ts.map +0 -1
- package/dist/commands/deployTheme.js +0 -68
- package/dist/commands/deployTheme.js.map +0 -1
- package/dist/commands/dev.d.ts +0 -3
- package/dist/commands/dev.d.ts.map +0 -1
- package/dist/commands/dev.js +0 -47
- package/dist/commands/dev.js.map +0 -1
- package/dist/commands/serve.d.ts +0 -1
- package/dist/commands/serve.d.ts.map +0 -1
- package/dist/commands/serve.js +0 -2
- package/dist/commands/serve.js.map +0 -1
- package/dist/commands/terseCliTheme.d.ts +0 -28
- package/dist/commands/terseCliTheme.d.ts.map +0 -1
- package/dist/commands/terseCliTheme.js +0 -68
- package/dist/commands/terseCliTheme.js.map +0 -1
- package/dist/perf.d.ts +0 -9
- package/dist/perf.d.ts.map +0 -1
- package/dist/perf.js +0 -59
- package/dist/perf.js.map +0 -1
- package/dist/providers/codegen.test.d.ts +0 -2
- package/dist/providers/codegen.test.d.ts.map +0 -1
- package/dist/providers/codegen.test.js +0 -45
- package/dist/providers/codegen.test.js.map +0 -1
- package/dist/providers/python/PythonProvider.test.d.ts +0 -2
- package/dist/providers/python/PythonProvider.test.d.ts.map +0 -1
- package/dist/providers/python/PythonProvider.test.js +0 -169
- package/dist/providers/python/PythonProvider.test.js.map +0 -1
- package/dist/providers/typescript/prepareCodegenData.test.d.ts +0 -2
- package/dist/providers/typescript/prepareCodegenData.test.d.ts.map +0 -1
- package/dist/providers/typescript/prepareCodegenData.test.js +0 -54
- package/dist/providers/typescript/prepareCodegenData.test.js.map +0 -1
package/dist/commands/test.js
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import { cancel, intro, isCancel, log, outro, select } from "@clack/prompts";
|
|
2
2
|
import chalk from "chalk";
|
|
3
|
+
import fs from "node:fs";
|
|
3
4
|
import { IntegrationType } from "terse-sdk";
|
|
4
|
-
import { ApiRoutes, debugTrigger, displayTrigger, formatTriggerForAgent } from "terse-types";
|
|
5
|
+
import { ApiRoutes, debugTrigger, displayTrigger, formatTriggerForAgent, serializedEventSchema } from "terse-types";
|
|
5
6
|
import { fetchWithAuth, readApiKeyOrBail } from "../api.js";
|
|
6
7
|
import { assertProjectRoot } from "../assertProjectRoot.js";
|
|
8
|
+
import { CliError } from "../cliError.js";
|
|
9
|
+
import { isNonInteractive } from "../cliHelpers.js";
|
|
7
10
|
import { createSpinner } from "../cliUi.js";
|
|
8
11
|
import { loadJob } from "../loadJob.js";
|
|
9
12
|
import { resolveProvider } from "../providers/resolveProvider.js";
|
|
10
13
|
export async function test(jobName, verbose, provider = resolveProvider(), entryFile) {
|
|
14
|
+
if (isNonInteractive()) {
|
|
15
|
+
throw new CliError("test_requires_interactive", "`terse test` needs a terminal.", {
|
|
16
|
+
detail: "In non-interactive contexts, use `terse test list` to enumerate sample events and `terse test run --id <id>` to execute one."
|
|
17
|
+
});
|
|
18
|
+
}
|
|
11
19
|
intro("terse test");
|
|
12
20
|
assertProjectRoot(provider);
|
|
13
21
|
const { job } = await loadJob(provider, jobName, entryFile);
|
|
@@ -15,61 +23,30 @@ export async function test(jobName, verbose, provider = resolveProvider(), entry
|
|
|
15
23
|
title: "Error: Not authenticated. Unable to fetch sample events.",
|
|
16
24
|
detail: "Run `terse login` to authenticate, or set TERSE_API_KEY in your environment."
|
|
17
25
|
});
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (integrationTriggers.length > 0) {
|
|
25
|
-
const spinner = createSpinner();
|
|
26
|
-
spinner.start("Fetching sample events");
|
|
27
|
-
try {
|
|
28
|
-
const result = await fetchWithAuth(ApiRoutes.SDK.SAMPLE_EVENTS, apiKey, {
|
|
29
|
-
triggers: integrationTriggers.map(trigger => ({
|
|
30
|
-
triggerId: undefined,
|
|
31
|
-
integrationId: trigger.integrationId,
|
|
32
|
-
integrationType: trigger.integrationType,
|
|
33
|
-
config: trigger
|
|
34
|
-
}))
|
|
35
|
-
}, "POST");
|
|
36
|
-
events = result.events;
|
|
37
|
-
spinner.stop(`Fetched ${events.length} sample event${events.length === 1 ? "" : "s"}`);
|
|
38
|
-
}
|
|
39
|
-
catch (err) {
|
|
40
|
-
spinner.stop(err instanceof Error ? err.message : "Failed to fetch sample events.");
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
// Add a synthetic manual trigger event for each time trigger
|
|
44
|
-
for (const trigger of timeTriggers) {
|
|
45
|
-
events.push(serializeEvent({
|
|
46
|
-
integrationType: IntegrationType.CRON_JOB,
|
|
47
|
-
eventType: "cron",
|
|
48
|
-
inputId: trigger.integrationId,
|
|
49
|
-
isManualTrigger: true,
|
|
50
|
-
manualContext: `Manual trigger from terse test (schedule: ${trigger.cronExpression ?? "unknown"})`
|
|
51
|
-
}));
|
|
26
|
+
const spinner = createSpinner();
|
|
27
|
+
spinner.start("Fetching sample events");
|
|
28
|
+
let candidates = [];
|
|
29
|
+
try {
|
|
30
|
+
candidates = await fetchSampleEventCandidatesForJob(job, apiKey);
|
|
31
|
+
spinner.stop(`Fetched ${candidates.length} sample event${candidates.length === 1 ? "" : "s"}`);
|
|
52
32
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
events.push(serializeEvent({
|
|
56
|
-
integrationType: IntegrationType.WEBHOOK,
|
|
57
|
-
eventType: "webhook",
|
|
58
|
-
body: {},
|
|
59
|
-
headers: {},
|
|
60
|
-
method: "POST"
|
|
61
|
-
}));
|
|
33
|
+
catch (err) {
|
|
34
|
+
spinner.stop(err instanceof Error ? err.message : "Failed to fetch sample events.");
|
|
62
35
|
}
|
|
63
|
-
if (
|
|
64
|
-
|
|
65
|
-
|
|
36
|
+
if (candidates.length === 0) {
|
|
37
|
+
const webhookHint = hasWebhookTrigger(job);
|
|
38
|
+
throw new CliError("no_sample_events", "No sample events available.", {
|
|
39
|
+
detail: webhookHint
|
|
40
|
+
? "Webhook triggers do not provide sample events yet. Use `--event` / `--event-file` with a concrete payload."
|
|
41
|
+
: "Make sure your triggers are configured and events have been received."
|
|
42
|
+
});
|
|
66
43
|
}
|
|
67
44
|
log.info(`Testing job ${chalk.cyan(job.name)}`);
|
|
68
|
-
const
|
|
45
|
+
const event = await chooseSampleEvent(candidates, apiKey);
|
|
69
46
|
const runSpinner = createSpinner();
|
|
70
|
-
runSpinner.start(`Running ${formatEventLabel(
|
|
47
|
+
runSpinner.start(`Running ${formatEventLabel(event)}`);
|
|
71
48
|
try {
|
|
72
|
-
await provider.executeJob(job, null,
|
|
49
|
+
await provider.executeJob(job, null, event, { verbose: !!verbose, entryFile });
|
|
73
50
|
runSpinner.stop("Run completed");
|
|
74
51
|
outro("Done");
|
|
75
52
|
}
|
|
@@ -78,11 +55,175 @@ export async function test(jobName, verbose, provider = resolveProvider(), entry
|
|
|
78
55
|
throw error;
|
|
79
56
|
}
|
|
80
57
|
}
|
|
58
|
+
export async function testList(opts = {}) {
|
|
59
|
+
const provider = opts.provider ?? resolveProvider();
|
|
60
|
+
assertProjectRoot(provider);
|
|
61
|
+
const { job } = await loadJob(provider, opts.jobName, opts.entryFile, { nonInteractive: true });
|
|
62
|
+
const apiKey = readApiKeyOrBail();
|
|
63
|
+
const candidates = await fetchSampleEventCandidatesForJob(job, apiKey);
|
|
64
|
+
if (opts.json) {
|
|
65
|
+
const payload = {
|
|
66
|
+
job: job.name,
|
|
67
|
+
events: candidates.map(candidate => ({
|
|
68
|
+
id: candidate.id,
|
|
69
|
+
integrationType: candidate.integrationType,
|
|
70
|
+
eventType: candidate.eventType,
|
|
71
|
+
label: candidate.label,
|
|
72
|
+
subtitle: candidate.subtitle,
|
|
73
|
+
entityType: candidate.kind === "ref" ? candidate.entityType : null,
|
|
74
|
+
entityId: candidate.kind === "ref" ? candidate.entityId : null
|
|
75
|
+
}))
|
|
76
|
+
};
|
|
77
|
+
process.stdout.write(JSON.stringify(payload, null, 2) + "\n");
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (candidates.length === 0) {
|
|
81
|
+
if (hasWebhookTrigger(job)) {
|
|
82
|
+
process.stdout.write("No sample events available. Webhook triggers are not supported for test samples.\n");
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
process.stdout.write("No sample events available.\n");
|
|
86
|
+
}
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
process.stdout.write(`Sample events for job ${job.name}:\n\n`);
|
|
90
|
+
for (const candidate of candidates) {
|
|
91
|
+
const subtitle = candidate.subtitle ? ` — ${normalizeSingleLine(candidate.subtitle)}` : "";
|
|
92
|
+
process.stdout.write(` ${chalk.cyan(candidate.id)} ${candidate.integrationType}/${candidate.eventType} ${candidate.label}${chalk.dim(subtitle)}\n`);
|
|
93
|
+
}
|
|
94
|
+
process.stdout.write("\n");
|
|
95
|
+
process.stdout.write(chalk.dim(`Run one with: terse test run --id <id>\n`));
|
|
96
|
+
}
|
|
97
|
+
export async function testShow(opts) {
|
|
98
|
+
const provider = opts.provider ?? resolveProvider();
|
|
99
|
+
assertProjectRoot(provider);
|
|
100
|
+
const event = await resolveEventById(provider, opts.id, opts.jobName, opts.entryFile);
|
|
101
|
+
if (opts.json) {
|
|
102
|
+
process.stdout.write(JSON.stringify({ id: opts.id, event }, null, 2) + "\n");
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
process.stdout.write(`${chalk.bold(formatEventLabel(event))}\n`);
|
|
106
|
+
if (event.display?.subtitle)
|
|
107
|
+
process.stdout.write(chalk.dim(event.display.subtitle) + "\n");
|
|
108
|
+
process.stdout.write(`\n${event.formattedContent}\n`);
|
|
109
|
+
}
|
|
110
|
+
export async function testRun(opts) {
|
|
111
|
+
const provider = opts.provider ?? resolveProvider();
|
|
112
|
+
assertProjectRoot(provider);
|
|
113
|
+
const modeCount = [opts.id, opts.eventJson, opts.eventFile].filter(Boolean).length;
|
|
114
|
+
if (modeCount === 0) {
|
|
115
|
+
throw new CliError("missing_event", "Provide one of --id, --event, or --event-file.", {
|
|
116
|
+
detail: "Run `terse test list --json` to see available sample ids."
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
if (modeCount > 1) {
|
|
120
|
+
throw new CliError("conflicting_flags", "--id, --event, and --event-file are mutually exclusive.");
|
|
121
|
+
}
|
|
122
|
+
const { job } = await loadJob(provider, opts.jobName, opts.entryFile, { nonInteractive: true });
|
|
123
|
+
let event;
|
|
124
|
+
if (opts.id) {
|
|
125
|
+
event = await resolveEventByIdForJob(job, opts.id);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
const rawJson = opts.eventJson ?? readEventFile(opts.eventFile);
|
|
129
|
+
event = parseEventJson(rawJson);
|
|
130
|
+
}
|
|
131
|
+
await provider.executeJob(job, null, event, { verbose: !!opts.verbose, entryFile: opts.entryFile });
|
|
132
|
+
}
|
|
133
|
+
async function resolveEventById(provider, id, jobNameHint, entryFile) {
|
|
134
|
+
const { job } = await loadJob(provider, jobNameHint, entryFile, { nonInteractive: true });
|
|
135
|
+
return resolveEventByIdForJob(job, id);
|
|
136
|
+
}
|
|
137
|
+
async function resolveEventByIdForJob(job, id) {
|
|
138
|
+
const apiKey = readApiKeyOrBail();
|
|
139
|
+
const candidates = await fetchSampleEventCandidatesForJob(job, apiKey);
|
|
140
|
+
const match = candidates.find(candidate => candidate.id === id);
|
|
141
|
+
if (match)
|
|
142
|
+
return hydrateCandidateEvent(match, apiKey);
|
|
143
|
+
throw new CliError("sample_not_found", `No sample event matches id ${id}.`, {
|
|
144
|
+
detail: "Run `terse test list` to refresh — the event may have rotated out of the sample buffer."
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
function readEventFile(filePath) {
|
|
148
|
+
try {
|
|
149
|
+
return fs.readFileSync(filePath, "utf-8");
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
throw new CliError("event_file_unreadable", `Could not read event file: ${filePath}`, {
|
|
153
|
+
detail: err instanceof Error ? err.message : String(err)
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function parseEventJson(raw) {
|
|
158
|
+
let parsed;
|
|
159
|
+
try {
|
|
160
|
+
parsed = JSON.parse(raw);
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
throw new CliError("invalid_event_json", "--event / --event-file must be valid JSON.", {
|
|
164
|
+
detail: err instanceof Error ? err.message : String(err)
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
try {
|
|
168
|
+
return serializedEventSchema.parse(parsed);
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
throw new CliError("invalid_event_shape", "Event JSON does not match the canonical Trigger schema.", {
|
|
172
|
+
detail: err instanceof Error ? err.message : String(err)
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
export async function fetchSampleEventCandidatesForJob(job, apiKey) {
|
|
177
|
+
const timeTriggers = job.triggers.filter(t => t.integrationType === IntegrationType.CRON_JOB);
|
|
178
|
+
const integrationTriggers = job.triggers.filter(t => t.integrationType !== IntegrationType.CRON_JOB && t.integrationType !== IntegrationType.WEBHOOK);
|
|
179
|
+
const candidates = [];
|
|
180
|
+
if (integrationTriggers.length > 0) {
|
|
181
|
+
const result = await fetchWithAuth(ApiRoutes.SDK.SAMPLE_EVENTS, apiKey, {
|
|
182
|
+
triggers: integrationTriggers.map(trigger => ({
|
|
183
|
+
triggerId: undefined,
|
|
184
|
+
integrationId: trigger.integrationId,
|
|
185
|
+
integrationType: trigger.integrationType,
|
|
186
|
+
config: trigger
|
|
187
|
+
}))
|
|
188
|
+
}, "POST");
|
|
189
|
+
candidates.push(...result.events.map(event => ({
|
|
190
|
+
id: encodeRefId(event.entity.entityType, event.entity.entityId),
|
|
191
|
+
kind: "ref",
|
|
192
|
+
integrationType: event.serializedEvent.integrationType,
|
|
193
|
+
eventType: event.serializedEvent.eventType,
|
|
194
|
+
label: normalizeSingleLine(event.serializedEvent.display?.title || `${event.serializedEvent.integrationType} / ${event.serializedEvent.eventType}`),
|
|
195
|
+
subtitle: event.serializedEvent.display?.subtitle ?? null,
|
|
196
|
+
entityType: event.entity.entityType,
|
|
197
|
+
entityId: event.entity.entityId
|
|
198
|
+
})));
|
|
199
|
+
}
|
|
200
|
+
for (const [index, trigger] of timeTriggers.entries()) {
|
|
201
|
+
const event = serializeEvent({
|
|
202
|
+
integrationType: IntegrationType.CRON_JOB,
|
|
203
|
+
eventType: "cron",
|
|
204
|
+
inputId: trigger.integrationId,
|
|
205
|
+
isManualTrigger: true,
|
|
206
|
+
manualContext: `Manual trigger from terse test (schedule: ${trigger.cronExpression})`
|
|
207
|
+
});
|
|
208
|
+
candidates.push({
|
|
209
|
+
id: `synthetic:cron:${index}`,
|
|
210
|
+
kind: "synthetic",
|
|
211
|
+
integrationType: event.integrationType,
|
|
212
|
+
eventType: event.eventType,
|
|
213
|
+
label: formatEventLabel(event),
|
|
214
|
+
subtitle: event.display?.subtitle ?? null,
|
|
215
|
+
event
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
return candidates;
|
|
219
|
+
}
|
|
81
220
|
function formatEventLabel(event) {
|
|
82
221
|
return normalizeSingleLine(event.display?.title || `${event.integrationType} / ${event.eventType}`);
|
|
83
222
|
}
|
|
84
|
-
function formatEventHint(
|
|
85
|
-
|
|
223
|
+
function formatEventHint(candidate) {
|
|
224
|
+
if (candidate.subtitle)
|
|
225
|
+
return truncate(normalizeSingleLine(candidate.subtitle), 120);
|
|
226
|
+
return candidate.kind === "ref" ? truncate(`${candidate.integrationType}/${candidate.eventType}`, 120) : "Synthetic sample event";
|
|
86
227
|
}
|
|
87
228
|
function truncate(value, maxLength) {
|
|
88
229
|
if (value.length <= maxLength) {
|
|
@@ -103,22 +244,37 @@ function abortIfCancelled(value) {
|
|
|
103
244
|
}
|
|
104
245
|
return value;
|
|
105
246
|
}
|
|
106
|
-
async function chooseSampleEvent(
|
|
247
|
+
async function chooseSampleEvent(candidates, apiKey) {
|
|
107
248
|
while (true) {
|
|
108
249
|
const choice = abortIfCancelled(await select({
|
|
109
250
|
message: "Choose a sample event",
|
|
110
|
-
options:
|
|
111
|
-
label: `${
|
|
112
|
-
hint: formatEventHint(
|
|
251
|
+
options: candidates.map((candidate, index) => ({
|
|
252
|
+
label: `${candidate.label} ${chalk.dim("›")}`,
|
|
253
|
+
hint: formatEventHint(candidate),
|
|
113
254
|
value: index
|
|
114
255
|
}))
|
|
115
256
|
}));
|
|
116
|
-
const
|
|
257
|
+
const event = await hydrateCandidateEvent(candidates[choice], apiKey);
|
|
258
|
+
const action = await inspectSampleEvent(event);
|
|
117
259
|
if (action === "run") {
|
|
118
|
-
return
|
|
260
|
+
return event;
|
|
119
261
|
}
|
|
120
262
|
}
|
|
121
263
|
}
|
|
264
|
+
async function hydrateCandidateEvent(candidate, apiKey) {
|
|
265
|
+
if (candidate.kind === "synthetic") {
|
|
266
|
+
return candidate.event;
|
|
267
|
+
}
|
|
268
|
+
const payload = await fetchWithAuth(ApiRoutes.SDK.HYDRATE_SAMPLE_EVENT, apiKey, { entityType: candidate.entityType, entityId: candidate.entityId }, "POST");
|
|
269
|
+
return payload.event;
|
|
270
|
+
}
|
|
271
|
+
function encodeRefId(entityType, entityId) {
|
|
272
|
+
const token = Buffer.from(JSON.stringify({ entityType, entityId }), "utf8").toString("base64url");
|
|
273
|
+
return `ref:${token}`;
|
|
274
|
+
}
|
|
275
|
+
function hasWebhookTrigger(job) {
|
|
276
|
+
return job.triggers.some(trigger => trigger.integrationType === IntegrationType.WEBHOOK);
|
|
277
|
+
}
|
|
122
278
|
async function inspectSampleEvent(event) {
|
|
123
279
|
log.info(chalk.bold(formatEventLabel(event)));
|
|
124
280
|
if (event.display?.subtitle) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import chalk from "chalk";
|
|
3
3
|
import { Command } from "commander";
|
|
4
|
+
import { CliError, emitCliError, isCliError, setErrorOutputJson } from "./cliError.js";
|
|
5
|
+
import { collectKeyValue, parseIntFlag } from "./cliHelpers.js";
|
|
4
6
|
import { getCliVersion } from "./cliVersion.js";
|
|
5
7
|
import { attach } from "./commands/attach.js";
|
|
6
8
|
import { loginAndPersist, logout } from "./commands/auth.js";
|
|
@@ -9,55 +11,197 @@ import { deploy } from "./commands/deploy.js";
|
|
|
9
11
|
import { openDocs } from "./commands/docs.js";
|
|
10
12
|
import { generate } from "./commands/generate.js";
|
|
11
13
|
import { history } from "./commands/history.js";
|
|
14
|
+
import { applyImprovement, listImprovements } from "./commands/improvements.js";
|
|
12
15
|
import { init } from "./commands/init.js";
|
|
13
|
-
import { integrate } from "./commands/integrate.js";
|
|
16
|
+
import { integrate, integrateConnect, integrateDescribe, integrateDisconnect, integrateList, integrateWait } from "./commands/integrate.js";
|
|
14
17
|
import { replay } from "./commands/replay.js";
|
|
15
18
|
import { run } from "./commands/run.js";
|
|
16
|
-
import { test } from "./commands/test.js";
|
|
19
|
+
import { test, testList, testRun, testShow } from "./commands/test.js";
|
|
17
20
|
import { isCliRunCommandEnabled } from "./env.js";
|
|
18
21
|
import { isPromptCancellationError } from "./promptErrors.js";
|
|
19
22
|
import { resolveProvider } from "./providers/resolveProvider.js";
|
|
20
23
|
const program = new Command();
|
|
24
|
+
const NON_INTERACTIVE_OPTION = ["-y, --non-interactive", "Run non-interactively; fail fast if authentication or choices are required"];
|
|
25
|
+
const ENTRY_FILE_OPTION = ["--entry-file <path>", "Path to the job entry file (overrides default)"];
|
|
26
|
+
function syncJsonErrorOutput(command) {
|
|
27
|
+
const { json } = command.opts();
|
|
28
|
+
setErrorOutputJson(Boolean(json));
|
|
29
|
+
}
|
|
21
30
|
program.name("terse").description("The Terse CLI — create and manage Terse projects").version(getCliVersion());
|
|
31
|
+
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
32
|
+
syncJsonErrorOutput(actionCommand);
|
|
33
|
+
});
|
|
22
34
|
program.commandsGroup("Getting started:");
|
|
23
35
|
program
|
|
24
36
|
.command("init")
|
|
25
37
|
.description("Create a new Terse project")
|
|
26
38
|
.argument("[project-name]", "Name for the project directory")
|
|
27
|
-
.
|
|
39
|
+
.option(...NON_INTERACTIVE_OPTION)
|
|
40
|
+
.addHelpText("after", `
|
|
41
|
+
Examples:
|
|
42
|
+
$ terse init myproj # interactive scaffold
|
|
43
|
+
$ terse init myproj --non-interactive # non-interactive; requires prior \`terse login\`
|
|
44
|
+
$ terse init myproj < /dev/null # auto non-interactive (no TTY)
|
|
45
|
+
`)
|
|
46
|
+
.action(async (projectName, opts) => {
|
|
28
47
|
const language = "ts";
|
|
29
48
|
const provider = resolveProvider({ command: "init", language });
|
|
30
|
-
await init(projectName, provider);
|
|
49
|
+
await init(projectName, provider, opts);
|
|
31
50
|
});
|
|
32
51
|
program
|
|
33
52
|
.command("attach")
|
|
34
53
|
.description("Add Terse to an existing project (self-hosted)")
|
|
35
|
-
.
|
|
36
|
-
|
|
54
|
+
.option(...NON_INTERACTIVE_OPTION)
|
|
55
|
+
.action(async (opts) => {
|
|
56
|
+
await attach(resolveProvider(), opts);
|
|
37
57
|
});
|
|
38
|
-
program
|
|
58
|
+
const testCommand = program
|
|
39
59
|
.command("test")
|
|
40
60
|
.description("Fetch sample events and run a job interactively")
|
|
41
61
|
.argument("[job-name]", "Name of the job to test (auto-selects if only one exists)")
|
|
42
62
|
.option("-v, --verbose", "Show agent stream output", true)
|
|
43
|
-
.option(
|
|
63
|
+
.option(...ENTRY_FILE_OPTION)
|
|
64
|
+
.addHelpText("after", `
|
|
65
|
+
Examples:
|
|
66
|
+
$ terse test # interactive picker
|
|
67
|
+
$ terse test my-job # test a specific job
|
|
68
|
+
|
|
69
|
+
Non-interactive subcommands (for AI agents and CI):
|
|
70
|
+
$ terse test list --json # enumerate sample events with ids
|
|
71
|
+
$ terse test show <id> # inspect a specific sample
|
|
72
|
+
$ terse test run --id <id> # run a cached sample by content hash
|
|
73
|
+
$ terse test run --event-file sample.json # run a sample event from disk
|
|
74
|
+
`)
|
|
44
75
|
.action(async (jobName, opts) => {
|
|
45
76
|
await test(jobName, opts?.verbose, resolveProvider(), opts?.entryFile);
|
|
46
77
|
});
|
|
78
|
+
testCommand
|
|
79
|
+
.command("list")
|
|
80
|
+
.description("List sample events for a job with content-addressed ids")
|
|
81
|
+
.argument("[job-name]", "Name of the job (auto-selects if only one exists)")
|
|
82
|
+
.option("--json", "Emit JSON with the full event payload for each id")
|
|
83
|
+
.option(...ENTRY_FILE_OPTION)
|
|
84
|
+
.action(async (jobName, opts) => {
|
|
85
|
+
await testList({ jobName, json: opts?.json, entryFile: opts?.entryFile });
|
|
86
|
+
});
|
|
87
|
+
testCommand
|
|
88
|
+
.command("show")
|
|
89
|
+
.description("Show the full contents of a cached sample event")
|
|
90
|
+
.argument("<id>", "Sample event id from `terse test list`")
|
|
91
|
+
.argument("[job-name]", "Name of the job (auto-selects if only one exists)")
|
|
92
|
+
.option("--json", "Emit JSON instead of rendered text")
|
|
93
|
+
.option(...ENTRY_FILE_OPTION)
|
|
94
|
+
.action(async (id, jobName, opts) => {
|
|
95
|
+
await testShow({ id, jobName, json: opts?.json, entryFile: opts?.entryFile });
|
|
96
|
+
});
|
|
97
|
+
testCommand
|
|
98
|
+
.command("run")
|
|
99
|
+
.description("Run a job against a sample event non-interactively")
|
|
100
|
+
.argument("[job-name]", "Name of the job (auto-selects if only one exists)")
|
|
101
|
+
.option("--id <id>", "Sample event id from `terse test list`")
|
|
102
|
+
.option("--event <json>", "Inline serialized event JSON string")
|
|
103
|
+
.option("--event-file <path>", "Path to a JSON file containing the serialized event")
|
|
104
|
+
.option("-v, --verbose", "Show agent stream output", true)
|
|
105
|
+
.option(...ENTRY_FILE_OPTION)
|
|
106
|
+
.addHelpText("after", `
|
|
107
|
+
Examples:
|
|
108
|
+
$ terse test list --json | jq -r '.events[0].id' | xargs -I{} terse test run --id {}
|
|
109
|
+
$ terse test run --event-file fixture.json
|
|
110
|
+
`)
|
|
111
|
+
.action(async (jobName, opts) => {
|
|
112
|
+
await testRun({
|
|
113
|
+
jobName,
|
|
114
|
+
id: opts?.id,
|
|
115
|
+
eventJson: opts?.event,
|
|
116
|
+
eventFile: opts?.eventFile,
|
|
117
|
+
verbose: opts?.verbose,
|
|
118
|
+
entryFile: opts?.entryFile
|
|
119
|
+
});
|
|
120
|
+
});
|
|
47
121
|
program
|
|
48
122
|
.command("deploy")
|
|
49
123
|
.description("Deploy all jobs to Terse (syncs with server — removed jobs are deleted)")
|
|
50
|
-
.option(
|
|
124
|
+
.option(...ENTRY_FILE_OPTION)
|
|
51
125
|
.action(async (opts) => {
|
|
52
126
|
await deploy(resolveProvider(), opts?.entryFile);
|
|
53
127
|
});
|
|
54
128
|
program.commandsGroup("Build with workspace context:");
|
|
55
|
-
program
|
|
129
|
+
const integrateCommand = program
|
|
56
130
|
.command("integrate")
|
|
57
|
-
.description("
|
|
131
|
+
.description("Connect and manage integrations")
|
|
132
|
+
.addHelpText("after", `
|
|
133
|
+
Examples:
|
|
134
|
+
$ terse integrate # interactive picker
|
|
135
|
+
$ terse integrate list --json # enumerate integrations
|
|
136
|
+
$ terse integrate describe snowflake --json # see required fields
|
|
137
|
+
$ terse integrate connect snowflake --field account=x --field username=y --fields-stdin <<< '{"password":"'"$PW"'"}'
|
|
138
|
+
$ terse integrate connect slack # OAuth → opens browser, exit 2 (follow up with 'wait')
|
|
139
|
+
$ terse integrate wait slack --timeout 300 # block until OAuth completes
|
|
140
|
+
$ terse integrate disconnect snowflake
|
|
141
|
+
`)
|
|
58
142
|
.action(async () => {
|
|
59
143
|
await integrate();
|
|
60
144
|
});
|
|
145
|
+
integrateCommand
|
|
146
|
+
.command("list")
|
|
147
|
+
.description("List integrations and their connection status")
|
|
148
|
+
.option("--json", "Emit JSON")
|
|
149
|
+
.option("--status <status>", "Filter to `connected` or `disconnected`")
|
|
150
|
+
.action(async (opts) => {
|
|
151
|
+
if (opts.status && opts.status !== "connected" && opts.status !== "disconnected") {
|
|
152
|
+
throw new CliError("invalid_status_filter", `--status must be "connected" or "disconnected", got "${opts.status}".`);
|
|
153
|
+
}
|
|
154
|
+
await integrateList({ json: opts.json, status: opts.status });
|
|
155
|
+
});
|
|
156
|
+
integrateCommand
|
|
157
|
+
.command("describe")
|
|
158
|
+
.description("Show schema and status for an integration type")
|
|
159
|
+
.argument("<type>", "Integration type (e.g. slack, snowflake)")
|
|
160
|
+
.option("--json", "Emit JSON")
|
|
161
|
+
.action(async (type, opts) => {
|
|
162
|
+
await integrateDescribe({ integrationType: type, json: opts.json });
|
|
163
|
+
});
|
|
164
|
+
integrateCommand
|
|
165
|
+
.command("connect")
|
|
166
|
+
.description("Connect (or refresh) an integration. OAuth types open a browser and exit 2 — follow up with `wait` to block.")
|
|
167
|
+
.argument("<type>", "Integration type (e.g. slack, gmail, snowflake)")
|
|
168
|
+
.option("--field <key=value>", "Form field value (repeatable). Never put secrets here — use --fields-stdin.", collectKeyValue, [])
|
|
169
|
+
.option("--fields-stdin", "Read a JSON object of additional fields from stdin (secrets go here)")
|
|
170
|
+
.option("-f, --force", "Re-run the install even if the integration is already connected")
|
|
171
|
+
.option("--json", "Emit JSON")
|
|
172
|
+
.addHelpText("after", `
|
|
173
|
+
Examples:
|
|
174
|
+
$ terse integrate connect snowflake --field account=xyz --field username=foo --fields-stdin <<< '{"password":"'"$PW"'"}'
|
|
175
|
+
$ terse integrate connect slack # OAuth: opens browser, prints URL + wait command, exit 2
|
|
176
|
+
$ terse integrate connect slack --json # OAuth: opens browser, emits handoff JSON, exit 2
|
|
177
|
+
$ terse integrate connect snowflake --force # refresh an existing connection
|
|
178
|
+
`)
|
|
179
|
+
.action(async (type, opts) => {
|
|
180
|
+
await integrateConnect({
|
|
181
|
+
integrationType: type,
|
|
182
|
+
fieldFlags: opts.field,
|
|
183
|
+
fieldsStdin: opts.fieldsStdin,
|
|
184
|
+
force: opts.force,
|
|
185
|
+
json: opts.json
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
integrateCommand
|
|
189
|
+
.command("disconnect")
|
|
190
|
+
.description("Disconnect an integration")
|
|
191
|
+
.argument("<type>", "Integration type (e.g. slack, snowflake)")
|
|
192
|
+
.option("--json", "Emit JSON")
|
|
193
|
+
.action(async (type, opts) => {
|
|
194
|
+
await integrateDisconnect({ integrationType: type, json: opts.json });
|
|
195
|
+
});
|
|
196
|
+
integrateCommand
|
|
197
|
+
.command("wait")
|
|
198
|
+
.description("Block until an OAuth integration finishes connecting (run after `connect` emits a handoff)")
|
|
199
|
+
.argument("<type>", "Integration type (e.g. slack, gmail)")
|
|
200
|
+
.option("--timeout <seconds>", "Timeout in seconds (default 300, max 900)", parseIntFlag)
|
|
201
|
+
.option("--json", "Emit JSON")
|
|
202
|
+
.action(async (type, opts) => {
|
|
203
|
+
await integrateWait({ integrationType: type, timeoutSeconds: opts.timeout, json: opts.json });
|
|
204
|
+
});
|
|
61
205
|
program
|
|
62
206
|
.command("generate")
|
|
63
207
|
.description("Autogenerate context from your connected workspaces")
|
|
@@ -72,11 +216,32 @@ if (isCliRunCommandEnabled()) {
|
|
|
72
216
|
.argument("[job-name]", "Name of the job to run (auto-selects if only one exists)")
|
|
73
217
|
.option("--event <json>", "Serialized event JSON string")
|
|
74
218
|
.option("--event-file <path>", "Path to a JSON file containing the serialized event")
|
|
75
|
-
.option(
|
|
219
|
+
.option(...ENTRY_FILE_OPTION)
|
|
76
220
|
.action(async (jobName, opts) => {
|
|
77
221
|
await run(jobName, opts?.event, opts?.eventFile, resolveProvider(), opts?.entryFile);
|
|
78
222
|
});
|
|
79
223
|
}
|
|
224
|
+
program.commandsGroup("Improvements:");
|
|
225
|
+
program
|
|
226
|
+
.command("apply")
|
|
227
|
+
.description("Apply a suggested improvement patch locally (runs `git apply`)")
|
|
228
|
+
.argument("[improvement-id]", "ID of the improvement to apply (prompts if omitted)")
|
|
229
|
+
.option(...NON_INTERACTIVE_OPTION)
|
|
230
|
+
.addHelpText("after", `
|
|
231
|
+
Examples:
|
|
232
|
+
$ terse apply # interactive picker
|
|
233
|
+
$ terse apply <improvement-id> # apply a specific improvement
|
|
234
|
+
$ terse apply <improvement-id> --non-interactive # fail fast on prompts (CI/agents)
|
|
235
|
+
`)
|
|
236
|
+
.action(async (improvementId, opts) => {
|
|
237
|
+
await applyImprovement(improvementId, opts);
|
|
238
|
+
});
|
|
239
|
+
program
|
|
240
|
+
.command("list")
|
|
241
|
+
.description("List Terse resources")
|
|
242
|
+
.addCommand(new Command("improvements").description("List pending improvements across all agents").action(async () => {
|
|
243
|
+
await listImprovements();
|
|
244
|
+
}));
|
|
80
245
|
program.commandsGroup("Observability:");
|
|
81
246
|
program
|
|
82
247
|
.command("replay")
|
|
@@ -90,8 +255,8 @@ program
|
|
|
90
255
|
.description("View past run events for a job (use --json to pipe into tooling like the Claude Code /improve skill)")
|
|
91
256
|
.argument("[job-name]", "Name of the job to view the history of")
|
|
92
257
|
.option("--json", "Output runs as JSON for machine consumption")
|
|
93
|
-
.option("--limit <n>", "Max runs to fetch (default 20, max 100)",
|
|
94
|
-
.option("--page <n>", "Page number (1-indexed)",
|
|
258
|
+
.option("--limit <n>", "Max runs to fetch (default 20, max 100)", parseIntFlag)
|
|
259
|
+
.option("--page <n>", "Page number (1-indexed)", parseIntFlag)
|
|
95
260
|
.option("--status <list>", "Comma-separated statuses (success,failed,cancelled,skipped,in_progress,awaiting_approval)")
|
|
96
261
|
.option("--since <iso>", "Only include runs at or after this ISO timestamp")
|
|
97
262
|
.option("--until <iso>", "Only include runs at or before this ISO timestamp")
|
|
@@ -145,6 +310,10 @@ catch (error) {
|
|
|
145
310
|
console.log(chalk.yellow("\n Cancelled.\n"));
|
|
146
311
|
process.exit(130);
|
|
147
312
|
}
|
|
313
|
+
if (isCliError(error)) {
|
|
314
|
+
emitCliError(error);
|
|
315
|
+
process.exit(error.exitCode);
|
|
316
|
+
}
|
|
148
317
|
throw error;
|
|
149
318
|
}
|
|
150
319
|
//# sourceMappingURL=index.js.map
|