@kikimoradev/kcloud 1.5.2 → 1.5.4
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/dist/main.js +80 -13
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -839,6 +839,7 @@ const errorCodes = Object.keys({
|
|
|
839
839
|
"infrastructure.provider_error": "internal",
|
|
840
840
|
"infrastructure.operation_in_progress": "conflict",
|
|
841
841
|
"infrastructure.host_ops_disabled": "rule_violation",
|
|
842
|
+
"platform.isolated": "rule_violation",
|
|
842
843
|
"backup.not_found": "not_found",
|
|
843
844
|
"backup.in_progress": "conflict",
|
|
844
845
|
"backup.unavailable": "rule_violation",
|
|
@@ -1130,7 +1131,9 @@ const agentProvisionSchema = z.object({
|
|
|
1130
1131
|
"ok",
|
|
1131
1132
|
"fetch_failed",
|
|
1132
1133
|
"clone_failed"
|
|
1133
|
-
])
|
|
1134
|
+
]),
|
|
1135
|
+
brokenCloneMovedTo: z.string().optional(),
|
|
1136
|
+
locksKeptForSandbox: z.array(z.string()).optional()
|
|
1134
1137
|
})),
|
|
1135
1138
|
docker: z.enum([
|
|
1136
1139
|
"ready",
|
|
@@ -1151,6 +1154,10 @@ const agentProgressSchema = z.object({
|
|
|
1151
1154
|
layersTotal: z.int().nonnegative().nullable(),
|
|
1152
1155
|
updatedAt: z.iso.datetime()
|
|
1153
1156
|
}).meta({ id: "AgentProgress" });
|
|
1157
|
+
const agentClaudeCodeSchema = z.object({
|
|
1158
|
+
version: z.string().nullable(),
|
|
1159
|
+
source: z.enum(["release", "host"])
|
|
1160
|
+
}).meta({ id: "AgentClaudeCode" });
|
|
1154
1161
|
const storageStates = [
|
|
1155
1162
|
"ok",
|
|
1156
1163
|
"warning",
|
|
@@ -1593,10 +1600,17 @@ z.object({
|
|
|
1593
1600
|
monitor: sessionSlotCountSchema.nullable(),
|
|
1594
1601
|
executor: sessionSlotCountSchema.nullable()
|
|
1595
1602
|
}).meta({ id: "UpdateSessionSlotsBody" });
|
|
1603
|
+
const admissionWaitReasonSchema = z.enum([
|
|
1604
|
+
"slot",
|
|
1605
|
+
"pool",
|
|
1606
|
+
"earlier_run",
|
|
1607
|
+
"renewal"
|
|
1608
|
+
]);
|
|
1596
1609
|
const agentAdmissionStateSchema = z.discriminatedUnion("state", [z.object({
|
|
1597
1610
|
state: z.literal("waiting"),
|
|
1598
1611
|
since: z.iso.datetime(),
|
|
1599
|
-
position: z.int().positive()
|
|
1612
|
+
position: z.int().positive(),
|
|
1613
|
+
reason: admissionWaitReasonSchema
|
|
1600
1614
|
}), z.object({ state: z.literal("holding") })]).meta({ id: "AgentAdmissionState" });
|
|
1601
1615
|
const agentAdmissionSchema = z.object({
|
|
1602
1616
|
monitor: agentAdmissionStateSchema.nullable(),
|
|
@@ -1816,6 +1830,8 @@ const nodeAgentSchema = z.object({
|
|
|
1816
1830
|
projectId: idSchema,
|
|
1817
1831
|
projectName: z.string(),
|
|
1818
1832
|
state: agentStateSchema,
|
|
1833
|
+
failureReason: z.string().nullable(),
|
|
1834
|
+
retryAt: z.iso.datetime().nullable(),
|
|
1819
1835
|
poolLimit: poolLimitSchema.nullable()
|
|
1820
1836
|
}).meta({ id: "NodeAgent" });
|
|
1821
1837
|
const nodeRuntimeSchema = z.object({
|
|
@@ -2131,7 +2147,10 @@ const cliTokenReadySchema = z.object({
|
|
|
2131
2147
|
user: meSchema
|
|
2132
2148
|
}).meta({ id: "CliTokenReady" });
|
|
2133
2149
|
z.discriminatedUnion("status", [cliTokenWaitingSchema, cliTokenReadySchema]).meta({ id: "ClaimedCliToken" });
|
|
2134
|
-
z.object({
|
|
2150
|
+
z.object({
|
|
2151
|
+
version: z.string(),
|
|
2152
|
+
isolated: z.boolean()
|
|
2153
|
+
}).meta({ id: "PlatformVersion" });
|
|
2135
2154
|
const auditActionSchema = z.enum([
|
|
2136
2155
|
"platform.bootstrapped",
|
|
2137
2156
|
"organization.created",
|
|
@@ -2695,7 +2714,8 @@ const agentRuntimeSchema = z.object({
|
|
|
2695
2714
|
stopDeadlineAt: z.iso.datetime().nullable(),
|
|
2696
2715
|
admission: agentAdmissionSchema.nullable(),
|
|
2697
2716
|
admissionHold: admissionHoldSchema.nullable(),
|
|
2698
|
-
poolLimit: poolLimitSchema.nullable()
|
|
2717
|
+
poolLimit: poolLimitSchema.nullable(),
|
|
2718
|
+
claudeCode: agentClaudeCodeSchema.nullable()
|
|
2699
2719
|
}).meta({ id: "AgentRuntime" });
|
|
2700
2720
|
const agentListItemSchema = z.object({
|
|
2701
2721
|
id: idSchema,
|
|
@@ -3053,6 +3073,14 @@ pageSchema(z.object({
|
|
|
3053
3073
|
}).meta({ id: "Backup" })).meta({ id: "BackupPage" });
|
|
3054
3074
|
z.object({ id: idSchema });
|
|
3055
3075
|
z.object({ confirm: z.string().min(1).max(512) }).meta({ id: "RestoreBackupBody" });
|
|
3076
|
+
const syncedBackupCountSchema = z.int().nonnegative();
|
|
3077
|
+
z.object({
|
|
3078
|
+
discovered: syncedBackupCountSchema,
|
|
3079
|
+
vanished: syncedBackupCountSchema,
|
|
3080
|
+
reappeared: syncedBackupCountSchema,
|
|
3081
|
+
finished: syncedBackupCountSchema,
|
|
3082
|
+
abandoned: syncedBackupCountSchema
|
|
3083
|
+
}).meta({ id: "BackupSync" });
|
|
3056
3084
|
const backupPartSchema = z.object({
|
|
3057
3085
|
name: z.enum(backupPartNames),
|
|
3058
3086
|
bytes: byteCountSchema$1,
|
|
@@ -3956,12 +3984,14 @@ const createVersionCommand = (adaptersOf, cliVersion) => defineCommand({
|
|
|
3956
3984
|
kcloud: cliVersion,
|
|
3957
3985
|
instance: platform.version,
|
|
3958
3986
|
origin: session.origin,
|
|
3959
|
-
matched
|
|
3987
|
+
matched,
|
|
3988
|
+
isolated: platform.isolated
|
|
3960
3989
|
});
|
|
3961
3990
|
return exitCodes.ok;
|
|
3962
3991
|
}
|
|
3963
3992
|
context.terminal.line(renderTable([{ header: "WHAT" }, { header: "VERSION" }], [["kcloud", cliVersion], [session.origin, platform.version]]));
|
|
3964
3993
|
if (!matched) context.terminal.error(context.terminal.errorStyles.warning(`warning kcloud ${cliVersion} is talking to an instance on ${platform.version}.`));
|
|
3994
|
+
if (platform.isolated) context.terminal.error(context.terminal.errorStyles.warning(`warning ${session.origin} is isolated: it reaches no outside service and admits no node.`));
|
|
3965
3995
|
return exitCodes.ok;
|
|
3966
3996
|
}
|
|
3967
3997
|
});
|
|
@@ -4047,7 +4077,7 @@ const providerHints = {
|
|
|
4047
4077
|
"provider.token_unauthorized": "DigitalOcean refused the token. Create a new one under API, Tokens in its control panel.",
|
|
4048
4078
|
"concurrency.conflict": "Someone changed the account meanwhile; run the command again."
|
|
4049
4079
|
};
|
|
4050
|
-
const reasonOf$
|
|
4080
|
+
const reasonOf$2 = (error) => {
|
|
4051
4081
|
const reason = error.details.reason;
|
|
4052
4082
|
return typeof reason === "string" && reason !== "" ? `: ${reason}` : "";
|
|
4053
4083
|
};
|
|
@@ -4063,7 +4093,7 @@ const explained = (error) => {
|
|
|
4063
4093
|
const failure = apiErrorOf$1(error);
|
|
4064
4094
|
switch (failure?.code) {
|
|
4065
4095
|
case "provider.token_scopes_missing": return new CliError(failure.message, `The token lacks ${missingScopesOf(failure)}. kcloud providers add --help lists every scope it needs.`, { cause: failure });
|
|
4066
|
-
case "provider.unavailable": return new CliError(failure.message, `DigitalOcean did not answer as expected${reasonOf$
|
|
4096
|
+
case "provider.unavailable": return new CliError(failure.message, `DigitalOcean did not answer as expected${reasonOf$2(failure)}. Try again in a moment.`, { cause: failure });
|
|
4067
4097
|
default: return error;
|
|
4068
4098
|
}
|
|
4069
4099
|
};
|
|
@@ -4713,6 +4743,11 @@ const agentsOf = async (scope, project) => {
|
|
|
4713
4743
|
}
|
|
4714
4744
|
return listed;
|
|
4715
4745
|
};
|
|
4746
|
+
const changeTakingActions = ["start", "update"];
|
|
4747
|
+
const changeTakerOf = ({ availableActions }) => {
|
|
4748
|
+
const takers = changeTakingActions.filter((action) => availableActions.includes(action)).map((action) => `kcloud agents ${action}`);
|
|
4749
|
+
return takers.length === 0 ? "a restart" : takers.join(" or ");
|
|
4750
|
+
};
|
|
4716
4751
|
const changedAgent = async (api, agentId, document) => {
|
|
4717
4752
|
const current = dataOf("describe the agent", await api.GET("/agents/{id}", { params: { path: { id: agentId } } }), agentHints);
|
|
4718
4753
|
const change = typeof document === "object" && document !== null && "version" in document ? document : {
|
|
@@ -4804,7 +4839,7 @@ const configCommands = (adaptersOf) => [
|
|
|
4804
4839
|
const file = invocation.values.file;
|
|
4805
4840
|
if (file === void 0) throw new UsageError("agents set needs --file <path>.", "The file holds the sections to change; kcloud agents show <agent> --json shows the current ones.");
|
|
4806
4841
|
const agent = await changedAgent(run.api, agentId, agentChangeWithoutLimits(run, await documentOf(run, file)));
|
|
4807
|
-
return printed(run, agent, (changed) => changed.restartRequired ? `Changed ${changed.name}; it needs
|
|
4842
|
+
return printed(run, agent, (changed) => changed.restartRequired ? `Changed ${changed.name}; it needs ${changeTakerOf(changed)} to take the change.` : `Changed ${changed.name}.`);
|
|
4808
4843
|
}
|
|
4809
4844
|
}),
|
|
4810
4845
|
defineCommand({
|
|
@@ -4848,9 +4883,25 @@ const admissionRowsOf = (agent) => {
|
|
|
4848
4883
|
const { admission } = agent.runtime;
|
|
4849
4884
|
return admission === null ? [] : [["monitor slot", slotOf(admission.monitor)], ["executor slot", slotOf(admission.executor)]];
|
|
4850
4885
|
};
|
|
4851
|
-
const
|
|
4852
|
-
|
|
4853
|
-
|
|
4886
|
+
const waitTexts = {
|
|
4887
|
+
slot: "waits for a slot",
|
|
4888
|
+
pool: "held by the pool of the node",
|
|
4889
|
+
earlier_run: "held until the node restarts its run of an earlier task run",
|
|
4890
|
+
renewal: "held while the node restarts the run"
|
|
4891
|
+
};
|
|
4892
|
+
const reasonOf$1 = ({ reason }) => reason ?? "slot";
|
|
4893
|
+
const waitRowsOf = ({ runtime }) => {
|
|
4894
|
+
const { admission } = runtime;
|
|
4895
|
+
if (admission === null) return [];
|
|
4896
|
+
const waits = ["monitor", "executor"].flatMap((role) => {
|
|
4897
|
+
const state = admission[role];
|
|
4898
|
+
return state?.state === "waiting" ? [`${role} ${waitTexts[reasonOf$1(state)]}`] : [];
|
|
4899
|
+
});
|
|
4900
|
+
return waits.length === 0 ? [] : [["admissions", waits.join("; ")]];
|
|
4901
|
+
};
|
|
4902
|
+
const admissionHoldRowsOf = (agent) => {
|
|
4903
|
+
const hold = agent.runtime.admissionHold;
|
|
4904
|
+
if (hold == null) return waitRowsOf(agent);
|
|
4854
4905
|
if (hold.updating || hold.awaits === "start") return [["admissions", `held while the node updates to ${hold.target ?? "-"}`]];
|
|
4855
4906
|
const all = hold.pools.includes("monitor");
|
|
4856
4907
|
const noun = all ? "session" : "executor session";
|
|
@@ -4858,6 +4909,15 @@ const admissionHoldRowsOf = ({ runtime }) => {
|
|
|
4858
4909
|
return [["admissions", `${all ? "held" : "executor held"} for the node update to ${hold.target ?? "-"}, waiting for ${waits}`]];
|
|
4859
4910
|
};
|
|
4860
4911
|
const poolLimitRowsOf = ({ runtime }) => runtime.poolLimit === null ? [] : [["pool limit", poolLimitText(runtime.poolLimit)]];
|
|
4912
|
+
const claudeCodeOf = ({ runtime, release }) => {
|
|
4913
|
+
const running = runtime.claudeCode ?? null;
|
|
4914
|
+
if (running?.source === "host") return "host";
|
|
4915
|
+
return running?.version ?? release?.claudeCodeVersion ?? "unknown";
|
|
4916
|
+
};
|
|
4917
|
+
const failureRowsOf = ({ failureReason, retryAt }) => {
|
|
4918
|
+
if (failureReason === null) return [];
|
|
4919
|
+
return [["failure", retryAt === null ? failureReason : `${failureReason}, retry at ${retryAt}`]];
|
|
4920
|
+
};
|
|
4861
4921
|
const detailsOf = (agent) => [
|
|
4862
4922
|
renderTable([{ header: "FIELD" }, { header: "VALUE" }], [
|
|
4863
4923
|
["name", agent.name],
|
|
@@ -4866,6 +4926,7 @@ const detailsOf = (agent) => [
|
|
|
4866
4926
|
["wanted", agent.desiredState],
|
|
4867
4927
|
["observed", agent.observedState],
|
|
4868
4928
|
["release", agent.kikimoraVersion],
|
|
4929
|
+
["claude code", claudeCodeOf(agent)],
|
|
4869
4930
|
["node", agent.node === null ? "none" : `${agent.node.name} (${agent.node.state})`],
|
|
4870
4931
|
["requires", agent.requiredCapabilities.length === 0 ? "nothing" : agent.requiredCapabilities.join(", ")],
|
|
4871
4932
|
["timezone", agent.timezone],
|
|
@@ -4874,6 +4935,7 @@ const detailsOf = (agent) => [
|
|
|
4874
4935
|
["browser", agent.machine.browser ? "yes" : "no"],
|
|
4875
4936
|
["container", agent.runtime.containerId ?? "none"],
|
|
4876
4937
|
["health", agent.runtime.health],
|
|
4938
|
+
...failureRowsOf(agent),
|
|
4877
4939
|
...admissionRowsOf(agent),
|
|
4878
4940
|
...admissionHoldRowsOf(agent),
|
|
4879
4941
|
...poolLimitRowsOf(agent),
|
|
@@ -6695,7 +6757,7 @@ const agentTools = [
|
|
|
6695
6757
|
defineTool({
|
|
6696
6758
|
name: "agent_update",
|
|
6697
6759
|
title: "Change an agent",
|
|
6698
|
-
description: "Change sections of an agent. Without version the change applies to the version read just before it. When restartRequired comes back true, agent_action update applies the change.",
|
|
6760
|
+
description: "Change sections of an agent. Without version the change applies to the version read just before it. When restartRequired comes back true, agent_action start or update applies the change, whichever availableActions offers.",
|
|
6699
6761
|
operations: ["updateAgent"],
|
|
6700
6762
|
safety: "write",
|
|
6701
6763
|
input: z.object({
|
|
@@ -6733,7 +6795,7 @@ const agentTools = [
|
|
|
6733
6795
|
defineTool({
|
|
6734
6796
|
name: "agent_action",
|
|
6735
6797
|
title: "Start, pause, resume, restart or update an agent",
|
|
6736
|
-
description: "start lets the agent work, pause holds it between sessions, resume lets a paused agent work again, restart restarts its container, update replaces the container to apply pending changes. The agent returns with the actions it takes next.",
|
|
6798
|
+
description: "start lets the agent work and applies pending changes, pause holds it between sessions, resume lets a paused agent work again, restart restarts its container, update replaces the container to apply pending changes. The agent returns with the actions it takes next.",
|
|
6737
6799
|
operations: ["runAgentAction"],
|
|
6738
6800
|
safety: "write",
|
|
6739
6801
|
input: z.object({
|
|
@@ -9957,6 +10019,10 @@ const lastUpdateOf = ({ update }) => {
|
|
|
9957
10019
|
const outcome = `${last.outcome} ${last.version ?? "-"} at ${last.at}`;
|
|
9958
10020
|
return last.reason === null ? outcome : `${outcome}: ${last.reason}`;
|
|
9959
10021
|
};
|
|
10022
|
+
const agentFailuresOf = ({ agents }) => agents.flatMap(({ slug, failureReason, retryAt }) => {
|
|
10023
|
+
if (failureReason === null) return [];
|
|
10024
|
+
return [`${slug} failure: ${retryAt === null ? failureReason : `${failureReason}, retry at ${retryAt}`}`];
|
|
10025
|
+
});
|
|
9960
10026
|
const nodeDetailsText = (node) => [
|
|
9961
10027
|
renderTable([{ header: "FIELD" }, { header: "VALUE" }], [
|
|
9962
10028
|
["name", node.name],
|
|
@@ -9995,6 +10061,7 @@ const nodeDetailsText = (node) => [
|
|
|
9995
10061
|
poolLimitText(agent.poolLimit),
|
|
9996
10062
|
agent.id
|
|
9997
10063
|
])),
|
|
10064
|
+
...agentFailuresOf(node),
|
|
9998
10065
|
"",
|
|
9999
10066
|
...node.runtime === null ? ["The node has reported no runtime yet."] : [
|
|
10000
10067
|
renderTable([{ header: "RUNTIME" }, { header: "VALUE" }], runtimeRowsOf(node.runtime, node.engine)),
|