@vendian/cli 0.0.43 → 0.0.45
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 -3
- package/cli-wrapper.mjs +144 -342
- package/dev-ui/css/app.css +0 -12
- package/dev-ui/index.html +2 -11
- package/dev-ui/js/app.js +1 -7
- package/dev-ui/js/serve.js +1 -77
- package/dev-ui/js/state.js +0 -4
- package/package.json +1 -1
package/cli-wrapper.mjs
CHANGED
|
@@ -863,26 +863,27 @@ function initOutputDir(args = []) {
|
|
|
863
863
|
}
|
|
864
864
|
return ".";
|
|
865
865
|
}
|
|
866
|
-
function
|
|
866
|
+
function resolveDocsPath(outputDir, { cwd = process.cwd(), platform = process.platform } = {}) {
|
|
867
867
|
const api = pathApi2(platform);
|
|
868
868
|
const raw = outputDir || ".";
|
|
869
869
|
return api.isAbsolute(raw) ? api.normalize(raw) : api.resolve(cwd, raw);
|
|
870
870
|
}
|
|
871
|
-
function
|
|
871
|
+
function recordAgentDocsDir(outputDir, {
|
|
872
872
|
env = process.env,
|
|
873
873
|
platform = process.platform,
|
|
874
874
|
cwd = process.cwd(),
|
|
875
875
|
now = /* @__PURE__ */ new Date()
|
|
876
876
|
} = {}) {
|
|
877
|
-
const
|
|
877
|
+
const docsPath = resolveDocsPath(outputDir, { cwd, platform });
|
|
878
878
|
const config = loadConfig(env, platform);
|
|
879
|
-
const existing =
|
|
880
|
-
const
|
|
879
|
+
const existing = agentDocsDirs(config);
|
|
880
|
+
const dirs = [docsPath, ...existing.filter((entry) => entry !== docsPath)];
|
|
881
881
|
const next = {
|
|
882
882
|
...config,
|
|
883
|
-
[
|
|
883
|
+
[DOC_DIRS_KEY]: dirs,
|
|
884
884
|
lastAgentDocsInitAt: now.toISOString()
|
|
885
885
|
};
|
|
886
|
+
delete next[LEGACY_DOC_DIRS_KEY];
|
|
886
887
|
saveConfig(next, env, platform);
|
|
887
888
|
return next;
|
|
888
889
|
}
|
|
@@ -890,10 +891,10 @@ function recordForwardedDocsCommand(args, code, options = {}) {
|
|
|
890
891
|
if (code !== 0 || !commandWritesAgentDocs(args)) {
|
|
891
892
|
return false;
|
|
892
893
|
}
|
|
893
|
-
|
|
894
|
+
recordAgentDocsDir(initOutputDir(args), options);
|
|
894
895
|
return true;
|
|
895
896
|
}
|
|
896
|
-
function
|
|
897
|
+
function refreshAgentDocsDirs({
|
|
897
898
|
config,
|
|
898
899
|
venvPath,
|
|
899
900
|
env = process.env,
|
|
@@ -902,41 +903,52 @@ function refreshAgentDocsWorkspaces({
|
|
|
902
903
|
now = /* @__PURE__ */ new Date()
|
|
903
904
|
} = {}) {
|
|
904
905
|
const currentConfig = config || loadConfig(env, platform);
|
|
905
|
-
const
|
|
906
|
-
if (
|
|
906
|
+
const dirs = agentDocsDirs(currentConfig);
|
|
907
|
+
if (dirs.length === 0) {
|
|
907
908
|
saveConfig(currentConfig, env, platform);
|
|
908
909
|
return { config: currentConfig, refreshed: 0, failed: 0 };
|
|
909
910
|
}
|
|
910
911
|
const vendianPath = venvVendian(venvPath, platform);
|
|
911
912
|
let refreshed = 0;
|
|
912
913
|
let failed = 0;
|
|
913
|
-
for (const
|
|
914
|
-
if (!fs7.existsSync(
|
|
914
|
+
for (const dir of dirs) {
|
|
915
|
+
if (!fs7.existsSync(dir)) {
|
|
915
916
|
continue;
|
|
916
917
|
}
|
|
917
|
-
const status = run2(vendianPath, ["init", "--output-dir",
|
|
918
|
+
const status = run2(vendianPath, ["init", "--output-dir", dir, "--yes"]);
|
|
918
919
|
if (status === 0) {
|
|
919
920
|
refreshed += 1;
|
|
920
921
|
} else {
|
|
921
922
|
failed += 1;
|
|
922
|
-
console.error(`[vendian] Could not refresh SDK docs in ${
|
|
923
|
+
console.error(`[vendian] Could not refresh SDK docs in ${dir}`);
|
|
923
924
|
}
|
|
924
925
|
}
|
|
925
926
|
const next = {
|
|
926
927
|
...currentConfig,
|
|
927
|
-
[
|
|
928
|
+
[DOC_DIRS_KEY]: dirs,
|
|
928
929
|
lastAgentDocsRefreshAt: now.toISOString()
|
|
929
930
|
};
|
|
931
|
+
delete next[LEGACY_DOC_DIRS_KEY];
|
|
930
932
|
saveConfig(next, env, platform);
|
|
931
933
|
return { config: next, refreshed, failed };
|
|
932
934
|
}
|
|
933
|
-
|
|
935
|
+
function agentDocsDirs(config = {}) {
|
|
936
|
+
return [.../* @__PURE__ */ new Set([
|
|
937
|
+
...stringList(config[DOC_DIRS_KEY]),
|
|
938
|
+
...stringList(config[LEGACY_DOC_DIRS_KEY])
|
|
939
|
+
])];
|
|
940
|
+
}
|
|
941
|
+
function stringList(value) {
|
|
942
|
+
return Array.isArray(value) ? value.filter((entry) => typeof entry === "string" && entry.trim()) : [];
|
|
943
|
+
}
|
|
944
|
+
var DOC_DIRS_KEY, LEGACY_DOC_DIRS_KEY;
|
|
934
945
|
var init_docs = __esm({
|
|
935
946
|
"src/docs.js"() {
|
|
936
947
|
init_config();
|
|
937
948
|
init_paths();
|
|
938
949
|
init_process();
|
|
939
|
-
|
|
950
|
+
DOC_DIRS_KEY = "agentDocDirs";
|
|
951
|
+
LEGACY_DOC_DIRS_KEY = ["agentDoc", "Work", "spaces"].join("");
|
|
940
952
|
}
|
|
941
953
|
});
|
|
942
954
|
|
|
@@ -1011,7 +1023,7 @@ async function setup({
|
|
|
1011
1023
|
saveConfig(next, env, platform);
|
|
1012
1024
|
installVendianPackages({ pythonPath, venvPath, config: next, env, platform });
|
|
1013
1025
|
const updated = { ...next, lastManagedUpdateAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
1014
|
-
|
|
1026
|
+
refreshAgentDocsDirs({ config: updated, venvPath, env, platform });
|
|
1015
1027
|
if (!verifyVendianImports(pythonPath)) {
|
|
1016
1028
|
throw new Error("Vendian packages installed, but import verification failed.");
|
|
1017
1029
|
}
|
|
@@ -1196,8 +1208,8 @@ function findAgentDirectoryCandidates({
|
|
|
1196
1208
|
]);
|
|
1197
1209
|
for (const root of roots) {
|
|
1198
1210
|
for (const manifest of findManifestFiles(root, { maxDepth, maxDirs, limit: 250 })) {
|
|
1199
|
-
const
|
|
1200
|
-
addCandidate(
|
|
1211
|
+
const agentsGroup = nearestAgentsAncestor(manifest, root);
|
|
1212
|
+
addCandidate(agentsGroup || path4.dirname(manifest));
|
|
1201
1213
|
if (candidates.length >= limit) {
|
|
1202
1214
|
return candidates.slice(0, limit);
|
|
1203
1215
|
}
|
|
@@ -1459,7 +1471,7 @@ function maybeAutoUpdateManagedEnv({
|
|
|
1459
1471
|
load = loadConfig,
|
|
1460
1472
|
save = saveConfig,
|
|
1461
1473
|
installPackages = installVendianPackages,
|
|
1462
|
-
refreshDocs =
|
|
1474
|
+
refreshDocs = refreshAgentDocsDirs,
|
|
1463
1475
|
now = Date.now(),
|
|
1464
1476
|
onProgress = null
|
|
1465
1477
|
} = {}) {
|
|
@@ -1509,66 +1521,12 @@ function reportProgress(onProgress, message) {
|
|
|
1509
1521
|
init_process();
|
|
1510
1522
|
init_paths();
|
|
1511
1523
|
|
|
1512
|
-
// src/workspaces.js
|
|
1513
|
-
init_process();
|
|
1514
|
-
async function listCloudWorkspaces({
|
|
1515
|
-
env = process.env,
|
|
1516
|
-
platform = process.platform,
|
|
1517
|
-
prepareInvocation = preparePythonVendianInvocation,
|
|
1518
|
-
run: run2 = runCapture,
|
|
1519
|
-
onProgress = null,
|
|
1520
|
-
timeoutMs = 2e4
|
|
1521
|
-
} = {}) {
|
|
1522
|
-
const progress = typeof onProgress === "function" ? onProgress : () => {
|
|
1523
|
-
};
|
|
1524
|
-
progress("Checking managed Python runtime");
|
|
1525
|
-
const invocation = await prepareInvocation(["cloud", "collections", "list", "--json"], {
|
|
1526
|
-
env,
|
|
1527
|
-
platform,
|
|
1528
|
-
onProgress: progress,
|
|
1529
|
-
skipAutoUpdate: true
|
|
1530
|
-
});
|
|
1531
|
-
progress("Loading workspaces from Vendian");
|
|
1532
|
-
const result = run2(invocation.command, invocation.args, { env: invocation.env, timeout: timeoutMs });
|
|
1533
|
-
if (!result.ok) {
|
|
1534
|
-
return {
|
|
1535
|
-
ok: false,
|
|
1536
|
-
workspaces: [],
|
|
1537
|
-
error: (result.stderr || result.stdout || `workspace list exited with code ${result.status}`).trim()
|
|
1538
|
-
};
|
|
1539
|
-
}
|
|
1540
|
-
try {
|
|
1541
|
-
return { ok: true, workspaces: normalizeWorkspaceList(JSON.parse(result.stdout)), error: "" };
|
|
1542
|
-
} catch (error) {
|
|
1543
|
-
const message = error && typeof error.message === "string" ? error.message : String(error);
|
|
1544
|
-
return { ok: false, workspaces: [], error: `Could not parse workspace list: ${message}` };
|
|
1545
|
-
}
|
|
1546
|
-
}
|
|
1547
|
-
function normalizeWorkspaceList(payload) {
|
|
1548
|
-
const data = payload && typeof payload === "object" && "data" in payload ? payload.data : payload;
|
|
1549
|
-
const raw = Array.isArray(data) ? data : data && typeof data === "object" && Array.isArray(data.data) ? data.data : data && typeof data === "object" && Array.isArray(data.collections) ? data.collections : [];
|
|
1550
|
-
return raw.filter((item) => item && typeof item === "object").map((item) => ({
|
|
1551
|
-
id: stringValue(item.id),
|
|
1552
|
-
name: stringValue(item.name || item.slug || item.id || "Unnamed workspace"),
|
|
1553
|
-
slug: stringValue(item.slug)
|
|
1554
|
-
})).filter((item) => item.id);
|
|
1555
|
-
}
|
|
1556
|
-
function workspaceLabel(workspace) {
|
|
1557
|
-
const name = workspace?.name || workspace?.slug || workspace?.id || "Unnamed workspace";
|
|
1558
|
-
const slug = workspace?.slug && workspace.slug !== name ? ` (${workspace.slug})` : "";
|
|
1559
|
-
return `${name}${slug}`;
|
|
1560
|
-
}
|
|
1561
|
-
function stringValue(value) {
|
|
1562
|
-
return value == null ? "" : String(value).trim();
|
|
1563
|
-
}
|
|
1564
|
-
|
|
1565
1524
|
// src/serve-events.js
|
|
1566
1525
|
function initialServeState() {
|
|
1567
1526
|
return {
|
|
1568
1527
|
connected: false,
|
|
1569
1528
|
daemonId: "",
|
|
1570
1529
|
cliSessionId: "",
|
|
1571
|
-
collectionId: "",
|
|
1572
1530
|
agents: [],
|
|
1573
1531
|
activity: "Starting local daemon",
|
|
1574
1532
|
currentJob: null,
|
|
@@ -1616,15 +1574,12 @@ function applyServeEvent(state, event) {
|
|
|
1616
1574
|
...state,
|
|
1617
1575
|
logs: appendLog(state.logs, event)
|
|
1618
1576
|
};
|
|
1619
|
-
if (event.type === "workspace_resolved") {
|
|
1620
|
-
return { ...next, collectionId: stringValue2(event.collectionId), activity: "Workspace resolved" };
|
|
1621
|
-
}
|
|
1622
1577
|
if (event.type === "daemon_registered") {
|
|
1623
1578
|
return {
|
|
1624
1579
|
...next,
|
|
1625
1580
|
connected: true,
|
|
1626
|
-
daemonId:
|
|
1627
|
-
cliSessionId:
|
|
1581
|
+
daemonId: stringValue(event.daemonId),
|
|
1582
|
+
cliSessionId: stringValue(event.cliSessionId),
|
|
1628
1583
|
activity: "Daemon registered"
|
|
1629
1584
|
};
|
|
1630
1585
|
}
|
|
@@ -1644,7 +1599,7 @@ function applyServeEvent(state, event) {
|
|
|
1644
1599
|
};
|
|
1645
1600
|
}
|
|
1646
1601
|
if (event.type === "daemon_wake_received") {
|
|
1647
|
-
const sourceType =
|
|
1602
|
+
const sourceType = stringValue(event.sourceEventType || "backend wake");
|
|
1648
1603
|
return {
|
|
1649
1604
|
...next,
|
|
1650
1605
|
activity: `Wake received: ${sourceType}`
|
|
@@ -1659,17 +1614,17 @@ function applyServeEvent(state, event) {
|
|
|
1659
1614
|
if (event.type === "dispatch_job_received") {
|
|
1660
1615
|
return {
|
|
1661
1616
|
...next,
|
|
1662
|
-
activity: `Dispatch received for run ${
|
|
1617
|
+
activity: `Dispatch received for run ${stringValue(event.runId || event.sessionId || "unknown")}`
|
|
1663
1618
|
};
|
|
1664
1619
|
}
|
|
1665
1620
|
if (event.type === "dispatch_job_acked") {
|
|
1666
1621
|
return {
|
|
1667
1622
|
...next,
|
|
1668
|
-
activity: `Dispatch acknowledged for run ${
|
|
1623
|
+
activity: `Dispatch acknowledged for run ${stringValue(event.runId || event.sessionId || "unknown")}`
|
|
1669
1624
|
};
|
|
1670
1625
|
}
|
|
1671
1626
|
if (event.type === "daemon_stderr") {
|
|
1672
|
-
const message =
|
|
1627
|
+
const message = stringValue(event.message || event.stderr || "Daemon wrote to stderr");
|
|
1673
1628
|
return {
|
|
1674
1629
|
...next,
|
|
1675
1630
|
activity: `Daemon stderr: ${message}`,
|
|
@@ -1714,14 +1669,14 @@ function applyServeEvent(state, event) {
|
|
|
1714
1669
|
if (event.type === "agent_prepare_progress") {
|
|
1715
1670
|
const relativePath = agentLabel(event);
|
|
1716
1671
|
const timestamp = event.timestamp || (/* @__PURE__ */ new Date()).toISOString();
|
|
1717
|
-
const message =
|
|
1672
|
+
const message = stringValue(event.message || event.stage || "Preparing agent");
|
|
1718
1673
|
return {
|
|
1719
1674
|
...next,
|
|
1720
1675
|
agentLogs: appendAgentLog(state.agentLogs, event),
|
|
1721
1676
|
agentRunState: setAgentRunState(state.agentRunState, relativePath, {
|
|
1722
1677
|
status: "preparing",
|
|
1723
1678
|
lastEventAt: timestamp,
|
|
1724
|
-
progressStage:
|
|
1679
|
+
progressStage: stringValue(event.stage),
|
|
1725
1680
|
progressMessage: message
|
|
1726
1681
|
}),
|
|
1727
1682
|
activity: `${relativePath}: ${message}`
|
|
@@ -1733,11 +1688,11 @@ function applyServeEvent(state, event) {
|
|
|
1733
1688
|
const runState = isError ? setAgentRunState(state.agentRunState, agentLabel(event), {
|
|
1734
1689
|
status: "error",
|
|
1735
1690
|
lastEventAt: event.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
|
|
1736
|
-
errorMessage:
|
|
1691
|
+
errorMessage: stringValue(event.error || event.errorMessage || "Agent setup failed")
|
|
1737
1692
|
}) : isDisabled ? setAgentRunState(state.agentRunState, agentLabel(event), {
|
|
1738
1693
|
status: "disabled",
|
|
1739
1694
|
lastEventAt: event.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
|
|
1740
|
-
disabledReason:
|
|
1695
|
+
disabledReason: stringValue(event.disabledReason || event.warning || "System dependency not met"),
|
|
1741
1696
|
resolutionHints: Array.isArray(event.resolutionHints) ? event.resolutionHints : []
|
|
1742
1697
|
}) : setAgentRunState(state.agentRunState, agentLabel(event), {
|
|
1743
1698
|
status: "ready",
|
|
@@ -1773,8 +1728,8 @@ function applyServeEvent(state, event) {
|
|
|
1773
1728
|
agentLogs: appendAgentLog(state.agentLogs, event),
|
|
1774
1729
|
agentRunState: setAgentRunState(state.agentRunState, relativePath, {
|
|
1775
1730
|
status: "running",
|
|
1776
|
-
runId:
|
|
1777
|
-
jobType:
|
|
1731
|
+
runId: stringValue(event.runId || event.deployRequestId),
|
|
1732
|
+
jobType: stringValue(event.jobType || "run"),
|
|
1778
1733
|
startedAt: timestamp,
|
|
1779
1734
|
completedAt: null,
|
|
1780
1735
|
lastEventAt: timestamp,
|
|
@@ -1788,7 +1743,7 @@ function applyServeEvent(state, event) {
|
|
|
1788
1743
|
const relativePath = agentLabel(event);
|
|
1789
1744
|
const timestamp = event.timestamp || (/* @__PURE__ */ new Date()).toISOString();
|
|
1790
1745
|
const success = event.success !== false;
|
|
1791
|
-
const runId =
|
|
1746
|
+
const runId = stringValue(event.runId || event.deployRequestId);
|
|
1792
1747
|
const previous = (state.agentRunState || {})[relativePath];
|
|
1793
1748
|
const effectiveSuccess = success && !(previous?.status === "error" && previous?.runId === runId);
|
|
1794
1749
|
return {
|
|
@@ -1797,10 +1752,10 @@ function applyServeEvent(state, event) {
|
|
|
1797
1752
|
agentRunState: setAgentRunState(state.agentRunState, relativePath, {
|
|
1798
1753
|
status: effectiveSuccess ? "completed" : "error",
|
|
1799
1754
|
runId,
|
|
1800
|
-
jobType:
|
|
1755
|
+
jobType: stringValue(event.jobType || "run"),
|
|
1801
1756
|
completedAt: timestamp,
|
|
1802
1757
|
lastEventAt: timestamp,
|
|
1803
|
-
errorMessage: effectiveSuccess ? null : previous?.errorMessage ||
|
|
1758
|
+
errorMessage: effectiveSuccess ? null : previous?.errorMessage || stringValue(event.error || "Job failed")
|
|
1804
1759
|
}),
|
|
1805
1760
|
jobsRun: state.jobsRun + 1,
|
|
1806
1761
|
currentJob: null,
|
|
@@ -1808,13 +1763,13 @@ function applyServeEvent(state, event) {
|
|
|
1808
1763
|
};
|
|
1809
1764
|
}
|
|
1810
1765
|
if (event.type === "backend_connection_lost") {
|
|
1811
|
-
return { ...next, connected: false, activity: `Connection lost during ${
|
|
1766
|
+
return { ...next, connected: false, activity: `Connection lost during ${stringValue(event.activity)}`, retry: event };
|
|
1812
1767
|
}
|
|
1813
1768
|
if (event.type === "backend_connection_restored") {
|
|
1814
1769
|
return { ...next, connected: true, activity: "Backend connection restored", retry: null };
|
|
1815
1770
|
}
|
|
1816
1771
|
if (event.type === "retry_scheduled") {
|
|
1817
|
-
return { ...next, retry: event, activity: `Retrying ${
|
|
1772
|
+
return { ...next, retry: event, activity: `Retrying ${stringValue(event.activity)} in ${formatSeconds(event.delaySeconds)}` };
|
|
1818
1773
|
}
|
|
1819
1774
|
if (event.type === "error") {
|
|
1820
1775
|
const relativePath = event.relativePath || event.path ? agentLabel(event) : "";
|
|
@@ -1825,11 +1780,11 @@ function applyServeEvent(state, event) {
|
|
|
1825
1780
|
agentLogs: hasAgentScope ? appendAgentLog(state.agentLogs, event) : state.agentLogs,
|
|
1826
1781
|
agentRunState: hasAgentScope ? setAgentRunState(state.agentRunState, relativePath, {
|
|
1827
1782
|
status: "error",
|
|
1828
|
-
runId:
|
|
1829
|
-
jobType:
|
|
1783
|
+
runId: stringValue(event.runId || event.deployRequestId),
|
|
1784
|
+
jobType: stringValue(event.jobType || "run"),
|
|
1830
1785
|
completedAt: timestamp,
|
|
1831
1786
|
lastEventAt: timestamp,
|
|
1832
|
-
errorMessage:
|
|
1787
|
+
errorMessage: stringValue(event.error || event.code || "Unknown error")
|
|
1833
1788
|
}) : state.agentRunState,
|
|
1834
1789
|
activity: "Error",
|
|
1835
1790
|
errors: appendError(state.errors, jobLabel(event), event.error || event.code || "Unknown error")
|
|
@@ -1847,8 +1802,8 @@ function applyServeEvent(state, event) {
|
|
|
1847
1802
|
}
|
|
1848
1803
|
if (event.type === "process_exit" || event.type === "daemon_exit") {
|
|
1849
1804
|
const timestamp = event.timestamp || (/* @__PURE__ */ new Date()).toISOString();
|
|
1850
|
-
const message =
|
|
1851
|
-
const relativePath =
|
|
1805
|
+
const message = stringValue(event.message || processExitMessage(event));
|
|
1806
|
+
const relativePath = stringValue(event.relativePath || "");
|
|
1852
1807
|
const runState = failRunningAgents(state.agentRunState, message, timestamp, relativePath);
|
|
1853
1808
|
return {
|
|
1854
1809
|
...next,
|
|
@@ -1903,7 +1858,7 @@ function mergeAgentLogRecords(agentLogs, records = []) {
|
|
|
1903
1858
|
let next = agentLogs || {};
|
|
1904
1859
|
for (const record of records) {
|
|
1905
1860
|
if (!record || typeof record !== "object") continue;
|
|
1906
|
-
const relativePath =
|
|
1861
|
+
const relativePath = stringValue(record.relativePath || ".");
|
|
1907
1862
|
const entry = record.entry && typeof record.entry === "object" ? record.entry : record;
|
|
1908
1863
|
const existing = next[relativePath] || [];
|
|
1909
1864
|
next = {
|
|
@@ -1918,13 +1873,13 @@ function agentRunStateFromLogs(agentLogs, { includeRunning = true } = {}) {
|
|
|
1918
1873
|
for (const [relativePath, entries] of Object.entries(agentLogs || {})) {
|
|
1919
1874
|
for (const entry of entries || []) {
|
|
1920
1875
|
const timestamp = entry.timestamp || (/* @__PURE__ */ new Date()).toISOString();
|
|
1921
|
-
const runId =
|
|
1876
|
+
const runId = stringValue(entry.runId);
|
|
1922
1877
|
const current = next[relativePath] || {};
|
|
1923
1878
|
if (entry.eventType === "job_started") {
|
|
1924
1879
|
next = setAgentRunState(next, relativePath, {
|
|
1925
1880
|
status: includeRunning ? "running" : current.status,
|
|
1926
1881
|
runId,
|
|
1927
|
-
jobType: entry.jobType ?
|
|
1882
|
+
jobType: entry.jobType ? stringValue(entry.jobType) : current.jobType,
|
|
1928
1883
|
startedAt: timestamp,
|
|
1929
1884
|
lastEventAt: timestamp
|
|
1930
1885
|
});
|
|
@@ -1935,10 +1890,10 @@ function agentRunStateFromLogs(agentLogs, { includeRunning = true } = {}) {
|
|
|
1935
1890
|
next = setAgentRunState(next, relativePath, {
|
|
1936
1891
|
status: failed ? "error" : "completed",
|
|
1937
1892
|
runId,
|
|
1938
|
-
jobType: entry.jobType ?
|
|
1893
|
+
jobType: entry.jobType ? stringValue(entry.jobType) : current.jobType,
|
|
1939
1894
|
completedAt: timestamp,
|
|
1940
1895
|
lastEventAt: timestamp,
|
|
1941
|
-
errorMessage: failed ? formatErrorMessage(entry.error) || current.errorMessage ||
|
|
1896
|
+
errorMessage: failed ? formatErrorMessage(entry.error) || current.errorMessage || stringValue(entry.message || "Job failed") : null
|
|
1942
1897
|
});
|
|
1943
1898
|
continue;
|
|
1944
1899
|
}
|
|
@@ -1946,10 +1901,10 @@ function agentRunStateFromLogs(agentLogs, { includeRunning = true } = {}) {
|
|
|
1946
1901
|
next = setAgentRunState(next, relativePath, {
|
|
1947
1902
|
status: "error",
|
|
1948
1903
|
runId,
|
|
1949
|
-
jobType: entry.jobType ?
|
|
1904
|
+
jobType: entry.jobType ? stringValue(entry.jobType) : current.jobType,
|
|
1950
1905
|
completedAt: timestamp,
|
|
1951
1906
|
lastEventAt: timestamp,
|
|
1952
|
-
errorMessage: formatErrorMessage(entry.error) ||
|
|
1907
|
+
errorMessage: formatErrorMessage(entry.error) || stringValue(entry.message || "Job failed")
|
|
1953
1908
|
});
|
|
1954
1909
|
continue;
|
|
1955
1910
|
}
|
|
@@ -1967,34 +1922,34 @@ function serveEventAgentLogEntry(event) {
|
|
|
1967
1922
|
if (!event || typeof event !== "object") {
|
|
1968
1923
|
return null;
|
|
1969
1924
|
}
|
|
1970
|
-
const type =
|
|
1971
|
-
const relativePath =
|
|
1925
|
+
const type = stringValue(event.type);
|
|
1926
|
+
const relativePath = stringValue(event.relativePath || event.path || ".");
|
|
1972
1927
|
const timestamp = event.timestamp || (/* @__PURE__ */ new Date()).toISOString();
|
|
1973
1928
|
if (type === "run_log") {
|
|
1974
1929
|
return {
|
|
1975
1930
|
relativePath,
|
|
1976
1931
|
entry: {
|
|
1977
1932
|
timestamp,
|
|
1978
|
-
runId:
|
|
1979
|
-
eventType:
|
|
1980
|
-
level:
|
|
1981
|
-
message:
|
|
1982
|
-
stepId: event.stepId ?
|
|
1933
|
+
runId: stringValue(event.runId),
|
|
1934
|
+
eventType: stringValue(event.eventType || "log"),
|
|
1935
|
+
level: stringValue(event.level || "info"),
|
|
1936
|
+
message: stringValue(event.message),
|
|
1937
|
+
stepId: event.stepId ? stringValue(event.stepId) : null,
|
|
1983
1938
|
current: event.current ?? null,
|
|
1984
1939
|
total: event.total ?? null,
|
|
1985
1940
|
success: event.success ?? null,
|
|
1986
1941
|
error: event.error ?? null,
|
|
1987
|
-
jobType: event.jobType ?
|
|
1942
|
+
jobType: event.jobType ? stringValue(event.jobType) : null
|
|
1988
1943
|
}
|
|
1989
1944
|
};
|
|
1990
1945
|
}
|
|
1991
1946
|
if (type === "job_started") {
|
|
1992
|
-
const jobType =
|
|
1947
|
+
const jobType = stringValue(event.jobType || "run");
|
|
1993
1948
|
return {
|
|
1994
1949
|
relativePath,
|
|
1995
1950
|
entry: {
|
|
1996
1951
|
timestamp,
|
|
1997
|
-
runId:
|
|
1952
|
+
runId: stringValue(event.runId || event.deployRequestId),
|
|
1998
1953
|
eventType: "job_started",
|
|
1999
1954
|
level: "info",
|
|
2000
1955
|
message: `Started ${jobType}`,
|
|
@@ -2009,15 +1964,15 @@ function serveEventAgentLogEntry(event) {
|
|
|
2009
1964
|
}
|
|
2010
1965
|
if (type === "job_completed") {
|
|
2011
1966
|
const success = event.success !== false;
|
|
2012
|
-
const jobType =
|
|
1967
|
+
const jobType = stringValue(event.jobType || "run");
|
|
2013
1968
|
return {
|
|
2014
1969
|
relativePath,
|
|
2015
1970
|
entry: {
|
|
2016
1971
|
timestamp,
|
|
2017
|
-
runId:
|
|
1972
|
+
runId: stringValue(event.runId || event.deployRequestId),
|
|
2018
1973
|
eventType: "job_completed",
|
|
2019
1974
|
level: success ? "info" : "error",
|
|
2020
|
-
message: success ? "Completed successfully" :
|
|
1975
|
+
message: success ? "Completed successfully" : stringValue(event.error || "Failed"),
|
|
2021
1976
|
stepId: null,
|
|
2022
1977
|
current: null,
|
|
2023
1978
|
total: null,
|
|
@@ -2032,16 +1987,16 @@ function serveEventAgentLogEntry(event) {
|
|
|
2032
1987
|
relativePath,
|
|
2033
1988
|
entry: {
|
|
2034
1989
|
timestamp,
|
|
2035
|
-
runId:
|
|
1990
|
+
runId: stringValue(event.runId || event.deployRequestId),
|
|
2036
1991
|
eventType: "error",
|
|
2037
1992
|
level: "error",
|
|
2038
|
-
message:
|
|
1993
|
+
message: stringValue(event.error || event.code || "Unknown error"),
|
|
2039
1994
|
stepId: null,
|
|
2040
1995
|
current: null,
|
|
2041
1996
|
total: null,
|
|
2042
1997
|
success: false,
|
|
2043
1998
|
error: event.error ?? event.code ?? null,
|
|
2044
|
-
jobType: event.jobType ?
|
|
1999
|
+
jobType: event.jobType ? stringValue(event.jobType) : null
|
|
2045
2000
|
}
|
|
2046
2001
|
};
|
|
2047
2002
|
}
|
|
@@ -2055,7 +2010,7 @@ function serveEventAgentLogEntry(event) {
|
|
|
2055
2010
|
eventType: type,
|
|
2056
2011
|
level: event.status === "error" ? "error" : "info",
|
|
2057
2012
|
message: agentPrepareLogMessage(event),
|
|
2058
|
-
stepId:
|
|
2013
|
+
stepId: stringValue(event.stage || type),
|
|
2059
2014
|
current: null,
|
|
2060
2015
|
total: null,
|
|
2061
2016
|
success,
|
|
@@ -2065,12 +2020,12 @@ function serveEventAgentLogEntry(event) {
|
|
|
2065
2020
|
};
|
|
2066
2021
|
}
|
|
2067
2022
|
if (type === "process_exit" || type === "daemon_exit") {
|
|
2068
|
-
const message =
|
|
2023
|
+
const message = stringValue(event.message || processExitMessage(event));
|
|
2069
2024
|
return {
|
|
2070
2025
|
relativePath,
|
|
2071
2026
|
entry: {
|
|
2072
2027
|
timestamp,
|
|
2073
|
-
runId:
|
|
2028
|
+
runId: stringValue(event.runId || event.sessionId || "daemon"),
|
|
2074
2029
|
eventType: type,
|
|
2075
2030
|
level: "error",
|
|
2076
2031
|
message,
|
|
@@ -2084,16 +2039,16 @@ function serveEventAgentLogEntry(event) {
|
|
|
2084
2039
|
signal: event.signal ?? null,
|
|
2085
2040
|
stderrTail: event.stderrTail ?? null
|
|
2086
2041
|
},
|
|
2087
|
-
jobType: event.jobType ?
|
|
2042
|
+
jobType: event.jobType ? stringValue(event.jobType) : null
|
|
2088
2043
|
}
|
|
2089
2044
|
};
|
|
2090
2045
|
}
|
|
2091
2046
|
return null;
|
|
2092
2047
|
}
|
|
2093
2048
|
function agentRuntimeStatus(agent, agentRunState = {}) {
|
|
2094
|
-
const path10 =
|
|
2049
|
+
const path10 = stringValue(agent?.relativePath || ".");
|
|
2095
2050
|
const run2 = (agentRunState || {})[path10];
|
|
2096
|
-
const inventoryStatus =
|
|
2051
|
+
const inventoryStatus = stringValue(agent?.status);
|
|
2097
2052
|
if (run2?.status === "running") {
|
|
2098
2053
|
return { status: "running", label: "running", run: run2 };
|
|
2099
2054
|
}
|
|
@@ -2121,28 +2076,26 @@ function agentRuntimeStatus(agent, agentRunState = {}) {
|
|
|
2121
2076
|
return { status: inventoryStatus || "unknown", label: inventoryStatus || "unknown", run: run2 };
|
|
2122
2077
|
}
|
|
2123
2078
|
function appendError(errors, scope, message) {
|
|
2124
|
-
return [...errors, { scope, message:
|
|
2079
|
+
return [...errors, { scope, message: stringValue(message) }].slice(-20);
|
|
2125
2080
|
}
|
|
2126
2081
|
function serveDebugEntry(event) {
|
|
2127
2082
|
if (!event || typeof event !== "object") return null;
|
|
2128
|
-
const type =
|
|
2083
|
+
const type = stringValue(event.type);
|
|
2129
2084
|
const timestamp = event.timestamp || event.occurredAt || (/* @__PURE__ */ new Date()).toISOString();
|
|
2130
2085
|
const base = { timestamp, eventType: type, level: debugLevel(event) };
|
|
2131
2086
|
switch (type) {
|
|
2132
|
-
case "workspace_resolved":
|
|
2133
|
-
return { ...base, message: `workspace resolved collection=${stringValue2(event.collectionId || "unknown")}` };
|
|
2134
2087
|
case "daemon_registered":
|
|
2135
2088
|
return { ...base, message: `daemon registered daemon=${shortId(event.daemonId)} cli=${shortId(event.cliSessionId)}` };
|
|
2136
2089
|
case "daemon_event_stream_connected":
|
|
2137
2090
|
return { ...base, message: `daemon event stream connected daemon=${shortId(event.daemonId)}` };
|
|
2138
2091
|
case "daemon_event_stream_lost":
|
|
2139
|
-
return { ...base, level: "warn", message: `daemon event stream lost retry=${formatSeconds(event.retryInSeconds)} error=${
|
|
2092
|
+
return { ...base, level: "warn", message: `daemon event stream lost retry=${formatSeconds(event.retryInSeconds)} error=${stringValue(event.error || "unknown")}` };
|
|
2140
2093
|
case "daemon_wake_received":
|
|
2141
2094
|
return {
|
|
2142
2095
|
...base,
|
|
2143
2096
|
message: [
|
|
2144
|
-
`wake received source=${
|
|
2145
|
-
event.eventType ? `event=${
|
|
2097
|
+
`wake received source=${stringValue(event.sourceEventType || "backend")}`,
|
|
2098
|
+
event.eventType ? `event=${stringValue(event.eventType)}` : "",
|
|
2146
2099
|
event.sessionId ? `session=${shortId(event.sessionId)}` : "",
|
|
2147
2100
|
event.runId ? `run=${shortId(event.runId)}` : "",
|
|
2148
2101
|
event.localAgentRowId ? `agentRow=${shortId(event.localAgentRowId)}` : ""
|
|
@@ -2165,7 +2118,7 @@ function serveDebugEntry(event) {
|
|
|
2165
2118
|
message: `dispatch acked delivery=${shortId(event.deliveryId)} run=${shortId(event.runId || event.sessionId)} attempt=${shortId(event.attemptId)}`
|
|
2166
2119
|
};
|
|
2167
2120
|
case "job_started":
|
|
2168
|
-
return { ...base, message: `job started type=${
|
|
2121
|
+
return { ...base, message: `job started type=${stringValue(event.jobType || "run")} run=${shortId(event.runId || event.sessionId || event.deployRequestId || event.testRunId)}` };
|
|
2169
2122
|
case "job_completed":
|
|
2170
2123
|
return {
|
|
2171
2124
|
...base,
|
|
@@ -2173,18 +2126,18 @@ function serveDebugEntry(event) {
|
|
|
2173
2126
|
message: `job completed success=${event.success !== false} run=${shortId(event.runId || event.sessionId || event.deployRequestId || event.testRunId)}${event.error ? ` error=${formatErrorMessage(event.error)}` : ""}`
|
|
2174
2127
|
};
|
|
2175
2128
|
case "backend_connection_lost":
|
|
2176
|
-
return { ...base, level: "warn", message: `backend connection lost activity=${
|
|
2129
|
+
return { ...base, level: "warn", message: `backend connection lost activity=${stringValue(event.activity)} error=${stringValue(event.error)}` };
|
|
2177
2130
|
case "backend_connection_restored":
|
|
2178
|
-
return { ...base, message: `backend connection restored activity=${
|
|
2131
|
+
return { ...base, message: `backend connection restored activity=${stringValue(event.activity)}` };
|
|
2179
2132
|
case "retry_scheduled":
|
|
2180
|
-
return { ...base, level: "warn", message: `retry scheduled activity=${
|
|
2133
|
+
return { ...base, level: "warn", message: `retry scheduled activity=${stringValue(event.activity)} delay=${formatSeconds(event.delaySeconds)}` };
|
|
2181
2134
|
case "daemon_stderr":
|
|
2182
|
-
return { ...base, level: looksLikeError(event.message || event.stderr) ? "error" : "warn", message: `stderr ${
|
|
2135
|
+
return { ...base, level: looksLikeError(event.message || event.stderr) ? "error" : "warn", message: `stderr ${stringValue(event.message || event.stderr)}` };
|
|
2183
2136
|
case "error":
|
|
2184
|
-
return { ...base, level: "error", message: `error scope=${
|
|
2137
|
+
return { ...base, level: "error", message: `error scope=${stringValue(event.relativePath || event.path || "daemon")} ${stringValue(event.error || event.code || "unknown")}` };
|
|
2185
2138
|
case "process_exit":
|
|
2186
2139
|
case "daemon_exit":
|
|
2187
|
-
return { ...base, level: "error", message:
|
|
2140
|
+
return { ...base, level: "error", message: stringValue(event.message || processExitMessage(event)) };
|
|
2188
2141
|
case "stopped":
|
|
2189
2142
|
return { ...base, message: `stopped jobsRun=${Number(event.jobsRun ?? 0)}` };
|
|
2190
2143
|
default:
|
|
@@ -2192,7 +2145,7 @@ function serveDebugEntry(event) {
|
|
|
2192
2145
|
}
|
|
2193
2146
|
}
|
|
2194
2147
|
function debugLevel(event) {
|
|
2195
|
-
if (event?.level) return
|
|
2148
|
+
if (event?.level) return stringValue(event.level);
|
|
2196
2149
|
if (event?.type === "error" || event?.type === "process_exit" || event?.type === "daemon_exit") return "error";
|
|
2197
2150
|
return "info";
|
|
2198
2151
|
}
|
|
@@ -2200,14 +2153,14 @@ function boolText(value) {
|
|
|
2200
2153
|
return value ? "yes" : "no";
|
|
2201
2154
|
}
|
|
2202
2155
|
function shortId(value) {
|
|
2203
|
-
const text =
|
|
2156
|
+
const text = stringValue(value);
|
|
2204
2157
|
return text ? text.slice(0, 8) : "unknown";
|
|
2205
2158
|
}
|
|
2206
2159
|
function looksLikeError(value) {
|
|
2207
|
-
return /(error|exception|traceback|failed|fatal|denied|unauthorized|timeout)/i.test(
|
|
2160
|
+
return /(error|exception|traceback|failed|fatal|denied|unauthorized|timeout)/i.test(stringValue(value));
|
|
2208
2161
|
}
|
|
2209
2162
|
function setAgentRunState(agentRunState, relativePath, patch) {
|
|
2210
|
-
const key =
|
|
2163
|
+
const key = stringValue(relativePath || ".");
|
|
2211
2164
|
return {
|
|
2212
2165
|
...agentRunState || {},
|
|
2213
2166
|
[key]: {
|
|
@@ -2259,19 +2212,19 @@ function appendProcessExitAgentLogs(agentLogs, event, agentRunState, relativePat
|
|
|
2259
2212
|
function reconcileInventoryRunState(agentRunState, agents, timestamp) {
|
|
2260
2213
|
let next = agentRunState || {};
|
|
2261
2214
|
for (const agent of agents || []) {
|
|
2262
|
-
const path10 =
|
|
2215
|
+
const path10 = stringValue(agent?.relativePath || ".");
|
|
2263
2216
|
const current = next[path10];
|
|
2264
2217
|
if (agent?.status === "error") {
|
|
2265
2218
|
next = setAgentRunState(next, path10, {
|
|
2266
2219
|
status: "error",
|
|
2267
2220
|
lastEventAt: timestamp || (/* @__PURE__ */ new Date()).toISOString(),
|
|
2268
|
-
errorMessage:
|
|
2221
|
+
errorMessage: stringValue(agent.errorMessage || agent.error || "Agent setup failed")
|
|
2269
2222
|
});
|
|
2270
2223
|
} else if (agent?.status === "disabled") {
|
|
2271
2224
|
next = setAgentRunState(next, path10, {
|
|
2272
2225
|
status: "disabled",
|
|
2273
2226
|
lastEventAt: timestamp || (/* @__PURE__ */ new Date()).toISOString(),
|
|
2274
|
-
disabledReason:
|
|
2227
|
+
disabledReason: stringValue(agent.disabledReason || "System dependency not met locally"),
|
|
2275
2228
|
resolutionHints: Array.isArray(agent.resolutionHints) ? agent.resolutionHints : []
|
|
2276
2229
|
});
|
|
2277
2230
|
} else if (agent?.status === "online" && ["preparing", "error", "disabled"].includes(current?.status) && !current?.runId) {
|
|
@@ -2291,22 +2244,22 @@ function reconcileInventoryRunState(agentRunState, agents, timestamp) {
|
|
|
2291
2244
|
function normalizeStoredAgentLogEntry(entry) {
|
|
2292
2245
|
return {
|
|
2293
2246
|
timestamp: entry.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
|
|
2294
|
-
runId:
|
|
2295
|
-
eventType:
|
|
2296
|
-
level:
|
|
2297
|
-
message:
|
|
2298
|
-
stepId: entry.stepId ?
|
|
2247
|
+
runId: stringValue(entry.runId),
|
|
2248
|
+
eventType: stringValue(entry.eventType || "log"),
|
|
2249
|
+
level: stringValue(entry.level || "info"),
|
|
2250
|
+
message: stringValue(entry.message),
|
|
2251
|
+
stepId: entry.stepId ? stringValue(entry.stepId) : null,
|
|
2299
2252
|
current: entry.current ?? null,
|
|
2300
2253
|
total: entry.total ?? null,
|
|
2301
2254
|
success: entry.success ?? null,
|
|
2302
2255
|
error: entry.error ?? null,
|
|
2303
|
-
jobType: entry.jobType ?
|
|
2256
|
+
jobType: entry.jobType ? stringValue(entry.jobType) : null
|
|
2304
2257
|
};
|
|
2305
2258
|
}
|
|
2306
2259
|
function formatErrorMessage(error) {
|
|
2307
2260
|
if (!error) return null;
|
|
2308
|
-
if (typeof error === "object") return
|
|
2309
|
-
return
|
|
2261
|
+
if (typeof error === "object") return stringValue(error.message || "error");
|
|
2262
|
+
return stringValue(error);
|
|
2310
2263
|
}
|
|
2311
2264
|
function findNewAgents(previous, next) {
|
|
2312
2265
|
const seen = new Set(previous.map(agentKey).filter(Boolean));
|
|
@@ -2319,15 +2272,15 @@ function agentKey(agent) {
|
|
|
2319
2272
|
if (!agent || typeof agent !== "object") {
|
|
2320
2273
|
return "";
|
|
2321
2274
|
}
|
|
2322
|
-
return
|
|
2275
|
+
return stringValue(agent.localAgentId || agent.relativePath || agent.path || agent.manifestName || agent.id);
|
|
2323
2276
|
}
|
|
2324
2277
|
function agentLabel(event) {
|
|
2325
|
-
return
|
|
2278
|
+
return stringValue(event.relativePath || event.path || ".");
|
|
2326
2279
|
}
|
|
2327
2280
|
function jobLabel(event) {
|
|
2328
|
-
return
|
|
2281
|
+
return stringValue(event.runId || event.deployRequestId || event.relativePath || event.jobType || "job");
|
|
2329
2282
|
}
|
|
2330
|
-
function
|
|
2283
|
+
function stringValue(value) {
|
|
2331
2284
|
return value == null ? "" : String(value);
|
|
2332
2285
|
}
|
|
2333
2286
|
function processExitMessage(event) {
|
|
@@ -2344,11 +2297,11 @@ function agentPrepareLogMessage(event) {
|
|
|
2344
2297
|
return "Preparing agent";
|
|
2345
2298
|
}
|
|
2346
2299
|
if (event.type === "agent_prepare_completed") {
|
|
2347
|
-
if (event.status === "error") return
|
|
2348
|
-
if (event.status === "disabled") return
|
|
2300
|
+
if (event.status === "error") return stringValue(event.error || event.errorMessage || "Agent setup failed");
|
|
2301
|
+
if (event.status === "disabled") return stringValue(event.warning || event.disabledReason || "Agent disabled locally");
|
|
2349
2302
|
return "Agent ready";
|
|
2350
2303
|
}
|
|
2351
|
-
return
|
|
2304
|
+
return stringValue(event.message || event.stage || "Preparing agent");
|
|
2352
2305
|
}
|
|
2353
2306
|
function textTail(value, limit = 800) {
|
|
2354
2307
|
const text = String(value || "").trim().replace(/\s+/g, " ");
|
|
@@ -2368,11 +2321,10 @@ var MAX_EVENTS = 5e3;
|
|
|
2368
2321
|
var MAX_RUNS = 50;
|
|
2369
2322
|
function createServeLogStore({
|
|
2370
2323
|
agentsDir: agentsDir2 = "./agents",
|
|
2371
|
-
collectionId: collectionId2 = "",
|
|
2372
2324
|
env = process.env,
|
|
2373
2325
|
platform = process.platform
|
|
2374
2326
|
} = {}) {
|
|
2375
|
-
const file = serveLogFilePath({ agentsDir: agentsDir2,
|
|
2327
|
+
const file = serveLogFilePath({ agentsDir: agentsDir2, env, platform });
|
|
2376
2328
|
let appendCount = 0;
|
|
2377
2329
|
return {
|
|
2378
2330
|
file,
|
|
@@ -2387,7 +2339,6 @@ function createServeLogStore({
|
|
|
2387
2339
|
fs10.mkdirSync(path7.dirname(file), { recursive: true });
|
|
2388
2340
|
const record = {
|
|
2389
2341
|
version: 1,
|
|
2390
|
-
collectionId: collectionId2 || "",
|
|
2391
2342
|
agentsDir: String(agentsDir2 || "./agents"),
|
|
2392
2343
|
relativePath: normalized.relativePath,
|
|
2393
2344
|
entry: normalized.entry
|
|
@@ -2407,14 +2358,13 @@ function createServeLogStore({
|
|
|
2407
2358
|
}
|
|
2408
2359
|
function serveLogFilePath({
|
|
2409
2360
|
agentsDir: agentsDir2 = "./agents",
|
|
2410
|
-
collectionId: collectionId2 = "",
|
|
2411
2361
|
env = process.env,
|
|
2412
2362
|
platform = process.platform
|
|
2413
2363
|
} = {}) {
|
|
2414
2364
|
const root = vendianHome(env, platform);
|
|
2415
2365
|
const resolvedAgentsDir = path7.resolve(String(agentsDir2 || "./agents"));
|
|
2416
|
-
const hash = crypto2.createHash("sha256").update(
|
|
2417
|
-
return path7.join(root, "serve-logs",
|
|
2366
|
+
const hash = crypto2.createHash("sha256").update(resolvedAgentsDir).digest("hex").slice(0, 16);
|
|
2367
|
+
return path7.join(root, "serve-logs", `default-${hash}.jsonl`);
|
|
2418
2368
|
}
|
|
2419
2369
|
function readServeLogRecords(file) {
|
|
2420
2370
|
if (!file || !fs10.existsSync(file)) {
|
|
@@ -2464,28 +2414,24 @@ function trimServeLogRecords(records) {
|
|
|
2464
2414
|
return !runId || keepRuns.has(runId);
|
|
2465
2415
|
}).slice(-MAX_EVENTS);
|
|
2466
2416
|
}
|
|
2467
|
-
function safePathPart(value) {
|
|
2468
|
-
return String(value || "default").replace(/[^a-zA-Z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80) || "default";
|
|
2469
|
-
}
|
|
2470
2417
|
|
|
2471
2418
|
// src/serve-process.js
|
|
2472
2419
|
import { spawn as spawn2 } from "node:child_process";
|
|
2473
2420
|
async function spawnLocalServeEventStream({
|
|
2474
2421
|
agentsDir: agentsDir2 = "./agents",
|
|
2475
|
-
collectionId: collectionId2 = "",
|
|
2476
2422
|
env = process.env,
|
|
2477
2423
|
platform = process.platform,
|
|
2478
2424
|
onProgress = null
|
|
2479
2425
|
} = {}) {
|
|
2480
|
-
const invocation = await preparePythonVendianInvocation(buildLocalServeEventStreamArgs({ agentsDir: agentsDir2
|
|
2426
|
+
const invocation = await preparePythonVendianInvocation(buildLocalServeEventStreamArgs({ agentsDir: agentsDir2 }), { env, platform, onProgress });
|
|
2481
2427
|
return spawn2(invocation.command, invocation.args, {
|
|
2482
2428
|
env: invocation.env,
|
|
2483
2429
|
stdio: ["ignore", "pipe", "pipe"],
|
|
2484
2430
|
shell: false
|
|
2485
2431
|
});
|
|
2486
2432
|
}
|
|
2487
|
-
function buildLocalServeEventStreamArgs({ agentsDir: agentsDir2 = "./agents"
|
|
2488
|
-
|
|
2433
|
+
function buildLocalServeEventStreamArgs({ agentsDir: agentsDir2 = "./agents" } = {}) {
|
|
2434
|
+
return [
|
|
2489
2435
|
"cloud",
|
|
2490
2436
|
"local",
|
|
2491
2437
|
"serve",
|
|
@@ -2493,14 +2439,10 @@ function buildLocalServeEventStreamArgs({ agentsDir: agentsDir2 = "./agents", co
|
|
|
2493
2439
|
agentsDir2 || "./agents",
|
|
2494
2440
|
"--event-stream"
|
|
2495
2441
|
];
|
|
2496
|
-
if (collectionId2) {
|
|
2497
|
-
args.push("--collection-id", collectionId2);
|
|
2498
|
-
}
|
|
2499
|
-
return args;
|
|
2500
2442
|
}
|
|
2501
2443
|
|
|
2502
2444
|
// src/version.js
|
|
2503
|
-
var CLI_VERSION = true ? "0.0.
|
|
2445
|
+
var CLI_VERSION = true ? "0.0.45" : process.env.npm_package_version || "0.0.0-dev";
|
|
2504
2446
|
|
|
2505
2447
|
// src/dev-server.js
|
|
2506
2448
|
var __dirname = path8.dirname(fileURLToPath(import.meta.url));
|
|
@@ -2512,7 +2454,6 @@ var serveLogs = [];
|
|
|
2512
2454
|
var logStore = null;
|
|
2513
2455
|
var agentsDir = "";
|
|
2514
2456
|
var activeServeAgentsDir = "";
|
|
2515
|
-
var collectionId = "";
|
|
2516
2457
|
var activeAuthLogin = null;
|
|
2517
2458
|
async function startDevServer({
|
|
2518
2459
|
port = 3859,
|
|
@@ -2621,8 +2562,6 @@ async function handleApi(req, res, pathname, parsed) {
|
|
|
2621
2562
|
return apiServeState(req, res);
|
|
2622
2563
|
case "/api/auth":
|
|
2623
2564
|
return apiAuth(req, res);
|
|
2624
|
-
case "/api/workspaces":
|
|
2625
|
-
return await apiWorkspaces(req, res);
|
|
2626
2565
|
default:
|
|
2627
2566
|
return jsonResponse(res, { error: "not found" }, 404);
|
|
2628
2567
|
}
|
|
@@ -2657,7 +2596,6 @@ function apiStatus(req, res) {
|
|
|
2657
2596
|
serving,
|
|
2658
2597
|
agentsDir,
|
|
2659
2598
|
serveAgentsDir: serving ? activeServeAgentsDir || agentsDir : "",
|
|
2660
|
-
collectionId,
|
|
2661
2599
|
connected: serveState.connected,
|
|
2662
2600
|
activity: serveState.activity,
|
|
2663
2601
|
agentCount: serveState.agents.length,
|
|
@@ -2785,10 +2723,6 @@ function apiAuth(req, res) {
|
|
|
2785
2723
|
backends
|
|
2786
2724
|
});
|
|
2787
2725
|
}
|
|
2788
|
-
async function apiWorkspaces(req, res) {
|
|
2789
|
-
const result = await listCloudWorkspaces({ timeoutMs: 15e3 });
|
|
2790
|
-
jsonResponse(res, result);
|
|
2791
|
-
}
|
|
2792
2726
|
async function apiAuthSwitch(req, res, body) {
|
|
2793
2727
|
const backend = body.backend;
|
|
2794
2728
|
if (!backend || !BACKEND_TARGETS[backend]) {
|
|
@@ -2875,41 +2809,34 @@ async function apiValidate(req, res, body) {
|
|
|
2875
2809
|
}
|
|
2876
2810
|
function resolveServeStartTarget(body = {}, current = {}) {
|
|
2877
2811
|
const targetDir = body.agentsDir || current.agentsDir || "";
|
|
2878
|
-
|
|
2879
|
-
if (!targetCollection) {
|
|
2880
|
-
return { ok: false, error: "Choose a workspace before starting local serve." };
|
|
2881
|
-
}
|
|
2882
|
-
return { ok: true, agentsDir: targetDir, collectionId: targetCollection };
|
|
2812
|
+
return { ok: true, agentsDir: targetDir };
|
|
2883
2813
|
}
|
|
2884
2814
|
function devServerStateAfterServeStart(current = {}, target = {}) {
|
|
2885
2815
|
return {
|
|
2886
2816
|
agentsDir: current.agentsDir || "",
|
|
2887
|
-
activeServeAgentsDir: target.agentsDir || current.agentsDir || ""
|
|
2888
|
-
collectionId: target.collectionId || current.collectionId || ""
|
|
2817
|
+
activeServeAgentsDir: target.agentsDir || current.agentsDir || ""
|
|
2889
2818
|
};
|
|
2890
2819
|
}
|
|
2891
2820
|
async function apiServeStart(req, res, body) {
|
|
2892
2821
|
if (childProcessIsRunning(serveChild)) {
|
|
2893
2822
|
return jsonResponse(res, { ok: false, error: "Already serving" });
|
|
2894
2823
|
}
|
|
2895
|
-
const target = resolveServeStartTarget(body, { agentsDir
|
|
2824
|
+
const target = resolveServeStartTarget(body, { agentsDir });
|
|
2896
2825
|
if (!target.ok) {
|
|
2897
2826
|
return jsonResponse(res, target, 400);
|
|
2898
2827
|
}
|
|
2899
2828
|
try {
|
|
2900
2829
|
const targetDir = target.agentsDir;
|
|
2901
|
-
const targetCollection = target.collectionId;
|
|
2902
2830
|
const invocation = await preparePythonVendianInvocation(
|
|
2903
|
-
buildLocalServeEventStreamArgs({ agentsDir: targetDir
|
|
2831
|
+
buildLocalServeEventStreamArgs({ agentsDir: targetDir }),
|
|
2904
2832
|
{ onProgress: null }
|
|
2905
2833
|
);
|
|
2906
|
-
const nextState = devServerStateAfterServeStart({ agentsDir
|
|
2834
|
+
const nextState = devServerStateAfterServeStart({ agentsDir }, target);
|
|
2907
2835
|
agentsDir = nextState.agentsDir;
|
|
2908
2836
|
activeServeAgentsDir = nextState.activeServeAgentsDir;
|
|
2909
|
-
collectionId = nextState.collectionId;
|
|
2910
2837
|
serveState = initialServeState();
|
|
2911
2838
|
serveLogs = [];
|
|
2912
|
-
logStore = createServeLogStore({ agentsDir: activeServeAgentsDir
|
|
2839
|
+
logStore = createServeLogStore({ agentsDir: activeServeAgentsDir });
|
|
2913
2840
|
serveChild = spawn3(invocation.command, invocation.args, {
|
|
2914
2841
|
env: invocation.env,
|
|
2915
2842
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -3392,7 +3319,6 @@ var HOME_ACTIONS = [
|
|
|
3392
3319
|
{ value: "serve", label: "Serve my agents", desc: "Start agents and stream their logs" },
|
|
3393
3320
|
{ value: "connect", label: "Login / Switch", desc: "Sign in or switch to a different environment" },
|
|
3394
3321
|
{ value: "create", label: "Create Agent", desc: "Build a new agent from a template" },
|
|
3395
|
-
{ value: "run", label: "Run once", desc: "Execute one agent immediately" },
|
|
3396
3322
|
{ value: "commands", label: "Commands", desc: "Show all CLI commands" },
|
|
3397
3323
|
{ value: "exit", label: "Exit", desc: "" }
|
|
3398
3324
|
];
|
|
@@ -3463,7 +3389,7 @@ async function connectCustomUrl({ env, platform }) {
|
|
|
3463
3389
|
var COMMAND_GROUPS = [
|
|
3464
3390
|
{ section: "Getting started", commands: [
|
|
3465
3391
|
{ cmd: "vendian login", desc: "Sign in and set up your computer" },
|
|
3466
|
-
{ cmd: "vendian init --output-dir ./agents", desc: "Set up
|
|
3392
|
+
{ cmd: "vendian init --output-dir ./agents", desc: "Set up SDK docs" }
|
|
3467
3393
|
] },
|
|
3468
3394
|
{ section: "Building agents", commands: [
|
|
3469
3395
|
{ cmd: 'vendian create "My Agent" --output-dir .', desc: "Create a new agent" },
|
|
@@ -3472,14 +3398,13 @@ var COMMAND_GROUPS = [
|
|
|
3472
3398
|
] },
|
|
3473
3399
|
{ section: "Running agents", commands: [
|
|
3474
3400
|
{ cmd: "vendian dev", desc: "Open the dev UI in your browser" },
|
|
3475
|
-
{ cmd: "vendian cloud local run --collection-id ID --path . --input-json '{}'", desc: "Run one agent" },
|
|
3476
3401
|
{ cmd: "vendian cloud local serve --agents-dir .", desc: "Start agents" },
|
|
3477
3402
|
{ cmd: "vendian login --backend staging", desc: "Sign in to staging" }
|
|
3478
3403
|
] },
|
|
3479
3404
|
{ section: "Syncing & deploying", commands: [
|
|
3480
|
-
{ cmd: "vendian cloud
|
|
3481
|
-
{ cmd: "vendian cloud
|
|
3482
|
-
{ cmd: "vendian cloud
|
|
3405
|
+
{ cmd: "vendian cloud suite status --remote", desc: "Check source-set status" },
|
|
3406
|
+
{ cmd: "vendian cloud suite push --wait", desc: "Push selected source-set code" },
|
|
3407
|
+
{ cmd: "vendian cloud suite deploy --environment staging", desc: "Deploy a source set" }
|
|
3483
3408
|
] },
|
|
3484
3409
|
{ section: "Maintenance", commands: [
|
|
3485
3410
|
{ cmd: "vendian doctor", desc: "Check if everything is set up" },
|
|
@@ -3554,84 +3479,6 @@ async function pickAgentsFromFolder({ env, platform, candidate }) {
|
|
|
3554
3479
|
if (idx === 0) return { agentsDir: candidate.path };
|
|
3555
3480
|
return { agentsDir: named[idx - 1].path };
|
|
3556
3481
|
}
|
|
3557
|
-
async function pickSingleAgentToRun({ env, platform, candidates }) {
|
|
3558
|
-
if (candidates.length === 0) {
|
|
3559
|
-
clearScreen();
|
|
3560
|
-
print("");
|
|
3561
|
-
print(col.yellow(" Couldn't find any agents."));
|
|
3562
|
-
const input = await ask("Agent folder", "./agents/my-agent");
|
|
3563
|
-
if (!input) return null;
|
|
3564
|
-
return { path: input, displayName: friendlyName(path9.basename(input) || "Agent") };
|
|
3565
|
-
}
|
|
3566
|
-
const agents = candidates.flatMap((candidate) => {
|
|
3567
|
-
const folders = findAgentFolders(candidate.absolutePath);
|
|
3568
|
-
if (folders.length > 0) {
|
|
3569
|
-
return folders.map((folder) => ({
|
|
3570
|
-
path: folder.path,
|
|
3571
|
-
displayName: readManifestName(folder.absolutePath) || friendlyName(folder.name || path9.basename(folder.path))
|
|
3572
|
-
}));
|
|
3573
|
-
}
|
|
3574
|
-
return [{
|
|
3575
|
-
path: candidate.path,
|
|
3576
|
-
displayName: readManifestName(candidate.absolutePath) || friendlyName(path9.basename(candidate.absolutePath) || candidate.path)
|
|
3577
|
-
}];
|
|
3578
|
-
});
|
|
3579
|
-
if (agents.length === 1) return agents[0];
|
|
3580
|
-
clearScreen();
|
|
3581
|
-
printHeader({ env, platform });
|
|
3582
|
-
print("");
|
|
3583
|
-
print(col.bold(" Which agent do you want to run?"));
|
|
3584
|
-
print("");
|
|
3585
|
-
const items = agents.map((a) => `${a.displayName.padEnd(32)} ${col.gray(a.path)}`);
|
|
3586
|
-
const idx = await pickMenu(items, { allowBack: true });
|
|
3587
|
-
if (idx === null || idx === -1) return null;
|
|
3588
|
-
return agents[idx];
|
|
3589
|
-
}
|
|
3590
|
-
async function chooseCloudWorkspace({ env, platform, loadingTitle, pickerTitle } = {}) {
|
|
3591
|
-
print("");
|
|
3592
|
-
process.stdout.write(` ${col.gray(loadingTitle || "Loading workspaces...")}
|
|
3593
|
-
`);
|
|
3594
|
-
let wsResult;
|
|
3595
|
-
try {
|
|
3596
|
-
wsResult = await listCloudWorkspaces({
|
|
3597
|
-
env,
|
|
3598
|
-
platform,
|
|
3599
|
-
onProgress: (msg) => {
|
|
3600
|
-
process.stdout.write(`\r ${col.gray(clip(msg, 60))} `);
|
|
3601
|
-
}
|
|
3602
|
-
});
|
|
3603
|
-
process.stdout.write("\r" + " ".repeat(70) + "\r");
|
|
3604
|
-
} catch (error) {
|
|
3605
|
-
process.stdout.write("\r" + " ".repeat(70) + "\r");
|
|
3606
|
-
print(col.red(`
|
|
3607
|
-
Couldn't connect: ${errMsg(error)}`));
|
|
3608
|
-
print(col.gray(" Make sure you are signed in (choose Login / Switch from the menu)."));
|
|
3609
|
-
await pressEnterToContinue({ grabActive: false });
|
|
3610
|
-
return null;
|
|
3611
|
-
}
|
|
3612
|
-
if (!wsResult.ok) {
|
|
3613
|
-
print(col.red(`
|
|
3614
|
-
${fig.cross} ${wsResult.error}`));
|
|
3615
|
-
await pressEnterToContinue({ grabActive: false });
|
|
3616
|
-
return null;
|
|
3617
|
-
}
|
|
3618
|
-
if (wsResult.workspaces.length === 0) return null;
|
|
3619
|
-
if (wsResult.workspaces.length === 1) {
|
|
3620
|
-
const ws2 = wsResult.workspaces[0];
|
|
3621
|
-
return { id: ws2.id || "", label: workspaceLabel(ws2) };
|
|
3622
|
-
}
|
|
3623
|
-
clearScreen();
|
|
3624
|
-
print("");
|
|
3625
|
-
printHeader({ env, platform });
|
|
3626
|
-
print("");
|
|
3627
|
-
print(col.bold(` ${pickerTitle || "Choose a workspace:"}`));
|
|
3628
|
-
print("");
|
|
3629
|
-
const items = wsResult.workspaces.map((ws2) => workspaceLabel(ws2));
|
|
3630
|
-
const idx = await pickMenu(items, { allowBack: true });
|
|
3631
|
-
if (idx === null || idx === -1) return null;
|
|
3632
|
-
const ws = wsResult.workspaces[idx];
|
|
3633
|
-
return { id: ws.id || "", label: workspaceLabel(ws) };
|
|
3634
|
-
}
|
|
3635
3482
|
async function showCreate({ env, platform }) {
|
|
3636
3483
|
clearScreen();
|
|
3637
3484
|
printHeader({ env, platform });
|
|
@@ -3647,43 +3494,18 @@ async function showCreate({ env, platform }) {
|
|
|
3647
3494
|
);
|
|
3648
3495
|
return "home";
|
|
3649
3496
|
}
|
|
3650
|
-
async function showRun({ env, platform }) {
|
|
3651
|
-
const candidates = findAgentDirectoryCandidates();
|
|
3652
|
-
const picked = await pickSingleAgentToRun({ env, platform, candidates });
|
|
3653
|
-
if (!picked) return "home";
|
|
3654
|
-
const workspace = await chooseCloudWorkspace({
|
|
3655
|
-
env,
|
|
3656
|
-
platform,
|
|
3657
|
-
loadingTitle: "Getting ready to run this agent...",
|
|
3658
|
-
pickerTitle: "Which project should own this run?"
|
|
3659
|
-
});
|
|
3660
|
-
if (!workspace) return "home";
|
|
3661
|
-
const inputJson = await ask("Input JSON", "{}");
|
|
3662
|
-
await withOutputMode(
|
|
3663
|
-
`Running ${picked.displayName}`,
|
|
3664
|
-
() => forwardToPythonVendian(buildLocalRunArgs({
|
|
3665
|
-
agentPath: picked.path,
|
|
3666
|
-
collectionId: workspace.id,
|
|
3667
|
-
inputJson: inputJson || "{}"
|
|
3668
|
-
}), { env, platform })
|
|
3669
|
-
);
|
|
3670
|
-
return "home";
|
|
3671
|
-
}
|
|
3672
3497
|
async function showServe({ env, platform }) {
|
|
3673
3498
|
const candidates = findAgentDirectoryCandidates();
|
|
3674
3499
|
const picked = await pickAgentsToRun({ env, platform, candidates });
|
|
3675
3500
|
if (!picked) return "home";
|
|
3676
3501
|
const { agentsDir: agentsDir2 } = picked;
|
|
3677
|
-
|
|
3502
|
+
return await runServeDashboard({
|
|
3678
3503
|
env,
|
|
3679
3504
|
platform,
|
|
3680
|
-
|
|
3681
|
-
pickerTitle: "Which project do you want to run?"
|
|
3505
|
+
agentsDir: agentsDir2
|
|
3682
3506
|
});
|
|
3683
|
-
if (!workspace) return "home";
|
|
3684
|
-
return await runServeDashboard({ env, platform, agentsDir: agentsDir2, collectionId: workspace.id, wsLabel: workspace.label });
|
|
3685
3507
|
}
|
|
3686
|
-
async function runServeDashboard({ env, platform, agentsDir: agentsDir2
|
|
3508
|
+
async function runServeDashboard({ env, platform, agentsDir: agentsDir2 }) {
|
|
3687
3509
|
let state = initialServeState();
|
|
3688
3510
|
let child = null;
|
|
3689
3511
|
let ctrlCArmed = false;
|
|
@@ -3703,7 +3525,7 @@ async function runServeDashboard({ env, platform, agentsDir: agentsDir2, collect
|
|
|
3703
3525
|
print(col.gray("\u2550".repeat(W)));
|
|
3704
3526
|
print(` ${col.cyan(col.bold("\u2191 VENDIAN"))} ${col.bold("Serving agents")}`);
|
|
3705
3527
|
print(` ${col.gray("Dir:")} ${agentsDir2}`);
|
|
3706
|
-
print(` ${col.gray("
|
|
3528
|
+
print(` ${col.gray("Backend:")} ${envLabel(activeCloudAuthStatus({ env, platform }).apiUrl) || "active endpoint"}`);
|
|
3707
3529
|
print(col.gray(hr(W)));
|
|
3708
3530
|
print(col.gray(" S stop gracefully | ^c ^c exit"));
|
|
3709
3531
|
print(col.gray(hr(W)));
|
|
@@ -3820,7 +3642,7 @@ async function runServeDashboard({ env, platform, agentsDir: agentsDir2, collect
|
|
|
3820
3642
|
}
|
|
3821
3643
|
}
|
|
3822
3644
|
try {
|
|
3823
|
-
logStore2 = createServeLogStore({ agentsDir: agentsDir2,
|
|
3645
|
+
logStore2 = createServeLogStore({ agentsDir: agentsDir2, env, platform });
|
|
3824
3646
|
const historicalLogs = logStore2.load();
|
|
3825
3647
|
if (historicalLogs.length > 0) {
|
|
3826
3648
|
const agentLogs = mergeAgentLogRecords(state.agentLogs, historicalLogs);
|
|
@@ -3828,7 +3650,6 @@ async function runServeDashboard({ env, platform, agentsDir: agentsDir2, collect
|
|
|
3828
3650
|
}
|
|
3829
3651
|
child = await spawnLocalServeEventStream({
|
|
3830
3652
|
agentsDir: agentsDir2,
|
|
3831
|
-
collectionId: collectionId2,
|
|
3832
3653
|
env,
|
|
3833
3654
|
platform,
|
|
3834
3655
|
onProgress: (msg) => {
|
|
@@ -4020,9 +3841,6 @@ async function mainLoop({ env, platform }) {
|
|
|
4020
3841
|
case "create":
|
|
4021
3842
|
next = await showCreate({ env, platform });
|
|
4022
3843
|
break;
|
|
4023
|
-
case "run":
|
|
4024
|
-
next = await showRun({ env, platform });
|
|
4025
|
-
break;
|
|
4026
3844
|
case "serve":
|
|
4027
3845
|
next = await showServe({ env, platform });
|
|
4028
3846
|
break;
|
|
@@ -4126,23 +3944,6 @@ function endpointErrorStatus(error) {
|
|
|
4126
3944
|
const message = error && typeof error.message === "string" ? error.message : String(error || "Connection failed");
|
|
4127
3945
|
return `${fig.cross} ${message}`;
|
|
4128
3946
|
}
|
|
4129
|
-
function buildLocalRunArgs({
|
|
4130
|
-
agentPath = ".",
|
|
4131
|
-
collectionId: collectionId2 = "",
|
|
4132
|
-
inputJson = "{}"
|
|
4133
|
-
} = {}) {
|
|
4134
|
-
return [
|
|
4135
|
-
"cloud",
|
|
4136
|
-
"local",
|
|
4137
|
-
"run",
|
|
4138
|
-
"--collection-id",
|
|
4139
|
-
collectionId2,
|
|
4140
|
-
"--path",
|
|
4141
|
-
agentPath || ".",
|
|
4142
|
-
"--input-json",
|
|
4143
|
-
inputJson || "{}"
|
|
4144
|
-
];
|
|
4145
|
-
}
|
|
4146
3947
|
function stopSignalForAttempt(attempt = 0) {
|
|
4147
3948
|
if (!Number.isFinite(attempt) || attempt <= 0) return "SIGINT";
|
|
4148
3949
|
if (attempt === 1) return "SIGTERM";
|
|
@@ -4162,7 +3963,7 @@ function helpText() {
|
|
|
4162
3963
|
" vendian login Sign in and prepare the local runtime",
|
|
4163
3964
|
" vendian doctor Check local bootstrap health",
|
|
4164
3965
|
" vendian update Update the managed runtime",
|
|
4165
|
-
" vendian init Write SDK agent docs into a
|
|
3966
|
+
" vendian init Write SDK agent docs into a folder",
|
|
4166
3967
|
' vendian create "My Agent" Scaffold a new agent from templates',
|
|
4167
3968
|
" vendian dev Open the dev UI (alias for bare vendian)",
|
|
4168
3969
|
" vendian <command> Run a managed Python SDK/cloud command",
|
|
@@ -4176,8 +3977,9 @@ function helpText() {
|
|
|
4176
3977
|
" vendian validate ./agents/my-agent --runtime",
|
|
4177
3978
|
" vendian models",
|
|
4178
3979
|
" vendian cloud local serve --agents-dir ./agents",
|
|
4179
|
-
" vendian cloud
|
|
4180
|
-
" vendian cloud
|
|
3980
|
+
" vendian cloud suite status --path vendian-suite.yaml --remote",
|
|
3981
|
+
" vendian cloud suite push --path vendian-suite.yaml --wait",
|
|
3982
|
+
" vendian cloud suite deploy --path vendian-suite.yaml --environment staging",
|
|
4181
3983
|
" vendian doctor",
|
|
4182
3984
|
" vendian update",
|
|
4183
3985
|
"",
|