@vendian/cli 0.0.8 → 0.0.10
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/cli-wrapper.mjs +1022 -137
- package/package.json +2 -1
package/cli-wrapper.mjs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as __vendianCreateRequire } from 'node:module';
|
|
3
|
+
const require = __vendianCreateRequire(import.meta.url);
|
|
2
4
|
|
|
3
5
|
var __create = Object.create;
|
|
4
6
|
var __defProp = Object.defineProperty;
|
|
@@ -1379,7 +1381,7 @@ var require_react_development = __commonJS({
|
|
|
1379
1381
|
var dispatcher = resolveDispatcher();
|
|
1380
1382
|
return dispatcher.useReducer(reducer, initialArg, init);
|
|
1381
1383
|
}
|
|
1382
|
-
function
|
|
1384
|
+
function useRef3(initialValue) {
|
|
1383
1385
|
var dispatcher = resolveDispatcher();
|
|
1384
1386
|
return dispatcher.useRef(initialValue);
|
|
1385
1387
|
}
|
|
@@ -2173,7 +2175,7 @@ var require_react_development = __commonJS({
|
|
|
2173
2175
|
exports.useLayoutEffect = useLayoutEffect2;
|
|
2174
2176
|
exports.useMemo = useMemo3;
|
|
2175
2177
|
exports.useReducer = useReducer;
|
|
2176
|
-
exports.useRef =
|
|
2178
|
+
exports.useRef = useRef3;
|
|
2177
2179
|
exports.useState = useState6;
|
|
2178
2180
|
exports.useSyncExternalStore = useSyncExternalStore;
|
|
2179
2181
|
exports.useTransition = useTransition;
|
|
@@ -36689,16 +36691,27 @@ function packageIndexEnv(config = {}, env3 = process.env, platform2 = process.pl
|
|
|
36689
36691
|
function joinIndexUrls(urls) {
|
|
36690
36692
|
return urls.flatMap((value) => String(value || "").split(/\s+/)).map((value) => value.trim()).filter(Boolean).filter((value, index, all) => all.indexOf(value) === index).join(" ");
|
|
36691
36693
|
}
|
|
36692
|
-
function maybeAutoUpdateManagedEnv({
|
|
36694
|
+
function maybeAutoUpdateManagedEnv({
|
|
36695
|
+
env: env3 = process.env,
|
|
36696
|
+
platform: platform2 = process.platform,
|
|
36697
|
+
venvPath = managedVenvPath(env3, platform2),
|
|
36698
|
+
force = false,
|
|
36699
|
+
log = true,
|
|
36700
|
+
load = loadConfig,
|
|
36701
|
+
save = saveConfig,
|
|
36702
|
+
installPackages = installVendianPackages,
|
|
36703
|
+
refreshDocs = refreshAgentDocsWorkspaces,
|
|
36704
|
+
now = Date.now()
|
|
36705
|
+
} = {}) {
|
|
36693
36706
|
if (env3.VENDIAN_SKIP_AUTO_UPDATE === "1") {
|
|
36694
36707
|
return false;
|
|
36695
36708
|
}
|
|
36696
|
-
const config =
|
|
36709
|
+
const config = load(env3, platform2);
|
|
36697
36710
|
const lastUpdate = Date.parse(config.lastManagedUpdateAt || "");
|
|
36698
|
-
if (Number.isFinite(lastUpdate) &&
|
|
36711
|
+
if (!force && Number.isFinite(lastUpdate) && now - lastUpdate < AUTO_UPDATE_INTERVAL_MS) {
|
|
36699
36712
|
return false;
|
|
36700
36713
|
}
|
|
36701
|
-
const registry = registryConfig(config, env3);
|
|
36714
|
+
const registry = registryConfig(config, env3, platform2);
|
|
36702
36715
|
if (!registry.token) {
|
|
36703
36716
|
return false;
|
|
36704
36717
|
}
|
|
@@ -36707,14 +36720,19 @@ function maybeAutoUpdateManagedEnv({ env: env3 = process.env, platform: platform
|
|
|
36707
36720
|
return false;
|
|
36708
36721
|
}
|
|
36709
36722
|
try {
|
|
36710
|
-
|
|
36711
|
-
|
|
36712
|
-
|
|
36713
|
-
|
|
36723
|
+
if (log) {
|
|
36724
|
+
console.error("[vendian] Checking managed CLI/runtime updates...");
|
|
36725
|
+
}
|
|
36726
|
+
installPackages({ pythonPath, venvPath, config, env: env3, platform: platform2 });
|
|
36727
|
+
const next = { ...config, lastManagedUpdateAt: new Date(now).toISOString() };
|
|
36728
|
+
save(next, env3, platform2);
|
|
36729
|
+
refreshDocs({ config: next, venvPath, env: env3, platform: platform2 });
|
|
36714
36730
|
return true;
|
|
36715
36731
|
} catch (error) {
|
|
36716
36732
|
const message = error && typeof error.message === "string" ? error.message : String(error);
|
|
36717
|
-
|
|
36733
|
+
if (log) {
|
|
36734
|
+
console.error(`[vendian] Update check failed; continuing with installed CLI. ${message}`);
|
|
36735
|
+
}
|
|
36718
36736
|
return false;
|
|
36719
36737
|
}
|
|
36720
36738
|
}
|
|
@@ -36723,16 +36741,12 @@ function maybeAutoUpdateManagedEnv({ env: env3 = process.env, platform: platform
|
|
|
36723
36741
|
import fs11 from "node:fs";
|
|
36724
36742
|
import readlinePromises from "node:readline/promises";
|
|
36725
36743
|
|
|
36726
|
-
// src/npm-update.js
|
|
36727
|
-
import { execFile } from "node:child_process";
|
|
36728
|
-
import { promisify } from "node:util";
|
|
36729
|
-
|
|
36730
36744
|
// src/version.js
|
|
36731
|
-
var CLI_VERSION = true ? "0.0.
|
|
36745
|
+
var CLI_VERSION = true ? "0.0.10" : process.env.npm_package_version || "0.0.0-dev";
|
|
36732
36746
|
|
|
36733
36747
|
// src/npm-update.js
|
|
36734
|
-
var execFileAsync = promisify(execFile);
|
|
36735
36748
|
var NPM_CHECK_INTERVAL_MS = 30 * 60 * 1e3;
|
|
36749
|
+
var CLI_PACKAGE_NAME = "@vendian/cli";
|
|
36736
36750
|
function npmPackageUpdateSummary({
|
|
36737
36751
|
config = {},
|
|
36738
36752
|
currentVersion = CLI_VERSION,
|
|
@@ -36755,21 +36769,14 @@ function npmPackageUpdateSummary({
|
|
|
36755
36769
|
async function checkNpmPackageUpdate({
|
|
36756
36770
|
env: env3 = process.env,
|
|
36757
36771
|
platform: platform2 = process.platform,
|
|
36758
|
-
packageName =
|
|
36772
|
+
packageName = CLI_PACKAGE_NAME,
|
|
36759
36773
|
registry = "https://registry.npmjs.org/",
|
|
36760
36774
|
currentVersion = CLI_VERSION,
|
|
36761
|
-
timeoutMs = 4e3
|
|
36775
|
+
timeoutMs = 4e3,
|
|
36776
|
+
fetchImpl = globalThis.fetch
|
|
36762
36777
|
} = {}) {
|
|
36763
|
-
const npm = platform2 === "win32" ? "npm.cmd" : "npm";
|
|
36764
|
-
const args = ["view", packageName, "dist-tags.latest", "--json", `--registry=${registry}`];
|
|
36765
36778
|
try {
|
|
36766
|
-
const
|
|
36767
|
-
env: env3,
|
|
36768
|
-
encoding: "utf8",
|
|
36769
|
-
timeout: timeoutMs,
|
|
36770
|
-
windowsHide: true
|
|
36771
|
-
});
|
|
36772
|
-
const latestVersion = parseNpmLatest(stdout);
|
|
36779
|
+
const latestVersion = await latestNpmPackageVersion({ packageName, registry, timeoutMs, fetchImpl });
|
|
36773
36780
|
const config = {
|
|
36774
36781
|
...loadConfig(env3, platform2),
|
|
36775
36782
|
latestNpmCliVersion: latestVersion,
|
|
@@ -36784,6 +36791,33 @@ async function checkNpmPackageUpdate({
|
|
|
36784
36791
|
};
|
|
36785
36792
|
}
|
|
36786
36793
|
}
|
|
36794
|
+
async function latestNpmPackageVersion({
|
|
36795
|
+
packageName = CLI_PACKAGE_NAME,
|
|
36796
|
+
registry = "https://registry.npmjs.org/",
|
|
36797
|
+
timeoutMs = 4e3,
|
|
36798
|
+
fetchImpl = globalThis.fetch
|
|
36799
|
+
} = {}) {
|
|
36800
|
+
if (typeof fetchImpl !== "function") {
|
|
36801
|
+
throw new Error("fetch is unavailable");
|
|
36802
|
+
}
|
|
36803
|
+
const controller = new AbortController();
|
|
36804
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
36805
|
+
try {
|
|
36806
|
+
const response = await fetchImpl(registryPackageUrl(registry, packageName), {
|
|
36807
|
+
headers: {
|
|
36808
|
+
accept: "application/vnd.npm.install-v1+json, application/json"
|
|
36809
|
+
},
|
|
36810
|
+
signal: controller.signal
|
|
36811
|
+
});
|
|
36812
|
+
if (!response?.ok) {
|
|
36813
|
+
throw new Error(`npm registry returned ${response?.status || "no response"}`);
|
|
36814
|
+
}
|
|
36815
|
+
const metadata = await response.json();
|
|
36816
|
+
return parseNpmLatest(metadata?.["dist-tags"]?.latest);
|
|
36817
|
+
} finally {
|
|
36818
|
+
clearTimeout(timeout);
|
|
36819
|
+
}
|
|
36820
|
+
}
|
|
36787
36821
|
function updateLabel({ runtime, npmUpdate }) {
|
|
36788
36822
|
if (npmUpdate?.updateAvailable) {
|
|
36789
36823
|
return `${npmUpdate.label} (current ${npmUpdate.currentVersion})`;
|
|
@@ -36811,6 +36845,19 @@ function parseNpmLatest(stdout) {
|
|
|
36811
36845
|
return raw.replace(/^"|"$/g, "").trim();
|
|
36812
36846
|
}
|
|
36813
36847
|
}
|
|
36848
|
+
function registryPackageUrl(registry, packageName) {
|
|
36849
|
+
const base = String(registry || "https://registry.npmjs.org/");
|
|
36850
|
+
const normalizedBase = base.endsWith("/") ? base : `${base}/`;
|
|
36851
|
+
return new URL(encodeRegistryPackageName(packageName), normalizedBase).toString();
|
|
36852
|
+
}
|
|
36853
|
+
function encodeRegistryPackageName(packageName) {
|
|
36854
|
+
const name = String(packageName || "").trim();
|
|
36855
|
+
if (!name.startsWith("@")) {
|
|
36856
|
+
return encodeURIComponent(name);
|
|
36857
|
+
}
|
|
36858
|
+
const [scope, pkg] = name.slice(1).split("/");
|
|
36859
|
+
return `@${encodeURIComponent(scope || "")}%2f${encodeURIComponent(pkg || "")}`;
|
|
36860
|
+
}
|
|
36814
36861
|
function compareSemver(left, right) {
|
|
36815
36862
|
const leftParts = semverParts(left);
|
|
36816
36863
|
const rightParts = semverParts(right);
|
|
@@ -37045,6 +37092,9 @@ function initialServeState() {
|
|
|
37045
37092
|
retry: null,
|
|
37046
37093
|
errors: [],
|
|
37047
37094
|
logs: [],
|
|
37095
|
+
agentLogs: {},
|
|
37096
|
+
// per-agent logs keyed by relativePath
|
|
37097
|
+
newAgents: [],
|
|
37048
37098
|
stopped: false,
|
|
37049
37099
|
jobsRun: 0
|
|
37050
37100
|
};
|
|
@@ -37060,6 +37110,19 @@ function parseServeEventLine(line) {
|
|
|
37060
37110
|
}
|
|
37061
37111
|
return parsed;
|
|
37062
37112
|
}
|
|
37113
|
+
function serveProcessExitMessage({ stderr = "", code = 0, signal = "" } = {}) {
|
|
37114
|
+
const text = String(stderr || "");
|
|
37115
|
+
if (/unrecognized arguments:\s*--event-stream/i.test(text)) {
|
|
37116
|
+
return "Managed Vendian runtime is too old for the local serve dashboard. Run `vendian update`, then start Serve Agents again.";
|
|
37117
|
+
}
|
|
37118
|
+
if (code && code !== 0) {
|
|
37119
|
+
return `Local serve exited with code ${code}. Toggle details for stderr.`;
|
|
37120
|
+
}
|
|
37121
|
+
if (signal && signal !== "SIGINT" && signal !== "SIGTERM") {
|
|
37122
|
+
return `Local serve exited from ${signal}. Toggle details for stderr.`;
|
|
37123
|
+
}
|
|
37124
|
+
return "";
|
|
37125
|
+
}
|
|
37063
37126
|
function applyServeEvent(state, event) {
|
|
37064
37127
|
if (!event || typeof event.type !== "string") {
|
|
37065
37128
|
return state;
|
|
@@ -37091,10 +37154,13 @@ function applyServeEvent(state, event) {
|
|
|
37091
37154
|
};
|
|
37092
37155
|
}
|
|
37093
37156
|
if (event.type === "inventory_synced") {
|
|
37157
|
+
const agents = Array.isArray(event.agents) ? event.agents : state.agents;
|
|
37158
|
+
const newAgents = state.agents.length > 0 ? findNewAgents(state.agents, agents) : [];
|
|
37094
37159
|
return {
|
|
37095
37160
|
...next,
|
|
37096
|
-
agents
|
|
37097
|
-
|
|
37161
|
+
agents,
|
|
37162
|
+
newAgents,
|
|
37163
|
+
activity: newAgents.length ? `${newAgents.length} new agent${newAgents.length === 1 ? "" : "s"} synced` : `Inventory synced (${Number(event.agentCount ?? agents.length ?? 0)} agent(s))`
|
|
37098
37164
|
};
|
|
37099
37165
|
}
|
|
37100
37166
|
if (event.type === "job_started") {
|
|
@@ -37138,6 +37204,12 @@ function applyServeEvent(state, event) {
|
|
|
37138
37204
|
jobsRun: Number(event.jobsRun ?? state.jobsRun)
|
|
37139
37205
|
};
|
|
37140
37206
|
}
|
|
37207
|
+
if (event.type === "run_log") {
|
|
37208
|
+
return {
|
|
37209
|
+
...next,
|
|
37210
|
+
agentLogs: appendAgentLog(state.agentLogs, event)
|
|
37211
|
+
};
|
|
37212
|
+
}
|
|
37141
37213
|
return next;
|
|
37142
37214
|
}
|
|
37143
37215
|
function agentSummary(agents = []) {
|
|
@@ -37159,9 +37231,45 @@ function agentSummary(agents = []) {
|
|
|
37159
37231
|
function appendLog(logs, event) {
|
|
37160
37232
|
return [...logs, event].slice(-200);
|
|
37161
37233
|
}
|
|
37234
|
+
function appendAgentLog(agentLogs, event) {
|
|
37235
|
+
const key = stringValue(event.relativePath || ".");
|
|
37236
|
+
const existing = agentLogs[key] || [];
|
|
37237
|
+
const entry = {
|
|
37238
|
+
timestamp: event.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
|
|
37239
|
+
runId: stringValue(event.runId),
|
|
37240
|
+
eventType: stringValue(event.eventType),
|
|
37241
|
+
level: stringValue(event.level || "info"),
|
|
37242
|
+
message: stringValue(event.message),
|
|
37243
|
+
stepId: event.stepId ? stringValue(event.stepId) : null,
|
|
37244
|
+
current: event.current ?? null,
|
|
37245
|
+
total: event.total ?? null,
|
|
37246
|
+
success: event.success ?? null,
|
|
37247
|
+
error: event.error ?? null
|
|
37248
|
+
};
|
|
37249
|
+
return {
|
|
37250
|
+
...agentLogs,
|
|
37251
|
+
[key]: [...existing, entry].slice(-100)
|
|
37252
|
+
};
|
|
37253
|
+
}
|
|
37254
|
+
function agentLogEntries(agentLogs, relativePath) {
|
|
37255
|
+
return (agentLogs || {})[relativePath] || [];
|
|
37256
|
+
}
|
|
37162
37257
|
function appendError(errors, scope, message) {
|
|
37163
37258
|
return [...errors, { scope, message: stringValue(message) }].slice(-20);
|
|
37164
37259
|
}
|
|
37260
|
+
function findNewAgents(previous, next) {
|
|
37261
|
+
const seen = new Set(previous.map(agentKey).filter(Boolean));
|
|
37262
|
+
return next.filter((agent) => {
|
|
37263
|
+
const key = agentKey(agent);
|
|
37264
|
+
return key && !seen.has(key);
|
|
37265
|
+
}).slice(0, 8);
|
|
37266
|
+
}
|
|
37267
|
+
function agentKey(agent) {
|
|
37268
|
+
if (!agent || typeof agent !== "object") {
|
|
37269
|
+
return "";
|
|
37270
|
+
}
|
|
37271
|
+
return stringValue(agent.localAgentId || agent.relativePath || agent.path || agent.manifestName || agent.id);
|
|
37272
|
+
}
|
|
37165
37273
|
function agentLabel(event) {
|
|
37166
37274
|
return stringValue(event.relativePath || event.path || ".");
|
|
37167
37275
|
}
|
|
@@ -37180,27 +37288,152 @@ function formatSeconds(value) {
|
|
|
37180
37288
|
import { spawn as spawn2 } from "node:child_process";
|
|
37181
37289
|
async function spawnLocalServeEventStream({
|
|
37182
37290
|
agentsDir = "./agents",
|
|
37291
|
+
collectionId = "",
|
|
37183
37292
|
env: env3 = process.env,
|
|
37184
37293
|
platform: platform2 = process.platform
|
|
37185
37294
|
} = {}) {
|
|
37186
|
-
const invocation = await preparePythonVendianInvocation(
|
|
37295
|
+
const invocation = await preparePythonVendianInvocation(buildLocalServeEventStreamArgs({ agentsDir, collectionId }), { env: env3, platform: platform2 });
|
|
37296
|
+
return spawn2(invocation.command, invocation.args, {
|
|
37297
|
+
env: invocation.env,
|
|
37298
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
37299
|
+
shell: false
|
|
37300
|
+
});
|
|
37301
|
+
}
|
|
37302
|
+
function buildLocalServeEventStreamArgs({ agentsDir = "./agents", collectionId = "" } = {}) {
|
|
37303
|
+
const args = [
|
|
37187
37304
|
"cloud",
|
|
37188
37305
|
"local",
|
|
37189
37306
|
"serve",
|
|
37190
37307
|
"--agents-dir",
|
|
37191
37308
|
agentsDir || "./agents",
|
|
37192
37309
|
"--event-stream"
|
|
37193
|
-
]
|
|
37194
|
-
|
|
37195
|
-
|
|
37196
|
-
|
|
37197
|
-
|
|
37198
|
-
|
|
37310
|
+
];
|
|
37311
|
+
if (collectionId) {
|
|
37312
|
+
args.push("--collection-id", collectionId);
|
|
37313
|
+
}
|
|
37314
|
+
return args;
|
|
37315
|
+
}
|
|
37316
|
+
|
|
37317
|
+
// src/workspaces.js
|
|
37318
|
+
async function listCloudWorkspaces({
|
|
37319
|
+
env: env3 = process.env,
|
|
37320
|
+
platform: platform2 = process.platform,
|
|
37321
|
+
prepareInvocation = preparePythonVendianInvocation,
|
|
37322
|
+
run: run2 = runCapture
|
|
37323
|
+
} = {}) {
|
|
37324
|
+
const invocation = await prepareInvocation(["cloud", "collections", "list", "--json"], { env: env3, platform: platform2 });
|
|
37325
|
+
const result = run2(invocation.command, invocation.args, { env: invocation.env });
|
|
37326
|
+
if (!result.ok) {
|
|
37327
|
+
return {
|
|
37328
|
+
ok: false,
|
|
37329
|
+
workspaces: [],
|
|
37330
|
+
error: (result.stderr || result.stdout || `workspace list exited with code ${result.status}`).trim()
|
|
37331
|
+
};
|
|
37332
|
+
}
|
|
37333
|
+
try {
|
|
37334
|
+
return { ok: true, workspaces: normalizeWorkspaceList(JSON.parse(result.stdout)), error: "" };
|
|
37335
|
+
} catch (error) {
|
|
37336
|
+
const message = error && typeof error.message === "string" ? error.message : String(error);
|
|
37337
|
+
return { ok: false, workspaces: [], error: `Could not parse workspace list: ${message}` };
|
|
37338
|
+
}
|
|
37199
37339
|
}
|
|
37340
|
+
function normalizeWorkspaceList(payload) {
|
|
37341
|
+
const data = payload && typeof payload === "object" && "data" in payload ? payload.data : payload;
|
|
37342
|
+
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 : [];
|
|
37343
|
+
return raw.filter((item) => item && typeof item === "object").map((item) => ({
|
|
37344
|
+
id: stringValue2(item.id),
|
|
37345
|
+
name: stringValue2(item.name || item.slug || item.id || "Unnamed workspace"),
|
|
37346
|
+
slug: stringValue2(item.slug)
|
|
37347
|
+
})).filter((item) => item.id);
|
|
37348
|
+
}
|
|
37349
|
+
function workspaceLabel(workspace) {
|
|
37350
|
+
const name = workspace?.name || workspace?.slug || workspace?.id || "Unnamed workspace";
|
|
37351
|
+
const slug = workspace?.slug && workspace.slug !== name ? ` (${workspace.slug})` : "";
|
|
37352
|
+
return `${name}${slug}`;
|
|
37353
|
+
}
|
|
37354
|
+
function stringValue2(value) {
|
|
37355
|
+
return value == null ? "" : String(value).trim();
|
|
37356
|
+
}
|
|
37357
|
+
|
|
37358
|
+
// src/ui/theme.js
|
|
37359
|
+
var colors = {
|
|
37360
|
+
brand: "cyan",
|
|
37361
|
+
brandBold: "cyanBright",
|
|
37362
|
+
success: "green",
|
|
37363
|
+
error: "red",
|
|
37364
|
+
warning: "yellow",
|
|
37365
|
+
muted: "gray",
|
|
37366
|
+
accent: "blueBright",
|
|
37367
|
+
text: "white",
|
|
37368
|
+
dim: "gray"
|
|
37369
|
+
};
|
|
37370
|
+
var spacing = {
|
|
37371
|
+
labelWidth: 14,
|
|
37372
|
+
indent: 2
|
|
37373
|
+
};
|
|
37374
|
+
|
|
37375
|
+
// src/ui/figures.js
|
|
37376
|
+
var supportsUnicode = process.platform !== "win32" || Boolean(
|
|
37377
|
+
process.env.WT_SESSION || // Windows Terminal
|
|
37378
|
+
process.env.TERM_PROGRAM === "vscode" || // VS Code terminal
|
|
37379
|
+
process.env.TERM === "xterm-256color" || process.env.ConEmuTask || process.env.TERMINAL_EMULATOR
|
|
37380
|
+
);
|
|
37381
|
+
var unicode = {
|
|
37382
|
+
dot: "\u25CF",
|
|
37383
|
+
dotEmpty: "\u25CB",
|
|
37384
|
+
check: "\u2714",
|
|
37385
|
+
cross: "\u2716",
|
|
37386
|
+
warning: "\u26A0",
|
|
37387
|
+
arrow: "\u25B6",
|
|
37388
|
+
arrowRight: "\u203A",
|
|
37389
|
+
arrowUp: "\u25B2",
|
|
37390
|
+
dash: "\u2500",
|
|
37391
|
+
ellipsis: "\u2026",
|
|
37392
|
+
topLeft: "\u256D",
|
|
37393
|
+
topRight: "\u256E",
|
|
37394
|
+
bottomLeft: "\u2570",
|
|
37395
|
+
bottomRight: "\u256F",
|
|
37396
|
+
horizontal: "\u2500",
|
|
37397
|
+
vertical: "\u2502",
|
|
37398
|
+
teeRight: "\u251C",
|
|
37399
|
+
teeLeft: "\u2524",
|
|
37400
|
+
teeDown: "\u252C",
|
|
37401
|
+
teeUp: "\u2534",
|
|
37402
|
+
cross_join: "\u253C",
|
|
37403
|
+
bar: "\u2588",
|
|
37404
|
+
barEmpty: "\u2591"
|
|
37405
|
+
};
|
|
37406
|
+
var ascii = {
|
|
37407
|
+
dot: "*",
|
|
37408
|
+
dotEmpty: "o",
|
|
37409
|
+
check: "+",
|
|
37410
|
+
cross: "x",
|
|
37411
|
+
warning: "!",
|
|
37412
|
+
arrow: ">",
|
|
37413
|
+
arrowRight: ">",
|
|
37414
|
+
arrowUp: "^",
|
|
37415
|
+
dash: "-",
|
|
37416
|
+
ellipsis: "...",
|
|
37417
|
+
topLeft: "+",
|
|
37418
|
+
topRight: "+",
|
|
37419
|
+
bottomLeft: "+",
|
|
37420
|
+
bottomRight: "+",
|
|
37421
|
+
horizontal: "-",
|
|
37422
|
+
vertical: "|",
|
|
37423
|
+
teeRight: "+",
|
|
37424
|
+
teeLeft: "+",
|
|
37425
|
+
teeDown: "+",
|
|
37426
|
+
teeUp: "+",
|
|
37427
|
+
cross_join: "+",
|
|
37428
|
+
bar: "#",
|
|
37429
|
+
barEmpty: "."
|
|
37430
|
+
};
|
|
37431
|
+
var fig = supportsUnicode ? unicode : ascii;
|
|
37200
37432
|
|
|
37201
37433
|
// src/tui.js
|
|
37202
37434
|
var h;
|
|
37203
37435
|
var useEffect6;
|
|
37436
|
+
var useRef2;
|
|
37204
37437
|
var useState5;
|
|
37205
37438
|
var Box2;
|
|
37206
37439
|
var Text2;
|
|
@@ -37217,15 +37450,25 @@ var ENDPOINTS = [
|
|
|
37217
37450
|
{ key: "prod", label: "Production" }
|
|
37218
37451
|
];
|
|
37219
37452
|
var ACTIONS = [
|
|
37220
|
-
{ value: "connect", label: "Connect Endpoint" },
|
|
37221
|
-
{ value: "init", label: "Initialize Docs" },
|
|
37222
|
-
{ value: "create", label: "Create Agent" },
|
|
37223
|
-
{ value: "serve", label: "Serve Agents" },
|
|
37224
|
-
{ value: "doctor", label: "Doctor" },
|
|
37225
|
-
{ value: "update", label: "Update" },
|
|
37226
|
-
{ value: "commands", label: "Commands" },
|
|
37227
|
-
{ value: "exit", label: "Exit" }
|
|
37453
|
+
{ value: "connect", label: "Connect Endpoint", desc: "Switch between environments" },
|
|
37454
|
+
{ value: "init", label: "Initialize Docs", desc: "Set up SDK documentation workspace" },
|
|
37455
|
+
{ value: "create", label: "Create Agent", desc: "Scaffold a new agent from templates" },
|
|
37456
|
+
{ value: "serve", label: "Serve Agents", desc: "Start local development server" },
|
|
37457
|
+
{ value: "doctor", label: "Doctor", desc: "Check system health" },
|
|
37458
|
+
{ value: "update", label: "Update", desc: "Update runtime & packages" },
|
|
37459
|
+
{ value: "commands", label: "Commands", desc: "Show CLI command reference" },
|
|
37460
|
+
{ value: "exit", label: "Exit", desc: "Close interactive shell" }
|
|
37228
37461
|
];
|
|
37462
|
+
var SCREEN_TITLES = {
|
|
37463
|
+
home: "Home",
|
|
37464
|
+
connect: "Connect Endpoint",
|
|
37465
|
+
init: "Initialize Docs",
|
|
37466
|
+
create: "Create Agent",
|
|
37467
|
+
serve: "Serve Agents",
|
|
37468
|
+
doctor: "Doctor",
|
|
37469
|
+
update: "Update",
|
|
37470
|
+
commands: "Commands"
|
|
37471
|
+
};
|
|
37229
37472
|
var COMMANDS = [
|
|
37230
37473
|
"vendian login",
|
|
37231
37474
|
"vendian init --output-dir ./agents",
|
|
@@ -37245,6 +37488,7 @@ async function runTui({ env: env3 = process.env, platform: platform2 = process.p
|
|
|
37245
37488
|
`);
|
|
37246
37489
|
return;
|
|
37247
37490
|
}
|
|
37491
|
+
await refreshInteractiveManagedRuntime({ env: env3, platform: platform2, output });
|
|
37248
37492
|
await loadInkRuntime();
|
|
37249
37493
|
const app = renderInk(h(VendianShell, { env: env3, platform: platform2, input, output }), {
|
|
37250
37494
|
stdin: input,
|
|
@@ -37253,6 +37497,25 @@ async function runTui({ env: env3 = process.env, platform: platform2 = process.p
|
|
|
37253
37497
|
});
|
|
37254
37498
|
await app.waitUntilExit();
|
|
37255
37499
|
}
|
|
37500
|
+
async function refreshInteractiveManagedRuntime({
|
|
37501
|
+
env: env3 = process.env,
|
|
37502
|
+
platform: platform2 = process.platform,
|
|
37503
|
+
output = process.stderr,
|
|
37504
|
+
refreshPackageAccess = refreshPackageAccessFromCloudAuth,
|
|
37505
|
+
autoUpdate = maybeAutoUpdateManagedEnv
|
|
37506
|
+
} = {}) {
|
|
37507
|
+
if (env3.VENDIAN_SKIP_AUTO_UPDATE === "1") {
|
|
37508
|
+
return false;
|
|
37509
|
+
}
|
|
37510
|
+
try {
|
|
37511
|
+
await refreshPackageAccess({ env: env3, platform: platform2 });
|
|
37512
|
+
} catch (error) {
|
|
37513
|
+
const message = errorMessage2(error);
|
|
37514
|
+
output.write(`[vendian] Package access refresh failed; continuing with installed runtime. ${message}
|
|
37515
|
+
`);
|
|
37516
|
+
}
|
|
37517
|
+
return autoUpdate({ env: env3, platform: platform2, force: true });
|
|
37518
|
+
}
|
|
37256
37519
|
async function loadInkRuntime() {
|
|
37257
37520
|
if (h) {
|
|
37258
37521
|
return;
|
|
@@ -37266,6 +37529,7 @@ async function loadInkRuntime() {
|
|
|
37266
37529
|
]);
|
|
37267
37530
|
h = reactModule.default.createElement;
|
|
37268
37531
|
useEffect6 = reactModule.useEffect;
|
|
37532
|
+
useRef2 = reactModule.useRef;
|
|
37269
37533
|
useState5 = reactModule.useState;
|
|
37270
37534
|
Box2 = inkModule.Box;
|
|
37271
37535
|
Text2 = inkModule.Text;
|
|
@@ -37276,6 +37540,20 @@ async function loadInkRuntime() {
|
|
|
37276
37540
|
TextInput2 = textInputModule.default;
|
|
37277
37541
|
Spinner2 = spinnerModule.default;
|
|
37278
37542
|
}
|
|
37543
|
+
function endpointRows({ env: env3 = process.env, platform: platform2 = process.platform } = {}) {
|
|
37544
|
+
return ENDPOINTS.map((endpoint) => {
|
|
37545
|
+
const status = cloudAuthStatus({ backend: endpoint.key, env: env3, platform: platform2 });
|
|
37546
|
+
const active = status.activeApiUrl === status.apiUrl;
|
|
37547
|
+
return {
|
|
37548
|
+
key: endpoint.key,
|
|
37549
|
+
label: endpoint.label,
|
|
37550
|
+
apiUrl: status.apiUrl,
|
|
37551
|
+
active,
|
|
37552
|
+
status: status.authenticated ? active ? "connected" : "signed in" : "not signed in",
|
|
37553
|
+
detail: status.authenticated ? status.email || status.apiUrl : status.apiUrl
|
|
37554
|
+
};
|
|
37555
|
+
});
|
|
37556
|
+
}
|
|
37279
37557
|
function runtimeSummary({ env: env3 = process.env, platform: platform2 = process.platform, now = Date.now() } = {}) {
|
|
37280
37558
|
const config = loadConfig(env3, platform2);
|
|
37281
37559
|
const venvPath = managedVenvPath(env3, platform2);
|
|
@@ -37296,37 +37574,92 @@ function packageAccessSummary({ env: env3 = process.env, platform: platform2 = p
|
|
|
37296
37574
|
source: registry.tokenSource || "local config"
|
|
37297
37575
|
};
|
|
37298
37576
|
}
|
|
37577
|
+
function isCtrlCInput(input = "", key = {}) {
|
|
37578
|
+
return input === "" || input === "" || Boolean(key?.ctrl && (key.name === "c" || input === "c"));
|
|
37579
|
+
}
|
|
37299
37580
|
function VendianShell({ env: env3, platform: platform2, input, output }) {
|
|
37300
37581
|
const app = useApp2();
|
|
37301
37582
|
const [screen, setScreen] = useState5("home");
|
|
37302
37583
|
const [serveState, setServeState] = useState5(null);
|
|
37303
|
-
|
|
37304
|
-
|
|
37584
|
+
const [exitArmed, setExitArmed] = useState5(false);
|
|
37585
|
+
const exitTimer = useRef2(null);
|
|
37586
|
+
const lastInterruptAt = useRef2(0);
|
|
37587
|
+
function armExit() {
|
|
37588
|
+
if (exitArmed) {
|
|
37305
37589
|
app.exit();
|
|
37590
|
+
return;
|
|
37591
|
+
}
|
|
37592
|
+
setExitArmed(true);
|
|
37593
|
+
if (exitTimer.current) {
|
|
37594
|
+
clearTimeout(exitTimer.current);
|
|
37595
|
+
}
|
|
37596
|
+
exitTimer.current = setTimeout(() => setExitArmed(false), 1500);
|
|
37597
|
+
}
|
|
37598
|
+
function handleInterrupt() {
|
|
37599
|
+
const now = Date.now();
|
|
37600
|
+
if (now - lastInterruptAt.current < 75) {
|
|
37601
|
+
return;
|
|
37602
|
+
}
|
|
37603
|
+
lastInterruptAt.current = now;
|
|
37604
|
+
if (screen === "serve") {
|
|
37605
|
+
return;
|
|
37606
|
+
}
|
|
37607
|
+
armExit();
|
|
37608
|
+
}
|
|
37609
|
+
useEffect6(() => () => {
|
|
37610
|
+
if (exitTimer.current) {
|
|
37611
|
+
clearTimeout(exitTimer.current);
|
|
37612
|
+
}
|
|
37613
|
+
}, []);
|
|
37614
|
+
useEffect6(() => {
|
|
37615
|
+
const onData = (chunk) => {
|
|
37616
|
+
if (isCtrlCInput(String(chunk || ""))) {
|
|
37617
|
+
handleInterrupt();
|
|
37618
|
+
}
|
|
37619
|
+
};
|
|
37620
|
+
input?.on?.("data", onData);
|
|
37621
|
+
process.on("SIGINT", handleInterrupt);
|
|
37622
|
+
return () => {
|
|
37623
|
+
input?.off?.("data", onData);
|
|
37624
|
+
process.off("SIGINT", handleInterrupt);
|
|
37625
|
+
};
|
|
37626
|
+
}, [input, screen, exitArmed]);
|
|
37627
|
+
useInput2((typedInput, key) => {
|
|
37628
|
+
if (isCtrlCInput(typedInput, key)) {
|
|
37629
|
+
handleInterrupt();
|
|
37306
37630
|
}
|
|
37307
37631
|
});
|
|
37308
37632
|
const goHome = () => setScreen("home");
|
|
37633
|
+
const breadcrumb = screen !== "home" ? ["Home", SCREEN_TITLES[screen] || screen] : ["Home"];
|
|
37309
37634
|
return h(
|
|
37310
37635
|
Box2,
|
|
37311
37636
|
{ flexDirection: "column" },
|
|
37312
|
-
h(Header, { env: env3, platform: platform2, serveState }),
|
|
37637
|
+
h(Header, { env: env3, platform: platform2, serveState, screen }),
|
|
37638
|
+
h(
|
|
37639
|
+
Text2,
|
|
37640
|
+
{ color: colors.muted },
|
|
37641
|
+
breadcrumb.map(
|
|
37642
|
+
(part, i) => i < breadcrumb.length - 1 ? `${part} ${fig.arrowRight} ` : part
|
|
37643
|
+
).join("")
|
|
37644
|
+
),
|
|
37645
|
+
h(Text2, null, ""),
|
|
37313
37646
|
screen === "home" && h(HomeScreen, { onSelect: (value) => value === "exit" ? app.exit() : setScreen(value) }),
|
|
37314
37647
|
screen === "connect" && h(ConnectScreen, { env: env3, platform: platform2, onBack: goHome }),
|
|
37315
37648
|
screen === "init" && h(InitScreen, { env: env3, platform: platform2, onBack: goHome }),
|
|
37316
37649
|
screen === "create" && h(CreateScreen, { env: env3, platform: platform2, onBack: goHome }),
|
|
37317
|
-
screen === "serve" && h(ServeScreen, { env: env3, platform: platform2, input, output, onBack: goHome, onState: setServeState }),
|
|
37650
|
+
screen === "serve" && h(ServeScreen, { env: env3, platform: platform2, input, output, onBack: goHome, onState: setServeState, onExitApp: app.exit }),
|
|
37318
37651
|
screen === "doctor" && h(DoctorScreen, { env: env3, platform: platform2, onBack: goHome }),
|
|
37319
37652
|
screen === "update" && h(UpdateScreen, { env: env3, platform: platform2, onBack: goHome }),
|
|
37320
|
-
screen === "commands" && h(CommandsScreen, { onBack: goHome })
|
|
37653
|
+
screen === "commands" && h(CommandsScreen, { onBack: goHome }),
|
|
37654
|
+
exitArmed && screen !== "serve" && h(Text2, { color: colors.warning, bold: true }, " Press Ctrl+C again to exit.")
|
|
37321
37655
|
);
|
|
37322
37656
|
}
|
|
37323
|
-
function Header({ env: env3, platform: platform2, serveState }) {
|
|
37657
|
+
function Header({ env: env3, platform: platform2, serveState, screen }) {
|
|
37324
37658
|
const active = activeCloudAuthStatus({ env: env3, platform: platform2 });
|
|
37325
37659
|
const runtime = runtimeSummary({ env: env3, platform: platform2 });
|
|
37326
37660
|
const [npmUpdate, setNpmUpdate] = useState5(() => npmPackageUpdateSummary({ config: loadConfig(env3, platform2) }));
|
|
37327
37661
|
const [npmCheckStarted, setNpmCheckStarted] = useState5(false);
|
|
37328
37662
|
const pkg = packageAccessSummary({ env: env3, platform: platform2 });
|
|
37329
|
-
const daemon = serveState?.daemonId ? `Daemon ${serveState.daemonId} | ${serveState.activity}` : "Daemon idle";
|
|
37330
37663
|
useEffect6(() => {
|
|
37331
37664
|
let cancelled = false;
|
|
37332
37665
|
if (!npmUpdate.stale || npmCheckStarted) {
|
|
@@ -37342,29 +37675,111 @@ function Header({ env: env3, platform: platform2, serveState }) {
|
|
|
37342
37675
|
cancelled = true;
|
|
37343
37676
|
};
|
|
37344
37677
|
}, [env3, platform2, npmCheckStarted, npmUpdate.stale]);
|
|
37678
|
+
const connStatus = active.authenticated ? "ok" : "error";
|
|
37679
|
+
const connValue = active.authenticated ? `${active.email || "Authenticated"} ${fig.dash} ${active.apiUrl}` : "Not connected \u2014 run vendian login";
|
|
37680
|
+
const rtStatus = runtime.installed ? "ok" : "error";
|
|
37681
|
+
const rtValue = runtime.installed ? "Ready" : "Missing \u2014 run vendian login";
|
|
37682
|
+
const pkgStatus = pkg.configured ? "ok" : "warning";
|
|
37683
|
+
const pkgValue = pkg.configured ? `Configured (${pkg.source})` : "Missing";
|
|
37684
|
+
const updValue = updateLabel({ runtime, npmUpdate });
|
|
37685
|
+
const updStatus = updValue.includes("available") ? "warning" : "ok";
|
|
37686
|
+
const w = Math.min(process.stdout.columns || 80, 90);
|
|
37687
|
+
const inner = w - 2;
|
|
37688
|
+
const titleLeft = `${fig.vertical} ${fig.arrowUp} VENDIAN`;
|
|
37689
|
+
const titleRight = `v${CLI_VERSION} ${fig.vertical}`;
|
|
37690
|
+
const titlePad = Math.max(0, inner - titleLeft.length - titleRight.length + 2);
|
|
37345
37691
|
return h(
|
|
37346
37692
|
Box2,
|
|
37347
37693
|
{ flexDirection: "column", marginBottom: 1 },
|
|
37348
|
-
h(Text2, {
|
|
37349
|
-
h(
|
|
37350
|
-
|
|
37351
|
-
|
|
37694
|
+
h(Text2, { color: colors.muted }, `${fig.topLeft}${fig.horizontal.repeat(inner)}${fig.topRight}`),
|
|
37695
|
+
h(
|
|
37696
|
+
Text2,
|
|
37697
|
+
null,
|
|
37698
|
+
h(Text2, { color: colors.muted }, fig.vertical),
|
|
37699
|
+
h(Text2, { bold: true, color: colors.brand }, ` ${fig.arrowUp} VENDIAN`),
|
|
37700
|
+
h(Text2, null, " ".repeat(titlePad)),
|
|
37701
|
+
h(Text2, { color: colors.muted }, `v${CLI_VERSION} `),
|
|
37702
|
+
h(Text2, { color: colors.muted }, fig.vertical)
|
|
37703
|
+
),
|
|
37704
|
+
h(Text2, { color: colors.muted }, `${fig.teeRight}${fig.horizontal.repeat(inner)}${fig.teeLeft}`),
|
|
37705
|
+
h(StatusRow, { status: connStatus, label: "Endpoint", value: connValue, width: inner }),
|
|
37706
|
+
h(StatusRow, { status: rtStatus, label: "Runtime", value: rtValue, width: inner }),
|
|
37707
|
+
h(StatusRow, { status: pkgStatus, label: "Packages", value: pkgValue, width: inner }),
|
|
37708
|
+
h(StatusRow, { status: updStatus, label: "Updates", value: updValue, width: inner }),
|
|
37709
|
+
serveState?.daemonId && h(StatusRow, {
|
|
37710
|
+
status: serveState.connected ? "ok" : "warning",
|
|
37711
|
+
label: "Daemon",
|
|
37712
|
+
value: serveState.activity || "Running",
|
|
37713
|
+
width: inner
|
|
37714
|
+
}),
|
|
37715
|
+
h(Text2, { color: colors.muted }, `${fig.bottomLeft}${fig.horizontal.repeat(inner)}${fig.bottomRight}`)
|
|
37716
|
+
);
|
|
37717
|
+
}
|
|
37718
|
+
function StatusRow({ status, label, value, width }) {
|
|
37719
|
+
const dotColor = status === "ok" ? colors.success : status === "warning" ? colors.warning : colors.error;
|
|
37720
|
+
const dot = status === "ok" ? fig.dot : status === "warning" ? fig.dot : fig.dot;
|
|
37721
|
+
const paddedLabel = String(label).padEnd(spacing.labelWidth);
|
|
37722
|
+
const maxVal = Math.max(0, (width || 70) - spacing.labelWidth - 6);
|
|
37723
|
+
const clipped = clip(value || "", maxVal);
|
|
37724
|
+
return h(
|
|
37725
|
+
Text2,
|
|
37726
|
+
null,
|
|
37727
|
+
h(Text2, { color: colors.muted }, `${fig.vertical} `),
|
|
37728
|
+
h(Text2, { color: dotColor }, `${dot} `),
|
|
37729
|
+
h(Text2, { bold: true }, paddedLabel),
|
|
37730
|
+
h(Text2, null, clipped),
|
|
37731
|
+
h(Text2, { color: colors.muted }, ` ${fig.vertical}`)
|
|
37352
37732
|
);
|
|
37353
37733
|
}
|
|
37354
37734
|
function HomeScreen({ onSelect }) {
|
|
37735
|
+
const [activeIndex, setActiveIndex] = useState5(0);
|
|
37736
|
+
useInput2((input, key) => {
|
|
37737
|
+
if (key.upArrow) {
|
|
37738
|
+
setActiveIndex((i) => (i - 1 + ACTIONS.length) % ACTIONS.length);
|
|
37739
|
+
} else if (key.downArrow) {
|
|
37740
|
+
setActiveIndex((i) => (i + 1) % ACTIONS.length);
|
|
37741
|
+
} else if (key.return) {
|
|
37742
|
+
onSelect(ACTIONS[activeIndex].value);
|
|
37743
|
+
}
|
|
37744
|
+
});
|
|
37355
37745
|
return h(
|
|
37356
37746
|
Box2,
|
|
37357
37747
|
{ flexDirection: "column" },
|
|
37358
|
-
|
|
37359
|
-
|
|
37748
|
+
...ACTIONS.map((action, i) => {
|
|
37749
|
+
const isActive = i === activeIndex;
|
|
37750
|
+
const isSeparator = action.value === "doctor";
|
|
37751
|
+
return h(
|
|
37752
|
+
Box2,
|
|
37753
|
+
{ key: action.value, flexDirection: "column" },
|
|
37754
|
+
isSeparator && h(Text2, { color: colors.muted }, ` ${fig.horizontal.repeat(40)}`),
|
|
37755
|
+
h(
|
|
37756
|
+
Text2,
|
|
37757
|
+
null,
|
|
37758
|
+
h(Text2, { color: isActive ? colors.accent : colors.muted }, isActive ? ` ${fig.arrow} ` : " "),
|
|
37759
|
+
h(Text2, { bold: isActive, color: isActive ? colors.text : colors.muted }, action.label.padEnd(22)),
|
|
37760
|
+
h(Text2, { color: colors.dim }, action.desc)
|
|
37761
|
+
)
|
|
37762
|
+
);
|
|
37763
|
+
}),
|
|
37764
|
+
h(Text2, null, ""),
|
|
37765
|
+
h(FooterBar, { items: [
|
|
37766
|
+
{ key: "\u2191\u2193", label: "Navigate" },
|
|
37767
|
+
{ key: "\u23CE", label: "Select" },
|
|
37768
|
+
{ key: "^c ^c", label: "Exit" }
|
|
37769
|
+
] })
|
|
37360
37770
|
);
|
|
37361
37771
|
}
|
|
37362
37772
|
function ConnectScreen({ env: env3, platform: platform2, onBack }) {
|
|
37363
37773
|
const [mode, setMode] = useState5("select");
|
|
37364
37774
|
const [apiUrl, setApiUrl] = useState5("");
|
|
37365
37775
|
const [status, setStatus] = useState5("");
|
|
37776
|
+
const rows = endpointRows({ env: env3, platform: platform2 });
|
|
37366
37777
|
const items = [
|
|
37367
|
-
...ENDPOINTS.map((endpoint) =>
|
|
37778
|
+
...ENDPOINTS.map((endpoint) => {
|
|
37779
|
+
const row = rows.find((r) => r.key === endpoint.key);
|
|
37780
|
+
const statusLabel = row ? row.active ? "\u25CF Connected" : row.status : "";
|
|
37781
|
+
return { label: `${endpoint.label.padEnd(12)} ${BACKEND_TARGETS[endpoint.key]} ${statusLabel}`, value: endpoint.key };
|
|
37782
|
+
}),
|
|
37368
37783
|
{ label: "Custom API URL", value: "custom" },
|
|
37369
37784
|
{ label: "Back", value: "back" }
|
|
37370
37785
|
];
|
|
@@ -37377,41 +37792,47 @@ function ConnectScreen({ env: env3, platform: platform2, onBack }) {
|
|
|
37377
37792
|
setMode("custom");
|
|
37378
37793
|
return;
|
|
37379
37794
|
}
|
|
37380
|
-
setStatus(`Connecting ${value}
|
|
37795
|
+
setStatus(`Connecting to ${value}...`);
|
|
37381
37796
|
await setup({ backend: value, forceAuth: true, env: env3, platform: platform2 });
|
|
37382
|
-
setStatus(
|
|
37797
|
+
setStatus(`${fig.check} Connected`);
|
|
37383
37798
|
}
|
|
37384
37799
|
if (mode === "custom") {
|
|
37385
37800
|
return h(
|
|
37386
37801
|
Box2,
|
|
37387
37802
|
{ flexDirection: "column" },
|
|
37388
|
-
h(Text2, { bold: true }, "
|
|
37803
|
+
h(Text2, { bold: true }, " Enter custom API URL:"),
|
|
37804
|
+
h(Text2, null, ""),
|
|
37389
37805
|
h(TextInput2, {
|
|
37390
37806
|
value: apiUrl,
|
|
37391
37807
|
placeholder: "https://api.example.test",
|
|
37392
37808
|
onChange: setApiUrl,
|
|
37393
37809
|
onSubmit: async (value) => {
|
|
37394
37810
|
if (!value) return;
|
|
37395
|
-
setStatus("Connecting
|
|
37811
|
+
setStatus("Connecting...");
|
|
37396
37812
|
await setup({ apiUrl: value, forceAuth: true, env: env3, platform: platform2 });
|
|
37397
|
-
setStatus(
|
|
37813
|
+
setStatus(`${fig.check} Connected`);
|
|
37398
37814
|
}
|
|
37399
37815
|
}),
|
|
37400
|
-
h(Text2,
|
|
37816
|
+
status && h(Text2, { color: status.includes(fig.check) ? colors.success : colors.muted }, ` ${status}`),
|
|
37817
|
+
h(Text2, null, ""),
|
|
37818
|
+
h(FooterBar, { items: [{ key: "\u23CE", label: "Submit" }, { key: "esc", label: "Back" }] }),
|
|
37401
37819
|
h(BackHint, { onBack })
|
|
37402
37820
|
);
|
|
37403
37821
|
}
|
|
37404
37822
|
return h(
|
|
37405
37823
|
Box2,
|
|
37406
37824
|
{ flexDirection: "column" },
|
|
37407
|
-
h(Text2, { bold: true }, "
|
|
37825
|
+
h(Text2, { bold: true }, " Select environment:"),
|
|
37826
|
+
h(Text2, null, ""),
|
|
37408
37827
|
h(SelectInput2, { items, onSelect: (item) => connect(item.value) }),
|
|
37409
|
-
status && h(Text2,
|
|
37828
|
+
status && h(Text2, { color: status.includes(fig.check) ? colors.success : colors.muted }, ` ${status}`),
|
|
37829
|
+
h(Text2, null, ""),
|
|
37830
|
+
h(FooterBar, { items: [{ key: "\u2191\u2193", label: "Navigate" }, { key: "\u23CE", label: "Select" }, { key: "esc", label: "Back" }] })
|
|
37410
37831
|
);
|
|
37411
37832
|
}
|
|
37412
37833
|
function InitScreen({ env: env3, platform: platform2, onBack }) {
|
|
37413
37834
|
return h(CommandPromptScreen, {
|
|
37414
|
-
title: "Initialize Docs",
|
|
37835
|
+
title: " Initialize Docs",
|
|
37415
37836
|
label: "Workspace directory",
|
|
37416
37837
|
initialValue: ".",
|
|
37417
37838
|
onBack,
|
|
@@ -37451,53 +37872,165 @@ function CreateScreen({ env: env3, platform: platform2, onBack }) {
|
|
|
37451
37872
|
h(BackHint, { onBack })
|
|
37452
37873
|
);
|
|
37453
37874
|
}
|
|
37454
|
-
function ServeScreen({ env: env3, platform: platform2, onBack, onState }) {
|
|
37875
|
+
function ServeScreen({ env: env3, platform: platform2, input, onBack, onState, onExitApp }) {
|
|
37455
37876
|
const [agentDirCandidates] = useState5(() => findAgentDirectoryCandidates());
|
|
37456
37877
|
const [agentsDir, setAgentsDir] = useState5(() => defaultAgentsDir(agentDirCandidates));
|
|
37457
37878
|
const [selectingDir, setSelectingDir] = useState5(() => agentDirCandidates.length > 0);
|
|
37879
|
+
const [workspaceChoices, setWorkspaceChoices] = useState5([]);
|
|
37880
|
+
const [pendingAgentsDir, setPendingAgentsDir] = useState5("");
|
|
37881
|
+
const [loadingWorkspaces, setLoadingWorkspaces] = useState5(false);
|
|
37458
37882
|
const [started, setStarted] = useState5(false);
|
|
37459
37883
|
const [state, setState] = useState5(initialServeState());
|
|
37460
37884
|
const [child, setChild] = useState5(null);
|
|
37461
|
-
const [
|
|
37885
|
+
const [logMode, setLogMode] = useState5(null);
|
|
37462
37886
|
const [confirmExit, setConfirmExit] = useState5(false);
|
|
37887
|
+
const [exitArmed, setExitArmed] = useState5(false);
|
|
37463
37888
|
const [startupError, setStartupError] = useState5("");
|
|
37889
|
+
const exitTimer = useRef2(null);
|
|
37890
|
+
const lastInterruptAt = useRef2(0);
|
|
37464
37891
|
useEffect6(() => {
|
|
37465
37892
|
onState(state);
|
|
37466
37893
|
}, [state, onState]);
|
|
37467
|
-
|
|
37894
|
+
useEffect6(() => () => {
|
|
37895
|
+
if (exitTimer.current) {
|
|
37896
|
+
clearTimeout(exitTimer.current);
|
|
37897
|
+
}
|
|
37898
|
+
}, []);
|
|
37899
|
+
function armExit() {
|
|
37900
|
+
if (exitArmed) {
|
|
37901
|
+
child?.kill("SIGINT");
|
|
37902
|
+
onState(null);
|
|
37903
|
+
onExitApp();
|
|
37904
|
+
return;
|
|
37905
|
+
}
|
|
37906
|
+
setExitArmed(true);
|
|
37907
|
+
setConfirmExit(false);
|
|
37908
|
+
if (exitTimer.current) {
|
|
37909
|
+
clearTimeout(exitTimer.current);
|
|
37910
|
+
}
|
|
37911
|
+
exitTimer.current = setTimeout(() => setExitArmed(false), 1500);
|
|
37912
|
+
}
|
|
37913
|
+
function handleInterrupt() {
|
|
37914
|
+
const now = Date.now();
|
|
37915
|
+
if (now - lastInterruptAt.current < 75) {
|
|
37916
|
+
return;
|
|
37917
|
+
}
|
|
37918
|
+
lastInterruptAt.current = now;
|
|
37919
|
+
armExit();
|
|
37920
|
+
}
|
|
37921
|
+
useEffect6(() => {
|
|
37922
|
+
const onData = (chunk) => {
|
|
37923
|
+
if (isCtrlCInput(String(chunk || ""))) {
|
|
37924
|
+
handleInterrupt();
|
|
37925
|
+
}
|
|
37926
|
+
};
|
|
37927
|
+
input?.on?.("data", onData);
|
|
37928
|
+
process.on("SIGINT", handleInterrupt);
|
|
37929
|
+
return () => {
|
|
37930
|
+
input?.off?.("data", onData);
|
|
37931
|
+
process.off("SIGINT", handleInterrupt);
|
|
37932
|
+
};
|
|
37933
|
+
}, [input, exitArmed, child]);
|
|
37934
|
+
useInput2((input2, key) => {
|
|
37935
|
+
if (isCtrlCInput(input2, key)) {
|
|
37936
|
+
handleInterrupt();
|
|
37937
|
+
return;
|
|
37938
|
+
}
|
|
37468
37939
|
if (!started) return;
|
|
37940
|
+
if (logMode !== null) {
|
|
37941
|
+
if (key.escape) {
|
|
37942
|
+
if (logMode === "picker") {
|
|
37943
|
+
setLogMode(null);
|
|
37944
|
+
} else {
|
|
37945
|
+
setLogMode("picker");
|
|
37946
|
+
}
|
|
37947
|
+
}
|
|
37948
|
+
return;
|
|
37949
|
+
}
|
|
37469
37950
|
if (confirmExit) {
|
|
37470
|
-
if (
|
|
37951
|
+
if (input2.toLowerCase() === "y" || key.return) {
|
|
37471
37952
|
child?.kill("SIGINT");
|
|
37472
37953
|
onState(null);
|
|
37473
37954
|
onBack();
|
|
37474
|
-
} else if (
|
|
37955
|
+
} else if (input2.toLowerCase() === "n" || key.escape) {
|
|
37475
37956
|
setConfirmExit(false);
|
|
37476
37957
|
}
|
|
37477
37958
|
return;
|
|
37478
37959
|
}
|
|
37479
|
-
if (
|
|
37480
|
-
|
|
37481
|
-
} else if (
|
|
37960
|
+
if (input2 === "l") {
|
|
37961
|
+
setLogMode("picker");
|
|
37962
|
+
} else if (input2 === "q") {
|
|
37482
37963
|
setConfirmExit(true);
|
|
37483
37964
|
}
|
|
37484
37965
|
});
|
|
37485
|
-
async function start(selectedAgentsDir = agentsDir) {
|
|
37966
|
+
async function start(selectedAgentsDir = agentsDir, collectionId = "") {
|
|
37486
37967
|
const serveRoot = selectedAgentsDir || "./agents";
|
|
37487
37968
|
setAgentsDir(serveRoot);
|
|
37488
37969
|
setStarted(true);
|
|
37489
37970
|
setStartupError("");
|
|
37490
37971
|
try {
|
|
37491
|
-
const nextChild = await spawnLocalServeEventStream({ agentsDir: serveRoot, env: env3, platform: platform2 });
|
|
37972
|
+
const nextChild = await spawnLocalServeEventStream({ agentsDir: serveRoot, collectionId, env: env3, platform: platform2 });
|
|
37492
37973
|
setChild(nextChild);
|
|
37493
|
-
attachServeChild(nextChild, setState, setStartupError, () => {
|
|
37494
|
-
setState((current) => current.stopped ? current : { ...current, stopped: true, activity: "Process exited" });
|
|
37974
|
+
attachServeChild(nextChild, setState, setStartupError, ({ message } = {}) => {
|
|
37975
|
+
setState((current) => current.stopped ? current : { ...current, stopped: true, activity: message ? "Runtime update required" : "Process exited" });
|
|
37495
37976
|
});
|
|
37496
37977
|
} catch (error) {
|
|
37497
37978
|
setStartupError(errorMessage2(error));
|
|
37498
37979
|
}
|
|
37499
37980
|
}
|
|
37981
|
+
async function chooseWorkspaceThenStart(selectedAgentsDir = agentsDir) {
|
|
37982
|
+
const serveRoot = selectedAgentsDir || "./agents";
|
|
37983
|
+
setAgentsDir(serveRoot);
|
|
37984
|
+
setPendingAgentsDir(serveRoot);
|
|
37985
|
+
setStartupError("");
|
|
37986
|
+
setLoadingWorkspaces(true);
|
|
37987
|
+
try {
|
|
37988
|
+
const result = await listCloudWorkspaces({ env: env3, platform: platform2 });
|
|
37989
|
+
if (!result.ok) {
|
|
37990
|
+
setStartupError(result.error || "Could not list workspaces.");
|
|
37991
|
+
return;
|
|
37992
|
+
}
|
|
37993
|
+
if (result.workspaces.length > 1) {
|
|
37994
|
+
setWorkspaceChoices(result.workspaces);
|
|
37995
|
+
return;
|
|
37996
|
+
}
|
|
37997
|
+
await start(serveRoot, result.workspaces[0]?.id || "");
|
|
37998
|
+
} catch (error) {
|
|
37999
|
+
setStartupError(errorMessage2(error));
|
|
38000
|
+
} finally {
|
|
38001
|
+
setLoadingWorkspaces(false);
|
|
38002
|
+
}
|
|
38003
|
+
}
|
|
37500
38004
|
if (!started) {
|
|
38005
|
+
if (workspaceChoices.length > 1) {
|
|
38006
|
+
return h(
|
|
38007
|
+
Box2,
|
|
38008
|
+
{ flexDirection: "column" },
|
|
38009
|
+
h(Text2, { bold: true }, "Select workspace:"),
|
|
38010
|
+
h(SelectInput2, {
|
|
38011
|
+
items: [
|
|
38012
|
+
...workspaceChoices.map((workspace) => ({
|
|
38013
|
+
label: workspaceLabel(workspace),
|
|
38014
|
+
value: workspace.id
|
|
38015
|
+
})),
|
|
38016
|
+
{ label: "Back", value: "__back__" }
|
|
38017
|
+
],
|
|
38018
|
+
onSelect: (item) => {
|
|
38019
|
+
if (item.value === "__back__") {
|
|
38020
|
+
setWorkspaceChoices([]);
|
|
38021
|
+
return;
|
|
38022
|
+
}
|
|
38023
|
+
start(pendingAgentsDir || agentsDir, item.value);
|
|
38024
|
+
}
|
|
38025
|
+
}),
|
|
38026
|
+
h(Text2, null, ""),
|
|
38027
|
+
h(FooterBar, { items: [
|
|
38028
|
+
{ key: "\u2191\u2193", label: "Navigate" },
|
|
38029
|
+
{ key: "\u23CE", label: "Select" },
|
|
38030
|
+
{ key: "esc", label: "Back" }
|
|
38031
|
+
] })
|
|
38032
|
+
);
|
|
38033
|
+
}
|
|
37501
38034
|
const items = [
|
|
37502
38035
|
...agentDirCandidates.map((candidate) => ({
|
|
37503
38036
|
label: `${candidate.path} (${candidate.agentCount} ${candidate.agentCount === 1 ? "agent" : "agents"})`,
|
|
@@ -37509,7 +38042,7 @@ function ServeScreen({ env: env3, platform: platform2, onBack, onState }) {
|
|
|
37509
38042
|
return h(
|
|
37510
38043
|
Box2,
|
|
37511
38044
|
{ flexDirection: "column" },
|
|
37512
|
-
h(Text2, { bold: true }, "
|
|
38045
|
+
h(Text2, { bold: true }, "Select agent directory:"),
|
|
37513
38046
|
selectingDir && h(SelectInput2, {
|
|
37514
38047
|
items,
|
|
37515
38048
|
onSelect: (item) => {
|
|
@@ -37523,77 +38056,378 @@ function ServeScreen({ env: env3, platform: platform2, onBack, onState }) {
|
|
|
37523
38056
|
return;
|
|
37524
38057
|
}
|
|
37525
38058
|
setAgentsDir(item.value);
|
|
37526
|
-
|
|
38059
|
+
chooseWorkspaceThenStart(item.value);
|
|
37527
38060
|
}
|
|
37528
38061
|
}),
|
|
37529
38062
|
!selectingDir && h(TextInput2, {
|
|
37530
38063
|
value: agentsDir,
|
|
37531
38064
|
placeholder: "./agents",
|
|
37532
38065
|
onChange: setAgentsDir,
|
|
37533
|
-
onSubmit: (value) =>
|
|
38066
|
+
onSubmit: (value) => chooseWorkspaceThenStart(value)
|
|
37534
38067
|
}),
|
|
37535
|
-
h(
|
|
38068
|
+
loadingWorkspaces && h(
|
|
38069
|
+
Box2,
|
|
38070
|
+
null,
|
|
38071
|
+
h(Text2, { color: colors.brand }, " "),
|
|
38072
|
+
h(Spinner2, { type: "dots" }),
|
|
38073
|
+
h(Text2, { color: colors.brand }, " Loading workspaces")
|
|
38074
|
+
),
|
|
38075
|
+
startupError && h(Text2, { color: colors.error }, ` ${fig.cross} ${startupError}`),
|
|
38076
|
+
h(Text2, null, ""),
|
|
38077
|
+
h(FooterBar, { items: [
|
|
38078
|
+
{ key: "\u2191\u2193", label: "Navigate" },
|
|
38079
|
+
{ key: "\u23CE", label: "Select" },
|
|
38080
|
+
{ key: "esc", label: "Back" }
|
|
38081
|
+
] })
|
|
37536
38082
|
);
|
|
37537
38083
|
}
|
|
37538
38084
|
const summary = agentSummary(state.agents);
|
|
38085
|
+
if (logMode !== null) {
|
|
38086
|
+
return h(
|
|
38087
|
+
Box2,
|
|
38088
|
+
{ flexDirection: "column" },
|
|
38089
|
+
h(AgentLogViewer, {
|
|
38090
|
+
agents: state.agents,
|
|
38091
|
+
agentLogs: state.agentLogs,
|
|
38092
|
+
logMode,
|
|
38093
|
+
onSelectAgent: (path7) => setLogMode(path7),
|
|
38094
|
+
onBack: () => {
|
|
38095
|
+
if (logMode === "picker") {
|
|
38096
|
+
setLogMode(null);
|
|
38097
|
+
} else {
|
|
38098
|
+
setLogMode("picker");
|
|
38099
|
+
}
|
|
38100
|
+
}
|
|
38101
|
+
})
|
|
38102
|
+
);
|
|
38103
|
+
}
|
|
37539
38104
|
return h(
|
|
37540
38105
|
Box2,
|
|
37541
38106
|
{ flexDirection: "column" },
|
|
37542
|
-
h(Text2, {
|
|
37543
|
-
|
|
37544
|
-
|
|
38107
|
+
startupError ? h(Text2, { color: colors.error }, ` ${fig.cross} ${startupError}`) : h(
|
|
38108
|
+
Box2,
|
|
38109
|
+
null,
|
|
38110
|
+
h(Text2, { color: colors.brand }, " "),
|
|
38111
|
+
h(Spinner2, { type: "dots" }),
|
|
38112
|
+
h(Text2, { color: colors.brand }, ` ${state.activity}`)
|
|
38113
|
+
),
|
|
38114
|
+
h(Text2, null, ""),
|
|
38115
|
+
h(
|
|
38116
|
+
Text2,
|
|
38117
|
+
null,
|
|
38118
|
+
h(Text2, { color: colors.muted }, " Agents: "),
|
|
38119
|
+
h(Text2, { color: colors.success, bold: true }, `${summary.ready} ready`),
|
|
38120
|
+
summary.needsSetup > 0 && h(Text2, { color: colors.warning }, ` ${fig.dot} ${summary.needsSetup} needs setup`),
|
|
38121
|
+
summary.errors > 0 && h(Text2, { color: colors.error }, ` ${fig.dot} ${summary.errors} errors`),
|
|
38122
|
+
h(Text2, { color: colors.muted }, ` ${fig.dot} ${summary.total} total`)
|
|
38123
|
+
),
|
|
38124
|
+
h(Text2, null, ""),
|
|
38125
|
+
state.newAgents?.length > 0 && h(
|
|
38126
|
+
Text2,
|
|
38127
|
+
{ color: colors.success },
|
|
38128
|
+
` ${fig.check} New agents synced automatically: ${state.newAgents.map((agent) => agent.relativePath || agent.manifestName || agent.path || "agent").join(", ")}`
|
|
38129
|
+
),
|
|
37545
38130
|
h(AgentTable, { agents: state.agents }),
|
|
37546
|
-
state.retry && h(Text2, { color:
|
|
37547
|
-
state.errors.
|
|
37548
|
-
|
|
37549
|
-
|
|
37550
|
-
|
|
38131
|
+
state.retry && h(Text2, { color: colors.warning }, ` ${fig.warning} Retry: ${state.retry.activity} in ${Number(state.retry.delaySeconds || 0).toFixed(1)}s`),
|
|
38132
|
+
state.errors.length > 0 && h(
|
|
38133
|
+
Box2,
|
|
38134
|
+
{ flexDirection: "column", marginTop: 1 },
|
|
38135
|
+
...state.errors.slice(-3).map((item, index) => h(Text2, { key: `error-${index}`, color: colors.error }, ` ${fig.cross} ${item.scope}: ${item.message}`))
|
|
38136
|
+
),
|
|
38137
|
+
h(Text2, null, ""),
|
|
38138
|
+
confirmExit ? h(
|
|
38139
|
+
Text2,
|
|
38140
|
+
{ color: colors.warning, bold: true },
|
|
38141
|
+
" Stop local serve? ",
|
|
38142
|
+
h(Text2, { color: colors.accent }, "y"),
|
|
38143
|
+
h(Text2, { color: colors.muted }, "/"),
|
|
38144
|
+
h(Text2, { color: colors.accent }, "n")
|
|
38145
|
+
) : h(FooterBar, { items: [
|
|
38146
|
+
{ key: "l", label: "Agent logs" },
|
|
38147
|
+
{ key: "q", label: "Stop" },
|
|
38148
|
+
{ key: "^c ^c", label: "Exit" }
|
|
38149
|
+
] }),
|
|
38150
|
+
exitArmed && h(Text2, { color: colors.warning, bold: true }, " Press Ctrl+C again to exit.")
|
|
37551
38151
|
);
|
|
37552
38152
|
}
|
|
37553
38153
|
function AgentTable({ agents }) {
|
|
37554
38154
|
if (!agents.length) {
|
|
37555
|
-
return h(Text2, {
|
|
38155
|
+
return h(Text2, { color: colors.muted }, ` ${fig.dotEmpty} No agents discovered yet.`);
|
|
38156
|
+
}
|
|
38157
|
+
const termWidth = Math.min(process.stdout.columns || 80, 100);
|
|
38158
|
+
const pathW = Math.min(22, Math.floor(termWidth * 0.25));
|
|
38159
|
+
const nameW = Math.min(28, Math.floor(termWidth * 0.32));
|
|
38160
|
+
const credW = 10;
|
|
38161
|
+
const statusW = 10;
|
|
38162
|
+
const headerLine = ` ${"Path".padEnd(pathW)} ${"Name".padEnd(nameW)} ${"Creds".padEnd(credW)} ${"Status".padEnd(statusW)}`;
|
|
38163
|
+
const separator = ` ${fig.horizontal.repeat(pathW + nameW + credW + statusW + 3)}`;
|
|
38164
|
+
const rows = agents.slice(0, 16).map((agent) => {
|
|
38165
|
+
const path7 = clip(agent.relativePath || ".", pathW);
|
|
38166
|
+
const name = clip(agent.manifestName || agent.manifest?.name || "-", nameW);
|
|
38167
|
+
const creds = credentialLabel(agent);
|
|
38168
|
+
const status = String(agent.status || "-");
|
|
38169
|
+
const statusColor = status === "online" ? colors.success : status === "error" ? colors.error : colors.warning;
|
|
38170
|
+
const statusIcon = status === "online" ? fig.dot : status === "error" ? fig.cross : fig.dotEmpty;
|
|
38171
|
+
return h(
|
|
38172
|
+
Text2,
|
|
38173
|
+
{ key: agent.localAgentId || agent.relativePath },
|
|
38174
|
+
h(Text2, { color: colors.muted }, " "),
|
|
38175
|
+
h(Text2, null, path7.padEnd(pathW)),
|
|
38176
|
+
h(Text2, null, " "),
|
|
38177
|
+
h(Text2, null, name.padEnd(nameW)),
|
|
38178
|
+
h(Text2, null, " "),
|
|
38179
|
+
h(Text2, { color: colors.muted }, creds.padEnd(credW)),
|
|
38180
|
+
h(Text2, null, " "),
|
|
38181
|
+
h(Text2, { color: statusColor }, `${statusIcon} ${status}`)
|
|
38182
|
+
);
|
|
38183
|
+
});
|
|
38184
|
+
const hiddenCount = agents.length - 16;
|
|
38185
|
+
return h(
|
|
38186
|
+
Box2,
|
|
38187
|
+
{ flexDirection: "column" },
|
|
38188
|
+
h(Text2, { color: colors.muted, bold: true }, headerLine),
|
|
38189
|
+
h(Text2, { color: colors.muted }, separator),
|
|
38190
|
+
...rows,
|
|
38191
|
+
hiddenCount > 0 && h(Text2, { color: colors.muted }, ` ${fig.ellipsis} and ${hiddenCount} more`)
|
|
38192
|
+
);
|
|
38193
|
+
}
|
|
38194
|
+
function FooterBar({ items }) {
|
|
38195
|
+
if (!items || !items.length) return null;
|
|
38196
|
+
return h(
|
|
38197
|
+
Text2,
|
|
38198
|
+
{ color: colors.muted },
|
|
38199
|
+
" ",
|
|
38200
|
+
...items.map((item, i) => [
|
|
38201
|
+
h(Text2, { key: `k-${i}`, color: colors.accent, bold: true }, item.key),
|
|
38202
|
+
h(Text2, { key: `l-${i}`, color: colors.muted }, ` ${item.label}`),
|
|
38203
|
+
i < items.length - 1 ? h(Text2, { key: `s-${i}` }, " ") : null
|
|
38204
|
+
]).flat().filter(Boolean)
|
|
38205
|
+
);
|
|
38206
|
+
}
|
|
38207
|
+
function AgentLogViewer({ agents, agentLogs, logMode, onSelectAgent, onBack }) {
|
|
38208
|
+
if (logMode === "picker") {
|
|
38209
|
+
return h(AgentLogPicker, { agents, agentLogs, onSelectAgent, onBack });
|
|
38210
|
+
}
|
|
38211
|
+
return h(AgentLogDetail, { relativePath: logMode, agentLogs, agents, onBack });
|
|
38212
|
+
}
|
|
38213
|
+
function AgentLogPicker({ agents, agentLogs, onSelectAgent, onBack }) {
|
|
38214
|
+
const [selectedIndex, setSelectedIndex] = useState5(0);
|
|
38215
|
+
const agentList = agents.map((agent) => {
|
|
38216
|
+
const path7 = agent.relativePath || ".";
|
|
38217
|
+
const logs = agentLogEntries(agentLogs, path7);
|
|
38218
|
+
const lastLog = logs.length > 0 ? logs[logs.length - 1] : null;
|
|
38219
|
+
const hasErrors = logs.some((l) => l.level === "error" || l.eventType === "completion" && l.success === false);
|
|
38220
|
+
return {
|
|
38221
|
+
path: path7,
|
|
38222
|
+
name: agent.manifestName || agent.manifest?.name || path7,
|
|
38223
|
+
logCount: logs.length,
|
|
38224
|
+
lastLog,
|
|
38225
|
+
hasErrors,
|
|
38226
|
+
status: agent.status || "-"
|
|
38227
|
+
};
|
|
38228
|
+
});
|
|
38229
|
+
const inventoryPaths = new Set(agentList.map((a) => a.path));
|
|
38230
|
+
for (const path7 of Object.keys(agentLogs || {})) {
|
|
38231
|
+
if (!inventoryPaths.has(path7)) {
|
|
38232
|
+
const logs = agentLogEntries(agentLogs, path7);
|
|
38233
|
+
agentList.push({
|
|
38234
|
+
path: path7,
|
|
38235
|
+
name: path7,
|
|
38236
|
+
logCount: logs.length,
|
|
38237
|
+
lastLog: logs.length > 0 ? logs[logs.length - 1] : null,
|
|
38238
|
+
hasErrors: logs.some((l) => l.level === "error"),
|
|
38239
|
+
status: "offline"
|
|
38240
|
+
});
|
|
38241
|
+
}
|
|
37556
38242
|
}
|
|
38243
|
+
useInput2((input, key) => {
|
|
38244
|
+
if (key.upArrow) {
|
|
38245
|
+
setSelectedIndex((i) => (i - 1 + agentList.length) % agentList.length);
|
|
38246
|
+
} else if (key.downArrow) {
|
|
38247
|
+
setSelectedIndex((i) => (i + 1) % agentList.length);
|
|
38248
|
+
} else if (key.return) {
|
|
38249
|
+
if (agentList.length > 0) {
|
|
38250
|
+
onSelectAgent(agentList[selectedIndex].path);
|
|
38251
|
+
}
|
|
38252
|
+
} else if (key.escape) {
|
|
38253
|
+
onBack();
|
|
38254
|
+
}
|
|
38255
|
+
});
|
|
38256
|
+
if (agentList.length === 0) {
|
|
38257
|
+
return h(
|
|
38258
|
+
Box2,
|
|
38259
|
+
{ flexDirection: "column" },
|
|
38260
|
+
h(Text2, { bold: true, color: colors.brand }, ` ${fig.horizontal.repeat(3)} Agent Logs`),
|
|
38261
|
+
h(Text2, null, ""),
|
|
38262
|
+
h(Text2, { color: colors.muted }, " No agent logs yet. Logs appear when agents run."),
|
|
38263
|
+
h(Text2, null, ""),
|
|
38264
|
+
h(FooterBar, { items: [{ key: "esc", label: "Back to serve" }] })
|
|
38265
|
+
);
|
|
38266
|
+
}
|
|
38267
|
+
const pathW = 24;
|
|
38268
|
+
const nameW = 26;
|
|
37557
38269
|
return h(
|
|
37558
38270
|
Box2,
|
|
37559
38271
|
{ flexDirection: "column" },
|
|
37560
|
-
h(Text2, {
|
|
37561
|
-
|
|
37562
|
-
|
|
37563
|
-
|
|
37564
|
-
|
|
37565
|
-
|
|
38272
|
+
h(Text2, { bold: true, color: colors.brand }, ` ${fig.horizontal.repeat(3)} Agent Logs ${fig.horizontal.repeat(20)}`),
|
|
38273
|
+
h(Text2, null, ""),
|
|
38274
|
+
h(Text2, { color: colors.muted }, ` ${"Agent".padEnd(nameW)} ${"Logs".padEnd(6)} ${"Last event"}`),
|
|
38275
|
+
h(Text2, { color: colors.muted }, ` ${fig.horizontal.repeat(nameW + 6 + 30)}`),
|
|
38276
|
+
...agentList.map((agent, i) => {
|
|
38277
|
+
const isActive = i === selectedIndex;
|
|
38278
|
+
const logCountColor = agent.hasErrors ? colors.error : agent.logCount > 0 ? colors.success : colors.muted;
|
|
38279
|
+
const lastEvent = agent.lastLog ? formatAgentLogEntry(agent.lastLog) : "No logs";
|
|
38280
|
+
return h(
|
|
38281
|
+
Text2,
|
|
38282
|
+
{ key: agent.path },
|
|
38283
|
+
h(Text2, { color: isActive ? colors.accent : colors.muted }, isActive ? ` ${fig.arrow} ` : " "),
|
|
38284
|
+
h(Text2, { bold: isActive }, clip(agent.name, nameW - 2).padEnd(nameW)),
|
|
38285
|
+
h(Text2, { color: logCountColor }, String(agent.logCount).padEnd(6)),
|
|
38286
|
+
h(Text2, { color: colors.muted }, clip(lastEvent, 36))
|
|
38287
|
+
);
|
|
38288
|
+
}),
|
|
38289
|
+
h(Text2, null, ""),
|
|
38290
|
+
h(FooterBar, { items: [
|
|
38291
|
+
{ key: "\u2191\u2193", label: "Navigate" },
|
|
38292
|
+
{ key: "\u23CE", label: "View logs" },
|
|
38293
|
+
{ key: "esc", label: "Back to serve" }
|
|
38294
|
+
] })
|
|
37566
38295
|
);
|
|
37567
38296
|
}
|
|
37568
|
-
function
|
|
38297
|
+
function AgentLogDetail({ relativePath, agentLogs, agents, onBack }) {
|
|
38298
|
+
const logs = agentLogEntries(agentLogs, relativePath);
|
|
38299
|
+
const agent = agents.find((a) => (a.relativePath || ".") === relativePath);
|
|
38300
|
+
const agentName = agent?.manifestName || agent?.manifest?.name || relativePath;
|
|
38301
|
+
const [scrollOffset, setScrollOffset] = useState5(0);
|
|
38302
|
+
const visibleCount = Math.min(20, Math.max(8, (process.stdout.rows || 24) - 10));
|
|
38303
|
+
useInput2((input, key) => {
|
|
38304
|
+
if (key.escape) {
|
|
38305
|
+
onBack();
|
|
38306
|
+
} else if (key.upArrow) {
|
|
38307
|
+
setScrollOffset((o) => Math.max(0, o - 1));
|
|
38308
|
+
} else if (key.downArrow) {
|
|
38309
|
+
setScrollOffset((o) => Math.min(Math.max(0, logs.length - visibleCount), o + 1));
|
|
38310
|
+
} else if (key.pageDown || input === " ") {
|
|
38311
|
+
setScrollOffset((o) => Math.min(Math.max(0, logs.length - visibleCount), o + visibleCount));
|
|
38312
|
+
} else if (key.pageUp) {
|
|
38313
|
+
setScrollOffset((o) => Math.max(0, o - visibleCount));
|
|
38314
|
+
}
|
|
38315
|
+
});
|
|
38316
|
+
const effectiveOffset = logs.length <= visibleCount ? 0 : scrollOffset >= logs.length - visibleCount - 2 ? Math.max(0, logs.length - visibleCount) : scrollOffset;
|
|
38317
|
+
const visibleLogs = logs.slice(effectiveOffset, effectiveOffset + visibleCount);
|
|
37569
38318
|
return h(
|
|
37570
38319
|
Box2,
|
|
37571
|
-
{ flexDirection: "column"
|
|
37572
|
-
h(Text2, { bold: true },
|
|
37573
|
-
|
|
37574
|
-
|
|
37575
|
-
|
|
37576
|
-
|
|
37577
|
-
|
|
38320
|
+
{ flexDirection: "column" },
|
|
38321
|
+
h(Text2, { bold: true, color: colors.brand }, ` ${fig.horizontal.repeat(3)} ${agentName}`),
|
|
38322
|
+
h(Text2, { color: colors.muted }, ` ${relativePath} ${fig.dash} ${logs.length} log entries`),
|
|
38323
|
+
h(Text2, null, ""),
|
|
38324
|
+
logs.length === 0 ? h(Text2, { color: colors.muted }, " No logs recorded yet for this agent. Logs appear during runs.") : h(
|
|
38325
|
+
Box2,
|
|
38326
|
+
{ flexDirection: "column" },
|
|
38327
|
+
...visibleLogs.map((entry, i) => {
|
|
38328
|
+
const levelColor = entry.level === "error" ? colors.error : entry.level === "warning" ? colors.warning : entry.level === "debug" ? colors.dim : colors.muted;
|
|
38329
|
+
const timeStr = formatLogTime(entry.timestamp);
|
|
38330
|
+
const icon = entry.eventType === "completion" ? entry.success ? fig.check : fig.cross : entry.eventType === "step_event" ? fig.arrow : entry.eventType === "progress" ? fig.dotEmpty : entry.level === "error" ? fig.cross : fig.dash;
|
|
38331
|
+
const iconColor = entry.eventType === "completion" ? entry.success ? colors.success : colors.error : levelColor;
|
|
38332
|
+
return h(
|
|
38333
|
+
Text2,
|
|
38334
|
+
{ key: `${effectiveOffset + i}` },
|
|
38335
|
+
h(Text2, { color: colors.dim }, ` ${timeStr} `),
|
|
38336
|
+
h(Text2, { color: iconColor }, `${icon} `),
|
|
38337
|
+
h(
|
|
38338
|
+
Text2,
|
|
38339
|
+
{ color: entry.level === "error" ? colors.error : colors.text },
|
|
38340
|
+
clip(formatAgentLogEntry(entry), 60)
|
|
38341
|
+
)
|
|
38342
|
+
);
|
|
38343
|
+
}),
|
|
38344
|
+
logs.length > visibleCount && h(
|
|
38345
|
+
Text2,
|
|
38346
|
+
{ color: colors.muted },
|
|
38347
|
+
` ${fig.ellipsis} Showing ${effectiveOffset + 1}-${effectiveOffset + visibleLogs.length} of ${logs.length}`
|
|
38348
|
+
)
|
|
38349
|
+
),
|
|
38350
|
+
h(Text2, null, ""),
|
|
38351
|
+
h(FooterBar, { items: [
|
|
38352
|
+
{ key: "\u2191\u2193", label: "Scroll" },
|
|
38353
|
+
{ key: "PgUp/Dn", label: "Page" },
|
|
38354
|
+
{ key: "esc", label: "Back to agents" }
|
|
38355
|
+
] })
|
|
37578
38356
|
);
|
|
37579
38357
|
}
|
|
38358
|
+
function formatAgentLogEntry(entry) {
|
|
38359
|
+
if (!entry) return "";
|
|
38360
|
+
const type = entry.eventType || "";
|
|
38361
|
+
switch (type) {
|
|
38362
|
+
case "log":
|
|
38363
|
+
return entry.message || "";
|
|
38364
|
+
case "progress": {
|
|
38365
|
+
const prog = entry.current != null && entry.total != null ? `${entry.current}/${entry.total}` : "";
|
|
38366
|
+
return `${prog}${entry.message ? ` ${entry.message}` : ""}`.trim() || "progress";
|
|
38367
|
+
}
|
|
38368
|
+
case "completion":
|
|
38369
|
+
if (entry.success) return "Completed successfully";
|
|
38370
|
+
if (entry.error && typeof entry.error === "object") return `Failed: ${entry.error.message || "error"}`;
|
|
38371
|
+
return `Failed: ${entry.error || "unknown error"}`;
|
|
38372
|
+
case "step_event":
|
|
38373
|
+
return `Step: ${entry.stepId || "unknown"}${entry.message ? ` - ${entry.message}` : ""}`;
|
|
38374
|
+
case "step_checkpoint":
|
|
38375
|
+
return `Checkpoint: ${entry.stepId || "unknown"}`;
|
|
38376
|
+
case "step_heartbeat":
|
|
38377
|
+
return `Heartbeat: ${entry.stepId || ""}${entry.message ? ` - ${entry.message}` : ""}`;
|
|
38378
|
+
case "artifact":
|
|
38379
|
+
return `Artifact: ${entry.message || "data"}`;
|
|
38380
|
+
default:
|
|
38381
|
+
return entry.message || type || "event";
|
|
38382
|
+
}
|
|
38383
|
+
}
|
|
38384
|
+
function formatLogTime(timestamp) {
|
|
38385
|
+
if (!timestamp) return " ";
|
|
38386
|
+
try {
|
|
38387
|
+
const d = new Date(timestamp);
|
|
38388
|
+
const h2 = String(d.getHours()).padStart(2, "0");
|
|
38389
|
+
const m = String(d.getMinutes()).padStart(2, "0");
|
|
38390
|
+
const s = String(d.getSeconds()).padStart(2, "0");
|
|
38391
|
+
return `${h2}:${m}:${s}`;
|
|
38392
|
+
} catch {
|
|
38393
|
+
return " ";
|
|
38394
|
+
}
|
|
38395
|
+
}
|
|
37580
38396
|
function DoctorScreen({ env: env3, platform: platform2, onBack }) {
|
|
37581
38397
|
const runtime = runtimeSummary({ env: env3, platform: platform2 });
|
|
37582
38398
|
const pkg = packageAccessSummary({ env: env3, platform: platform2 });
|
|
38399
|
+
const checks = [
|
|
38400
|
+
{ label: "Managed Python", passed: runtime.installed, value: runtime.installed ? "Present" : "Missing" },
|
|
38401
|
+
{ label: "Managed Env", passed: runtime.installed, value: runtime.detail },
|
|
38402
|
+
{ label: "Package Access", passed: pkg.configured, value: pkg.configured ? `Configured (${pkg.source})` : "Missing" }
|
|
38403
|
+
];
|
|
38404
|
+
const allPassed = checks.every((c) => c.passed);
|
|
37583
38405
|
return h(
|
|
37584
38406
|
Box2,
|
|
37585
38407
|
{ flexDirection: "column" },
|
|
37586
|
-
h(Text2, { bold: true }, "
|
|
37587
|
-
h(Text2, null,
|
|
37588
|
-
|
|
37589
|
-
|
|
38408
|
+
h(Text2, { bold: true }, " System Health"),
|
|
38409
|
+
h(Text2, null, ""),
|
|
38410
|
+
...checks.map((check) => h(
|
|
38411
|
+
Text2,
|
|
38412
|
+
{ key: check.label },
|
|
38413
|
+
h(Text2, { color: check.passed ? colors.success : colors.error }, ` ${check.passed ? fig.check : fig.cross} `),
|
|
38414
|
+
h(Text2, null, `${check.label.padEnd(18)}${check.value}`)
|
|
38415
|
+
)),
|
|
38416
|
+
h(Text2, null, ""),
|
|
38417
|
+
h(
|
|
38418
|
+
Text2,
|
|
38419
|
+
{ color: allPassed ? colors.success : colors.warning, bold: true },
|
|
38420
|
+
allPassed ? ` ${fig.check} All checks passed` : ` ${fig.warning} Some checks need attention`
|
|
38421
|
+
),
|
|
38422
|
+
h(Text2, null, ""),
|
|
37590
38423
|
h(SelectInput2, {
|
|
37591
|
-
items: [{ label: "Run
|
|
38424
|
+
items: [{ label: "Run full doctor output", value: "run" }, { label: "Back", value: "back" }],
|
|
37592
38425
|
onSelect: async (item) => {
|
|
37593
38426
|
if (item.value === "back") onBack();
|
|
37594
38427
|
else doctor({ env: env3, platform: platform2 });
|
|
37595
38428
|
}
|
|
37596
|
-
})
|
|
38429
|
+
}),
|
|
38430
|
+
h(FooterBar, { items: [{ key: "\u23CE", label: "Select" }, { key: "esc", label: "Back" }] })
|
|
37597
38431
|
);
|
|
37598
38432
|
}
|
|
37599
38433
|
function UpdateScreen({ env: env3, platform: platform2, onBack }) {
|
|
@@ -37601,29 +38435,65 @@ function UpdateScreen({ env: env3, platform: platform2, onBack }) {
|
|
|
37601
38435
|
return h(
|
|
37602
38436
|
Box2,
|
|
37603
38437
|
{ flexDirection: "column" },
|
|
37604
|
-
h(Text2, { bold: true }, "Update"),
|
|
38438
|
+
h(Text2, { bold: true }, " Update Runtime"),
|
|
38439
|
+
h(Text2, null, ""),
|
|
37605
38440
|
h(SelectInput2, {
|
|
37606
|
-
items: [{ label: "Update managed runtime", value: "run" }, { label: "Back", value: "back" }],
|
|
38441
|
+
items: [{ label: "Update managed runtime & packages", value: "run" }, { label: "Back", value: "back" }],
|
|
37607
38442
|
onSelect: async (item) => {
|
|
37608
38443
|
if (item.value === "back") {
|
|
37609
38444
|
onBack();
|
|
37610
38445
|
return;
|
|
37611
38446
|
}
|
|
37612
|
-
setStatus(
|
|
38447
|
+
setStatus(`${fig.dotEmpty} Updating managed runtime...`);
|
|
37613
38448
|
await setup({ nonInteractive: true, env: env3, platform: platform2 });
|
|
37614
|
-
setStatus(
|
|
38449
|
+
setStatus(`${fig.check} Update finished`);
|
|
37615
38450
|
}
|
|
37616
38451
|
}),
|
|
37617
|
-
status && h(Text2,
|
|
38452
|
+
status && h(Text2, { color: status.includes(fig.check) ? colors.success : colors.muted }, ` ${status}`),
|
|
38453
|
+
h(Text2, null, ""),
|
|
38454
|
+
h(FooterBar, { items: [{ key: "\u23CE", label: "Select" }, { key: "esc", label: "Back" }] }),
|
|
38455
|
+
h(BackHint, { onBack })
|
|
37618
38456
|
);
|
|
37619
38457
|
}
|
|
37620
38458
|
function CommandsScreen({ onBack }) {
|
|
38459
|
+
const grouped = [
|
|
38460
|
+
{ section: "Getting Started", commands: [
|
|
38461
|
+
{ cmd: "vendian login", desc: "Sign in and prepare runtime" },
|
|
38462
|
+
{ cmd: "vendian init --output-dir ./agents", desc: "Initialize docs workspace" }
|
|
38463
|
+
] },
|
|
38464
|
+
{ section: "Agent Development", commands: [
|
|
38465
|
+
{ cmd: 'vendian create "My Agent" --output-dir .', desc: "Scaffold new agent" },
|
|
38466
|
+
{ cmd: "vendian validate ./agents/my-agent --runtime", desc: "Validate manifest" },
|
|
38467
|
+
{ cmd: "vendian test ./agents/my-agent --dry-run", desc: "Test locally" },
|
|
38468
|
+
{ cmd: "vendian models", desc: "List available models" }
|
|
38469
|
+
] },
|
|
38470
|
+
{ section: "Cloud & Deploy", commands: [
|
|
38471
|
+
{ cmd: "vendian cloud local serve --agents-dir .", desc: "Start cloud-connected serve" },
|
|
38472
|
+
{ cmd: "vendian login --backend staging", desc: "Connect to staging" }
|
|
38473
|
+
] },
|
|
38474
|
+
{ section: "Maintenance", commands: [
|
|
38475
|
+
{ cmd: "vendian doctor", desc: "Check system health" },
|
|
38476
|
+
{ cmd: "vendian update", desc: "Update runtime & packages" }
|
|
38477
|
+
] }
|
|
38478
|
+
];
|
|
37621
38479
|
return h(
|
|
37622
38480
|
Box2,
|
|
37623
38481
|
{ flexDirection: "column" },
|
|
37624
|
-
h(Text2, { bold: true }, "
|
|
37625
|
-
|
|
37626
|
-
|
|
38482
|
+
h(Text2, { bold: true }, " Quick Reference"),
|
|
38483
|
+
h(Text2, null, ""),
|
|
38484
|
+
...grouped.map((group) => [
|
|
38485
|
+
h(Text2, { key: `title-${group.section}`, color: colors.accent, bold: true }, ` ${group.section}`),
|
|
38486
|
+
...group.commands.map((item) => h(
|
|
38487
|
+
Text2,
|
|
38488
|
+
{ key: item.cmd },
|
|
38489
|
+
h(Text2, { color: colors.muted }, " "),
|
|
38490
|
+
h(Text2, { color: colors.brand }, item.cmd.padEnd(44)),
|
|
38491
|
+
h(Text2, { color: colors.muted }, item.desc)
|
|
38492
|
+
)),
|
|
38493
|
+
h(Text2, { key: `gap-${group.section}` }, "")
|
|
38494
|
+
]).flat(),
|
|
38495
|
+
h(FooterBar, { items: [{ key: "esc", label: "Back" }] }),
|
|
38496
|
+
h(BackHint, { onBack })
|
|
37627
38497
|
);
|
|
37628
38498
|
}
|
|
37629
38499
|
function CommandPromptScreen({ title, label, initialValue, onSubmit, onBack }) {
|
|
@@ -37633,17 +38503,20 @@ function CommandPromptScreen({ title, label, initialValue, onSubmit, onBack }) {
|
|
|
37633
38503
|
Box2,
|
|
37634
38504
|
{ flexDirection: "column" },
|
|
37635
38505
|
h(Text2, { bold: true }, title),
|
|
38506
|
+
h(Text2, null, ""),
|
|
37636
38507
|
h(TextInput2, {
|
|
37637
38508
|
value,
|
|
37638
38509
|
placeholder: label,
|
|
37639
38510
|
onChange: setValue,
|
|
37640
38511
|
onSubmit: async (submitted) => {
|
|
37641
|
-
setStatus(
|
|
38512
|
+
setStatus(`${fig.dotEmpty} Running...`);
|
|
37642
38513
|
await onSubmit(submitted);
|
|
37643
|
-
setStatus(
|
|
38514
|
+
setStatus(`${fig.check} Done`);
|
|
37644
38515
|
}
|
|
37645
38516
|
}),
|
|
37646
|
-
status && h(Text2,
|
|
38517
|
+
status && h(Text2, { color: status.includes(fig.check) ? colors.success : colors.muted }, ` ${status}`),
|
|
38518
|
+
h(Text2, null, ""),
|
|
38519
|
+
h(FooterBar, { items: [{ key: "\u23CE", label: "Submit" }, { key: "esc", label: "Back" }] }),
|
|
37647
38520
|
h(BackHint, { onBack })
|
|
37648
38521
|
);
|
|
37649
38522
|
}
|
|
@@ -37651,10 +38524,11 @@ function BackHint({ onBack }) {
|
|
|
37651
38524
|
useInput2((input, key) => {
|
|
37652
38525
|
if (key.escape || input === "\x1B") onBack();
|
|
37653
38526
|
});
|
|
37654
|
-
return
|
|
38527
|
+
return null;
|
|
37655
38528
|
}
|
|
37656
38529
|
function attachServeChild(child, setState, setStartupError, onExit) {
|
|
37657
38530
|
let buffer = "";
|
|
38531
|
+
const stderrChunks = [];
|
|
37658
38532
|
child.stdout.setEncoding("utf8");
|
|
37659
38533
|
child.stdout.on("data", (chunk) => {
|
|
37660
38534
|
buffer += chunk;
|
|
@@ -37675,6 +38549,7 @@ function attachServeChild(child, setState, setStartupError, onExit) {
|
|
|
37675
38549
|
child.stderr.on("data", (chunk) => {
|
|
37676
38550
|
const text = String(chunk).trim();
|
|
37677
38551
|
if (text) {
|
|
38552
|
+
stderrChunks.push(text);
|
|
37678
38553
|
setState((current) => ({
|
|
37679
38554
|
...current,
|
|
37680
38555
|
logs: [...current.logs, { type: "stderr", message: text }].slice(-200)
|
|
@@ -37682,23 +38557,33 @@ function attachServeChild(child, setState, setStartupError, onExit) {
|
|
|
37682
38557
|
}
|
|
37683
38558
|
});
|
|
37684
38559
|
child.on("error", (error) => setStartupError(errorMessage2(error)));
|
|
37685
|
-
child.on("exit",
|
|
38560
|
+
child.on("exit", (code, signal) => {
|
|
38561
|
+
const message = serveProcessExitMessage({ stderr: stderrChunks.join("\n"), code, signal });
|
|
38562
|
+
if (message) {
|
|
38563
|
+
setStartupError(message);
|
|
38564
|
+
}
|
|
38565
|
+
onExit({ code, signal, message });
|
|
38566
|
+
});
|
|
37686
38567
|
}
|
|
37687
38568
|
function helpText() {
|
|
37688
38569
|
return [
|
|
37689
|
-
"Vendian CLI",
|
|
37690
38570
|
"",
|
|
37691
|
-
|
|
37692
|
-
"
|
|
37693
|
-
"
|
|
37694
|
-
"
|
|
37695
|
-
"
|
|
37696
|
-
"
|
|
37697
|
-
|
|
37698
|
-
"
|
|
38571
|
+
` ${fig.arrowUp} VENDIAN CLI v${CLI_VERSION}`,
|
|
38572
|
+
"",
|
|
38573
|
+
" Usage:",
|
|
38574
|
+
" vendian Open the interactive shell",
|
|
38575
|
+
" vendian login Sign in and prepare the local runtime",
|
|
38576
|
+
" vendian doctor Check local bootstrap health",
|
|
38577
|
+
" vendian update Update the managed runtime",
|
|
38578
|
+
" vendian init Write SDK agent docs into a workspace",
|
|
38579
|
+
' vendian create "My Agent" Scaffold a new agent from templates',
|
|
38580
|
+
" vendian <command> Run a managed Python SDK/cloud command",
|
|
38581
|
+
"",
|
|
38582
|
+
" Examples:",
|
|
38583
|
+
...COMMANDS.map((command) => ` ${command}`),
|
|
37699
38584
|
"",
|
|
37700
|
-
|
|
37701
|
-
|
|
38585
|
+
` Run ${fig.arrowRight} vendian ${fig.arrowRight} to open the interactive TUI`,
|
|
38586
|
+
""
|
|
37702
38587
|
].join("\n");
|
|
37703
38588
|
}
|
|
37704
38589
|
function credentialLabel(agent) {
|