@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.
- package/dist/main.js +100 -55
- 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/
|
|
3195
|
-
const
|
|
3196
|
-
const
|
|
3197
|
-
const
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
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",
|