@vm0/cli 4.5.2 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +148 -9
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -391,6 +391,28 @@ var ApiClient = class {
|
|
|
391
391
|
}
|
|
392
392
|
return await response.json();
|
|
393
393
|
}
|
|
394
|
+
async getNetworkLogs(runId, options) {
|
|
395
|
+
const baseUrl = await this.getBaseUrl();
|
|
396
|
+
const headers = await this.getHeaders();
|
|
397
|
+
const params = new URLSearchParams();
|
|
398
|
+
if (options?.since !== void 0) {
|
|
399
|
+
params.set("since", String(options.since));
|
|
400
|
+
}
|
|
401
|
+
if (options?.limit !== void 0) {
|
|
402
|
+
params.set("limit", String(options.limit));
|
|
403
|
+
}
|
|
404
|
+
const queryString = params.toString();
|
|
405
|
+
const url2 = `${baseUrl}/api/agent/runs/${runId}/telemetry/network${queryString ? `?${queryString}` : ""}`;
|
|
406
|
+
const response = await fetch(url2, {
|
|
407
|
+
method: "GET",
|
|
408
|
+
headers
|
|
409
|
+
});
|
|
410
|
+
if (!response.ok) {
|
|
411
|
+
const error43 = await response.json();
|
|
412
|
+
throw new Error(error43.error?.message || "Failed to fetch network logs");
|
|
413
|
+
}
|
|
414
|
+
return await response.json();
|
|
415
|
+
}
|
|
394
416
|
async createImage(body) {
|
|
395
417
|
const baseUrl = await this.getBaseUrl();
|
|
396
418
|
const headers = await this.getHeaders();
|
|
@@ -14217,7 +14239,14 @@ var agentDefinitionSchema = external_exports.object({
|
|
|
14217
14239
|
provider: external_exports.string().min(1, "Provider is required"),
|
|
14218
14240
|
volumes: external_exports.array(external_exports.string()).optional(),
|
|
14219
14241
|
working_dir: external_exports.string().min(1, "Working directory is required"),
|
|
14220
|
-
environment: external_exports.record(external_exports.string(), external_exports.string()).optional()
|
|
14242
|
+
environment: external_exports.record(external_exports.string(), external_exports.string()).optional(),
|
|
14243
|
+
/**
|
|
14244
|
+
* Enable network security mode for secrets.
|
|
14245
|
+
* When true, secrets are encrypted into proxy tokens and all traffic
|
|
14246
|
+
* is routed through mitmproxy -> VM0 Proxy for decryption.
|
|
14247
|
+
* Default: false (plaintext secrets in env vars)
|
|
14248
|
+
*/
|
|
14249
|
+
beta_network_security: external_exports.boolean().optional().default(false)
|
|
14221
14250
|
});
|
|
14222
14251
|
var agentComposeContentSchema = external_exports.object({
|
|
14223
14252
|
version: external_exports.string().min(1, "Version is required"),
|
|
@@ -14477,6 +14506,19 @@ var agentEventsResponseSchema = external_exports.object({
|
|
|
14477
14506
|
events: external_exports.array(runEventSchema),
|
|
14478
14507
|
hasMore: external_exports.boolean()
|
|
14479
14508
|
});
|
|
14509
|
+
var networkLogEntrySchema = external_exports.object({
|
|
14510
|
+
timestamp: external_exports.string(),
|
|
14511
|
+
method: external_exports.string(),
|
|
14512
|
+
url: external_exports.string(),
|
|
14513
|
+
status: external_exports.number(),
|
|
14514
|
+
latency_ms: external_exports.number(),
|
|
14515
|
+
request_size: external_exports.number(),
|
|
14516
|
+
response_size: external_exports.number()
|
|
14517
|
+
});
|
|
14518
|
+
var networkLogsResponseSchema = external_exports.object({
|
|
14519
|
+
networkLogs: external_exports.array(networkLogEntrySchema),
|
|
14520
|
+
hasMore: external_exports.boolean()
|
|
14521
|
+
});
|
|
14480
14522
|
var telemetryResponseSchema = external_exports.object({
|
|
14481
14523
|
systemLog: external_exports.string(),
|
|
14482
14524
|
metrics: external_exports.array(telemetryMetricSchema)
|
|
@@ -14569,6 +14611,29 @@ var runAgentEventsContract = c3.router({
|
|
|
14569
14611
|
summary: "Get agent events with pagination"
|
|
14570
14612
|
}
|
|
14571
14613
|
});
|
|
14614
|
+
var runNetworkLogsContract = c3.router({
|
|
14615
|
+
/**
|
|
14616
|
+
* GET /api/agent/runs/:id/telemetry/network
|
|
14617
|
+
* Get network logs with pagination (for vm0 logs --network)
|
|
14618
|
+
*/
|
|
14619
|
+
getNetworkLogs: {
|
|
14620
|
+
method: "GET",
|
|
14621
|
+
path: "/api/agent/runs/:id/telemetry/network",
|
|
14622
|
+
pathParams: external_exports.object({
|
|
14623
|
+
id: external_exports.string().min(1, "Run ID is required")
|
|
14624
|
+
}),
|
|
14625
|
+
query: external_exports.object({
|
|
14626
|
+
since: external_exports.coerce.number().optional(),
|
|
14627
|
+
limit: external_exports.coerce.number().min(1).max(100).default(5)
|
|
14628
|
+
}),
|
|
14629
|
+
responses: {
|
|
14630
|
+
200: networkLogsResponseSchema,
|
|
14631
|
+
401: apiErrorSchema,
|
|
14632
|
+
404: apiErrorSchema
|
|
14633
|
+
},
|
|
14634
|
+
summary: "Get network logs with pagination"
|
|
14635
|
+
}
|
|
14636
|
+
});
|
|
14572
14637
|
|
|
14573
14638
|
// ../../packages/core/src/contracts/sessions.ts
|
|
14574
14639
|
var c4 = initContract();
|
|
@@ -14918,10 +14983,19 @@ var metricDataSchema = external_exports.object({
|
|
|
14918
14983
|
disk_used: external_exports.number(),
|
|
14919
14984
|
disk_total: external_exports.number()
|
|
14920
14985
|
});
|
|
14986
|
+
var networkLogSchema = external_exports.object({
|
|
14987
|
+
timestamp: external_exports.string(),
|
|
14988
|
+
method: external_exports.string(),
|
|
14989
|
+
url: external_exports.string(),
|
|
14990
|
+
status: external_exports.number(),
|
|
14991
|
+
latency_ms: external_exports.number(),
|
|
14992
|
+
request_size: external_exports.number(),
|
|
14993
|
+
response_size: external_exports.number()
|
|
14994
|
+
});
|
|
14921
14995
|
var webhookTelemetryContract = c6.router({
|
|
14922
14996
|
/**
|
|
14923
14997
|
* POST /api/webhooks/agent/telemetry
|
|
14924
|
-
* Receive telemetry data (system log and
|
|
14998
|
+
* Receive telemetry data (system log, metrics, and network logs) from sandbox
|
|
14925
14999
|
*/
|
|
14926
15000
|
send: {
|
|
14927
15001
|
method: "POST",
|
|
@@ -14929,7 +15003,8 @@ var webhookTelemetryContract = c6.router({
|
|
|
14929
15003
|
body: external_exports.object({
|
|
14930
15004
|
runId: external_exports.string().min(1, "runId is required"),
|
|
14931
15005
|
systemLog: external_exports.string().optional(),
|
|
14932
|
-
metrics: external_exports.array(metricDataSchema).optional()
|
|
15006
|
+
metrics: external_exports.array(metricDataSchema).optional(),
|
|
15007
|
+
networkLogs: external_exports.array(networkLogSchema).optional()
|
|
14933
15008
|
}),
|
|
14934
15009
|
responses: {
|
|
14935
15010
|
200: external_exports.object({
|
|
@@ -15172,6 +15247,20 @@ var cronCleanupSandboxesContract = c10.router({
|
|
|
15172
15247
|
}
|
|
15173
15248
|
});
|
|
15174
15249
|
|
|
15250
|
+
// ../../packages/core/src/contracts/proxy.ts
|
|
15251
|
+
var proxyErrorSchema = external_exports.object({
|
|
15252
|
+
error: external_exports.object({
|
|
15253
|
+
message: external_exports.string(),
|
|
15254
|
+
code: external_exports.enum([
|
|
15255
|
+
"UNAUTHORIZED",
|
|
15256
|
+
"BAD_REQUEST",
|
|
15257
|
+
"BAD_GATEWAY",
|
|
15258
|
+
"INTERNAL_ERROR"
|
|
15259
|
+
]),
|
|
15260
|
+
targetUrl: external_exports.string().optional()
|
|
15261
|
+
})
|
|
15262
|
+
});
|
|
15263
|
+
|
|
15175
15264
|
// src/lib/secrets-client.ts
|
|
15176
15265
|
async function getClientConfig() {
|
|
15177
15266
|
const baseUrl = await getApiUrl();
|
|
@@ -15837,6 +15926,27 @@ function formatMetric(metric) {
|
|
|
15837
15926
|
const diskPercent = (metric.disk_used / metric.disk_total * 100).toFixed(1);
|
|
15838
15927
|
return `[${metric.ts}] CPU: ${metric.cpu.toFixed(1)}% | Mem: ${formatBytes5(metric.mem_used)}/${formatBytes5(metric.mem_total)} (${memPercent}%) | Disk: ${formatBytes5(metric.disk_used)}/${formatBytes5(metric.disk_total)} (${diskPercent}%)`;
|
|
15839
15928
|
}
|
|
15929
|
+
function formatNetworkLog(entry) {
|
|
15930
|
+
let statusColor;
|
|
15931
|
+
if (entry.status >= 200 && entry.status < 300) {
|
|
15932
|
+
statusColor = chalk18.green;
|
|
15933
|
+
} else if (entry.status >= 300 && entry.status < 400) {
|
|
15934
|
+
statusColor = chalk18.yellow;
|
|
15935
|
+
} else if (entry.status >= 400) {
|
|
15936
|
+
statusColor = chalk18.red;
|
|
15937
|
+
} else {
|
|
15938
|
+
statusColor = chalk18.gray;
|
|
15939
|
+
}
|
|
15940
|
+
let latencyColor;
|
|
15941
|
+
if (entry.latency_ms < 500) {
|
|
15942
|
+
latencyColor = chalk18.green;
|
|
15943
|
+
} else if (entry.latency_ms < 2e3) {
|
|
15944
|
+
latencyColor = chalk18.yellow;
|
|
15945
|
+
} else {
|
|
15946
|
+
latencyColor = chalk18.red;
|
|
15947
|
+
}
|
|
15948
|
+
return `[${entry.timestamp}] ${chalk18.cyan(entry.method.padEnd(6))} ${statusColor(entry.status)} ${latencyColor(entry.latency_ms + "ms")} ${formatBytes5(entry.request_size)}/${formatBytes5(entry.response_size)} ${chalk18.gray(entry.url)}`;
|
|
15949
|
+
}
|
|
15840
15950
|
function renderAgentEvent(event) {
|
|
15841
15951
|
const parsed = ClaudeEventParser.parse(
|
|
15842
15952
|
event.eventData
|
|
@@ -15847,22 +15957,26 @@ function renderAgentEvent(event) {
|
|
|
15847
15957
|
}
|
|
15848
15958
|
}
|
|
15849
15959
|
function getLogType(options) {
|
|
15850
|
-
const selected = [
|
|
15851
|
-
|
|
15852
|
-
|
|
15960
|
+
const selected = [
|
|
15961
|
+
options.agent,
|
|
15962
|
+
options.system,
|
|
15963
|
+
options.metrics,
|
|
15964
|
+
options.network
|
|
15965
|
+
].filter(Boolean).length;
|
|
15853
15966
|
if (selected > 1) {
|
|
15854
15967
|
console.error(
|
|
15855
15968
|
chalk18.red(
|
|
15856
|
-
"Options --agent, --system, and --
|
|
15969
|
+
"Options --agent, --system, --metrics, and --network are mutually exclusive"
|
|
15857
15970
|
)
|
|
15858
15971
|
);
|
|
15859
15972
|
process.exit(1);
|
|
15860
15973
|
}
|
|
15861
15974
|
if (options.system) return "system";
|
|
15862
15975
|
if (options.metrics) return "metrics";
|
|
15976
|
+
if (options.network) return "network";
|
|
15863
15977
|
return "agent";
|
|
15864
15978
|
}
|
|
15865
|
-
var logsCommand = new Command20().name("logs").description("View logs for an agent run").argument("<runId>", "Run ID to fetch logs for").option("-a, --agent", "Show agent events (default)").option("-s, --system", "Show system log").option("-m, --metrics", "Show metrics").option(
|
|
15979
|
+
var logsCommand = new Command20().name("logs").description("View logs for an agent run").argument("<runId>", "Run ID to fetch logs for").option("-a, --agent", "Show agent events (default)").option("-s, --system", "Show system log").option("-m, --metrics", "Show metrics").option("-n, --network", "Show network logs (proxy traffic)").option(
|
|
15866
15980
|
"--since <time>",
|
|
15867
15981
|
"Show logs since timestamp (e.g., 5m, 2h, 1d, 2024-01-15T10:30:00Z, 1705312200)"
|
|
15868
15982
|
).option(
|
|
@@ -15891,6 +16005,9 @@ var logsCommand = new Command20().name("logs").description("View logs for an age
|
|
|
15891
16005
|
case "metrics":
|
|
15892
16006
|
await showMetrics(runId, { since, limit });
|
|
15893
16007
|
break;
|
|
16008
|
+
case "network":
|
|
16009
|
+
await showNetworkLogs(runId, { since, limit });
|
|
16010
|
+
break;
|
|
15894
16011
|
}
|
|
15895
16012
|
} catch (error43) {
|
|
15896
16013
|
handleError(error43, runId);
|
|
@@ -15948,6 +16065,28 @@ async function showMetrics(runId, options) {
|
|
|
15948
16065
|
);
|
|
15949
16066
|
}
|
|
15950
16067
|
}
|
|
16068
|
+
async function showNetworkLogs(runId, options) {
|
|
16069
|
+
const response = await apiClient.getNetworkLogs(runId, options);
|
|
16070
|
+
if (response.networkLogs.length === 0) {
|
|
16071
|
+
console.log(
|
|
16072
|
+
chalk18.yellow(
|
|
16073
|
+
"No network logs found for this run. Network logs are only captured when beta_network_security is enabled."
|
|
16074
|
+
)
|
|
16075
|
+
);
|
|
16076
|
+
return;
|
|
16077
|
+
}
|
|
16078
|
+
for (const entry of response.networkLogs) {
|
|
16079
|
+
console.log(formatNetworkLog(entry));
|
|
16080
|
+
}
|
|
16081
|
+
if (response.hasMore) {
|
|
16082
|
+
console.log();
|
|
16083
|
+
console.log(
|
|
16084
|
+
chalk18.gray(
|
|
16085
|
+
`Showing ${response.networkLogs.length} network logs. Use --limit to see more.`
|
|
16086
|
+
)
|
|
16087
|
+
);
|
|
16088
|
+
}
|
|
16089
|
+
}
|
|
15951
16090
|
function handleError(error43, runId) {
|
|
15952
16091
|
if (error43 instanceof Error) {
|
|
15953
16092
|
if (error43.message.includes("Not authenticated")) {
|
|
@@ -15967,7 +16106,7 @@ function handleError(error43, runId) {
|
|
|
15967
16106
|
|
|
15968
16107
|
// src/index.ts
|
|
15969
16108
|
var program = new Command21();
|
|
15970
|
-
program.name("vm0").description("VM0 CLI - A modern build tool").version("4.
|
|
16109
|
+
program.name("vm0").description("VM0 CLI - A modern build tool").version("4.6.0");
|
|
15971
16110
|
program.command("info").description("Display environment information").action(async () => {
|
|
15972
16111
|
console.log(chalk19.cyan("System Information:"));
|
|
15973
16112
|
console.log(`Node Version: ${process.version}`);
|