@kikimoradev/kcloud 0.9.0 → 0.10.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 +100 -55
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -947,6 +947,10 @@ 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",
@@ -1172,6 +1176,10 @@ z.object({
1172
1176
  title: z.string().trim().min(1).max(200).optional(),
1173
1177
  description: z.string().trim().min(1).max(maxTaskDescriptionLength)
1174
1178
  }).meta({ id: "AddAgentTaskBody" });
1179
+ z.object({
1180
+ state: z.enum(["requested", "running"]),
1181
+ cycle: z.int().nonnegative().nullable()
1182
+ }).meta({ id: "MonitorCheck" });
1175
1183
  z.object({ status: taskStatusSchema.optional() });
1176
1184
  z.object({
1177
1185
  id: idSchema,
@@ -3191,43 +3199,22 @@ const createWhoamiCommand = (adaptersOf) => defineCommand({
3191
3199
  }
3192
3200
  });
3193
3201
  //#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.");
3202
+ //#region src/commands/run.ts
3203
+ const runOf = async (adaptersOf, { settings, context }) => {
3204
+ const adapters = adaptersOf(context);
3205
+ const session = await openSession({
3206
+ settings,
3207
+ context,
3208
+ api: adapters.api
3209
+ });
3210
+ return {
3211
+ api: session.api,
3212
+ origin: session.origin,
3213
+ adapters,
3214
+ prompt: adapters.prompter(settings),
3215
+ settings,
3216
+ context
3217
+ };
3231
3218
  };
3232
3219
  //#endregion
3233
3220
  //#region src/resolve.ts
@@ -3264,24 +3251,6 @@ const resolveAgentId = async (api, reference, project) => {
3264
3251
  return first.agent.id;
3265
3252
  };
3266
3253
  //#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
3254
  //#region src/commands/agents/shared.ts
3286
3255
  const agentOption = { project: { type: "string" } };
3287
3256
  const agentUsage = [["--project <name>", "the project of the agent, when the agent is named alone"]];
@@ -3297,6 +3266,72 @@ const agentFrom = async (run, reference, project) => {
3297
3266
  return resolveAgentId(run.api, reference, project);
3298
3267
  };
3299
3268
  //#endregion
3269
+ //#region src/commands/agents/check.ts
3270
+ const checkHints = {
3271
+ ...agentHints,
3272
+ "runtime.control_unreachable": "The worker is not answering; kcloud agents show <agent> tells whether it runs.",
3273
+ "runtime.monitor_paused": "kcloud agents resume <agent> lets the agent work again.",
3274
+ "runtime.monitor_draining": "The agent stops after its current session; start it again to run a cycle.",
3275
+ "runtime.monitor_limited": "The Claude usage limit holds; the monitor runs its next cycle once it resets.",
3276
+ "runtime.monitor_check_unsupported": "Move the agent to Kikimora 0.10.0 or newer with kcloud agents set, then kcloud agents update."
3277
+ };
3278
+ const checkCommand = (adaptersOf) => defineCommand({
3279
+ name: "check",
3280
+ summary: "Run a monitor cycle now instead of waiting for the interval.",
3281
+ usage: "agents check <agent> [--project <name>]",
3282
+ optionsUsage: agentUsage,
3283
+ options: agentOption,
3284
+ positionals: {
3285
+ min: 1,
3286
+ max: 1
3287
+ },
3288
+ run: async (invocation) => {
3289
+ const run = await runOf(adaptersOf, invocation);
3290
+ const agentId = await agentFrom(run, invocation.positionals[0], invocation.values.project);
3291
+ const check = dataOf("check the monitor", await run.api.POST("/agents/{id}/monitor/check", { params: { path: { id: agentId } } }), checkHints);
3292
+ 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.");
3293
+ }
3294
+ });
3295
+ //#endregion
3296
+ //#region src/render/body.ts
3297
+ const isTerminal$1 = (stream) => stream.isTTY === true;
3298
+ const pipedText$1 = async (stream) => {
3299
+ const chunks = [];
3300
+ for await (const chunk of stream) chunks.push(Buffer.from(chunk));
3301
+ return Buffer.concat(chunks).toString("utf8");
3302
+ };
3303
+ const fileOptions = { file: { type: "string" } };
3304
+ const fileUsage = (what) => [["--file <path>", `read ${what} from a JSON file, or from stdin with -`]];
3305
+ const documentOf = async (run, file) => {
3306
+ const text = file === "-" ? isTerminal$1(run.context.io.stdin) ? "" : await pipedText$1(run.context.io.stdin) : await readFileOrRefuse(resolve(run.context.workingDirectory, file));
3307
+ if (text.trim() === "") throw new UsageError(file === "-" ? "Nothing is piped on stdin." : `${file} is empty.`);
3308
+ try {
3309
+ return JSON.parse(text);
3310
+ } catch {
3311
+ throw new CliError(`${file === "-" ? "stdin" : file} is not JSON.`);
3312
+ }
3313
+ };
3314
+ const readFileOrRefuse = async (path) => {
3315
+ try {
3316
+ return await readFile(path, "utf8");
3317
+ } catch {
3318
+ throw new CliError(`${path} could not be read.`);
3319
+ }
3320
+ };
3321
+ const validated = (schema, document, what) => {
3322
+ const parsed = schema.safeParse(document);
3323
+ if (!parsed.success) throw new CliError(`That is not ${what}.`, z.prettifyError(parsed.error));
3324
+ };
3325
+ //#endregion
3326
+ //#region src/render/confirm.ts
3327
+ const confirmed = async ({ prompt, settings, question }) => {
3328
+ if (settings.yes) return;
3329
+ if (!await prompt.confirm({
3330
+ message: question,
3331
+ initialValue: false
3332
+ })) throw new CancelledError("Nothing was changed.");
3333
+ };
3334
+ //#endregion
3300
3335
  //#region src/commands/agents/plan.ts
3301
3336
  const agentPlanOf = (agent) => ({
3302
3337
  name: agent.name,
@@ -4477,6 +4512,7 @@ const createAgentsCommand = (adaptersOf) => defineGroup({
4477
4512
  ...configCommands(adaptersOf),
4478
4513
  createCommand(adaptersOf),
4479
4514
  ...lifecycleCommands(adaptersOf),
4515
+ checkCommand(adaptersOf),
4480
4516
  tasksCommand(adaptersOf),
4481
4517
  ...observabilityCommands(adaptersOf),
4482
4518
  ...streamCommands(adaptersOf)
@@ -5081,6 +5117,15 @@ const agentTools = [
5081
5117
  }),
5082
5118
  run: async ({ action, ...reference }, run) => actionOn(run, await agentIdOf(run, reference), action, false)
5083
5119
  }),
5120
+ defineTool({
5121
+ name: "agent_check",
5122
+ title: "Run a monitor cycle now",
5123
+ 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.",
5124
+ operations: ["checkAgentMonitor"],
5125
+ safety: "write",
5126
+ input: z.object(agentFields),
5127
+ run: async (reference, run) => dataOf("check the monitor", await run.api.POST("/agents/{id}/monitor/check", { params: { path: { id: await agentIdOf(run, reference) } } }), checkHints)
5128
+ }),
5084
5129
  defineTool({
5085
5130
  name: "agent_interrupt",
5086
5131
  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.10.0",
19
19
  "dependencies": {
20
20
  "@clack/prompts": "1.8.1",
21
21
  "@modelcontextprotocol/server": "2.1.0",