@ricsam/r5dctl 0.0.122 → 0.0.124
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 +3 -1
- package/dist/cjs/cli.cjs +30 -2
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/cli.mjs +28 -2
- package/dist/mjs/package.json +1 -1
- package/dist/types/cli.d.ts +5 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -155,7 +155,9 @@ Add `-f`/`--follow`/`--watch` to `session start` to poll the provisioning handle
|
|
|
155
155
|
|
|
156
156
|
`shell` connects to the same live worker PTY as the web Shell tab. Without `-c` it attaches the local terminal interactively. With `-c`/`--command`, it runs the supplied shell expression, streams combined PTY output, and exits with the remote command's status. Because command output uses a PTY, stdout and stderr are combined and programs may emit colors or other terminal control sequences.
|
|
157
157
|
|
|
158
|
-
`ps list` shows active long-running commands managed by r5d. It does not expose the worker host's general OS process table or interactive PTYs. Global project, branch, and session options filter the list, while `--worker` selects a worker label. `ps stop` sends `SIGTERM` to the selected run. Inside an r5d-provided worker shell, the temporary credential can only list and stop runs on that shell's worker.
|
|
158
|
+
`ps list` shows active long-running commands managed by r5d. It does not expose the worker host's general OS process table or interactive PTYs. Global project, branch, and session options filter the list, while `--worker` selects a worker label. The `LANE` column names the worker command lane each run holds (`general`, `utility`, or `control`) or waits for (`queued:general`), from the worker's latest capacity report; `-` means the worker did not report the run. `ps stop` sends `SIGTERM` to the selected run. Inside an r5d-provided worker shell, the temporary credential can only list and stop runs on that shell's worker.
|
|
159
|
+
|
|
160
|
+
A managed worker runs two general shells at a time; a third waits up to 60 seconds and then fails with "command capacity is busy". Coordination does not compete for those slots: when an agent shell runs one plain `r5dctl` coordination command (`ps list`, `ps stop`, `workspace status`, `session status|stop|prompt|claim|claims|process-log`, `describe …`, `get …`, `sessions recent`, the `conversation` read forms, `create|update|delete session`, `answer-questions`, `answer-env-request`) with plain or simply quoted arguments, the platform runs it in a reserved control lane: two small slots, no shell, a 120-second limit. Shell operators, pipes, redirections, `$` expansions, environment assignments, wrappers, paths to r5dctl, `--`, `--follow`, and credential or endpoint flags make it an ordinary shell command again. `workspace status` prints each worker's lane totals, holders, and queue.
|
|
159
161
|
|
|
160
162
|
`k8s usage` shows current and rolling CPU and memory usage for every workload container in your managed vCluster. The default window is `24h`; pass `--window 7d` for seven days. Filter with `--namespace`, `--workload`, or `--container`; a workload may be identified by name, `namespace/name`, or Kubernetes UID. Human-readable output shows current totals across sampled replicas and the selected window's maximum. Global `--json` includes min/max summaries, the complete five-minute history envelope, per-pod series, coverage, and freshness metadata.
|
|
161
163
|
|
package/dist/cjs/cli.cjs
CHANGED
|
@@ -43,6 +43,7 @@ __export(cli_exports, {
|
|
|
43
43
|
formatK8sCpu: () => formatK8sCpu,
|
|
44
44
|
formatK8sMemory: () => formatK8sMemory,
|
|
45
45
|
formatProcessAge: () => formatProcessAge,
|
|
46
|
+
formatProcessLane: () => formatProcessLane,
|
|
46
47
|
getCliHelpText: () => getCliHelpText,
|
|
47
48
|
getK8sUsageState: () => getK8sUsageState,
|
|
48
49
|
getProjectEnvValue: () => getProjectEnvValue,
|
|
@@ -100,6 +101,7 @@ __export(cli_exports, {
|
|
|
100
101
|
renderSessionList: () => renderSessionList,
|
|
101
102
|
renderSessionRunStart: () => renderSessionRunStart,
|
|
102
103
|
renderSessionRunStatus: () => renderSessionRunStatus,
|
|
104
|
+
renderWorkerCapacity: () => renderWorkerCapacity,
|
|
103
105
|
renderWorkspaceStatus: () => renderWorkspaceStatus,
|
|
104
106
|
renderWorkspaceSync: () => renderWorkspaceSync,
|
|
105
107
|
resolveCommandExecution: () => resolveCommandExecution,
|
|
@@ -1890,6 +1892,23 @@ function renderRecentSessionList(sessions) {
|
|
|
1890
1892
|
return `${sessions.map((session) => `${session.id} ${session.projectPath}/${session.branchName} ${session.name ?? "(unnamed)"}`).join("\n")}
|
|
1891
1893
|
`;
|
|
1892
1894
|
}
|
|
1895
|
+
function renderWorkerCapacity(workerLabel, capacity) {
|
|
1896
|
+
if (!capacity) return [`Command capacity on ${workerLabel}: not reported yet`];
|
|
1897
|
+
if (!capacity.bounded) return [`Command capacity on ${workerLabel}: unbounded (no managed launcher)`];
|
|
1898
|
+
const describeLane = (lane) => {
|
|
1899
|
+
const report = capacity.lanes[lane];
|
|
1900
|
+
const slots = report.slots === null ? "?" : String(report.slots);
|
|
1901
|
+
const holders = report.active.map((entry) => `${entry.id}${entry.sessionId ? ` (session ${entry.sessionId})` : ""}`);
|
|
1902
|
+
const queued = report.queued.map((entry) => `${entry.id}${entry.sessionId ? ` (session ${entry.sessionId})` : ""}`);
|
|
1903
|
+
return ` ${lane}: ${report.active.length}/${slots} busy${holders.length ? `, held by ${holders.join(", ")}` : ""}${queued.length ? `; queued: ${queued.join(", ")}` : ""}`;
|
|
1904
|
+
};
|
|
1905
|
+
return [
|
|
1906
|
+
`Command capacity on ${workerLabel} (reported ${capacity.reportedAt}):`,
|
|
1907
|
+
describeLane("general"),
|
|
1908
|
+
describeLane("utility"),
|
|
1909
|
+
`${describeLane("control")}${capacity.controlRuntimeMs !== null ? ` (plain r5dctl coordination, ${Math.round(capacity.controlRuntimeMs / 1e3)}s limit)` : ""}`
|
|
1910
|
+
];
|
|
1911
|
+
}
|
|
1893
1912
|
function renderWorkspaceStatus(status) {
|
|
1894
1913
|
const lines = [
|
|
1895
1914
|
`Workspace HEAD: ${status.head ?? "(not initialized)"}`,
|
|
@@ -1897,7 +1916,8 @@ function renderWorkspaceStatus(status) {
|
|
|
1897
1916
|
`Remediation: ${status.incident ? `${status.incident.kind} ${status.incident.status} (${status.incident.id}) on ${status.incident.originWorkerLabel}` : "none"}`,
|
|
1898
1917
|
...status.workers.flatMap((worker) => [
|
|
1899
1918
|
`Worker ${worker.workerLabel}: ${worker.configured ? "configured" : "configuring"}; head ${worker.localHead ?? "(none)"}; pending checkouts ${worker.pendingCheckouts.length}`,
|
|
1900
|
-
...renderMissingCheckouts(worker.workerLabel, worker.missingCheckouts ?? [])
|
|
1919
|
+
...renderMissingCheckouts(worker.workerLabel, worker.missingCheckouts ?? []),
|
|
1920
|
+
...renderWorkerCapacity(worker.workerLabel, worker.capacity)
|
|
1901
1921
|
])
|
|
1902
1922
|
];
|
|
1903
1923
|
if (status.latestSync?.missingCheckouts?.length && !status.workers.some((worker) => worker.missingCheckouts?.length)) {
|
|
@@ -2131,10 +2151,11 @@ function renderProcessList(processes, nowMs = Date.now()) {
|
|
|
2131
2151
|
if (processes.length === 0) {
|
|
2132
2152
|
return "No active processes.\n";
|
|
2133
2153
|
}
|
|
2134
|
-
const headers = ["RUN ID", "STATUS", "AGE", "WORKER", "TARGET", "SCOPE", "SESSION", "COMMAND"];
|
|
2154
|
+
const headers = ["RUN ID", "STATUS", "LANE", "AGE", "WORKER", "TARGET", "SCOPE", "SESSION", "COMMAND"];
|
|
2135
2155
|
const rows = processes.map((process2) => [
|
|
2136
2156
|
process2.runId,
|
|
2137
2157
|
process2.status,
|
|
2158
|
+
formatProcessLane(process2),
|
|
2138
2159
|
formatProcessAge(process2.startedAt, nowMs),
|
|
2139
2160
|
process2.workerLabel,
|
|
2140
2161
|
process2.projectPath,
|
|
@@ -2148,6 +2169,10 @@ function renderProcessList(processes, nowMs = Date.now()) {
|
|
|
2148
2169
|
return `${[formatRow(headers), separator, ...rows.map(formatRow)].join("\n")}
|
|
2149
2170
|
`;
|
|
2150
2171
|
}
|
|
2172
|
+
function formatProcessLane(process2) {
|
|
2173
|
+
if (process2.admission) return process2.admission.phase === "queued" ? `queued:${process2.admission.lane}` : process2.admission.lane;
|
|
2174
|
+
return process2.commandClass ?? "-";
|
|
2175
|
+
}
|
|
2151
2176
|
function renderProcessHistory(processes, nowMs = Date.now()) {
|
|
2152
2177
|
return processes.length === 0 ? "No process history.\n" : renderProcessList(processes, nowMs);
|
|
2153
2178
|
}
|
|
@@ -2185,6 +2210,7 @@ function renderProcessInspection(process2) {
|
|
|
2185
2210
|
`Worker: ${process2.workerLabel} (${process2.platform ?? "unknown"}/${process2.arch ?? "unknown"})`,
|
|
2186
2211
|
`Target: ${process2.projectPath} ${process2.target.type === "project" ? process2.target.branchName : process2.target.rootProfile}`,
|
|
2187
2212
|
`Session: ${process2.sessionId}`,
|
|
2213
|
+
`Lane: ${formatProcessLane(process2)}${process2.admission ? ` since ${process2.admission.since}` : ""}`,
|
|
2188
2214
|
`Command: ${process2.command}`,
|
|
2189
2215
|
`Argv: ${JSON.stringify(process2.argv)}`,
|
|
2190
2216
|
`CWD: ${process2.cwd ?? "(execution root)"}`,
|
|
@@ -4046,6 +4072,7 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
4046
4072
|
formatK8sCpu,
|
|
4047
4073
|
formatK8sMemory,
|
|
4048
4074
|
formatProcessAge,
|
|
4075
|
+
formatProcessLane,
|
|
4049
4076
|
getCliHelpText,
|
|
4050
4077
|
getK8sUsageState,
|
|
4051
4078
|
getProjectEnvValue,
|
|
@@ -4103,6 +4130,7 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
4103
4130
|
renderSessionList,
|
|
4104
4131
|
renderSessionRunStart,
|
|
4105
4132
|
renderSessionRunStatus,
|
|
4133
|
+
renderWorkerCapacity,
|
|
4106
4134
|
renderWorkspaceStatus,
|
|
4107
4135
|
renderWorkspaceSync,
|
|
4108
4136
|
resolveCommandExecution,
|
package/dist/cjs/package.json
CHANGED
package/dist/mjs/cli.mjs
CHANGED
|
@@ -1781,6 +1781,23 @@ function renderRecentSessionList(sessions) {
|
|
|
1781
1781
|
return `${sessions.map((session) => `${session.id} ${session.projectPath}/${session.branchName} ${session.name ?? "(unnamed)"}`).join("\n")}
|
|
1782
1782
|
`;
|
|
1783
1783
|
}
|
|
1784
|
+
function renderWorkerCapacity(workerLabel, capacity) {
|
|
1785
|
+
if (!capacity) return [`Command capacity on ${workerLabel}: not reported yet`];
|
|
1786
|
+
if (!capacity.bounded) return [`Command capacity on ${workerLabel}: unbounded (no managed launcher)`];
|
|
1787
|
+
const describeLane = (lane) => {
|
|
1788
|
+
const report = capacity.lanes[lane];
|
|
1789
|
+
const slots = report.slots === null ? "?" : String(report.slots);
|
|
1790
|
+
const holders = report.active.map((entry) => `${entry.id}${entry.sessionId ? ` (session ${entry.sessionId})` : ""}`);
|
|
1791
|
+
const queued = report.queued.map((entry) => `${entry.id}${entry.sessionId ? ` (session ${entry.sessionId})` : ""}`);
|
|
1792
|
+
return ` ${lane}: ${report.active.length}/${slots} busy${holders.length ? `, held by ${holders.join(", ")}` : ""}${queued.length ? `; queued: ${queued.join(", ")}` : ""}`;
|
|
1793
|
+
};
|
|
1794
|
+
return [
|
|
1795
|
+
`Command capacity on ${workerLabel} (reported ${capacity.reportedAt}):`,
|
|
1796
|
+
describeLane("general"),
|
|
1797
|
+
describeLane("utility"),
|
|
1798
|
+
`${describeLane("control")}${capacity.controlRuntimeMs !== null ? ` (plain r5dctl coordination, ${Math.round(capacity.controlRuntimeMs / 1e3)}s limit)` : ""}`
|
|
1799
|
+
];
|
|
1800
|
+
}
|
|
1784
1801
|
function renderWorkspaceStatus(status) {
|
|
1785
1802
|
const lines = [
|
|
1786
1803
|
`Workspace HEAD: ${status.head ?? "(not initialized)"}`,
|
|
@@ -1788,7 +1805,8 @@ function renderWorkspaceStatus(status) {
|
|
|
1788
1805
|
`Remediation: ${status.incident ? `${status.incident.kind} ${status.incident.status} (${status.incident.id}) on ${status.incident.originWorkerLabel}` : "none"}`,
|
|
1789
1806
|
...status.workers.flatMap((worker) => [
|
|
1790
1807
|
`Worker ${worker.workerLabel}: ${worker.configured ? "configured" : "configuring"}; head ${worker.localHead ?? "(none)"}; pending checkouts ${worker.pendingCheckouts.length}`,
|
|
1791
|
-
...renderMissingCheckouts(worker.workerLabel, worker.missingCheckouts ?? [])
|
|
1808
|
+
...renderMissingCheckouts(worker.workerLabel, worker.missingCheckouts ?? []),
|
|
1809
|
+
...renderWorkerCapacity(worker.workerLabel, worker.capacity)
|
|
1792
1810
|
])
|
|
1793
1811
|
];
|
|
1794
1812
|
if (status.latestSync?.missingCheckouts?.length && !status.workers.some((worker) => worker.missingCheckouts?.length)) {
|
|
@@ -2022,10 +2040,11 @@ function renderProcessList(processes, nowMs = Date.now()) {
|
|
|
2022
2040
|
if (processes.length === 0) {
|
|
2023
2041
|
return "No active processes.\n";
|
|
2024
2042
|
}
|
|
2025
|
-
const headers = ["RUN ID", "STATUS", "AGE", "WORKER", "TARGET", "SCOPE", "SESSION", "COMMAND"];
|
|
2043
|
+
const headers = ["RUN ID", "STATUS", "LANE", "AGE", "WORKER", "TARGET", "SCOPE", "SESSION", "COMMAND"];
|
|
2026
2044
|
const rows = processes.map((process2) => [
|
|
2027
2045
|
process2.runId,
|
|
2028
2046
|
process2.status,
|
|
2047
|
+
formatProcessLane(process2),
|
|
2029
2048
|
formatProcessAge(process2.startedAt, nowMs),
|
|
2030
2049
|
process2.workerLabel,
|
|
2031
2050
|
process2.projectPath,
|
|
@@ -2039,6 +2058,10 @@ function renderProcessList(processes, nowMs = Date.now()) {
|
|
|
2039
2058
|
return `${[formatRow(headers), separator, ...rows.map(formatRow)].join("\n")}
|
|
2040
2059
|
`;
|
|
2041
2060
|
}
|
|
2061
|
+
function formatProcessLane(process2) {
|
|
2062
|
+
if (process2.admission) return process2.admission.phase === "queued" ? `queued:${process2.admission.lane}` : process2.admission.lane;
|
|
2063
|
+
return process2.commandClass ?? "-";
|
|
2064
|
+
}
|
|
2042
2065
|
function renderProcessHistory(processes, nowMs = Date.now()) {
|
|
2043
2066
|
return processes.length === 0 ? "No process history.\n" : renderProcessList(processes, nowMs);
|
|
2044
2067
|
}
|
|
@@ -2076,6 +2099,7 @@ function renderProcessInspection(process2) {
|
|
|
2076
2099
|
`Worker: ${process2.workerLabel} (${process2.platform ?? "unknown"}/${process2.arch ?? "unknown"})`,
|
|
2077
2100
|
`Target: ${process2.projectPath} ${process2.target.type === "project" ? process2.target.branchName : process2.target.rootProfile}`,
|
|
2078
2101
|
`Session: ${process2.sessionId}`,
|
|
2102
|
+
`Lane: ${formatProcessLane(process2)}${process2.admission ? ` since ${process2.admission.since}` : ""}`,
|
|
2079
2103
|
`Command: ${process2.command}`,
|
|
2080
2104
|
`Argv: ${JSON.stringify(process2.argv)}`,
|
|
2081
2105
|
`CWD: ${process2.cwd ?? "(execution root)"}`,
|
|
@@ -3936,6 +3960,7 @@ export {
|
|
|
3936
3960
|
formatK8sCpu,
|
|
3937
3961
|
formatK8sMemory,
|
|
3938
3962
|
formatProcessAge,
|
|
3963
|
+
formatProcessLane,
|
|
3939
3964
|
getCliHelpText,
|
|
3940
3965
|
getK8sUsageState,
|
|
3941
3966
|
getProjectEnvValue,
|
|
@@ -3993,6 +4018,7 @@ export {
|
|
|
3993
4018
|
renderSessionList,
|
|
3994
4019
|
renderSessionRunStart,
|
|
3995
4020
|
renderSessionRunStatus,
|
|
4021
|
+
renderWorkerCapacity,
|
|
3996
4022
|
renderWorkspaceStatus,
|
|
3997
4023
|
renderWorkspaceSync,
|
|
3998
4024
|
resolveCommandExecution,
|
package/dist/mjs/package.json
CHANGED
package/dist/types/cli.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { R5dctlApiError, R5dctlClient, type R5dctlConversationForkResponse, type R5dctlConversationHeadResponse, type R5dctlConversationRenderOptions, type R5dctlConversationResponse, type R5dctlConversationNodeResponse, type R5dctlConversationOverviewResponse, type R5dctlConversationWorkDetail, type R5dctlConversationWorkResponse, type R5dctlEnvData, type R5dctlK8sResourceHistory, type R5dctlK8sUsage, type R5dctlK8sWorkload, type R5dctlProcessInspection, type R5dctlProcessListInput, type R5dctlProcessLog, type R5dctlProcessRun, type R5dctlBranch, type R5dctlBranchDeletionStatus, type R5dctlBranchDescription, type R5dctlBranchOperation, type R5dctlSessionSummary, type R5dctlSessionClaim, type R5dctlSessionClaimListResponse, type R5dctlSessionEvent, type R5dctlSessionStartInput, type R5dctlWorkspaceStatus, type R5dctlWorkspaceSyncResult, type R5dctlWorkingTreeMode, type R5dctlWorktreeSource, type R5dctlPromptDelivery, type R5dctlSessionMode, type ChatMode, type ModelTier } from "@ricsam/r5d-api";
|
|
1
|
+
import { R5dctlApiError, R5dctlClient, type R5dctlConversationForkResponse, type R5dctlConversationHeadResponse, type R5dctlConversationRenderOptions, type R5dctlConversationResponse, type R5dctlConversationNodeResponse, type R5dctlConversationOverviewResponse, type R5dctlConversationWorkDetail, type R5dctlConversationWorkResponse, type R5dctlEnvData, type R5dctlK8sResourceHistory, type R5dctlK8sUsage, type R5dctlK8sWorkload, type R5dctlProcessInspection, type R5dctlProcessListInput, type R5dctlProcessLog, type R5dctlProcessRun, type R5dctlWorkerCapacityReport, type R5dctlBranch, type R5dctlBranchDeletionStatus, type R5dctlBranchDescription, type R5dctlBranchOperation, type R5dctlSessionSummary, type R5dctlSessionClaim, type R5dctlSessionClaimListResponse, type R5dctlSessionEvent, type R5dctlSessionStartInput, type R5dctlWorkspaceStatus, type R5dctlWorkspaceSyncResult, type R5dctlWorkingTreeMode, type R5dctlWorktreeSource, type R5dctlPromptDelivery, type R5dctlSessionMode, type ChatMode, type ModelTier } from "@ricsam/r5d-api";
|
|
2
2
|
export type GlobalOptions = {
|
|
3
3
|
baseUrl?: string;
|
|
4
4
|
json: boolean;
|
|
@@ -278,6 +278,8 @@ export declare function advanceTransientDevicePollBackoff(intervalMs: number, tr
|
|
|
278
278
|
};
|
|
279
279
|
export declare function handleAuthLogin(client: R5dctlClient, options: GlobalOptions, commandArgs: string[], config: R5dctlConfig): Promise<void>;
|
|
280
280
|
export declare function renderSessionList(sessions: R5dctlSessionSummary[], nowMs?: number): string;
|
|
281
|
+
/** One line per worker naming every lane's holders and queue, so an agent can see whom to ask to free capacity. */
|
|
282
|
+
export declare function renderWorkerCapacity(workerLabel: string, capacity: R5dctlWorkerCapacityReport | null | undefined): string[];
|
|
281
283
|
export declare function renderWorkspaceStatus(status: R5dctlWorkspaceStatus): string;
|
|
282
284
|
export declare function renderBranchList(branches: R5dctlBranch[]): string;
|
|
283
285
|
export declare function renderWorkspaceSync(result: R5dctlWorkspaceSyncResult): string;
|
|
@@ -318,6 +320,8 @@ export declare function getK8sUsageState(entry: K8sUsageReport["entries"][number
|
|
|
318
320
|
export declare function renderK8sUsageReport(report: K8sUsageReport): string;
|
|
319
321
|
export declare function formatProcessAge(startedAt: string, nowMs?: number): string;
|
|
320
322
|
export declare function renderProcessList(processes: R5dctlProcessRun[], nowMs?: number): string;
|
|
323
|
+
/** `general`, `control`, `queued:general`, or `-` when the worker reported nothing for this run. */
|
|
324
|
+
export declare function formatProcessLane(process: Pick<R5dctlProcessRun, "admission" | "commandClass">): string;
|
|
321
325
|
export declare function renderProcessHistory(processes: R5dctlProcessRun[], nowMs?: number): string;
|
|
322
326
|
/** Streams go to stdout under `==> name <==` headers; the selection summary is returned separately for stderr. */
|
|
323
327
|
export declare function renderProcessLog(log: R5dctlProcessLog): {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ricsam/r5dctl",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.124",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/cjs/cli.cjs",
|
|
6
6
|
"module": "./dist/mjs/cli.mjs",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"r5dctl": "dist/cjs/main.cjs"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@ricsam/r5d-api": "^0.0.
|
|
29
|
+
"@ricsam/r5d-api": "^0.0.124",
|
|
30
30
|
"dotenv": "^17",
|
|
31
31
|
"qrcode": "^1.5.4",
|
|
32
32
|
"ws": "^8.18.3"
|