@kikimoradev/kcloud 1.5.1 → 1.5.3

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.
Files changed (2) hide show
  1. package/dist/main.js +62 -10
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -1130,7 +1130,9 @@ const agentProvisionSchema = z.object({
1130
1130
  "ok",
1131
1131
  "fetch_failed",
1132
1132
  "clone_failed"
1133
- ])
1133
+ ]),
1134
+ brokenCloneMovedTo: z.string().optional(),
1135
+ locksKeptForSandbox: z.array(z.string()).optional()
1134
1136
  })),
1135
1137
  docker: z.enum([
1136
1138
  "ready",
@@ -1151,6 +1153,10 @@ const agentProgressSchema = z.object({
1151
1153
  layersTotal: z.int().nonnegative().nullable(),
1152
1154
  updatedAt: z.iso.datetime()
1153
1155
  }).meta({ id: "AgentProgress" });
1156
+ const agentClaudeCodeSchema = z.object({
1157
+ version: z.string().nullable(),
1158
+ source: z.enum(["release", "host"])
1159
+ }).meta({ id: "AgentClaudeCode" });
1154
1160
  const storageStates = [
1155
1161
  "ok",
1156
1162
  "warning",
@@ -1602,11 +1608,13 @@ const agentAdmissionSchema = z.object({
1602
1608
  monitor: agentAdmissionStateSchema.nullable(),
1603
1609
  executor: agentAdmissionStateSchema.nullable()
1604
1610
  }).meta({ id: "AgentAdmission" });
1611
+ const nodeUpdateAwaits = ["start", "end"];
1605
1612
  const admissionHoldSchema = z.object({
1606
1613
  pools: z.array(sessionRoleSchema),
1607
1614
  sessions: z.int().nonnegative(),
1608
1615
  target: z.string().nullable(),
1609
- updating: z.boolean()
1616
+ updating: z.boolean(),
1617
+ awaits: z.enum(nodeUpdateAwaits)
1610
1618
  }).meta({ id: "AdmissionHold" });
1611
1619
  const nodeStateSchema = z.enum([
1612
1620
  "pending",
@@ -1679,7 +1687,12 @@ const poolUsageSchema = z.object({
1679
1687
  memoryMaxBytes: z.int().nonnegative().nullable(),
1680
1688
  cpus: z.number().nonnegative().nullable(),
1681
1689
  memoryKills: z.int().nonnegative(),
1682
- processors: z.int().positive().nullable().optional()
1690
+ processors: z.int().positive().nullable().optional(),
1691
+ earlierRun: z.object({
1692
+ memoryBytes: z.int().nonnegative().nullable(),
1693
+ holds: z.boolean()
1694
+ }).meta({ id: "EarlierPoolRun" }).nullable().optional(),
1695
+ limitRaised: z.boolean().optional()
1683
1696
  }).meta({ id: "PoolUsage" });
1684
1697
  const nodePoolSchema = z.object({
1685
1698
  slots: z.int().nonnegative(),
@@ -1790,6 +1803,7 @@ const nodeUpdateSchema = z.object({
1790
1803
  sessions: z.int().nonnegative(),
1791
1804
  since: z.iso.datetime().nullable(),
1792
1805
  held: z.array(sessionRoleSchema),
1806
+ awaits: z.enum(nodeUpdateAwaits),
1793
1807
  last: z.object({
1794
1808
  outcome: z.enum([
1795
1809
  "updated",
@@ -1808,6 +1822,8 @@ const nodeAgentSchema = z.object({
1808
1822
  projectId: idSchema,
1809
1823
  projectName: z.string(),
1810
1824
  state: agentStateSchema,
1825
+ failureReason: z.string().nullable(),
1826
+ retryAt: z.iso.datetime().nullable(),
1811
1827
  poolLimit: poolLimitSchema.nullable()
1812
1828
  }).meta({ id: "NodeAgent" });
1813
1829
  const nodeRuntimeSchema = z.object({
@@ -2687,7 +2703,8 @@ const agentRuntimeSchema = z.object({
2687
2703
  stopDeadlineAt: z.iso.datetime().nullable(),
2688
2704
  admission: agentAdmissionSchema.nullable(),
2689
2705
  admissionHold: admissionHoldSchema.nullable(),
2690
- poolLimit: poolLimitSchema.nullable()
2706
+ poolLimit: poolLimitSchema.nullable(),
2707
+ claudeCode: agentClaudeCodeSchema.nullable()
2691
2708
  }).meta({ id: "AgentRuntime" });
2692
2709
  const agentListItemSchema = z.object({
2693
2710
  id: idSchema,
@@ -4507,7 +4524,11 @@ const sessionFailures = {
4507
4524
  launcherRefused: "refused by the session starter"
4508
4525
  };
4509
4526
  const sessionFailureText = (reason) => reason === null ? "-" : sessionFailures[reason] ?? reason;
4510
- const unsupportedReasons = { node_outdated: "the node runs a version that reports no pools" };
4527
+ const unsupportedReasons = {
4528
+ node_outdated: "the node runs a version that reports no pools",
4529
+ configure_failed: "the host did not take the limits",
4530
+ configure_failing: "the node keeps failing to apply the limits, so sessions run without them until it succeeds"
4531
+ };
4511
4532
  const enforcementText = ({ state, reason }) => {
4512
4533
  switch (state) {
4513
4534
  case "enforced": return "The node holds each pool to the CPU and memory of its split.";
@@ -4538,6 +4559,12 @@ const memoryOf$1 = (pool) => {
4538
4559
  return memoryMaxBytes === null ? bytesOf(memoryBytes) : `${bytesOf(memoryBytes)} of ${bytesOf(memoryMaxBytes)}`;
4539
4560
  };
4540
4561
  const roles = ["monitor", "executor"];
4562
+ const earlierRunTexts = (pools) => roles.flatMap((role) => {
4563
+ const earlier = pools[role].usage?.earlierRun ?? null;
4564
+ if (earlier === null) return [];
4565
+ return [`The ${role} pool shares its memory with the sessions of the earlier run of the node, which use ${earlier.memoryBytes === null ? "an unknown amount" : bytesOf(earlier.memoryBytes)}${earlier.holds ? "; new sessions wait until they end" : ""}.`];
4566
+ });
4567
+ const limitRaisedTexts = (pools) => roles.filter((role) => pools[role].usage?.limitRaised === true).map((role) => `The ${role} pool keeps its memory limit above its share while its sessions use more; new sessions wait until they use less.`);
4541
4568
  const workOf = (role, { taskId, taskTitle, readable }) => {
4542
4569
  if (readable === false) return "another project";
4543
4570
  if (taskId === null) return role === "monitor" ? "monitor cycle" : "-";
@@ -4593,6 +4620,8 @@ const poolsText = (pools, split) => {
4593
4620
  ...pools.agentsSlice == null ? [] : [agentsSliceText(pools.agentsSlice)],
4594
4621
  ...pools.refused == null ? [] : [refusedText(pools.refused)],
4595
4622
  ...pools.layout == null ? [] : layoutTexts(pools.layout, split),
4623
+ ...earlierRunTexts(pools),
4624
+ ...limitRaisedTexts(pools),
4596
4625
  renderTable([
4597
4626
  { header: "POOL" },
4598
4627
  { header: "SLOTS IN USE" },
@@ -4693,6 +4722,11 @@ const agentsOf = async (scope, project) => {
4693
4722
  }
4694
4723
  return listed;
4695
4724
  };
4725
+ const changeTakingActions = ["start", "update"];
4726
+ const changeTakerOf = ({ availableActions }) => {
4727
+ const takers = changeTakingActions.filter((action) => availableActions.includes(action)).map((action) => `kcloud agents ${action}`);
4728
+ return takers.length === 0 ? "a restart" : takers.join(" or ");
4729
+ };
4696
4730
  const changedAgent = async (api, agentId, document) => {
4697
4731
  const current = dataOf("describe the agent", await api.GET("/agents/{id}", { params: { path: { id: agentId } } }), agentHints);
4698
4732
  const change = typeof document === "object" && document !== null && "version" in document ? document : {
@@ -4784,7 +4818,7 @@ const configCommands = (adaptersOf) => [
4784
4818
  const file = invocation.values.file;
4785
4819
  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.");
4786
4820
  const agent = await changedAgent(run.api, agentId, agentChangeWithoutLimits(run, await documentOf(run, file)));
4787
- return printed(run, agent, (changed) => changed.restartRequired ? `Changed ${changed.name}; it needs kcloud agents update to take the change.` : `Changed ${changed.name}.`);
4821
+ return printed(run, agent, (changed) => changed.restartRequired ? `Changed ${changed.name}; it needs ${changeTakerOf(changed)} to take the change.` : `Changed ${changed.name}.`);
4788
4822
  }
4789
4823
  }),
4790
4824
  defineCommand({
@@ -4831,13 +4865,22 @@ const admissionRowsOf = (agent) => {
4831
4865
  const admissionHoldRowsOf = ({ runtime }) => {
4832
4866
  const hold = runtime.admissionHold;
4833
4867
  if (hold == null) return [];
4834
- if (hold.updating) return [["admissions", `held while the node updates to ${hold.target ?? "-"}`]];
4868
+ if (hold.updating || hold.awaits === "start") return [["admissions", `held while the node updates to ${hold.target ?? "-"}`]];
4835
4869
  const all = hold.pools.includes("monitor");
4836
4870
  const noun = all ? "session" : "executor session";
4837
4871
  const waits = `${String(hold.sessions)} ${noun}${hold.sessions === 1 ? "" : "s"}`;
4838
4872
  return [["admissions", `${all ? "held" : "executor held"} for the node update to ${hold.target ?? "-"}, waiting for ${waits}`]];
4839
4873
  };
4840
4874
  const poolLimitRowsOf = ({ runtime }) => runtime.poolLimit === null ? [] : [["pool limit", poolLimitText(runtime.poolLimit)]];
4875
+ const claudeCodeOf = ({ runtime, release }) => {
4876
+ const running = runtime.claudeCode ?? null;
4877
+ if (running?.source === "host") return "host";
4878
+ return running?.version ?? release?.claudeCodeVersion ?? "unknown";
4879
+ };
4880
+ const failureRowsOf = ({ failureReason, retryAt }) => {
4881
+ if (failureReason === null) return [];
4882
+ return [["failure", retryAt === null ? failureReason : `${failureReason}, retry at ${retryAt}`]];
4883
+ };
4841
4884
  const detailsOf = (agent) => [
4842
4885
  renderTable([{ header: "FIELD" }, { header: "VALUE" }], [
4843
4886
  ["name", agent.name],
@@ -4846,6 +4889,7 @@ const detailsOf = (agent) => [
4846
4889
  ["wanted", agent.desiredState],
4847
4890
  ["observed", agent.observedState],
4848
4891
  ["release", agent.kikimoraVersion],
4892
+ ["claude code", claudeCodeOf(agent)],
4849
4893
  ["node", agent.node === null ? "none" : `${agent.node.name} (${agent.node.state})`],
4850
4894
  ["requires", agent.requiredCapabilities.length === 0 ? "nothing" : agent.requiredCapabilities.join(", ")],
4851
4895
  ["timezone", agent.timezone],
@@ -4854,6 +4898,7 @@ const detailsOf = (agent) => [
4854
4898
  ["browser", agent.machine.browser ? "yes" : "no"],
4855
4899
  ["container", agent.runtime.containerId ?? "none"],
4856
4900
  ["health", agent.runtime.health],
4901
+ ...failureRowsOf(agent),
4857
4902
  ...admissionRowsOf(agent),
4858
4903
  ...admissionHoldRowsOf(agent),
4859
4904
  ...poolLimitRowsOf(agent),
@@ -6675,7 +6720,7 @@ const agentTools = [
6675
6720
  defineTool({
6676
6721
  name: "agent_update",
6677
6722
  title: "Change an agent",
6678
- 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.",
6723
+ 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.",
6679
6724
  operations: ["updateAgent"],
6680
6725
  safety: "write",
6681
6726
  input: z.object({
@@ -6713,7 +6758,7 @@ const agentTools = [
6713
6758
  defineTool({
6714
6759
  name: "agent_action",
6715
6760
  title: "Start, pause, resume, restart or update an agent",
6716
- 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.",
6761
+ 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.",
6717
6762
  operations: ["runAgentAction"],
6718
6763
  safety: "write",
6719
6764
  input: z.object({
@@ -9923,7 +9968,9 @@ const updateOf = ({ update }) => {
9923
9968
  if (update === null) return "not reported";
9924
9969
  switch (update.state) {
9925
9970
  case "current": return "current";
9926
- case "waiting": return heldPoolsOf(update).includes("monitor") ? `admissions held for ${update.target ?? "-"}, waits for ${sessionsText(update.sessions, "session")}` : `executor admissions held for ${update.target ?? "-"}, waits for ${sessionsText(update.sessions, "executor session")}; monitors go on until the executor pool is empty`;
9971
+ case "waiting":
9972
+ if (update.awaits === "start") return `admissions held while the node updates to ${update.target ?? "-"}`;
9973
+ return heldPoolsOf(update).includes("monitor") ? `admissions held for ${update.target ?? "-"}, waits for ${sessionsText(update.sessions, "session")}` : `executor admissions held for ${update.target ?? "-"}, waits for ${sessionsText(update.sessions, "executor session")}; monitors go on until the executor pool is empty`;
9927
9974
  case "updating": return `updating to ${update.target ?? "-"}`;
9928
9975
  case "failed": return `failed to reach ${update.target ?? "-"}, runs its previous version`;
9929
9976
  case "unmanaged": return "updated with its platform";
@@ -9935,6 +9982,10 @@ const lastUpdateOf = ({ update }) => {
9935
9982
  const outcome = `${last.outcome} ${last.version ?? "-"} at ${last.at}`;
9936
9983
  return last.reason === null ? outcome : `${outcome}: ${last.reason}`;
9937
9984
  };
9985
+ const agentFailuresOf = ({ agents }) => agents.flatMap(({ slug, failureReason, retryAt }) => {
9986
+ if (failureReason === null) return [];
9987
+ return [`${slug} failure: ${retryAt === null ? failureReason : `${failureReason}, retry at ${retryAt}`}`];
9988
+ });
9938
9989
  const nodeDetailsText = (node) => [
9939
9990
  renderTable([{ header: "FIELD" }, { header: "VALUE" }], [
9940
9991
  ["name", node.name],
@@ -9973,6 +10024,7 @@ const nodeDetailsText = (node) => [
9973
10024
  poolLimitText(agent.poolLimit),
9974
10025
  agent.id
9975
10026
  ])),
10027
+ ...agentFailuresOf(node),
9976
10028
  "",
9977
10029
  ...node.runtime === null ? ["The node has reported no runtime yet."] : [
9978
10030
  renderTable([{ header: "RUNTIME" }, { header: "VALUE" }], runtimeRowsOf(node.runtime, node.engine)),
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "publishConfig": {
16
16
  "access": "public"
17
17
  },
18
- "version": "1.5.1",
18
+ "version": "1.5.3",
19
19
  "dependencies": {
20
20
  "@clack/prompts": "1.8.1",
21
21
  "@modelcontextprotocol/server": "2.1.0",