@syntropic137/cli 0.20.1 → 0.21.0
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/syn.js +85 -65
- package/package.json +1 -1
package/dist/syn.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// src/config.ts
|
|
4
4
|
var CLI_NAME = "syn";
|
|
5
5
|
var CLI_DESCRIPTION = "Syntropic137 - Event-sourced workflow engine for AI agents";
|
|
6
|
-
var CLI_VERSION = true ? "0.
|
|
6
|
+
var CLI_VERSION = true ? "0.21.0" : "0.0.0-dev";
|
|
7
7
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
8
8
|
var SSE_CONNECT_TIMEOUT_MS = 5e3;
|
|
9
9
|
function getApiUrl() {
|
|
@@ -79,40 +79,40 @@ var SynClient = class {
|
|
|
79
79
|
this.timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
80
80
|
this.authHeaders = getAuthHeaders();
|
|
81
81
|
}
|
|
82
|
-
async get(
|
|
83
|
-
const url = this.buildUrl(
|
|
82
|
+
async get(path9, params) {
|
|
83
|
+
const url = this.buildUrl(path9, params);
|
|
84
84
|
return this.request(url, { method: "GET" });
|
|
85
85
|
}
|
|
86
|
-
async post(
|
|
87
|
-
const url = this.buildUrl(
|
|
86
|
+
async post(path9, body, params) {
|
|
87
|
+
const url = this.buildUrl(path9, params);
|
|
88
88
|
return this.request(url, {
|
|
89
89
|
method: "POST",
|
|
90
90
|
headers: { "Content-Type": "application/json" },
|
|
91
91
|
...body !== void 0 ? { body: JSON.stringify(body) } : {}
|
|
92
92
|
});
|
|
93
93
|
}
|
|
94
|
-
async put(
|
|
95
|
-
const url = this.buildUrl(
|
|
94
|
+
async put(path9, body) {
|
|
95
|
+
const url = this.buildUrl(path9);
|
|
96
96
|
return this.request(url, {
|
|
97
97
|
method: "PUT",
|
|
98
98
|
headers: { "Content-Type": "application/json" },
|
|
99
99
|
...body !== void 0 ? { body: JSON.stringify(body) } : {}
|
|
100
100
|
});
|
|
101
101
|
}
|
|
102
|
-
async patch(
|
|
103
|
-
const url = this.buildUrl(
|
|
102
|
+
async patch(path9, body) {
|
|
103
|
+
const url = this.buildUrl(path9);
|
|
104
104
|
return this.request(url, {
|
|
105
105
|
method: "PATCH",
|
|
106
106
|
headers: { "Content-Type": "application/json" },
|
|
107
107
|
...body !== void 0 ? { body: JSON.stringify(body) } : {}
|
|
108
108
|
});
|
|
109
109
|
}
|
|
110
|
-
async delete(
|
|
111
|
-
const url = this.buildUrl(
|
|
110
|
+
async delete(path9) {
|
|
111
|
+
const url = this.buildUrl(path9);
|
|
112
112
|
return this.request(url, { method: "DELETE" });
|
|
113
113
|
}
|
|
114
|
-
async stream(
|
|
115
|
-
const url = this.buildUrl(
|
|
114
|
+
async stream(path9) {
|
|
115
|
+
const url = this.buildUrl(path9);
|
|
116
116
|
const controller = new AbortController();
|
|
117
117
|
const timer = setTimeout(() => controller.abort(), SSE_CONNECT_TIMEOUT_MS);
|
|
118
118
|
const response = await fetch(url.toString(), {
|
|
@@ -126,10 +126,10 @@ var SynClient = class {
|
|
|
126
126
|
}
|
|
127
127
|
return response.body;
|
|
128
128
|
}
|
|
129
|
-
buildUrl(
|
|
129
|
+
buildUrl(path9, params) {
|
|
130
130
|
const base = new URL(this.baseUrl);
|
|
131
131
|
const basePath = base.pathname.replace(/\/+$/, "");
|
|
132
|
-
const reqPath =
|
|
132
|
+
const reqPath = path9.startsWith("/") ? path9 : `/${path9}`;
|
|
133
133
|
const prefix = basePath.endsWith(API_PREFIX) ? "" : API_PREFIX;
|
|
134
134
|
const url = new URL(`${basePath}${prefix}${reqPath}`, base);
|
|
135
135
|
if (params) {
|
|
@@ -181,66 +181,66 @@ async function safeRequest(fn) {
|
|
|
181
181
|
handleConnectError();
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
|
-
async function apiGet(
|
|
184
|
+
async function apiGet(path9, options) {
|
|
185
185
|
const client = new SynClient();
|
|
186
186
|
const { status, data } = await safeRequest(
|
|
187
|
-
() => client.get(
|
|
187
|
+
() => client.get(path9, options?.params)
|
|
188
188
|
);
|
|
189
189
|
checkResponse(status, data, options?.expected ?? [200]);
|
|
190
190
|
return data;
|
|
191
191
|
}
|
|
192
|
-
async function apiGetList(
|
|
192
|
+
async function apiGetList(path9, options) {
|
|
193
193
|
const client = new SynClient();
|
|
194
194
|
const { status, data } = await safeRequest(
|
|
195
|
-
() => client.get(
|
|
195
|
+
() => client.get(path9, options?.params)
|
|
196
196
|
);
|
|
197
197
|
checkResponse(status, data, options?.expected ?? [200]);
|
|
198
198
|
return data;
|
|
199
199
|
}
|
|
200
|
-
async function apiGetPaginated(
|
|
200
|
+
async function apiGetPaginated(path9, key, options) {
|
|
201
201
|
const client = new SynClient();
|
|
202
202
|
const { status, data } = await safeRequest(
|
|
203
|
-
() => client.get(
|
|
203
|
+
() => client.get(path9, options?.params)
|
|
204
204
|
);
|
|
205
205
|
checkResponse(status, data, options?.expected ?? [200]);
|
|
206
206
|
if (typeof data !== "object" || data === null) {
|
|
207
|
-
throw new CLIError(`Unexpected API response for "${
|
|
207
|
+
throw new CLIError(`Unexpected API response for "${path9}": expected an object containing "${key}".`);
|
|
208
208
|
}
|
|
209
209
|
const items = data[key];
|
|
210
210
|
if (!Array.isArray(items)) {
|
|
211
|
-
throw new CLIError(`Unexpected API response for "${
|
|
211
|
+
throw new CLIError(`Unexpected API response for "${path9}": expected "${key}" to be an array.`);
|
|
212
212
|
}
|
|
213
213
|
return items;
|
|
214
214
|
}
|
|
215
|
-
async function apiPost(
|
|
215
|
+
async function apiPost(path9, options) {
|
|
216
216
|
const client = new SynClient(
|
|
217
217
|
options?.timeoutMs !== void 0 ? { timeoutMs: options.timeoutMs } : void 0
|
|
218
218
|
);
|
|
219
219
|
const { status, data } = await safeRequest(
|
|
220
|
-
() => client.post(
|
|
220
|
+
() => client.post(path9, options?.body, options?.params)
|
|
221
221
|
);
|
|
222
|
-
checkResponse(status, data, options?.expected ?? [200]);
|
|
222
|
+
checkResponse(status, data, options?.expected ?? [200, 201]);
|
|
223
223
|
return data;
|
|
224
224
|
}
|
|
225
|
-
async function apiPut(
|
|
225
|
+
async function apiPut(path9, options) {
|
|
226
226
|
const client = new SynClient();
|
|
227
227
|
const { status, data } = await safeRequest(
|
|
228
|
-
() => client.put(
|
|
228
|
+
() => client.put(path9, options?.body)
|
|
229
229
|
);
|
|
230
230
|
checkResponse(status, data, options?.expected ?? [200]);
|
|
231
231
|
return data;
|
|
232
232
|
}
|
|
233
|
-
async function apiPatch(
|
|
233
|
+
async function apiPatch(path9, options) {
|
|
234
234
|
const client = new SynClient();
|
|
235
235
|
const { status, data } = await safeRequest(
|
|
236
|
-
() => client.patch(
|
|
236
|
+
() => client.patch(path9, options?.body)
|
|
237
237
|
);
|
|
238
238
|
checkResponse(status, data, options?.expected ?? [200]);
|
|
239
239
|
return data;
|
|
240
240
|
}
|
|
241
|
-
async function apiDelete(
|
|
241
|
+
async function apiDelete(path9, options) {
|
|
242
242
|
const client = new SynClient();
|
|
243
|
-
const { status, data } = await safeRequest(() => client.delete(
|
|
243
|
+
const { status, data } = await safeRequest(() => client.delete(path9));
|
|
244
244
|
checkResponse(status, data, options?.expected ?? [200]);
|
|
245
245
|
return data;
|
|
246
246
|
}
|
|
@@ -1103,6 +1103,7 @@ syn workflow run ${wfName}-v1 --task "Your task here"
|
|
|
1103
1103
|
}
|
|
1104
1104
|
|
|
1105
1105
|
// src/commands/workflow/crud.ts
|
|
1106
|
+
import path4 from "path";
|
|
1106
1107
|
var createCommand = {
|
|
1107
1108
|
name: "create",
|
|
1108
1109
|
description: "Create a new workflow",
|
|
@@ -1219,8 +1220,9 @@ var validateCommand = {
|
|
|
1219
1220
|
validatePackageDir(file);
|
|
1220
1221
|
return;
|
|
1221
1222
|
}
|
|
1223
|
+
const content = fs8.readFileSync(file, "utf-8");
|
|
1222
1224
|
const data = await apiPost("/workflows/validate", {
|
|
1223
|
-
body: { file }
|
|
1225
|
+
body: { content, filename: path4.basename(file) }
|
|
1224
1226
|
});
|
|
1225
1227
|
if (data["valid"]) {
|
|
1226
1228
|
printSuccess("Valid workflow definition\n");
|
|
@@ -1492,11 +1494,11 @@ var statusCommand = {
|
|
|
1492
1494
|
|
|
1493
1495
|
// src/commands/workflow/install.ts
|
|
1494
1496
|
import fs5 from "fs";
|
|
1495
|
-
import
|
|
1497
|
+
import path6 from "path";
|
|
1496
1498
|
|
|
1497
1499
|
// src/marketplace/client.ts
|
|
1498
1500
|
import fs4 from "fs";
|
|
1499
|
-
import
|
|
1501
|
+
import path5 from "path";
|
|
1500
1502
|
|
|
1501
1503
|
// src/marketplace/models.ts
|
|
1502
1504
|
import { z as z2 } from "zod";
|
|
@@ -1553,7 +1555,7 @@ function saveRegistries(config) {
|
|
|
1553
1555
|
}
|
|
1554
1556
|
function loadCachedIndex(registryName) {
|
|
1555
1557
|
validateRegistryName(registryName);
|
|
1556
|
-
const cachePath =
|
|
1558
|
+
const cachePath = path5.join(CACHE_DIR, `${registryName}.json`);
|
|
1557
1559
|
if (!fs4.existsSync(cachePath)) return null;
|
|
1558
1560
|
try {
|
|
1559
1561
|
const content = fs4.readFileSync(cachePath, "utf-8");
|
|
@@ -1565,7 +1567,7 @@ function loadCachedIndex(registryName) {
|
|
|
1565
1567
|
function saveCachedIndex(registryName, cached) {
|
|
1566
1568
|
validateRegistryName(registryName);
|
|
1567
1569
|
fs4.mkdirSync(CACHE_DIR, { recursive: true });
|
|
1568
|
-
const cachePath =
|
|
1570
|
+
const cachePath = path5.join(CACHE_DIR, `${registryName}.json`);
|
|
1569
1571
|
writeJsonFile(cachePath, cached);
|
|
1570
1572
|
}
|
|
1571
1573
|
function isCacheStale(cached) {
|
|
@@ -1582,7 +1584,7 @@ async function fetchMarketplaceJson(repo, ref = "main") {
|
|
|
1582
1584
|
const tmpdir = makeTempDir("syn-mkt-");
|
|
1583
1585
|
try {
|
|
1584
1586
|
await gitClone(url, ref, tmpdir);
|
|
1585
|
-
const marketplacePath =
|
|
1587
|
+
const marketplacePath = path5.join(tmpdir, "marketplace.json");
|
|
1586
1588
|
if (!fs4.existsSync(marketplacePath)) {
|
|
1587
1589
|
throw new Error(`No marketplace.json found in ${repo}`);
|
|
1588
1590
|
}
|
|
@@ -1694,7 +1696,7 @@ async function tryMarketplaceResolution(source, ref) {
|
|
|
1694
1696
|
removeTempDir(tmpdir);
|
|
1695
1697
|
throw err;
|
|
1696
1698
|
}
|
|
1697
|
-
const subdir =
|
|
1699
|
+
const subdir = path6.resolve(tmpdir, plugin.source.replace(/^\.\//, ""));
|
|
1698
1700
|
if (!subdir.startsWith(tmpdir)) {
|
|
1699
1701
|
removeTempDir(tmpdir);
|
|
1700
1702
|
throw new Error(`Plugin source path escapes repository: ${plugin.source}`);
|
|
@@ -1710,7 +1712,7 @@ async function resolveSource(source, ref) {
|
|
|
1710
1712
|
const { tmpdir, manifest: manifest2, workflows: workflows2 } = await resolveFromGit(resolved, ref);
|
|
1711
1713
|
return { packagePath: tmpdir, manifest: manifest2, workflows: workflows2, tmpdir };
|
|
1712
1714
|
}
|
|
1713
|
-
const packagePath =
|
|
1715
|
+
const packagePath = path6.resolve(resolved);
|
|
1714
1716
|
const { manifest, workflows } = resolvePackage(packagePath);
|
|
1715
1717
|
return { packagePath, manifest, workflows, tmpdir: null };
|
|
1716
1718
|
}
|
|
@@ -1788,7 +1790,7 @@ var installCommand = {
|
|
|
1788
1790
|
throw new CLIError("No workflows", 1);
|
|
1789
1791
|
}
|
|
1790
1792
|
const fmt = detectFormat(packagePath);
|
|
1791
|
-
const pkgName = manifest?.name ??
|
|
1793
|
+
const pkgName = manifest?.name ?? path6.basename(packagePath);
|
|
1792
1794
|
const pkgVersion = manifest?.version ?? "0.0.0";
|
|
1793
1795
|
printPackagePreview(pkgName, pkgVersion, source, fmt, workflows);
|
|
1794
1796
|
if (dryRun) {
|
|
@@ -1881,11 +1883,11 @@ var initCommand = {
|
|
|
1881
1883
|
},
|
|
1882
1884
|
handler: async (parsed) => {
|
|
1883
1885
|
const directory = parsed.positionals[0] ?? ".";
|
|
1884
|
-
const resolvedDir =
|
|
1886
|
+
const resolvedDir = path6.resolve(directory);
|
|
1885
1887
|
const workflowType = parsed.values["type"] ?? "research";
|
|
1886
1888
|
const numPhases = parseInt(parsed.values["phases"] ?? "3", 10);
|
|
1887
1889
|
const multi = parsed.values["multi"] === true;
|
|
1888
|
-
const wfName = parsed.values["name"] ??
|
|
1890
|
+
const wfName = parsed.values["name"] ?? path6.basename(resolvedDir).replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
1889
1891
|
if (fs5.existsSync(resolvedDir)) {
|
|
1890
1892
|
const entries = fs5.readdirSync(resolvedDir);
|
|
1891
1893
|
if (entries.length > 0) {
|
|
@@ -1909,7 +1911,7 @@ var initCommand = {
|
|
|
1909
1911
|
|
|
1910
1912
|
// src/commands/workflow/export.ts
|
|
1911
1913
|
import fs6 from "fs";
|
|
1912
|
-
import
|
|
1914
|
+
import path7 from "path";
|
|
1913
1915
|
var exportCommand = {
|
|
1914
1916
|
name: "export",
|
|
1915
1917
|
description: "Export a workflow as a distributable package or Claude Code plugin",
|
|
@@ -1939,7 +1941,7 @@ var exportCommand = {
|
|
|
1939
1941
|
printError("Export returned no files");
|
|
1940
1942
|
throw new CLIError("Export empty", 1);
|
|
1941
1943
|
}
|
|
1942
|
-
const outDir =
|
|
1944
|
+
const outDir = path7.resolve(outputDir);
|
|
1943
1945
|
if (fs6.existsSync(outDir)) {
|
|
1944
1946
|
const entries = fs6.readdirSync(outDir);
|
|
1945
1947
|
if (entries.length > 0) {
|
|
@@ -1952,12 +1954,12 @@ var exportCommand = {
|
|
|
1952
1954
|
printError(`Unsafe file path in export manifest: ${relPath}`);
|
|
1953
1955
|
throw new CLIError("Path traversal", 1);
|
|
1954
1956
|
}
|
|
1955
|
-
const filePath =
|
|
1957
|
+
const filePath = path7.resolve(outDir, relPath);
|
|
1956
1958
|
if (!filePath.startsWith(outDir)) {
|
|
1957
1959
|
printError(`Path escapes output directory: ${relPath}`);
|
|
1958
1960
|
throw new CLIError("Path traversal", 1);
|
|
1959
1961
|
}
|
|
1960
|
-
fs6.mkdirSync(
|
|
1962
|
+
fs6.mkdirSync(path7.dirname(filePath), { recursive: true });
|
|
1961
1963
|
fs6.writeFileSync(filePath, content, "utf-8");
|
|
1962
1964
|
}
|
|
1963
1965
|
const workflowName = data.workflow_name ?? workflowId;
|
|
@@ -1968,7 +1970,7 @@ var exportCommand = {
|
|
|
1968
1970
|
print(` Output: ${outDir}`);
|
|
1969
1971
|
print(` Files: ${Object.keys(files).length}`);
|
|
1970
1972
|
print("");
|
|
1971
|
-
print(style(`${
|
|
1973
|
+
print(style(`${path7.basename(outDir)}/`, CYAN));
|
|
1972
1974
|
const sortedPaths = Object.keys(files).sort();
|
|
1973
1975
|
for (const relPath of sortedPaths) {
|
|
1974
1976
|
const parts = relPath.split("/");
|
|
@@ -2242,7 +2244,7 @@ workflowGroup.command(createCommand).command(listCommand).command(showCommand).c
|
|
|
2242
2244
|
|
|
2243
2245
|
// src/commands/marketplace/registry.ts
|
|
2244
2246
|
import fs7 from "fs";
|
|
2245
|
-
import
|
|
2247
|
+
import path8 from "path";
|
|
2246
2248
|
var addCommand = {
|
|
2247
2249
|
name: "add",
|
|
2248
2250
|
description: "Register a GitHub repo as a workflow marketplace",
|
|
@@ -2347,7 +2349,7 @@ var removeCommand = {
|
|
|
2347
2349
|
saveRegistries({ version: config.version, registries: remaining });
|
|
2348
2350
|
try {
|
|
2349
2351
|
validateRegistryName(name);
|
|
2350
|
-
const cachePath =
|
|
2352
|
+
const cachePath = path8.join(synPath("marketplace", "cache"), `${name}.json`);
|
|
2351
2353
|
if (fs7.existsSync(cachePath)) fs7.unlinkSync(cachePath);
|
|
2352
2354
|
} catch {
|
|
2353
2355
|
}
|
|
@@ -2491,7 +2493,7 @@ var createCommand2 = {
|
|
|
2491
2493
|
description: "Create a new artifact",
|
|
2492
2494
|
options: {
|
|
2493
2495
|
workflow: { type: "string", short: "w", description: "Workflow ID" },
|
|
2494
|
-
type: { type: "string", short: "t", description: "Artifact type (code,
|
|
2496
|
+
type: { type: "string", short: "t", description: "Artifact type (code, markdown, text, json, yaml, research_summary, plan, other)" },
|
|
2495
2497
|
title: { type: "string", description: "Artifact title" },
|
|
2496
2498
|
content: { type: "string", short: "c", description: "Artifact content" },
|
|
2497
2499
|
phase: { type: "string", short: "p", description: "Phase ID" }
|
|
@@ -2755,6 +2757,10 @@ var metadataCommand = {
|
|
|
2755
2757
|
throw new CLIError("Missing argument", 1);
|
|
2756
2758
|
}
|
|
2757
2759
|
const m = await apiGet(`/conversations/${sessionId}/metadata`);
|
|
2760
|
+
if (!m || !m.session_id) {
|
|
2761
|
+
printError("Session not found or no metadata available.");
|
|
2762
|
+
throw new CLIError("Not found", 1);
|
|
2763
|
+
}
|
|
2758
2764
|
print(`${style("Metadata:", BOLD)} ${m.session_id}`);
|
|
2759
2765
|
if (m.model != null) print(` Model: ${m.model}`);
|
|
2760
2766
|
if (m.event_count != null) print(` Events: ${m.event_count.toLocaleString()}`);
|
|
@@ -2940,10 +2946,17 @@ function reqSessionId(parsed) {
|
|
|
2940
2946
|
var recentCommand = {
|
|
2941
2947
|
name: "recent",
|
|
2942
2948
|
description: "Show recent domain events across all sessions",
|
|
2943
|
-
options: {
|
|
2949
|
+
options: {
|
|
2950
|
+
limit: { type: "string", description: "Max events (max 200)", default: "50" },
|
|
2951
|
+
type: { type: "string", short: "t", description: "Filter by event type" }
|
|
2952
|
+
},
|
|
2944
2953
|
handler: async (parsed) => {
|
|
2945
2954
|
const limit = parsed.values["limit"] ?? "50";
|
|
2946
|
-
const
|
|
2955
|
+
const params = buildParams({
|
|
2956
|
+
limit,
|
|
2957
|
+
event_type: parsed.values["type"] ?? null
|
|
2958
|
+
});
|
|
2959
|
+
const data = await apiGet("/events/recent", { params });
|
|
2947
2960
|
if (data.events.length === 0) {
|
|
2948
2961
|
printDim("No recent events.");
|
|
2949
2962
|
return;
|
|
@@ -3545,11 +3558,14 @@ var registerCommand = {
|
|
|
3545
3558
|
printError("Missing --url");
|
|
3546
3559
|
throw new CLIError("Missing option", 1);
|
|
3547
3560
|
}
|
|
3548
|
-
const body = { repo_url: url };
|
|
3549
|
-
const system = parsed.values["system"];
|
|
3550
3561
|
const org = parsed.values["org"];
|
|
3562
|
+
if (!org) {
|
|
3563
|
+
printError("Missing --org");
|
|
3564
|
+
throw new CLIError("Missing option", 1);
|
|
3565
|
+
}
|
|
3566
|
+
const body = { full_name: url, organization_id: org };
|
|
3567
|
+
const system = parsed.values["system"];
|
|
3551
3568
|
if (system) body["system_id"] = system;
|
|
3552
|
-
if (org) body["organization_id"] = org;
|
|
3553
3569
|
const d = await apiPost("/repos", { body, expected: [200, 201] });
|
|
3554
3570
|
printSuccess(`Repository registered: ${d["repo_id"] ?? ""}`);
|
|
3555
3571
|
print(` Name: ${d["full_name"] ?? url}`);
|
|
@@ -4187,8 +4203,8 @@ function reqId4(parsed) {
|
|
|
4187
4203
|
function parseConditions(condStrs) {
|
|
4188
4204
|
return condStrs.map((c) => {
|
|
4189
4205
|
const eqIdx = c.indexOf("=");
|
|
4190
|
-
if (eqIdx < 1) throw new CLIError(`Invalid condition format: ${c} (expected
|
|
4191
|
-
return {
|
|
4206
|
+
if (eqIdx < 1) throw new CLIError(`Invalid condition format: ${c} (expected field=value)`, 1);
|
|
4207
|
+
return { field: c.slice(0, eqIdx), operator: "eq", value: c.slice(eqIdx + 1) };
|
|
4192
4208
|
});
|
|
4193
4209
|
}
|
|
4194
4210
|
var registerCommand2 = {
|
|
@@ -4198,7 +4214,7 @@ var registerCommand2 = {
|
|
|
4198
4214
|
repo: { type: "string", short: "r", description: "Repository ID" },
|
|
4199
4215
|
workflow: { type: "string", short: "w", description: "Workflow ID to execute" },
|
|
4200
4216
|
event: { type: "string", short: "e", description: "GitHub event type (e.g. check_run.completed)" },
|
|
4201
|
-
condition: { type: "string", short: "c", multiple: true, description: "Condition as
|
|
4217
|
+
condition: { type: "string", short: "c", multiple: true, description: "Condition as field=value (repeatable, uses 'eq' operator)" },
|
|
4202
4218
|
"max-fires": { type: "string", description: "Maximum fires per period", default: "5" },
|
|
4203
4219
|
cooldown: { type: "string", description: "Cooldown in seconds", default: "300" },
|
|
4204
4220
|
budget: { type: "string", description: "Budget limit in USD" }
|
|
@@ -4239,9 +4255,10 @@ var registerCommand2 = {
|
|
|
4239
4255
|
var enablePresetCommand = {
|
|
4240
4256
|
name: "enable",
|
|
4241
4257
|
description: "Enable a built-in trigger preset",
|
|
4242
|
-
args: [{ name: "preset", description: "Preset name (self-healing, review-fix)", required: true }],
|
|
4258
|
+
args: [{ name: "preset", description: "Preset name (self-healing, review-fix, comment-command)", required: true }],
|
|
4243
4259
|
options: {
|
|
4244
|
-
repo: { type: "string", short: "r", description: "Repository ID" }
|
|
4260
|
+
repo: { type: "string", short: "r", description: "Repository ID" },
|
|
4261
|
+
workflow: { type: "string", short: "w", description: "Workflow ID to dispatch (default: preset default)" }
|
|
4245
4262
|
},
|
|
4246
4263
|
handler: async (parsed) => {
|
|
4247
4264
|
const preset = parsed.positionals[0];
|
|
@@ -4254,7 +4271,10 @@ var enablePresetCommand = {
|
|
|
4254
4271
|
printError("Missing --repo");
|
|
4255
4272
|
throw new CLIError("Missing option", 1);
|
|
4256
4273
|
}
|
|
4257
|
-
const
|
|
4274
|
+
const workflow = parsed.values["workflow"];
|
|
4275
|
+
const body = { repository: repo };
|
|
4276
|
+
if (workflow) body["workflow_id"] = workflow;
|
|
4277
|
+
const d = await apiPost(`/triggers/presets/${encodeURIComponent(preset)}`, { body, expected: [200, 201] });
|
|
4258
4278
|
printSuccess(`Preset "${preset}" enabled: ${d["trigger_id"] ?? ""}`);
|
|
4259
4279
|
}
|
|
4260
4280
|
};
|
|
@@ -4315,7 +4335,7 @@ var showCommand11 = {
|
|
|
4315
4335
|
if (conditions.length > 0) {
|
|
4316
4336
|
print(style(" Conditions:", BOLD));
|
|
4317
4337
|
for (const c of conditions) {
|
|
4318
|
-
print(` ${c["
|
|
4338
|
+
print(` ${c["field"] ?? ""} = ${c["value"] ?? ""}`);
|
|
4319
4339
|
}
|
|
4320
4340
|
}
|
|
4321
4341
|
}
|
|
@@ -4437,9 +4457,9 @@ function parseSseLine(line) {
|
|
|
4437
4457
|
return null;
|
|
4438
4458
|
}
|
|
4439
4459
|
}
|
|
4440
|
-
async function* streamSSE(
|
|
4460
|
+
async function* streamSSE(path9) {
|
|
4441
4461
|
const client = new SynClient();
|
|
4442
|
-
const body = await client.stream(
|
|
4462
|
+
const body = await client.stream(path9);
|
|
4443
4463
|
const reader = body.pipeThrough(new TextDecoderStream()).getReader();
|
|
4444
4464
|
let buffer = "";
|
|
4445
4465
|
try {
|