auix 0.0.5 → 0.0.6
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 +1 -1
- package/dist/index.js +975 -142
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -1393,16 +1393,40 @@ function resolveApp() {
|
|
|
1393
1393
|
if (cwd === full || cwd.startsWith(`${full}/`)) return app;
|
|
1394
1394
|
}
|
|
1395
1395
|
}
|
|
1396
|
-
function
|
|
1397
|
-
|
|
1398
|
-
|
|
1396
|
+
function isJwtExpired(jwt) {
|
|
1397
|
+
try {
|
|
1398
|
+
const payload = JSON.parse(Buffer.from(jwt.split(".")[1], "base64url").toString());
|
|
1399
|
+
return Date.now() >= (payload.exp ?? 0) * 1e3;
|
|
1400
|
+
} catch {
|
|
1401
|
+
return true;
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
async function refreshJwt(config) {
|
|
1405
|
+
if (!config.sessionToken || !config.appUrl) return void 0;
|
|
1406
|
+
const base = config.appUrl.replace(/\/$/, "");
|
|
1407
|
+
const res = await fetch(`${base}/api/auth/token`, { headers: { Authorization: `Bearer ${config.sessionToken}` } });
|
|
1408
|
+
if (!res.ok) return void 0;
|
|
1409
|
+
return (await res.json()).token;
|
|
1410
|
+
}
|
|
1411
|
+
async function getToken() {
|
|
1412
|
+
const envToken = process.env.AUIX_TOKEN;
|
|
1413
|
+
if (envToken) return envToken;
|
|
1399
1414
|
const config = loadGlobalConfig();
|
|
1400
|
-
if (config.
|
|
1415
|
+
if (!config.token) return void 0;
|
|
1416
|
+
if (!isJwtExpired(config.token)) return config.token;
|
|
1417
|
+
const fresh = await refreshJwt(config);
|
|
1418
|
+
if (fresh) {
|
|
1419
|
+
saveGlobalConfig({
|
|
1420
|
+
...config,
|
|
1421
|
+
token: fresh
|
|
1422
|
+
});
|
|
1423
|
+
return fresh;
|
|
1424
|
+
}
|
|
1401
1425
|
}
|
|
1402
|
-
function
|
|
1403
|
-
const
|
|
1404
|
-
if (!
|
|
1405
|
-
return
|
|
1426
|
+
async function requireToken() {
|
|
1427
|
+
const token = await getToken();
|
|
1428
|
+
if (!token) throw new Error("Not authenticated. Run `auix login` or set AUIX_TOKEN.");
|
|
1429
|
+
return token;
|
|
1406
1430
|
}
|
|
1407
1431
|
function getBaseUrl() {
|
|
1408
1432
|
return process.env.AUIX_BASE_URL ?? loadGlobalConfig().baseUrl ?? DEFAULT_BASE_URL;
|
|
@@ -1434,7 +1458,7 @@ async function apiRequest(path, body) {
|
|
|
1434
1458
|
method: "POST",
|
|
1435
1459
|
headers: {
|
|
1436
1460
|
"Content-Type": "application/json",
|
|
1437
|
-
Authorization: `Bearer ${
|
|
1461
|
+
Authorization: `Bearer ${await requireToken()}`
|
|
1438
1462
|
},
|
|
1439
1463
|
body: JSON.stringify(body)
|
|
1440
1464
|
});
|
|
@@ -1467,6 +1491,72 @@ function maskValue(value) {
|
|
|
1467
1491
|
return `${value.slice(0, 2)}****${value.slice(-2)}`;
|
|
1468
1492
|
}
|
|
1469
1493
|
|
|
1494
|
+
//#endregion
|
|
1495
|
+
//#region src/actions.ts
|
|
1496
|
+
async function callAction(name, args) {
|
|
1497
|
+
const baseUrl = getBaseUrl().replace(/\/$/, "");
|
|
1498
|
+
const token = await requireToken();
|
|
1499
|
+
const res = await fetch(`${baseUrl}/v1/actions/${name}`, {
|
|
1500
|
+
method: "POST",
|
|
1501
|
+
headers: {
|
|
1502
|
+
"Content-Type": "application/json",
|
|
1503
|
+
Authorization: `Bearer ${token}`
|
|
1504
|
+
},
|
|
1505
|
+
body: JSON.stringify(args)
|
|
1506
|
+
});
|
|
1507
|
+
if (!res.ok) {
|
|
1508
|
+
const text = await res.text().catch(() => "");
|
|
1509
|
+
let msg;
|
|
1510
|
+
try {
|
|
1511
|
+
msg = JSON.parse(text).error ?? text;
|
|
1512
|
+
} catch {
|
|
1513
|
+
msg = text;
|
|
1514
|
+
}
|
|
1515
|
+
logError(`${name} failed (${res.status}): ${msg}`);
|
|
1516
|
+
}
|
|
1517
|
+
return res.json();
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
//#endregion
|
|
1521
|
+
//#region src/commands/audit-list.ts
|
|
1522
|
+
const auditListCommand = defineCommand({
|
|
1523
|
+
meta: {
|
|
1524
|
+
name: "list",
|
|
1525
|
+
description: "Query audit logs"
|
|
1526
|
+
},
|
|
1527
|
+
args: {
|
|
1528
|
+
type: {
|
|
1529
|
+
type: "string",
|
|
1530
|
+
description: "Filter by resource type"
|
|
1531
|
+
},
|
|
1532
|
+
action: {
|
|
1533
|
+
type: "string",
|
|
1534
|
+
description: "created, updated, deleted, or accessed"
|
|
1535
|
+
},
|
|
1536
|
+
limit: {
|
|
1537
|
+
type: "string",
|
|
1538
|
+
description: "Max results (default 50)"
|
|
1539
|
+
}
|
|
1540
|
+
},
|
|
1541
|
+
async run({ args }) {
|
|
1542
|
+
const data = await callAction("auix__audit_log_query", {
|
|
1543
|
+
resourceType: args.type,
|
|
1544
|
+
action: args.action,
|
|
1545
|
+
limit: args.limit ? Number(args.limit) : void 0
|
|
1546
|
+
});
|
|
1547
|
+
if (data.items.length === 0) {
|
|
1548
|
+
console.log("No audit logs found.");
|
|
1549
|
+
return;
|
|
1550
|
+
}
|
|
1551
|
+
for (const a of data.items) {
|
|
1552
|
+
const time = new Date(a.createdAt).toISOString().slice(0, 19);
|
|
1553
|
+
const actor = a.actorName ?? "system";
|
|
1554
|
+
console.log(` ${time} ${actor.padEnd(16)} ${a.summary}`);
|
|
1555
|
+
}
|
|
1556
|
+
console.log(`\nShowing ${data.items.length} of ${data.total} logs`);
|
|
1557
|
+
}
|
|
1558
|
+
});
|
|
1559
|
+
|
|
1470
1560
|
//#endregion
|
|
1471
1561
|
//#region src/commands/branch-create.ts
|
|
1472
1562
|
const branchCreateCommand = defineCommand({
|
|
@@ -1807,6 +1897,257 @@ const dynamicListCommand = defineCommand({
|
|
|
1807
1897
|
}
|
|
1808
1898
|
});
|
|
1809
1899
|
|
|
1900
|
+
//#endregion
|
|
1901
|
+
//#region src/commands/flow-create.ts
|
|
1902
|
+
const flowCreateCommand = defineCommand({
|
|
1903
|
+
meta: {
|
|
1904
|
+
name: "create",
|
|
1905
|
+
description: "Create a new flow"
|
|
1906
|
+
},
|
|
1907
|
+
args: {
|
|
1908
|
+
name: {
|
|
1909
|
+
type: "string",
|
|
1910
|
+
description: "Flow name",
|
|
1911
|
+
required: true
|
|
1912
|
+
},
|
|
1913
|
+
trigger: {
|
|
1914
|
+
type: "string",
|
|
1915
|
+
description: "Trigger type",
|
|
1916
|
+
required: true
|
|
1917
|
+
},
|
|
1918
|
+
actions: {
|
|
1919
|
+
type: "string",
|
|
1920
|
+
description: "Actions JSON array",
|
|
1921
|
+
required: true
|
|
1922
|
+
},
|
|
1923
|
+
conditions: {
|
|
1924
|
+
type: "string",
|
|
1925
|
+
description: "Conditions JSON array"
|
|
1926
|
+
},
|
|
1927
|
+
visibility: {
|
|
1928
|
+
type: "string",
|
|
1929
|
+
description: "personal, project, or organization"
|
|
1930
|
+
},
|
|
1931
|
+
project: {
|
|
1932
|
+
type: "string",
|
|
1933
|
+
description: "Project ID"
|
|
1934
|
+
}
|
|
1935
|
+
},
|
|
1936
|
+
async run({ args }) {
|
|
1937
|
+
let actions;
|
|
1938
|
+
try {
|
|
1939
|
+
actions = JSON.parse(args.actions);
|
|
1940
|
+
} catch {
|
|
1941
|
+
logError("Invalid JSON for --actions");
|
|
1942
|
+
return;
|
|
1943
|
+
}
|
|
1944
|
+
let conditions;
|
|
1945
|
+
if (args.conditions) try {
|
|
1946
|
+
conditions = JSON.parse(args.conditions);
|
|
1947
|
+
} catch {
|
|
1948
|
+
logError("Invalid JSON for --conditions");
|
|
1949
|
+
return;
|
|
1950
|
+
}
|
|
1951
|
+
const data = await callAction("auix__flow_create", {
|
|
1952
|
+
name: args.name,
|
|
1953
|
+
trigger: args.trigger,
|
|
1954
|
+
actions,
|
|
1955
|
+
conditions,
|
|
1956
|
+
visibility: args.visibility,
|
|
1957
|
+
projectId: args.project
|
|
1958
|
+
});
|
|
1959
|
+
console.log(`Created flow ${data.id} (disabled by default)`);
|
|
1960
|
+
}
|
|
1961
|
+
});
|
|
1962
|
+
|
|
1963
|
+
//#endregion
|
|
1964
|
+
//#region src/commands/flow-delete.ts
|
|
1965
|
+
const flowDeleteCommand = defineCommand({
|
|
1966
|
+
meta: {
|
|
1967
|
+
name: "delete",
|
|
1968
|
+
description: "Delete a flow"
|
|
1969
|
+
},
|
|
1970
|
+
args: { id: {
|
|
1971
|
+
type: "positional",
|
|
1972
|
+
description: "Flow ID",
|
|
1973
|
+
required: true
|
|
1974
|
+
} },
|
|
1975
|
+
async run({ args }) {
|
|
1976
|
+
const confirmed = await consola.prompt(`Delete flow ${args.id}?`, { type: "confirm" });
|
|
1977
|
+
if (!confirmed || typeof confirmed === "symbol") {
|
|
1978
|
+
console.log("Cancelled.");
|
|
1979
|
+
return;
|
|
1980
|
+
}
|
|
1981
|
+
await callAction("auix__flow_delete", { flowId: args.id });
|
|
1982
|
+
console.log("Deleted.");
|
|
1983
|
+
}
|
|
1984
|
+
});
|
|
1985
|
+
|
|
1986
|
+
//#endregion
|
|
1987
|
+
//#region src/commands/flow-dispatch.ts
|
|
1988
|
+
const flowDispatchCommand = defineCommand({
|
|
1989
|
+
meta: {
|
|
1990
|
+
name: "dispatch",
|
|
1991
|
+
description: "Manually trigger a flow"
|
|
1992
|
+
},
|
|
1993
|
+
args: { id: {
|
|
1994
|
+
type: "positional",
|
|
1995
|
+
description: "Flow ID",
|
|
1996
|
+
required: true
|
|
1997
|
+
} },
|
|
1998
|
+
async run({ args }) {
|
|
1999
|
+
const data = await callAction("auix__flow_dispatch", { flowId: args.id });
|
|
2000
|
+
console.log(`Dispatched execution ${data.executionId} (${data.mode})`);
|
|
2001
|
+
}
|
|
2002
|
+
});
|
|
2003
|
+
|
|
2004
|
+
//#endregion
|
|
2005
|
+
//#region src/commands/flow-duplicate.ts
|
|
2006
|
+
const flowDuplicateCommand = defineCommand({
|
|
2007
|
+
meta: {
|
|
2008
|
+
name: "duplicate",
|
|
2009
|
+
description: "Duplicate a flow"
|
|
2010
|
+
},
|
|
2011
|
+
args: { id: {
|
|
2012
|
+
type: "positional",
|
|
2013
|
+
description: "Flow ID",
|
|
2014
|
+
required: true
|
|
2015
|
+
} },
|
|
2016
|
+
async run({ args }) {
|
|
2017
|
+
const data = await callAction("auix__flow_duplicate", { flowId: args.id });
|
|
2018
|
+
console.log(`Duplicated as ${data.id} ("${data.name}")`);
|
|
2019
|
+
}
|
|
2020
|
+
});
|
|
2021
|
+
|
|
2022
|
+
//#endregion
|
|
2023
|
+
//#region src/commands/flow-executions.ts
|
|
2024
|
+
const flowExecutionsCommand = defineCommand({
|
|
2025
|
+
meta: {
|
|
2026
|
+
name: "executions",
|
|
2027
|
+
description: "List flow execution history"
|
|
2028
|
+
},
|
|
2029
|
+
args: {
|
|
2030
|
+
id: {
|
|
2031
|
+
type: "positional",
|
|
2032
|
+
description: "Flow ID",
|
|
2033
|
+
required: true
|
|
2034
|
+
},
|
|
2035
|
+
limit: {
|
|
2036
|
+
type: "string",
|
|
2037
|
+
description: "Max results (default 20)"
|
|
2038
|
+
}
|
|
2039
|
+
},
|
|
2040
|
+
async run({ args }) {
|
|
2041
|
+
const data = await callAction("auix__flow_executions", {
|
|
2042
|
+
flowId: args.id,
|
|
2043
|
+
limit: args.limit ? Number(args.limit) : void 0
|
|
2044
|
+
});
|
|
2045
|
+
if (data.length === 0) {
|
|
2046
|
+
console.log("No executions found.");
|
|
2047
|
+
return;
|
|
2048
|
+
}
|
|
2049
|
+
for (const e of data) {
|
|
2050
|
+
const time = new Date(e.startedAt).toISOString().slice(0, 19);
|
|
2051
|
+
const err = e.error ? ` | ${e.error.slice(0, 60)}` : "";
|
|
2052
|
+
console.log(` ${e.id.slice(0, 8)} ${e.status.padEnd(8)} ${e.mode.padEnd(10)} ${time}${err}`);
|
|
2053
|
+
}
|
|
2054
|
+
console.log(`\n${data.length} executions`);
|
|
2055
|
+
}
|
|
2056
|
+
});
|
|
2057
|
+
|
|
2058
|
+
//#endregion
|
|
2059
|
+
//#region src/commands/flow-get.ts
|
|
2060
|
+
const flowGetCommand = defineCommand({
|
|
2061
|
+
meta: {
|
|
2062
|
+
name: "get",
|
|
2063
|
+
description: "Get flow details"
|
|
2064
|
+
},
|
|
2065
|
+
args: { id: {
|
|
2066
|
+
type: "positional",
|
|
2067
|
+
description: "Flow ID",
|
|
2068
|
+
required: true
|
|
2069
|
+
} },
|
|
2070
|
+
async run({ args }) {
|
|
2071
|
+
const data = await callAction("auix__flow_get", { flowId: args.id });
|
|
2072
|
+
console.log(JSON.stringify(data, null, 2));
|
|
2073
|
+
}
|
|
2074
|
+
});
|
|
2075
|
+
|
|
2076
|
+
//#endregion
|
|
2077
|
+
//#region src/commands/flow-list.ts
|
|
2078
|
+
const flowListCommand = defineCommand({
|
|
2079
|
+
meta: {
|
|
2080
|
+
name: "list",
|
|
2081
|
+
description: "List automation flows"
|
|
2082
|
+
},
|
|
2083
|
+
args: {
|
|
2084
|
+
search: {
|
|
2085
|
+
type: "string",
|
|
2086
|
+
description: "Filter by name"
|
|
2087
|
+
},
|
|
2088
|
+
status: {
|
|
2089
|
+
type: "string",
|
|
2090
|
+
description: "active or disabled"
|
|
2091
|
+
},
|
|
2092
|
+
trigger: {
|
|
2093
|
+
type: "string",
|
|
2094
|
+
description: "Filter by trigger prefix"
|
|
2095
|
+
},
|
|
2096
|
+
limit: {
|
|
2097
|
+
type: "string",
|
|
2098
|
+
description: "Max results (default 20)"
|
|
2099
|
+
}
|
|
2100
|
+
},
|
|
2101
|
+
async run({ args }) {
|
|
2102
|
+
const data = await callAction("auix__flow_list", {
|
|
2103
|
+
search: args.search,
|
|
2104
|
+
status: args.status,
|
|
2105
|
+
trigger: args.trigger,
|
|
2106
|
+
limit: args.limit ? Number(args.limit) : void 0
|
|
2107
|
+
});
|
|
2108
|
+
if (data.length === 0) {
|
|
2109
|
+
console.log("No flows found.");
|
|
2110
|
+
return;
|
|
2111
|
+
}
|
|
2112
|
+
for (const f of data) {
|
|
2113
|
+
const status = f.enabled ? "active" : "disabled";
|
|
2114
|
+
const lastExec = f.lastExecution ? ` [last: ${f.lastExecution.status}]` : "";
|
|
2115
|
+
console.log(` ${f.id.slice(0, 8)} ${status.padEnd(8)} ${f.trigger.padEnd(30)} ${f.name}${lastExec}`);
|
|
2116
|
+
}
|
|
2117
|
+
console.log(`\n${data.length} flows`);
|
|
2118
|
+
}
|
|
2119
|
+
});
|
|
2120
|
+
|
|
2121
|
+
//#endregion
|
|
2122
|
+
//#region src/commands/flow-toggle.ts
|
|
2123
|
+
const flowToggleCommand = defineCommand({
|
|
2124
|
+
meta: {
|
|
2125
|
+
name: "toggle",
|
|
2126
|
+
description: "Enable or disable a flow"
|
|
2127
|
+
},
|
|
2128
|
+
args: {
|
|
2129
|
+
id: {
|
|
2130
|
+
type: "positional",
|
|
2131
|
+
description: "Flow ID",
|
|
2132
|
+
required: true
|
|
2133
|
+
},
|
|
2134
|
+
enabled: {
|
|
2135
|
+
type: "string",
|
|
2136
|
+
description: "true or false",
|
|
2137
|
+
required: true
|
|
2138
|
+
}
|
|
2139
|
+
},
|
|
2140
|
+
async run({ args }) {
|
|
2141
|
+
if (args.enabled !== "true" && args.enabled !== "false") logError("--enabled must be true or false");
|
|
2142
|
+
const enabled = args.enabled === "true";
|
|
2143
|
+
const data = await callAction("auix__flow_toggle", {
|
|
2144
|
+
flowId: args.id,
|
|
2145
|
+
enabled
|
|
2146
|
+
});
|
|
2147
|
+
console.log(`Flow ${data.id} ${data.enabled ? "enabled" : "disabled"}`);
|
|
2148
|
+
}
|
|
2149
|
+
});
|
|
2150
|
+
|
|
1810
2151
|
//#endregion
|
|
1811
2152
|
//#region src/commands/history.ts
|
|
1812
2153
|
const historyCommand = defineCommand({
|
|
@@ -2067,6 +2408,24 @@ async function selectProject() {
|
|
|
2067
2408
|
return trimmed;
|
|
2068
2409
|
}
|
|
2069
2410
|
|
|
2411
|
+
//#endregion
|
|
2412
|
+
//#region src/commands/integration-list.ts
|
|
2413
|
+
const integrationListCommand = defineCommand({
|
|
2414
|
+
meta: {
|
|
2415
|
+
name: "list",
|
|
2416
|
+
description: "List connected integrations"
|
|
2417
|
+
},
|
|
2418
|
+
async run() {
|
|
2419
|
+
const data = await callAction("auix__integration_list", {});
|
|
2420
|
+
if (data.length === 0) {
|
|
2421
|
+
console.log("No integrations connected.");
|
|
2422
|
+
return;
|
|
2423
|
+
}
|
|
2424
|
+
for (const i of data) console.log(` ${i.provider.padEnd(16)} ${i.status}`);
|
|
2425
|
+
console.log(`\n${data.length} integrations`);
|
|
2426
|
+
}
|
|
2427
|
+
});
|
|
2428
|
+
|
|
2070
2429
|
//#endregion
|
|
2071
2430
|
//#region src/commands/list.ts
|
|
2072
2431
|
const listCommand = defineCommand({
|
|
@@ -2228,6 +2587,51 @@ const lockStatusCommand = defineCommand({
|
|
|
2228
2587
|
}
|
|
2229
2588
|
});
|
|
2230
2589
|
|
|
2590
|
+
//#endregion
|
|
2591
|
+
//#region src/commands/log-query.ts
|
|
2592
|
+
const logQueryCommand = defineCommand({
|
|
2593
|
+
meta: {
|
|
2594
|
+
name: "query",
|
|
2595
|
+
description: "Query structured logs"
|
|
2596
|
+
},
|
|
2597
|
+
args: {
|
|
2598
|
+
source: {
|
|
2599
|
+
type: "string",
|
|
2600
|
+
description: "Filter by source ID"
|
|
2601
|
+
},
|
|
2602
|
+
level: {
|
|
2603
|
+
type: "string",
|
|
2604
|
+
description: "info, warn, error, or fatal"
|
|
2605
|
+
},
|
|
2606
|
+
search: {
|
|
2607
|
+
type: "string",
|
|
2608
|
+
description: "Search in message"
|
|
2609
|
+
},
|
|
2610
|
+
limit: {
|
|
2611
|
+
type: "string",
|
|
2612
|
+
description: "Max results (default 50)"
|
|
2613
|
+
}
|
|
2614
|
+
},
|
|
2615
|
+
async run({ args }) {
|
|
2616
|
+
const data = await callAction("auix__logs_query", {
|
|
2617
|
+
sourceId: args.source,
|
|
2618
|
+
level: args.level,
|
|
2619
|
+
search: args.search,
|
|
2620
|
+
limit: args.limit ? Number(args.limit) : void 0
|
|
2621
|
+
});
|
|
2622
|
+
if (data.items.length === 0) {
|
|
2623
|
+
console.log("No logs found.");
|
|
2624
|
+
return;
|
|
2625
|
+
}
|
|
2626
|
+
for (const l of data.items) {
|
|
2627
|
+
const time = new Date(l.timestamp).toISOString().slice(11, 19);
|
|
2628
|
+
const src = l.source?.name ?? "-";
|
|
2629
|
+
console.log(` ${time} ${l.level.padEnd(5)} ${src.padEnd(16)} ${l.message.slice(0, 80)}`);
|
|
2630
|
+
}
|
|
2631
|
+
console.log(`\nShowing ${data.items.length} of ${data.total} logs`);
|
|
2632
|
+
}
|
|
2633
|
+
});
|
|
2634
|
+
|
|
2231
2635
|
//#endregion
|
|
2232
2636
|
//#region src/commands/login.ts
|
|
2233
2637
|
const CLIENT_ID = "auix-cli";
|
|
@@ -2277,9 +2681,9 @@ async function deviceFlow(appUrl) {
|
|
|
2277
2681
|
logError("Device code expired. Please try again.");
|
|
2278
2682
|
return "";
|
|
2279
2683
|
}
|
|
2280
|
-
async function selectOrganization(appUrl,
|
|
2684
|
+
async function selectOrganization(appUrl, sessionToken) {
|
|
2281
2685
|
const base = appUrl.replace(/\/$/, "");
|
|
2282
|
-
const res = await fetch(`${base}/api/auth/organization/list`, { headers: { Authorization: `Bearer ${
|
|
2686
|
+
const res = await fetch(`${base}/api/auth/organization/list`, { headers: { Authorization: `Bearer ${sessionToken}` } });
|
|
2283
2687
|
if (!res.ok) logError(`Failed to list organizations (${res.status}).`);
|
|
2284
2688
|
const orgs = await res.json();
|
|
2285
2689
|
if (orgs.length === 0) logError("No organizations found. Create one at the web dashboard.");
|
|
@@ -2297,9 +2701,9 @@ async function selectOrganization(appUrl, token) {
|
|
|
2297
2701
|
if (typeof selected === "symbol") logError("Cancelled.");
|
|
2298
2702
|
return orgs.find((o) => o.id === selected);
|
|
2299
2703
|
}
|
|
2300
|
-
async function fetchUser(appUrl,
|
|
2704
|
+
async function fetchUser(appUrl, sessionToken) {
|
|
2301
2705
|
const base = appUrl.replace(/\/$/, "");
|
|
2302
|
-
const res = await fetch(`${base}/api/auth/get-session`, { headers: { Authorization: `Bearer ${
|
|
2706
|
+
const res = await fetch(`${base}/api/auth/get-session`, { headers: { Authorization: `Bearer ${sessionToken}` } });
|
|
2303
2707
|
if (!res.ok) return {
|
|
2304
2708
|
name: "unknown",
|
|
2305
2709
|
email: "unknown"
|
|
@@ -2310,96 +2714,278 @@ async function fetchUser(appUrl, token) {
|
|
|
2310
2714
|
email: data.user?.email ?? "unknown"
|
|
2311
2715
|
};
|
|
2312
2716
|
}
|
|
2313
|
-
async function
|
|
2717
|
+
async function getJwt(appUrl, sessionToken, organizationId) {
|
|
2314
2718
|
const base = appUrl.replace(/\/$/, "");
|
|
2315
|
-
|
|
2719
|
+
if (!(await fetch(`${base}/api/auth/organization/set-active`, {
|
|
2316
2720
|
method: "POST",
|
|
2317
2721
|
headers: {
|
|
2318
2722
|
"Content-Type": "application/json",
|
|
2319
|
-
Authorization: `Bearer ${
|
|
2723
|
+
Authorization: `Bearer ${sessionToken}`
|
|
2320
2724
|
},
|
|
2321
2725
|
body: JSON.stringify({ organizationId })
|
|
2322
|
-
});
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2726
|
+
})).ok) logError("Failed to set active organization.");
|
|
2727
|
+
const tokenRes = await fetch(`${base}/api/auth/token`, { headers: { Authorization: `Bearer ${sessionToken}` } });
|
|
2728
|
+
if (!tokenRes.ok) logError("Failed to obtain access token.");
|
|
2729
|
+
return (await tokenRes.json()).token;
|
|
2730
|
+
}
|
|
2731
|
+
const loginCommand = defineCommand({
|
|
2732
|
+
meta: {
|
|
2733
|
+
name: "login",
|
|
2734
|
+
description: "Authenticate with auix"
|
|
2735
|
+
},
|
|
2736
|
+
args: {
|
|
2737
|
+
url: {
|
|
2738
|
+
type: "string",
|
|
2739
|
+
description: "Custom API base URL"
|
|
2740
|
+
},
|
|
2741
|
+
"app-url": {
|
|
2742
|
+
type: "string",
|
|
2743
|
+
description: "Custom web app URL"
|
|
2744
|
+
}
|
|
2745
|
+
},
|
|
2746
|
+
async run({ args }) {
|
|
2747
|
+
const baseUrl = args.url ?? getBaseUrl();
|
|
2748
|
+
const appUrl = args["app-url"] ?? getAppUrl();
|
|
2749
|
+
const sessionToken = await deviceFlow(appUrl);
|
|
2750
|
+
const user = await fetchUser(appUrl, sessionToken);
|
|
2751
|
+
console.log(`Authenticated as ${user.email}\n`);
|
|
2752
|
+
const org = await selectOrganization(appUrl, sessionToken);
|
|
2753
|
+
saveGlobalConfig({
|
|
2754
|
+
token: await getJwt(appUrl, sessionToken, org.id),
|
|
2755
|
+
sessionToken,
|
|
2756
|
+
baseUrl,
|
|
2757
|
+
appUrl,
|
|
2758
|
+
user,
|
|
2759
|
+
organization: {
|
|
2760
|
+
name: org.name,
|
|
2761
|
+
slug: org.slug
|
|
2762
|
+
}
|
|
2763
|
+
});
|
|
2764
|
+
console.log(`\nLogged in to ${org.name}.`);
|
|
2765
|
+
}
|
|
2766
|
+
});
|
|
2767
|
+
|
|
2768
|
+
//#endregion
|
|
2769
|
+
//#region src/commands/logout.ts
|
|
2770
|
+
const CONFIG_FILE = join(homedir(), ".auix", "config.json");
|
|
2771
|
+
const logoutCommand = defineCommand({
|
|
2772
|
+
meta: {
|
|
2773
|
+
name: "logout",
|
|
2774
|
+
description: "Log out and remove credentials"
|
|
2775
|
+
},
|
|
2776
|
+
async run() {
|
|
2777
|
+
if (!existsSync(CONFIG_FILE)) {
|
|
2778
|
+
console.log("Not logged in.");
|
|
2779
|
+
return;
|
|
2780
|
+
}
|
|
2781
|
+
rmSync(CONFIG_FILE);
|
|
2782
|
+
console.log("Logged out.");
|
|
2783
|
+
}
|
|
2784
|
+
});
|
|
2785
|
+
|
|
2786
|
+
//#endregion
|
|
2787
|
+
//#region src/commands/member-list.ts
|
|
2788
|
+
const memberListCommand = defineCommand({
|
|
2789
|
+
meta: {
|
|
2790
|
+
name: "list",
|
|
2791
|
+
description: "List organization members"
|
|
2792
|
+
},
|
|
2793
|
+
async run() {
|
|
2794
|
+
const data = await callAction("auix__member_list", {});
|
|
2795
|
+
if (data.length === 0) {
|
|
2796
|
+
console.log("No members found.");
|
|
2797
|
+
return;
|
|
2798
|
+
}
|
|
2799
|
+
for (const m of data) {
|
|
2800
|
+
const name = m.user.name ?? m.user.email;
|
|
2801
|
+
const active = m.lastActiveAt ? new Date(m.lastActiveAt).toISOString().slice(0, 10) : "never";
|
|
2802
|
+
console.log(` ${m.role.padEnd(6)} ${name.padEnd(30)} ${active}`);
|
|
2803
|
+
}
|
|
2804
|
+
console.log(`\n${data.length} members`);
|
|
2805
|
+
}
|
|
2806
|
+
});
|
|
2807
|
+
|
|
2808
|
+
//#endregion
|
|
2809
|
+
//#region src/commands/prism-list.ts
|
|
2810
|
+
const prismListCommand = defineCommand({
|
|
2811
|
+
meta: {
|
|
2812
|
+
name: "list",
|
|
2813
|
+
description: "List LLM traces"
|
|
2814
|
+
},
|
|
2815
|
+
args: {
|
|
2816
|
+
model: {
|
|
2817
|
+
type: "string",
|
|
2818
|
+
description: "Filter by model"
|
|
2819
|
+
},
|
|
2820
|
+
name: {
|
|
2821
|
+
type: "string",
|
|
2822
|
+
description: "Filter by name"
|
|
2823
|
+
},
|
|
2824
|
+
project: {
|
|
2825
|
+
type: "string",
|
|
2826
|
+
description: "Filter by project ID"
|
|
2827
|
+
},
|
|
2828
|
+
limit: {
|
|
2829
|
+
type: "string",
|
|
2830
|
+
description: "Max results (default 50)"
|
|
2831
|
+
}
|
|
2832
|
+
},
|
|
2833
|
+
async run({ args }) {
|
|
2834
|
+
const data = await callAction("auix__prism_traces", {
|
|
2835
|
+
model: args.model,
|
|
2836
|
+
name: args.name,
|
|
2837
|
+
projectId: args.project,
|
|
2838
|
+
limit: args.limit ? Number(args.limit) : void 0
|
|
2839
|
+
});
|
|
2840
|
+
if (data.length === 0) {
|
|
2841
|
+
console.log("No traces found.");
|
|
2842
|
+
return;
|
|
2843
|
+
}
|
|
2844
|
+
for (const t of data) {
|
|
2845
|
+
const time = new Date(t.createdAt).toISOString().slice(0, 19);
|
|
2846
|
+
const cost = t.totalCostUsd ? `$${Number(t.totalCostUsd).toFixed(4)}` : "-";
|
|
2847
|
+
const tokens = t.totalTokens ?? "-";
|
|
2848
|
+
console.log(` ${t.id.slice(0, 8)} ${(t.model ?? "-").padEnd(20)} ${String(tokens).padEnd(8)} ${cost.padEnd(8)} ${time}`);
|
|
2849
|
+
}
|
|
2850
|
+
console.log(`\n${data.length} traces`);
|
|
2851
|
+
}
|
|
2852
|
+
});
|
|
2853
|
+
|
|
2854
|
+
//#endregion
|
|
2855
|
+
//#region src/commands/prism-metrics.ts
|
|
2856
|
+
const prismMetricsCommand = defineCommand({
|
|
2857
|
+
meta: {
|
|
2858
|
+
name: "metrics",
|
|
2859
|
+
description: "Show LLM usage metrics"
|
|
2860
|
+
},
|
|
2861
|
+
args: {
|
|
2862
|
+
project: {
|
|
2863
|
+
type: "string",
|
|
2864
|
+
description: "Filter by project ID"
|
|
2865
|
+
},
|
|
2866
|
+
start: {
|
|
2867
|
+
type: "string",
|
|
2868
|
+
description: "Start date (ISO)"
|
|
2869
|
+
},
|
|
2870
|
+
end: {
|
|
2871
|
+
type: "string",
|
|
2872
|
+
description: "End date (ISO)"
|
|
2873
|
+
}
|
|
2874
|
+
},
|
|
2875
|
+
async run({ args }) {
|
|
2876
|
+
const data = await callAction("auix__prism_metrics", {
|
|
2877
|
+
projectId: args.project,
|
|
2878
|
+
startDate: args.start,
|
|
2879
|
+
endDate: args.end
|
|
2880
|
+
});
|
|
2881
|
+
const s = data.summary;
|
|
2882
|
+
console.log(`Total traces: ${s.total}`);
|
|
2883
|
+
console.log(`Total tokens: ${s.totalTokens ?? 0}`);
|
|
2884
|
+
console.log(`Total cost: $${s.totalCost ? Number(s.totalCost).toFixed(4) : "0.0000"}`);
|
|
2885
|
+
console.log(`Avg latency: ${s.avgLatencyMs ? Math.round(Number(s.avgLatencyMs)) : 0}ms`);
|
|
2886
|
+
console.log(`Errors: ${s.errorCount}`);
|
|
2887
|
+
if (data.byModel.length > 0) {
|
|
2888
|
+
console.log("\nBy model:");
|
|
2889
|
+
for (const m of data.byModel) {
|
|
2890
|
+
const cost = m.totalCost ? `$${Number(m.totalCost).toFixed(4)}` : "-";
|
|
2891
|
+
console.log(` ${m.model.padEnd(24)} ${String(m.count).padEnd(6)} ${cost}`);
|
|
2892
|
+
}
|
|
2893
|
+
}
|
|
2326
2894
|
}
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2895
|
+
});
|
|
2896
|
+
|
|
2897
|
+
//#endregion
|
|
2898
|
+
//#region src/commands/project-create.ts
|
|
2899
|
+
const projectCreateCommand = defineCommand({
|
|
2330
2900
|
meta: {
|
|
2331
|
-
name: "
|
|
2332
|
-
description: "
|
|
2901
|
+
name: "create",
|
|
2902
|
+
description: "Create a project"
|
|
2333
2903
|
},
|
|
2334
2904
|
args: {
|
|
2335
|
-
|
|
2905
|
+
name: {
|
|
2336
2906
|
type: "string",
|
|
2337
|
-
description: "
|
|
2907
|
+
description: "Project name",
|
|
2908
|
+
required: true
|
|
2338
2909
|
},
|
|
2339
|
-
|
|
2910
|
+
slug: {
|
|
2340
2911
|
type: "string",
|
|
2341
|
-
description: "
|
|
2912
|
+
description: "URL slug",
|
|
2913
|
+
required: true
|
|
2342
2914
|
},
|
|
2343
|
-
|
|
2915
|
+
description: {
|
|
2344
2916
|
type: "string",
|
|
2345
|
-
description: "
|
|
2917
|
+
description: "Description"
|
|
2346
2918
|
}
|
|
2347
2919
|
},
|
|
2348
2920
|
async run({ args }) {
|
|
2349
|
-
const
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2921
|
+
const data = await callAction("auix__project_create", {
|
|
2922
|
+
name: args.name,
|
|
2923
|
+
slug: args.slug,
|
|
2924
|
+
description: args.description
|
|
2925
|
+
});
|
|
2926
|
+
console.log(`Created project ${data.slug} (${data.id})`);
|
|
2927
|
+
}
|
|
2928
|
+
});
|
|
2929
|
+
|
|
2930
|
+
//#endregion
|
|
2931
|
+
//#region src/commands/project-delete.ts
|
|
2932
|
+
const projectDeleteCommand = defineCommand({
|
|
2933
|
+
meta: {
|
|
2934
|
+
name: "delete",
|
|
2935
|
+
description: "Delete a project"
|
|
2936
|
+
},
|
|
2937
|
+
args: { id: {
|
|
2938
|
+
type: "positional",
|
|
2939
|
+
description: "Project ID",
|
|
2940
|
+
required: true
|
|
2941
|
+
} },
|
|
2942
|
+
async run({ args }) {
|
|
2943
|
+
const confirmed = await consola.prompt(`Delete project ${args.id}?`, { type: "confirm" });
|
|
2944
|
+
if (!confirmed || typeof confirmed === "symbol") {
|
|
2945
|
+
console.log("Cancelled.");
|
|
2368
2946
|
return;
|
|
2369
2947
|
}
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
console.log(`Authenticated as ${user.email}\n`);
|
|
2373
|
-
const org = await selectOrganization(appUrl, token);
|
|
2374
|
-
saveGlobalConfig({
|
|
2375
|
-
apiKey: await createApiKey$1(appUrl, token, org.id),
|
|
2376
|
-
baseUrl,
|
|
2377
|
-
appUrl,
|
|
2378
|
-
user,
|
|
2379
|
-
organization: {
|
|
2380
|
-
name: org.name,
|
|
2381
|
-
slug: org.slug
|
|
2382
|
-
}
|
|
2383
|
-
});
|
|
2384
|
-
console.log(`\nLogged in to ${org.name}.`);
|
|
2948
|
+
await callAction("auix__project_delete", { projectId: args.id });
|
|
2949
|
+
console.log("Deleted.");
|
|
2385
2950
|
}
|
|
2386
2951
|
});
|
|
2387
2952
|
|
|
2388
2953
|
//#endregion
|
|
2389
|
-
//#region src/commands/
|
|
2390
|
-
const
|
|
2391
|
-
const logoutCommand = defineCommand({
|
|
2954
|
+
//#region src/commands/project-get.ts
|
|
2955
|
+
const projectGetCommand = defineCommand({
|
|
2392
2956
|
meta: {
|
|
2393
|
-
name: "
|
|
2394
|
-
description: "
|
|
2957
|
+
name: "get",
|
|
2958
|
+
description: "Get project details"
|
|
2959
|
+
},
|
|
2960
|
+
args: { id: {
|
|
2961
|
+
type: "positional",
|
|
2962
|
+
description: "Project ID",
|
|
2963
|
+
required: true
|
|
2964
|
+
} },
|
|
2965
|
+
async run({ args }) {
|
|
2966
|
+
const data = await callAction("auix__project_get", { projectId: args.id });
|
|
2967
|
+
console.log(JSON.stringify(data, null, 2));
|
|
2968
|
+
}
|
|
2969
|
+
});
|
|
2970
|
+
|
|
2971
|
+
//#endregion
|
|
2972
|
+
//#region src/commands/project-list.ts
|
|
2973
|
+
const projectListCommand = defineCommand({
|
|
2974
|
+
meta: {
|
|
2975
|
+
name: "list",
|
|
2976
|
+
description: "List projects"
|
|
2395
2977
|
},
|
|
2396
2978
|
async run() {
|
|
2397
|
-
|
|
2398
|
-
|
|
2979
|
+
const data = await callAction("auix__project_list", {});
|
|
2980
|
+
if (data.length === 0) {
|
|
2981
|
+
console.log("No projects found.");
|
|
2399
2982
|
return;
|
|
2400
2983
|
}
|
|
2401
|
-
|
|
2402
|
-
|
|
2984
|
+
for (const p of data) {
|
|
2985
|
+
const desc = p.description ? ` ${p.description}` : "";
|
|
2986
|
+
console.log(` ${p.slug.padEnd(24)} ${p.name}${desc}`);
|
|
2987
|
+
}
|
|
2988
|
+
console.log(`\n${data.length} projects`);
|
|
2403
2989
|
}
|
|
2404
2990
|
});
|
|
2405
2991
|
|
|
@@ -2773,8 +3359,8 @@ function getFingerprint() {
|
|
|
2773
3359
|
return id;
|
|
2774
3360
|
}
|
|
2775
3361
|
async function ensureToken(project) {
|
|
2776
|
-
const
|
|
2777
|
-
if (
|
|
3362
|
+
const token = await getToken();
|
|
3363
|
+
if (token) return token;
|
|
2778
3364
|
const session = loadSession();
|
|
2779
3365
|
if (session && session.project === project) return session.token;
|
|
2780
3366
|
const fingerprint = getFingerprint();
|
|
@@ -2798,7 +3384,7 @@ async function ensureToken(project) {
|
|
|
2798
3384
|
os: process.platform,
|
|
2799
3385
|
arch: process.arch,
|
|
2800
3386
|
nodeVersion: process.version,
|
|
2801
|
-
cliVersion: "0.0.
|
|
3387
|
+
cliVersion: "0.0.6",
|
|
2802
3388
|
shell: process.env.SHELL ?? process.env.COMSPEC,
|
|
2803
3389
|
ci: isCI || void 0,
|
|
2804
3390
|
ciName: process.env.GITHUB_ACTIONS ? "github-actions" : process.env.GITLAB_CI ? "gitlab-ci" : process.env.CIRCLECI ? "circleci" : void 0,
|
|
@@ -3068,22 +3654,6 @@ const shareCreateCommand = defineCommand({
|
|
|
3068
3654
|
|
|
3069
3655
|
//#endregion
|
|
3070
3656
|
//#region src/commands/switch.ts
|
|
3071
|
-
async function createApiKey(appUrl, token, organizationId) {
|
|
3072
|
-
const base = appUrl.replace(/\/$/, "");
|
|
3073
|
-
const res = await fetch(`${base}/api/cli/create-key`, {
|
|
3074
|
-
method: "POST",
|
|
3075
|
-
headers: {
|
|
3076
|
-
"Content-Type": "application/json",
|
|
3077
|
-
Authorization: `Bearer ${token}`
|
|
3078
|
-
},
|
|
3079
|
-
body: JSON.stringify({ organizationId })
|
|
3080
|
-
});
|
|
3081
|
-
if (!res.ok) {
|
|
3082
|
-
const text = await res.text().catch(() => "");
|
|
3083
|
-
logError(`Failed to create API key (${res.status}): ${text}`);
|
|
3084
|
-
}
|
|
3085
|
-
return (await res.json()).key;
|
|
3086
|
-
}
|
|
3087
3657
|
const switchCommand = defineCommand({
|
|
3088
3658
|
meta: {
|
|
3089
3659
|
name: "switch",
|
|
@@ -3092,49 +3662,11 @@ const switchCommand = defineCommand({
|
|
|
3092
3662
|
async run() {
|
|
3093
3663
|
const config = loadGlobalConfig();
|
|
3094
3664
|
const appUrl = config.appUrl ?? getAppUrl();
|
|
3095
|
-
if (!config.
|
|
3665
|
+
if (!config.sessionToken) logError("Not logged in. Run `auix login`.");
|
|
3096
3666
|
const base = appUrl.replace(/\/$/, "");
|
|
3097
|
-
|
|
3098
|
-
const
|
|
3099
|
-
|
|
3100
|
-
headers: { "Content-Type": "application/json" },
|
|
3101
|
-
body: JSON.stringify({ client_id: "auix-cli" })
|
|
3102
|
-
});
|
|
3103
|
-
if (!codeRes.ok) logError("Failed to start authentication. Is the server running?");
|
|
3104
|
-
const codeData = await codeRes.json();
|
|
3105
|
-
console.log(`Open: ${codeData.verification_uri_complete}`);
|
|
3106
|
-
console.log(`Code: ${codeData.user_code}\n`);
|
|
3107
|
-
try {
|
|
3108
|
-
const { execSync } = await import("node:child_process");
|
|
3109
|
-
execSync(`${process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open"} ${JSON.stringify(codeData.verification_uri_complete)}`, { stdio: "ignore" });
|
|
3110
|
-
} catch {}
|
|
3111
|
-
const deadline = Date.now() + codeData.expires_in * 1e3;
|
|
3112
|
-
const interval = Math.max((codeData.interval || 5) * 1e3, 5e3);
|
|
3113
|
-
let token = "";
|
|
3114
|
-
while (Date.now() < deadline) {
|
|
3115
|
-
await new Promise((r) => setTimeout(r, interval));
|
|
3116
|
-
const tokenRes = await fetch(`${base}/api/auth/device/token`, {
|
|
3117
|
-
method: "POST",
|
|
3118
|
-
headers: { "Content-Type": "application/json" },
|
|
3119
|
-
body: JSON.stringify({
|
|
3120
|
-
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
3121
|
-
device_code: codeData.device_code,
|
|
3122
|
-
client_id: "auix-cli"
|
|
3123
|
-
})
|
|
3124
|
-
});
|
|
3125
|
-
if (tokenRes.ok) {
|
|
3126
|
-
token = (await tokenRes.json()).access_token;
|
|
3127
|
-
break;
|
|
3128
|
-
}
|
|
3129
|
-
const err = await tokenRes.json().catch(() => ({}));
|
|
3130
|
-
if (err.error === "authorization_pending" || err.error === "slow_down") continue;
|
|
3131
|
-
if (err.error === "expired_token") logError("Code expired.");
|
|
3132
|
-
if (err.error === "access_denied") logError("Access denied.");
|
|
3133
|
-
logError(`Unexpected error: ${err.error ?? tokenRes.status}`);
|
|
3134
|
-
}
|
|
3135
|
-
if (!token) logError("Code expired. Try again.");
|
|
3136
|
-
const orgsRes = await fetch(`${base}/api/auth/organization/list`, { headers: { Authorization: `Bearer ${token}` } });
|
|
3137
|
-
if (!orgsRes.ok) logError("Failed to list organizations.");
|
|
3667
|
+
const sessionToken = config.sessionToken;
|
|
3668
|
+
const orgsRes = await fetch(`${base}/api/auth/organization/list`, { headers: { Authorization: `Bearer ${sessionToken}` } });
|
|
3669
|
+
if (!orgsRes.ok) logError("Session expired. Run `auix login` to re-authenticate.");
|
|
3138
3670
|
const orgs = await orgsRes.json();
|
|
3139
3671
|
if (orgs.length === 0) logError("No organizations found.");
|
|
3140
3672
|
const selected = await consola.prompt("Select organization", {
|
|
@@ -3146,10 +3678,20 @@ const switchCommand = defineCommand({
|
|
|
3146
3678
|
});
|
|
3147
3679
|
if (typeof selected === "symbol") logError("Cancelled.");
|
|
3148
3680
|
const org = orgs.find((o) => o.id === selected);
|
|
3149
|
-
|
|
3681
|
+
if (!(await fetch(`${base}/api/auth/organization/set-active`, {
|
|
3682
|
+
method: "POST",
|
|
3683
|
+
headers: {
|
|
3684
|
+
"Content-Type": "application/json",
|
|
3685
|
+
Authorization: `Bearer ${sessionToken}`
|
|
3686
|
+
},
|
|
3687
|
+
body: JSON.stringify({ organizationId: org.id })
|
|
3688
|
+
})).ok) logError("Failed to set active organization.");
|
|
3689
|
+
const tokenRes = await fetch(`${base}/api/auth/token`, { headers: { Authorization: `Bearer ${sessionToken}` } });
|
|
3690
|
+
if (!tokenRes.ok) logError("Failed to obtain access token.");
|
|
3691
|
+
const data = await tokenRes.json();
|
|
3150
3692
|
saveGlobalConfig({
|
|
3151
3693
|
...config,
|
|
3152
|
-
|
|
3694
|
+
token: data.token,
|
|
3153
3695
|
organization: {
|
|
3154
3696
|
name: org.name,
|
|
3155
3697
|
slug: org.slug
|
|
@@ -3517,6 +4059,224 @@ const tokenRevokeCommand = defineCommand({
|
|
|
3517
4059
|
}
|
|
3518
4060
|
});
|
|
3519
4061
|
|
|
4062
|
+
//#endregion
|
|
4063
|
+
//#region src/commands/tool-list.ts
|
|
4064
|
+
const toolListCommand = defineCommand({
|
|
4065
|
+
meta: {
|
|
4066
|
+
name: "list",
|
|
4067
|
+
description: "List all tools"
|
|
4068
|
+
},
|
|
4069
|
+
args: { provider: {
|
|
4070
|
+
type: "string",
|
|
4071
|
+
description: "Filter by provider ID"
|
|
4072
|
+
} },
|
|
4073
|
+
async run({ args }) {
|
|
4074
|
+
const data = await callAction("auix__tool_list", { providerId: args.provider });
|
|
4075
|
+
if (data.length === 0) {
|
|
4076
|
+
console.log("No tools found.");
|
|
4077
|
+
return;
|
|
4078
|
+
}
|
|
4079
|
+
for (const t of data) {
|
|
4080
|
+
const status = t.enabled ? "on " : "off";
|
|
4081
|
+
const desc = t.description ? ` ${t.description.slice(0, 50)}` : "";
|
|
4082
|
+
console.log(` ${status} ${t.providerName}/${t.name}${desc}`);
|
|
4083
|
+
}
|
|
4084
|
+
console.log(`\n${data.length} tools`);
|
|
4085
|
+
}
|
|
4086
|
+
});
|
|
4087
|
+
|
|
4088
|
+
//#endregion
|
|
4089
|
+
//#region src/commands/tool-provider-create.ts
|
|
4090
|
+
const toolProviderCreateCommand = defineCommand({
|
|
4091
|
+
meta: {
|
|
4092
|
+
name: "create",
|
|
4093
|
+
description: "Create a tool provider"
|
|
4094
|
+
},
|
|
4095
|
+
args: {
|
|
4096
|
+
name: {
|
|
4097
|
+
type: "string",
|
|
4098
|
+
description: "Provider name",
|
|
4099
|
+
required: true
|
|
4100
|
+
},
|
|
4101
|
+
kind: {
|
|
4102
|
+
type: "string",
|
|
4103
|
+
description: "mcp, managed, or openapi",
|
|
4104
|
+
required: true
|
|
4105
|
+
},
|
|
4106
|
+
config: {
|
|
4107
|
+
type: "string",
|
|
4108
|
+
description: "Config JSON",
|
|
4109
|
+
required: true
|
|
4110
|
+
},
|
|
4111
|
+
description: {
|
|
4112
|
+
type: "string",
|
|
4113
|
+
description: "Description"
|
|
4114
|
+
},
|
|
4115
|
+
credentialSource: {
|
|
4116
|
+
type: "string",
|
|
4117
|
+
description: "e.g. integration:github"
|
|
4118
|
+
}
|
|
4119
|
+
},
|
|
4120
|
+
async run({ args }) {
|
|
4121
|
+
let config;
|
|
4122
|
+
try {
|
|
4123
|
+
config = JSON.parse(args.config);
|
|
4124
|
+
} catch {
|
|
4125
|
+
logError("Invalid JSON for --config");
|
|
4126
|
+
return;
|
|
4127
|
+
}
|
|
4128
|
+
const data = await callAction("auix__tool_provider_create", {
|
|
4129
|
+
name: args.name,
|
|
4130
|
+
kind: args.kind,
|
|
4131
|
+
config,
|
|
4132
|
+
description: args.description,
|
|
4133
|
+
credentialSource: args.credentialSource
|
|
4134
|
+
});
|
|
4135
|
+
console.log(`Created provider ${data.id}`);
|
|
4136
|
+
}
|
|
4137
|
+
});
|
|
4138
|
+
|
|
4139
|
+
//#endregion
|
|
4140
|
+
//#region src/commands/tool-provider-delete.ts
|
|
4141
|
+
const toolProviderDeleteCommand = defineCommand({
|
|
4142
|
+
meta: {
|
|
4143
|
+
name: "delete",
|
|
4144
|
+
description: "Delete a tool provider"
|
|
4145
|
+
},
|
|
4146
|
+
args: { id: {
|
|
4147
|
+
type: "positional",
|
|
4148
|
+
description: "Provider ID",
|
|
4149
|
+
required: true
|
|
4150
|
+
} },
|
|
4151
|
+
async run({ args }) {
|
|
4152
|
+
const confirmed = await consola.prompt(`Delete provider ${args.id}?`, { type: "confirm" });
|
|
4153
|
+
if (!confirmed || typeof confirmed === "symbol") {
|
|
4154
|
+
console.log("Cancelled.");
|
|
4155
|
+
return;
|
|
4156
|
+
}
|
|
4157
|
+
await callAction("auix__tool_provider_delete", { providerId: args.id });
|
|
4158
|
+
console.log("Deleted.");
|
|
4159
|
+
}
|
|
4160
|
+
});
|
|
4161
|
+
|
|
4162
|
+
//#endregion
|
|
4163
|
+
//#region src/commands/tool-provider-get.ts
|
|
4164
|
+
const toolProviderGetCommand = defineCommand({
|
|
4165
|
+
meta: {
|
|
4166
|
+
name: "get",
|
|
4167
|
+
description: "Get tool provider details"
|
|
4168
|
+
},
|
|
4169
|
+
args: { id: {
|
|
4170
|
+
type: "positional",
|
|
4171
|
+
description: "Provider ID",
|
|
4172
|
+
required: true
|
|
4173
|
+
} },
|
|
4174
|
+
async run({ args }) {
|
|
4175
|
+
const data = await callAction("auix__tool_provider_get", { providerId: args.id });
|
|
4176
|
+
console.log(JSON.stringify(data, null, 2));
|
|
4177
|
+
}
|
|
4178
|
+
});
|
|
4179
|
+
|
|
4180
|
+
//#endregion
|
|
4181
|
+
//#region src/commands/tool-provider-list.ts
|
|
4182
|
+
const toolProviderListCommand = defineCommand({
|
|
4183
|
+
meta: {
|
|
4184
|
+
name: "list",
|
|
4185
|
+
description: "List tool providers"
|
|
4186
|
+
},
|
|
4187
|
+
async run() {
|
|
4188
|
+
const data = await callAction("auix__tool_provider_list", {});
|
|
4189
|
+
if (data.length === 0) {
|
|
4190
|
+
console.log("No providers found.");
|
|
4191
|
+
return;
|
|
4192
|
+
}
|
|
4193
|
+
for (const p of data) console.log(` ${p.id.slice(0, 8)} ${p.kind.padEnd(8)} ${p.status.padEnd(8)} ${p.name}`);
|
|
4194
|
+
console.log(`\n${data.length} providers`);
|
|
4195
|
+
}
|
|
4196
|
+
});
|
|
4197
|
+
|
|
4198
|
+
//#endregion
|
|
4199
|
+
//#region src/commands/tool-provider-sync.ts
|
|
4200
|
+
const toolProviderSyncCommand = defineCommand({
|
|
4201
|
+
meta: {
|
|
4202
|
+
name: "sync",
|
|
4203
|
+
description: "Discover tools from MCP provider"
|
|
4204
|
+
},
|
|
4205
|
+
args: { id: {
|
|
4206
|
+
type: "positional",
|
|
4207
|
+
description: "Provider ID",
|
|
4208
|
+
required: true
|
|
4209
|
+
} },
|
|
4210
|
+
async run({ args }) {
|
|
4211
|
+
const data = await callAction("auix__tool_provider_sync", { providerId: args.id });
|
|
4212
|
+
console.log(`Synced ${data.synced} tools:`);
|
|
4213
|
+
for (const name of data.tools) console.log(` ${name}`);
|
|
4214
|
+
}
|
|
4215
|
+
});
|
|
4216
|
+
|
|
4217
|
+
//#endregion
|
|
4218
|
+
//#region src/commands/trace-get.ts
|
|
4219
|
+
const traceGetCommand = defineCommand({
|
|
4220
|
+
meta: {
|
|
4221
|
+
name: "get",
|
|
4222
|
+
description: "Get trace details with spans"
|
|
4223
|
+
},
|
|
4224
|
+
args: { id: {
|
|
4225
|
+
type: "positional",
|
|
4226
|
+
description: "Trace ID",
|
|
4227
|
+
required: true
|
|
4228
|
+
} },
|
|
4229
|
+
async run({ args }) {
|
|
4230
|
+
const data = await callAction("auix__trace_get", { traceId: args.id });
|
|
4231
|
+
console.log(JSON.stringify(data, null, 2));
|
|
4232
|
+
}
|
|
4233
|
+
});
|
|
4234
|
+
|
|
4235
|
+
//#endregion
|
|
4236
|
+
//#region src/commands/trace-list.ts
|
|
4237
|
+
const traceListCommand = defineCommand({
|
|
4238
|
+
meta: {
|
|
4239
|
+
name: "list",
|
|
4240
|
+
description: "List workflow traces"
|
|
4241
|
+
},
|
|
4242
|
+
args: {
|
|
4243
|
+
status: {
|
|
4244
|
+
type: "string",
|
|
4245
|
+
description: "Filter by status"
|
|
4246
|
+
},
|
|
4247
|
+
name: {
|
|
4248
|
+
type: "string",
|
|
4249
|
+
description: "Filter by name"
|
|
4250
|
+
},
|
|
4251
|
+
project: {
|
|
4252
|
+
type: "string",
|
|
4253
|
+
description: "Filter by project ID"
|
|
4254
|
+
},
|
|
4255
|
+
limit: {
|
|
4256
|
+
type: "string",
|
|
4257
|
+
description: "Max results (default 50)"
|
|
4258
|
+
}
|
|
4259
|
+
},
|
|
4260
|
+
async run({ args }) {
|
|
4261
|
+
const data = await callAction("auix__trace_list", {
|
|
4262
|
+
status: args.status,
|
|
4263
|
+
name: args.name,
|
|
4264
|
+
projectId: args.project,
|
|
4265
|
+
limit: args.limit ? Number(args.limit) : void 0
|
|
4266
|
+
});
|
|
4267
|
+
if (data.length === 0) {
|
|
4268
|
+
console.log("No traces found.");
|
|
4269
|
+
return;
|
|
4270
|
+
}
|
|
4271
|
+
for (const t of data) {
|
|
4272
|
+
const time = new Date(t.createdAt).toISOString().slice(0, 19);
|
|
4273
|
+
const latency = t.latencyMs != null ? `${t.latencyMs}ms` : "-";
|
|
4274
|
+
console.log(` ${t.id.slice(0, 8)} ${t.status.padEnd(10)} ${latency.padEnd(8)} ${time} ${t.name}`);
|
|
4275
|
+
}
|
|
4276
|
+
console.log(`\n${data.length} traces`);
|
|
4277
|
+
}
|
|
4278
|
+
});
|
|
4279
|
+
|
|
3520
4280
|
//#endregion
|
|
3521
4281
|
//#region src/commands/unlock.ts
|
|
3522
4282
|
const unlockCommand = defineCommand({
|
|
@@ -3698,10 +4458,9 @@ const whoamiCommand = defineCommand({
|
|
|
3698
4458
|
},
|
|
3699
4459
|
async run() {
|
|
3700
4460
|
const config = loadGlobalConfig();
|
|
3701
|
-
if (!config.
|
|
4461
|
+
if (!config.token) logError("Not logged in. Run `auix login`.");
|
|
3702
4462
|
if (config.user) console.log(`User: ${config.user.name} (${config.user.email})`);
|
|
3703
4463
|
if (config.organization) console.log(`Org: ${config.organization.name} (${config.organization.slug})`);
|
|
3704
|
-
console.log(`Key: ${config.apiKey.slice(0, 12)}...`);
|
|
3705
4464
|
console.log(`API: ${config.baseUrl ?? "https://api.auix.dev"}`);
|
|
3706
4465
|
console.log(`App: ${config.appUrl ?? "https://auix.dev"}`);
|
|
3707
4466
|
}
|
|
@@ -3712,7 +4471,7 @@ const whoamiCommand = defineCommand({
|
|
|
3712
4471
|
runMain(defineCommand({
|
|
3713
4472
|
meta: {
|
|
3714
4473
|
name: "auix",
|
|
3715
|
-
version: "0.0.
|
|
4474
|
+
version: "0.0.6",
|
|
3716
4475
|
description: "AUIX CLI"
|
|
3717
4476
|
},
|
|
3718
4477
|
subCommands: {
|
|
@@ -3808,7 +4567,7 @@ runMain(defineCommand({
|
|
|
3808
4567
|
dynamic: defineCommand({
|
|
3809
4568
|
meta: {
|
|
3810
4569
|
name: "dynamic",
|
|
3811
|
-
description: "Manage dynamic
|
|
4570
|
+
description: "Manage dynamic secrets"
|
|
3812
4571
|
},
|
|
3813
4572
|
subCommands: {
|
|
3814
4573
|
create: dynamicCreateCommand,
|
|
@@ -3817,7 +4576,81 @@ runMain(defineCommand({
|
|
|
3817
4576
|
}
|
|
3818
4577
|
})
|
|
3819
4578
|
}
|
|
3820
|
-
})
|
|
4579
|
+
}),
|
|
4580
|
+
flow: defineCommand({
|
|
4581
|
+
meta: {
|
|
4582
|
+
name: "flow",
|
|
4583
|
+
description: "Manage automation flows"
|
|
4584
|
+
},
|
|
4585
|
+
subCommands: {
|
|
4586
|
+
list: flowListCommand,
|
|
4587
|
+
get: flowGetCommand,
|
|
4588
|
+
create: flowCreateCommand,
|
|
4589
|
+
toggle: flowToggleCommand,
|
|
4590
|
+
duplicate: flowDuplicateCommand,
|
|
4591
|
+
dispatch: flowDispatchCommand,
|
|
4592
|
+
executions: flowExecutionsCommand,
|
|
4593
|
+
delete: flowDeleteCommand
|
|
4594
|
+
}
|
|
4595
|
+
}),
|
|
4596
|
+
tool: defineCommand({
|
|
4597
|
+
meta: {
|
|
4598
|
+
name: "tool",
|
|
4599
|
+
description: "Manage tools and providers"
|
|
4600
|
+
},
|
|
4601
|
+
subCommands: {
|
|
4602
|
+
list: toolListCommand,
|
|
4603
|
+
provider: defineCommand({
|
|
4604
|
+
meta: {
|
|
4605
|
+
name: "provider",
|
|
4606
|
+
description: "Manage tool providers"
|
|
4607
|
+
},
|
|
4608
|
+
subCommands: {
|
|
4609
|
+
list: toolProviderListCommand,
|
|
4610
|
+
get: toolProviderGetCommand,
|
|
4611
|
+
create: toolProviderCreateCommand,
|
|
4612
|
+
sync: toolProviderSyncCommand,
|
|
4613
|
+
delete: toolProviderDeleteCommand
|
|
4614
|
+
}
|
|
4615
|
+
})
|
|
4616
|
+
}
|
|
4617
|
+
}),
|
|
4618
|
+
project: defineCommand({
|
|
4619
|
+
meta: {
|
|
4620
|
+
name: "project",
|
|
4621
|
+
description: "Manage projects"
|
|
4622
|
+
},
|
|
4623
|
+
subCommands: {
|
|
4624
|
+
list: projectListCommand,
|
|
4625
|
+
get: projectGetCommand,
|
|
4626
|
+
create: projectCreateCommand,
|
|
4627
|
+
delete: projectDeleteCommand
|
|
4628
|
+
}
|
|
4629
|
+
}),
|
|
4630
|
+
trace: defineCommand({
|
|
4631
|
+
meta: {
|
|
4632
|
+
name: "trace",
|
|
4633
|
+
description: "Workflow execution traces"
|
|
4634
|
+
},
|
|
4635
|
+
subCommands: {
|
|
4636
|
+
list: traceListCommand,
|
|
4637
|
+
get: traceGetCommand
|
|
4638
|
+
}
|
|
4639
|
+
}),
|
|
4640
|
+
prism: defineCommand({
|
|
4641
|
+
meta: {
|
|
4642
|
+
name: "prism",
|
|
4643
|
+
description: "LLM call tracing"
|
|
4644
|
+
},
|
|
4645
|
+
subCommands: {
|
|
4646
|
+
list: prismListCommand,
|
|
4647
|
+
metrics: prismMetricsCommand
|
|
4648
|
+
}
|
|
4649
|
+
}),
|
|
4650
|
+
log: logQueryCommand,
|
|
4651
|
+
member: memberListCommand,
|
|
4652
|
+
audit: auditListCommand,
|
|
4653
|
+
integration: integrationListCommand
|
|
3821
4654
|
}
|
|
3822
4655
|
}));
|
|
3823
4656
|
|