@kisev/agentomatic 12.0.1-dev.119.g39468b0d95be → 12.0.1-dev.121.ga002662711e9
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/agent-profiles.d.ts +1 -0
- package/dist/agent-profiles.js +13 -1
- package/dist/cli-output.d.ts +1 -0
- package/dist/cli-output.js +15 -0
- package/dist/command-cli.js +57 -38
- package/package.json +2 -2
package/dist/agent-profiles.d.ts
CHANGED
|
@@ -106,6 +106,7 @@ type BuiltPlan = {
|
|
|
106
106
|
legacyTransferred: string[];
|
|
107
107
|
};
|
|
108
108
|
export declare function validateAgentName(name: string): string;
|
|
109
|
+
export declare function suggestCriticName(input: string): string | null;
|
|
109
110
|
export declare function validateModel(model: string): string;
|
|
110
111
|
export declare function validateVariant(variant: string | null | undefined): string | undefined;
|
|
111
112
|
export declare function renderAgentProfile(name: string, config: AgentProfileConfig, canonical: Record<FixedAgentRole, Buffer>): Buffer;
|
package/dist/agent-profiles.js
CHANGED
|
@@ -60,7 +60,19 @@ function emptyConfig() {
|
|
|
60
60
|
export function validateAgentName(name) {
|
|
61
61
|
if (NAME_PATTERN.test(name) || CRITIC_PATTERN.test(name))
|
|
62
62
|
return name;
|
|
63
|
-
throw new AgentProfileError("invalid_name", "Agent must be a fixed role or critic-<
|
|
63
|
+
throw new AgentProfileError("invalid_name", "Agent must be a fixed role (manager, architect, mapper, worker, review, critic) or critic-<suffix> where suffix uses lowercase letters, digits, and hyphens between parts (for example critic-sonnet-5-5)");
|
|
64
|
+
}
|
|
65
|
+
// Convert free-form critic input such as "Sonnet 5.5" or "critic-sonnet-5.5" into a
|
|
66
|
+
// safe critic name; null when no safe form exists.
|
|
67
|
+
export function suggestCriticName(input) {
|
|
68
|
+
const cleaned = input.trim().toLowerCase();
|
|
69
|
+
if (CRITIC_PATTERN.test(cleaned))
|
|
70
|
+
return cleaned;
|
|
71
|
+
const body = cleaned
|
|
72
|
+
.replace(/^critic-/, "")
|
|
73
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
74
|
+
.replace(/^-+|-+$/g, "");
|
|
75
|
+
return body ? `critic-${body}` : null;
|
|
64
76
|
}
|
|
65
77
|
export function validateModel(model) {
|
|
66
78
|
if (!MODEL_PATTERN.test(model))
|
package/dist/cli-output.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export declare function renderConfigSetup(plan: ConfigSetupPlan, options: {
|
|
|
16
16
|
applyHint?: string;
|
|
17
17
|
hint?: string;
|
|
18
18
|
}): string;
|
|
19
|
+
export declare function renderCriticsTable(inventory: AgentInventory): string;
|
|
19
20
|
export declare function renderInventory(inventory: AgentInventory): string;
|
|
20
21
|
export declare function shellCommand(arguments_: readonly string[]): string;
|
|
21
22
|
export declare function scopeArguments(scope: Scope): [] | ["--global"];
|
package/dist/cli-output.js
CHANGED
|
@@ -165,6 +165,21 @@ function table(rows) {
|
|
|
165
165
|
.join(" ")
|
|
166
166
|
.trimEnd());
|
|
167
167
|
}
|
|
168
|
+
export function renderCriticsTable(inventory) {
|
|
169
|
+
const critics = inventory.profiles.filter((profile) => profile.name.startsWith("critic-") && profile.ownership !== "user-owned");
|
|
170
|
+
if (!critics.length)
|
|
171
|
+
return "Critics:\n No critics\n";
|
|
172
|
+
const rows = [
|
|
173
|
+
["NAME", "MODEL", "VARIANT", "PROVIDER"],
|
|
174
|
+
...critics.map((profile) => [
|
|
175
|
+
terminalSafe(profile.name),
|
|
176
|
+
terminalSafe(profile.model ?? "default"),
|
|
177
|
+
terminalSafe(profile.variant ?? "-"),
|
|
178
|
+
terminalSafe(profile.model?.split("/", 1)[0] ?? "-"),
|
|
179
|
+
]),
|
|
180
|
+
];
|
|
181
|
+
return `Critics:\n${table(rows).join("\n")}\n`;
|
|
182
|
+
}
|
|
168
183
|
export function renderInventory(inventory) {
|
|
169
184
|
const rows = [
|
|
170
185
|
["NAME", "MODEL", "VARIANT", "OWNER", "STATE"],
|
package/dist/command-cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Command, Option, common, applyConfig, configFileSync, reporter } from "./generated/cli.js";
|
|
2
|
-
import { applyAgentProfileChange, previewAgentProfileChange, listAgentProfiles, availableModels, availableModelVariants, validateAgentName, validateModel, validateVariant, FIXED_AGENT_ROLES, } from "./agent-profiles.js";
|
|
2
|
+
import { applyAgentProfileChange, previewAgentProfileChange, listAgentProfiles, availableModels, availableModelVariants, validateAgentName, validateModel, validateVariant, suggestCriticName, FIXED_AGENT_ROLES, } from "./agent-profiles.js";
|
|
3
3
|
import { apply, preview, installedSelection, defaultSelection, normalizeSelection, InstallerError, SKILL_COMMANDS, SELECTABLE_PLUGINS, } from "./installer.js";
|
|
4
4
|
import { applyConfigSetup, previewConfigSetup, recoverConfigSetup, normalizeConfigSelection, defaultConfigSelection, CONFIG_TARGETS, CONFIG_FRAGMENTS, inspectIntegration, } from "./config-setup.js";
|
|
5
5
|
import { collectDoctorFacts, doctorExitCode } from "./doctor.js";
|
|
@@ -9,7 +9,7 @@ import { skillsInstallerSpec } from "./package-metadata.js";
|
|
|
9
9
|
import { LifecycleError } from "./lifecycle.js";
|
|
10
10
|
import { previewDependencyRemoval, removeDependency, planDependency } from "./self-install.js";
|
|
11
11
|
import { selectOption, selectOptions, promptText, confirmQuestion } from "./terminal-wizard.js";
|
|
12
|
-
import { renderPlan, renderInventory, renderDoctor, renderConfigSetup, renderReconcile, terminalSafe, shellCommand, scopeArguments, } from "./cli-output.js";
|
|
12
|
+
import { renderPlan, renderInventory, renderCriticsTable, renderDoctor, renderConfigSetup, renderReconcile, terminalSafe, shellCommand, scopeArguments, } from "./cli-output.js";
|
|
13
13
|
let diagnostics;
|
|
14
14
|
let machineOutput = false;
|
|
15
15
|
let diagnosticJSON = false;
|
|
@@ -27,12 +27,12 @@ const commands = {
|
|
|
27
27
|
options: ["commands", "agents", "plugins", "core", "dependency", "targets", "fragments"],
|
|
28
28
|
},
|
|
29
29
|
"configure agent": {
|
|
30
|
-
description: "
|
|
30
|
+
description: "Open a staged editor for every agent, or set one model with a name and --model provider/model.",
|
|
31
31
|
options: ["provider", "model", "variant", "clearVariant"],
|
|
32
32
|
name: true,
|
|
33
33
|
},
|
|
34
34
|
"configure critics": {
|
|
35
|
-
description: "
|
|
35
|
+
description: "Alias of configure agent: staged agent models and critic management.",
|
|
36
36
|
options: [],
|
|
37
37
|
},
|
|
38
38
|
"configure integration": {
|
|
@@ -104,6 +104,26 @@ function json(value) {
|
|
|
104
104
|
function applyHint(args) {
|
|
105
105
|
return `${shellCommand(args)} (confirm interactively; add --yes outside a terminal)`;
|
|
106
106
|
}
|
|
107
|
+
// Prompt for a critic name, auto-converting unsafe input such as "sonnet-5.5" to
|
|
108
|
+
// "critic-sonnet-5-5" after explicit confirmation; exact safe names pass untouched.
|
|
109
|
+
async function promptCriticName() {
|
|
110
|
+
for (;;) {
|
|
111
|
+
const input = value(await promptText("Critic name (critic-<suffix>)"));
|
|
112
|
+
const suggestion = suggestCriticName(input);
|
|
113
|
+
if (suggestion !== null && suggestion === input.trim().toLowerCase())
|
|
114
|
+
return suggestion;
|
|
115
|
+
if (suggestion) {
|
|
116
|
+
const accept = value(await selectOption(`"${terminalSafe(input)}" is not a safe critic name`, [
|
|
117
|
+
`Use ${suggestion}`,
|
|
118
|
+
"Enter a different name",
|
|
119
|
+
]));
|
|
120
|
+
if (accept === 0)
|
|
121
|
+
return suggestion;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
process.stderr.write("Invalid critic name: use a fixed role or critic-<suffix> with lowercase letters, digits, and hyphens between parts (for example critic-sonnet-5-5).\n");
|
|
125
|
+
}
|
|
126
|
+
}
|
|
107
127
|
function help(topic = "") {
|
|
108
128
|
if (topic && !commands[topic])
|
|
109
129
|
fail("invalid_input", `Unknown command: ${topic}`);
|
|
@@ -348,15 +368,18 @@ async function modelSelection(options, name, current) {
|
|
|
348
368
|
const candidates = models.filter((model) => model.startsWith(`${provider}/`));
|
|
349
369
|
const model = candidates[value(await selectOption("Model", candidates))];
|
|
350
370
|
const variants = await availableModelVariants(model);
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
:
|
|
354
|
-
|
|
371
|
+
let variant = null;
|
|
372
|
+
if (variants.length) {
|
|
373
|
+
const labels = variants.map((item) => item === current?.variant ? `${item} (default)` : item);
|
|
374
|
+
const choice = value(await selectOption("Variant", ["(none)", ...labels], undefined, undefined, current?.variant ? variants.indexOf(current.variant) + 1 : 0));
|
|
375
|
+
variant = choice === 0 ? null : (variants[choice - 1] ?? null);
|
|
376
|
+
}
|
|
377
|
+
return { action: "model-set", name, model, variant };
|
|
355
378
|
}
|
|
356
379
|
catch (error) {
|
|
357
380
|
if (!(error instanceof LifecycleError && error.code === "catalog_unavailable"))
|
|
358
381
|
throw error;
|
|
359
|
-
process.stderr.write("
|
|
382
|
+
process.stderr.write("Start opencode in another terminal to browse models, or enter provider/model manually\n");
|
|
360
383
|
const model = validateModel(value(await promptText("Model (provider/model)")));
|
|
361
384
|
const answer = await promptText(current?.variant ? "Variant (empty keeps current)" : "Variant (optional)");
|
|
362
385
|
const variant = (answer ? validateVariant(answer) : current?.variant) ?? null;
|
|
@@ -375,8 +398,7 @@ async function profileDraft(options, names) {
|
|
|
375
398
|
if (action === "Done")
|
|
376
399
|
return changes;
|
|
377
400
|
if (action === "Add critic") {
|
|
378
|
-
const
|
|
379
|
-
const name = validateAgentName(suffix.startsWith("critic-") ? suffix : `critic-${suffix}`);
|
|
401
|
+
const name = await promptCriticName();
|
|
380
402
|
if (records.has(name))
|
|
381
403
|
fail("profile_exists", `Profile already exists: ${name}`);
|
|
382
404
|
const request = { ...(await modelSelection(options, name)), action: "critic-add" };
|
|
@@ -821,16 +843,10 @@ async function run(args) {
|
|
|
821
843
|
const options = parse(topic, args);
|
|
822
844
|
if (topic === "configure") {
|
|
823
845
|
requireApply(options);
|
|
824
|
-
const routes = [
|
|
825
|
-
"configure components",
|
|
826
|
-
"configure agent",
|
|
827
|
-
"configure critics",
|
|
828
|
-
"configure integration",
|
|
829
|
-
];
|
|
846
|
+
const routes = ["configure components", "configure agent", "configure integration"];
|
|
830
847
|
const selected = value(await selectOption("What would you like to configure?", [
|
|
831
848
|
"Installed components",
|
|
832
|
-
"Agent models",
|
|
833
|
-
"Additional critics",
|
|
849
|
+
"Agent models and critics",
|
|
834
850
|
"Application connection and presets",
|
|
835
851
|
]));
|
|
836
852
|
topic = routes[selected];
|
|
@@ -888,12 +904,32 @@ async function run(args) {
|
|
|
888
904
|
process.exitCode = doctorExitCode(report);
|
|
889
905
|
return;
|
|
890
906
|
}
|
|
891
|
-
if (topic === "configure
|
|
907
|
+
if (topic === "configure critics" ||
|
|
908
|
+
topic === "configure agent" ||
|
|
909
|
+
topic === "agent add-critic") {
|
|
892
910
|
const inventory = await listAgentProfiles(options.scope);
|
|
911
|
+
// configure critics is an alias; a nameless configure agent opens the same staged editor.
|
|
912
|
+
if (topic === "configure critics" || (topic === "configure agent" && !options.name)) {
|
|
913
|
+
requireApply(options);
|
|
914
|
+
if (!options.json)
|
|
915
|
+
process.stdout.write(renderCriticsTable(inventory));
|
|
916
|
+
const changes = await profileDraft(options, inventory.profiles
|
|
917
|
+
.filter((profile) => profile.ownership !== "user-owned")
|
|
918
|
+
.map((profile) => profile.name));
|
|
919
|
+
if (!changes.length) {
|
|
920
|
+
if (options.json)
|
|
921
|
+
json({ status: "ok", applied: false });
|
|
922
|
+
else
|
|
923
|
+
process.stdout.write("No profile changes selected.\n");
|
|
924
|
+
return;
|
|
925
|
+
}
|
|
926
|
+
await profileChange(options, { action: "model-set", changes });
|
|
927
|
+
return;
|
|
928
|
+
}
|
|
893
929
|
let name = options.name;
|
|
894
930
|
if (!name) {
|
|
895
931
|
if (topic === "agent add-critic")
|
|
896
|
-
name =
|
|
932
|
+
name = await promptCriticName();
|
|
897
933
|
else {
|
|
898
934
|
const names = inventory.profiles
|
|
899
935
|
.filter((profile) => profile.ownership !== "user-owned")
|
|
@@ -916,23 +952,6 @@ async function run(args) {
|
|
|
916
952
|
await profileChange(options, { action: "critic-remove", name: options.name });
|
|
917
953
|
return;
|
|
918
954
|
}
|
|
919
|
-
if (topic === "configure critics") {
|
|
920
|
-
requireApply(options);
|
|
921
|
-
const inventory = await listAgentProfiles(options.scope);
|
|
922
|
-
const changes = await profileDraft(options, inventory.profiles
|
|
923
|
-
.filter((profile) => (profile.name === "critic" || profile.name.startsWith("critic-")) &&
|
|
924
|
-
profile.ownership !== "user-owned")
|
|
925
|
-
.map((profile) => profile.name));
|
|
926
|
-
if (!changes.length) {
|
|
927
|
-
if (options.json)
|
|
928
|
-
json({ status: "ok", applied: false });
|
|
929
|
-
else
|
|
930
|
-
process.stdout.write("No profile changes selected.\n");
|
|
931
|
-
return;
|
|
932
|
-
}
|
|
933
|
-
await profileChange(options, { action: "model-set", changes });
|
|
934
|
-
return;
|
|
935
|
-
}
|
|
936
955
|
if (topic === "maintenance recover") {
|
|
937
956
|
requireApply(options);
|
|
938
957
|
const plan = await recoverConfigSetup(options.scope, true);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kisev/agentomatic",
|
|
3
|
-
"version": "12.0.1-dev.
|
|
3
|
+
"version": "12.0.1-dev.121.ga002662711e9",
|
|
4
4
|
"description": "OpenCode integration and opt-in installer for portable Agent Skills.",
|
|
5
5
|
"homepage": "https://github.com/kisev/skills#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"@clack/prompts": "^1.8.1",
|
|
53
|
-
"@kisev/safe-fs": "12.0.1-dev.
|
|
53
|
+
"@kisev/safe-fs": "12.0.1-dev.121.ga002662711e9",
|
|
54
54
|
"commander": "15.0.0",
|
|
55
55
|
"zod": "4.1.8"
|
|
56
56
|
},
|