@kikimoradev/kcloud 0.9.0 → 0.11.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.
Files changed (2) hide show
  1. package/dist/main.js +112 -57
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -947,11 +947,16 @@ const errorCodes = Object.keys({
947
947
  "runtime.control_tampered": "rule_violation",
948
948
  "runtime.workspace_tampered": "rule_violation",
949
949
  "runtime.sandbox_unavailable": "rule_violation",
950
+ "runtime.monitor_paused": "conflict",
951
+ "runtime.monitor_draining": "conflict",
952
+ "runtime.monitor_limited": "conflict",
953
+ "runtime.monitor_check_unsupported": "rule_violation",
950
954
  "stream.too_many": "rate_limited",
951
955
  "infrastructure.not_configured": "rule_violation",
952
956
  "infrastructure.provider_error": "internal",
953
957
  "infrastructure.operation_in_progress": "conflict",
954
958
  "infrastructure.host_ops_disabled": "rule_violation",
959
+ "infrastructure.backups_unavailable": "rule_violation",
955
960
  "infrastructure.maintenance_in_progress": "conflict",
956
961
  "infrastructure.maintenance_not_in_progress": "conflict",
957
962
  "backup.not_found": "not_found",
@@ -1034,6 +1039,7 @@ const storageStates = [
1034
1039
  "blocked",
1035
1040
  "unknown"
1036
1041
  ];
1042
+ const runtimeEngineKinds = ["docker", "native"];
1037
1043
  const dockerStates = [
1038
1044
  "ok",
1039
1045
  "unavailable",
@@ -1074,6 +1080,7 @@ const degradedAgentSchema = z.object({
1074
1080
  z.object({
1075
1081
  status: z.enum(runtimeHealthStates),
1076
1082
  database: z.object({ ok: z.boolean() }),
1083
+ engine: z.enum(runtimeEngineKinds),
1077
1084
  docker: z.object({
1078
1085
  state: z.enum(dockerStates),
1079
1086
  lastError: z.string().nullable(),
@@ -1172,6 +1179,10 @@ z.object({
1172
1179
  title: z.string().trim().min(1).max(200).optional(),
1173
1180
  description: z.string().trim().min(1).max(maxTaskDescriptionLength)
1174
1181
  }).meta({ id: "AddAgentTaskBody" });
1182
+ z.object({
1183
+ state: z.enum(["requested", "running"]),
1184
+ cycle: z.int().nonnegative().nullable()
1185
+ }).meta({ id: "MonitorCheck" });
1175
1186
  z.object({ status: taskStatusSchema.optional() });
1176
1187
  z.object({
1177
1188
  id: idSchema,
@@ -2404,6 +2415,7 @@ const registryUnavailableSchema = z.object({
2404
2415
  detail: z.string().nullable()
2405
2416
  }).meta({ id: "RegistryUnavailable" });
2406
2417
  const hostOperationsAvailabilities = ["enabled", "disabled"];
2418
+ const backupsAvailabilities = ["enabled", "unavailable"];
2407
2419
  const installedImageSchema = z.string().regex(pinnedPlatformImagePattern).nullable();
2408
2420
  z.object({
2409
2421
  version: z.string(),
@@ -2417,6 +2429,7 @@ z.object({
2417
2429
  expectedScriptsVersion: z.string(),
2418
2430
  imagePrefix: z.string(),
2419
2431
  hostOperations: z.enum(hostOperationsAvailabilities),
2432
+ backups: z.enum(backupsAvailabilities),
2420
2433
  operations: z.array(hostOperationSchema)
2421
2434
  }).meta({ id: "Platform" });
2422
2435
  const keyVersionSchema = z.int().positive();
@@ -2463,10 +2476,15 @@ const hostPointSchema = z.object({
2463
2476
  memoryUsedBytesAvg: byteCountSchema,
2464
2477
  memoryUsedBytesMax: byteCountSchema,
2465
2478
  memoryTotalBytes: byteCountSchema,
2466
- load1Avg: z.number().nonnegative(),
2479
+ load1Avg: z.number().nonnegative().nullable(),
2467
2480
  diskRootUsedRatio: hostRatioSchema.nullable(),
2468
2481
  diskDataUsedRatio: hostRatioSchema.nullable(),
2469
- diskAgentsUsedRatio: hostRatioSchema.nullable()
2482
+ diskAgentsUsedRatio: hostRatioSchema.nullable(),
2483
+ gpuUtilRatioAvg: hostRatioSchema.nullable(),
2484
+ gpuUtilRatioMax: hostRatioSchema.nullable(),
2485
+ gpuMemoryUsedBytesAvg: byteCountSchema.nullable(),
2486
+ gpuMemoryUsedBytesMax: byteCountSchema.nullable(),
2487
+ gpuMemoryTotalBytes: byteCountSchema.nullable()
2470
2488
  }).meta({ id: "HostPoint" });
2471
2489
  const containerPointSchema = z.object({
2472
2490
  ts: instantSchema,
@@ -3191,43 +3209,22 @@ const createWhoamiCommand = (adaptersOf) => defineCommand({
3191
3209
  }
3192
3210
  });
3193
3211
  //#endregion
3194
- //#region src/render/body.ts
3195
- const isTerminal$1 = (stream) => stream.isTTY === true;
3196
- const pipedText$1 = async (stream) => {
3197
- const chunks = [];
3198
- for await (const chunk of stream) chunks.push(Buffer.from(chunk));
3199
- return Buffer.concat(chunks).toString("utf8");
3200
- };
3201
- const fileOptions = { file: { type: "string" } };
3202
- const fileUsage = (what) => [["--file <path>", `read ${what} from a JSON file, or from stdin with -`]];
3203
- const documentOf = async (run, file) => {
3204
- const text = file === "-" ? isTerminal$1(run.context.io.stdin) ? "" : await pipedText$1(run.context.io.stdin) : await readFileOrRefuse(resolve(run.context.workingDirectory, file));
3205
- if (text.trim() === "") throw new UsageError(file === "-" ? "Nothing is piped on stdin." : `${file} is empty.`);
3206
- try {
3207
- return JSON.parse(text);
3208
- } catch {
3209
- throw new CliError(`${file === "-" ? "stdin" : file} is not JSON.`);
3210
- }
3211
- };
3212
- const readFileOrRefuse = async (path) => {
3213
- try {
3214
- return await readFile(path, "utf8");
3215
- } catch {
3216
- throw new CliError(`${path} could not be read.`);
3217
- }
3218
- };
3219
- const validated = (schema, document, what) => {
3220
- const parsed = schema.safeParse(document);
3221
- if (!parsed.success) throw new CliError(`That is not ${what}.`, z.prettifyError(parsed.error));
3222
- };
3223
- //#endregion
3224
- //#region src/render/confirm.ts
3225
- const confirmed = async ({ prompt, settings, question }) => {
3226
- if (settings.yes) return;
3227
- if (!await prompt.confirm({
3228
- message: question,
3229
- initialValue: false
3230
- })) throw new CancelledError("Nothing was changed.");
3212
+ //#region src/commands/run.ts
3213
+ const runOf = async (adaptersOf, { settings, context }) => {
3214
+ const adapters = adaptersOf(context);
3215
+ const session = await openSession({
3216
+ settings,
3217
+ context,
3218
+ api: adapters.api
3219
+ });
3220
+ return {
3221
+ api: session.api,
3222
+ origin: session.origin,
3223
+ adapters,
3224
+ prompt: adapters.prompter(settings),
3225
+ settings,
3226
+ context
3227
+ };
3231
3228
  };
3232
3229
  //#endregion
3233
3230
  //#region src/resolve.ts
@@ -3264,24 +3261,6 @@ const resolveAgentId = async (api, reference, project) => {
3264
3261
  return first.agent.id;
3265
3262
  };
3266
3263
  //#endregion
3267
- //#region src/commands/run.ts
3268
- const runOf = async (adaptersOf, { settings, context }) => {
3269
- const adapters = adaptersOf(context);
3270
- const session = await openSession({
3271
- settings,
3272
- context,
3273
- api: adapters.api
3274
- });
3275
- return {
3276
- api: session.api,
3277
- origin: session.origin,
3278
- adapters,
3279
- prompt: adapters.prompter(settings),
3280
- settings,
3281
- context
3282
- };
3283
- };
3284
- //#endregion
3285
3264
  //#region src/commands/agents/shared.ts
3286
3265
  const agentOption = { project: { type: "string" } };
3287
3266
  const agentUsage = [["--project <name>", "the project of the agent, when the agent is named alone"]];
@@ -3297,6 +3276,72 @@ const agentFrom = async (run, reference, project) => {
3297
3276
  return resolveAgentId(run.api, reference, project);
3298
3277
  };
3299
3278
  //#endregion
3279
+ //#region src/commands/agents/check.ts
3280
+ const checkHints = {
3281
+ ...agentHints,
3282
+ "runtime.control_unreachable": "The worker is not answering; kcloud agents show <agent> tells whether it runs.",
3283
+ "runtime.monitor_paused": "kcloud agents resume <agent> lets the agent work again.",
3284
+ "runtime.monitor_draining": "The agent stops after its current session; start it again to run a cycle.",
3285
+ "runtime.monitor_limited": "The Claude usage limit holds; the monitor runs its next cycle once it resets.",
3286
+ "runtime.monitor_check_unsupported": "Move the agent to Kikimora 0.10.0 or newer with kcloud agents set, then kcloud agents update."
3287
+ };
3288
+ const checkCommand = (adaptersOf) => defineCommand({
3289
+ name: "check",
3290
+ summary: "Run a monitor cycle now instead of waiting for the interval.",
3291
+ usage: "agents check <agent> [--project <name>]",
3292
+ optionsUsage: agentUsage,
3293
+ options: agentOption,
3294
+ positionals: {
3295
+ min: 1,
3296
+ max: 1
3297
+ },
3298
+ run: async (invocation) => {
3299
+ const run = await runOf(adaptersOf, invocation);
3300
+ const agentId = await agentFrom(run, invocation.positionals[0], invocation.values.project);
3301
+ const check = dataOf("check the monitor", await run.api.POST("/agents/{id}/monitor/check", { params: { path: { id: agentId } } }), checkHints);
3302
+ return printed(run, check, (answer) => answer.state === "running" ? `Monitor cycle ${String(answer.cycle)} is already running.` : "Monitor cycle requested; it starts now, also outside the active hours.");
3303
+ }
3304
+ });
3305
+ //#endregion
3306
+ //#region src/render/body.ts
3307
+ const isTerminal$1 = (stream) => stream.isTTY === true;
3308
+ const pipedText$1 = async (stream) => {
3309
+ const chunks = [];
3310
+ for await (const chunk of stream) chunks.push(Buffer.from(chunk));
3311
+ return Buffer.concat(chunks).toString("utf8");
3312
+ };
3313
+ const fileOptions = { file: { type: "string" } };
3314
+ const fileUsage = (what) => [["--file <path>", `read ${what} from a JSON file, or from stdin with -`]];
3315
+ const documentOf = async (run, file) => {
3316
+ const text = file === "-" ? isTerminal$1(run.context.io.stdin) ? "" : await pipedText$1(run.context.io.stdin) : await readFileOrRefuse(resolve(run.context.workingDirectory, file));
3317
+ if (text.trim() === "") throw new UsageError(file === "-" ? "Nothing is piped on stdin." : `${file} is empty.`);
3318
+ try {
3319
+ return JSON.parse(text);
3320
+ } catch {
3321
+ throw new CliError(`${file === "-" ? "stdin" : file} is not JSON.`);
3322
+ }
3323
+ };
3324
+ const readFileOrRefuse = async (path) => {
3325
+ try {
3326
+ return await readFile(path, "utf8");
3327
+ } catch {
3328
+ throw new CliError(`${path} could not be read.`);
3329
+ }
3330
+ };
3331
+ const validated = (schema, document, what) => {
3332
+ const parsed = schema.safeParse(document);
3333
+ if (!parsed.success) throw new CliError(`That is not ${what}.`, z.prettifyError(parsed.error));
3334
+ };
3335
+ //#endregion
3336
+ //#region src/render/confirm.ts
3337
+ const confirmed = async ({ prompt, settings, question }) => {
3338
+ if (settings.yes) return;
3339
+ if (!await prompt.confirm({
3340
+ message: question,
3341
+ initialValue: false
3342
+ })) throw new CancelledError("Nothing was changed.");
3343
+ };
3344
+ //#endregion
3300
3345
  //#region src/commands/agents/plan.ts
3301
3346
  const agentPlanOf = (agent) => ({
3302
3347
  name: agent.name,
@@ -4477,6 +4522,7 @@ const createAgentsCommand = (adaptersOf) => defineGroup({
4477
4522
  ...configCommands(adaptersOf),
4478
4523
  createCommand(adaptersOf),
4479
4524
  ...lifecycleCommands(adaptersOf),
4525
+ checkCommand(adaptersOf),
4480
4526
  tasksCommand(adaptersOf),
4481
4527
  ...observabilityCommands(adaptersOf),
4482
4528
  ...streamCommands(adaptersOf)
@@ -5081,6 +5127,15 @@ const agentTools = [
5081
5127
  }),
5082
5128
  run: async ({ action, ...reference }, run) => actionOn(run, await agentIdOf(run, reference), action, false)
5083
5129
  }),
5130
+ defineTool({
5131
+ name: "agent_check",
5132
+ title: "Run a monitor cycle now",
5133
+ description: "Ask the monitor of an agent to look for work now instead of waiting for its interval, also outside its active hours. state requested means a cycle starts at once; running names the cycle already in progress. A paused, stopping or usage-limited monitor refuses with an error.",
5134
+ operations: ["checkAgentMonitor"],
5135
+ safety: "write",
5136
+ input: z.object(agentFields),
5137
+ run: async (reference, run) => dataOf("check the monitor", await run.api.POST("/agents/{id}/monitor/check", { params: { path: { id: await agentIdOf(run, reference) } } }), checkHints)
5138
+ }),
5084
5139
  defineTool({
5085
5140
  name: "agent_interrupt",
5086
5141
  title: "Stop, reset or cancel an agent",
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "publishConfig": {
16
16
  "access": "public"
17
17
  },
18
- "version": "0.9.0",
18
+ "version": "0.11.0",
19
19
  "dependencies": {
20
20
  "@clack/prompts": "1.8.1",
21
21
  "@modelcontextprotocol/server": "2.1.0",