@kisev/agentomatic 12.0.1-dev.127.g96b4fdeed7cd → 12.0.1-dev.128.g273b5ff20349
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 +2 -1
- package/dist/agent-profiles.js +42 -5
- package/dist/command-cli.js +32 -16
- package/package.json +2 -2
package/dist/agent-profiles.d.ts
CHANGED
|
@@ -117,8 +117,9 @@ export declare function previewAgentProfileChange(request: AgentProfileRequest,
|
|
|
117
117
|
export declare function applyAgentProfileChange(request: AgentProfileRequest, scope: Scope, cwd?: string, home?: string, options?: TransactionOptions & {
|
|
118
118
|
expectedDigest?: string;
|
|
119
119
|
}): Promise<AgentProfileResult>;
|
|
120
|
+
export declare function parseModelsOutput(stdout: string): string[];
|
|
120
121
|
export declare function availableModels(): Promise<string[]>;
|
|
121
|
-
export declare function availableModelVariants(model: string): Promise<string[]>;
|
|
122
|
+
export declare function availableModelVariants(model: string): Promise<string[] | null>;
|
|
122
123
|
export declare function inspectFileMode(path: string): Promise<number | undefined>;
|
|
123
124
|
export declare function readLegacyManifest(root: string): Promise<LegacyAgentOwnership | undefined>;
|
|
124
125
|
export declare function applyBuiltAgentPlan(built: BuiltPlan, stateRoot: string, options?: TransactionOptions): Promise<void>;
|
package/dist/agent-profiles.js
CHANGED
|
@@ -752,8 +752,44 @@ export async function applyAgentProfileChange(request, scope, cwd = process.cwd(
|
|
|
752
752
|
});
|
|
753
753
|
}
|
|
754
754
|
async function modelCatalog() {
|
|
755
|
-
|
|
756
|
-
|
|
755
|
+
// The CLI catalog is the primary source: it works in a clean terminal, needs
|
|
756
|
+
// no background service, and never depends on the per-directory location
|
|
757
|
+
// filter that returns an empty list for some checkouts. If the background
|
|
758
|
+
// service is down, retry standalone before giving up with a remedy.
|
|
759
|
+
const models = await cliModels().catch((error) => cliModels(["--standalone"]).catch(() => {
|
|
760
|
+
throw new AgentProfileError("catalog_unavailable", `The opencode models CLI is unavailable (${error instanceof Error ? error.message : String(error)}); start opencode in a clean terminal or run 'opencode models' yourself to verify, then retry - or pass an explicit provider/model`);
|
|
761
|
+
}));
|
|
762
|
+
return models.map((model) => {
|
|
763
|
+
const [providerID, ...rest] = model.split("/");
|
|
764
|
+
return { providerID, id: rest.join("/") };
|
|
765
|
+
});
|
|
766
|
+
}
|
|
767
|
+
// Line-by-line `provider/model` output of `opencode models`; anything else in
|
|
768
|
+
// the stream is ignored. Exported for the parser test.
|
|
769
|
+
export function parseModelsOutput(stdout) {
|
|
770
|
+
return [
|
|
771
|
+
...new Set(stdout
|
|
772
|
+
.split("\n")
|
|
773
|
+
.map((line) => line.trim())
|
|
774
|
+
.filter((line) => MODEL_PATTERN.test(line))),
|
|
775
|
+
].sort();
|
|
776
|
+
}
|
|
777
|
+
async function cliModels(extra = []) {
|
|
778
|
+
const { stdout } = await execFileAsync("opencode", ["models", ...extra], {
|
|
779
|
+
timeout: 10_000,
|
|
780
|
+
encoding: "utf8",
|
|
781
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
782
|
+
});
|
|
783
|
+
const models = parseModelsOutput(stdout);
|
|
784
|
+
if (!models.length)
|
|
785
|
+
throw new Error("opencode models printed no provider/model lines");
|
|
786
|
+
return models;
|
|
787
|
+
}
|
|
788
|
+
// The variants (effort) metadata still comes from the API - without the
|
|
789
|
+
// location filter: some directories answer an empty list to a located query,
|
|
790
|
+
// and that must never zero the cascade.
|
|
791
|
+
async function modelApiEntries() {
|
|
792
|
+
const { stdout } = await execFileAsync("opencode", ["api", "get", "/api/model"], {
|
|
757
793
|
timeout: 10_000,
|
|
758
794
|
encoding: "utf8",
|
|
759
795
|
maxBuffer: 10 * 1024 * 1024,
|
|
@@ -783,7 +819,7 @@ export async function availableModels() {
|
|
|
783
819
|
export async function availableModelVariants(model) {
|
|
784
820
|
const selected = validateModel(model);
|
|
785
821
|
try {
|
|
786
|
-
const metadata = (await
|
|
822
|
+
const metadata = (await modelApiEntries()).find((entry) => `${entry.providerID}/${entry.id}` === selected);
|
|
787
823
|
if (!metadata)
|
|
788
824
|
throw new Error("selected model is absent");
|
|
789
825
|
if (metadata.variants === undefined)
|
|
@@ -793,8 +829,9 @@ export async function availableModelVariants(model) {
|
|
|
793
829
|
throw new Error("invalid variants metadata");
|
|
794
830
|
return metadata.variants.map((variant) => variant.id);
|
|
795
831
|
}
|
|
796
|
-
catch
|
|
797
|
-
|
|
832
|
+
catch {
|
|
833
|
+
// Unknown is honest: the cascade says so and allows a manual variant.
|
|
834
|
+
return null;
|
|
798
835
|
}
|
|
799
836
|
}
|
|
800
837
|
export async function inspectFileMode(path) {
|
package/dist/command-cli.js
CHANGED
|
@@ -373,7 +373,14 @@ async function modelSelection(options, name, current) {
|
|
|
373
373
|
const model = candidates[value(await selectOption("Model", candidates))];
|
|
374
374
|
const variants = await availableModelVariants(model);
|
|
375
375
|
let variant = null;
|
|
376
|
-
if (variants
|
|
376
|
+
if (variants === null) {
|
|
377
|
+
// The variants metadata is unavailable: say so honestly and accept a
|
|
378
|
+
// manual variant instead of degrading the whole model selection.
|
|
379
|
+
process.stderr.write("Model variants are unknown (variants metadata unavailable); enter one manually or leave it empty.\n");
|
|
380
|
+
const answer = await promptText(current?.variant ? "Variant (empty keeps current)" : "Variant (optional)");
|
|
381
|
+
variant = (answer ? validateVariant(answer) : current?.variant) ?? null;
|
|
382
|
+
}
|
|
383
|
+
else if (variants.length) {
|
|
377
384
|
const labels = variants.map((item) => item === current?.variant ? `${item} (default)` : item);
|
|
378
385
|
const choice = value(await selectOption("Variant", ["(none)", ...labels], undefined, undefined, current?.variant ? variants.indexOf(current.variant) + 1 : 0));
|
|
379
386
|
variant = choice === 0 ? null : (variants[choice - 1] ?? null);
|
|
@@ -510,18 +517,9 @@ async function deploy(options, repair = false) {
|
|
|
510
517
|
],
|
|
511
518
|
};
|
|
512
519
|
}
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
value(await confirmQuestion("Configure agent models or additional critics now?"))) {
|
|
517
|
-
const inventory = await listAgentProfiles(options.scope);
|
|
518
|
-
changes = await profileDraft(options, [
|
|
519
|
-
...selection.agents,
|
|
520
|
-
...inventory.profiles
|
|
521
|
-
.filter((profile) => profile.name.startsWith("critic-") && profile.ownership !== "user-owned")
|
|
522
|
-
.map((profile) => profile.name),
|
|
523
|
-
]);
|
|
524
|
-
}
|
|
520
|
+
// Install never mutates the critic panel: the summary ends with the panel
|
|
521
|
+
// table and the pointer to configure agent, the single mutation point.
|
|
522
|
+
const changes = [];
|
|
525
523
|
const plan = await preview("install", options.scope, undefined, undefined, selection, !options.noDependency, changes);
|
|
526
524
|
const config = await previewConfigSetup(integration, options.scope, undefined, undefined, false, false);
|
|
527
525
|
const report = {
|
|
@@ -571,6 +569,7 @@ async function deploy(options, repair = false) {
|
|
|
571
569
|
if (changes.length)
|
|
572
570
|
process.stdout.write(`Staged profiles: ${terminalSafe(JSON.stringify(changes))}\n`);
|
|
573
571
|
process.stdout.write("Components, npm, and application configuration are separate stages; a later failure does not roll back completed stages.\n");
|
|
572
|
+
await criticsEpilogue(options);
|
|
574
573
|
}
|
|
575
574
|
if (options.dryRun) {
|
|
576
575
|
if (options.json)
|
|
@@ -609,8 +608,10 @@ async function deploy(options, repair = false) {
|
|
|
609
608
|
};
|
|
610
609
|
if (options.json)
|
|
611
610
|
json(result);
|
|
612
|
-
else
|
|
611
|
+
else {
|
|
613
612
|
process.stdout.write(renderPlan(applied, { applied: true }) + renderConfigSetup(connected, { applied: true }));
|
|
613
|
+
await criticsEpilogue(options);
|
|
614
|
+
}
|
|
614
615
|
}
|
|
615
616
|
catch (error) {
|
|
616
617
|
if (error instanceof LifecycleError &&
|
|
@@ -620,6 +621,16 @@ async function deploy(options, repair = false) {
|
|
|
620
621
|
partial(options, error, completed, `Run status, then ${repair ? "maintenance repair" : "install"} with the same selected components; use configure integration for configuration-only continuation.`, completed.includes("owned-components-and-profiles") && plan.requires_restart);
|
|
621
622
|
}
|
|
622
623
|
}
|
|
624
|
+
// The critic panel epilogue: the table plus the canonical view and mutation
|
|
625
|
+
// pointers, printed wherever the panel matters (install, staged applies,
|
|
626
|
+
// configure integration).
|
|
627
|
+
async function criticsEpilogue(options) {
|
|
628
|
+
if (options.json)
|
|
629
|
+
return;
|
|
630
|
+
const inventory = await listAgentProfiles(options.scope);
|
|
631
|
+
process.stdout.write(renderCriticsTable(inventory));
|
|
632
|
+
process.stdout.write("Inspect any time: agentomatic agent list | Manage critics: agentomatic configure agent\n");
|
|
633
|
+
}
|
|
623
634
|
function partial(options, error, completed, next, requiresRestart = false) {
|
|
624
635
|
const code = error instanceof LifecycleError ? error.code : "internal_error";
|
|
625
636
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -676,8 +687,10 @@ async function configureIntegration(options) {
|
|
|
676
687
|
plan: result,
|
|
677
688
|
requires_restart: result.requires_restart,
|
|
678
689
|
});
|
|
679
|
-
else
|
|
690
|
+
else {
|
|
680
691
|
process.stdout.write(renderConfigSetup(result, { applied: true }));
|
|
692
|
+
await criticsEpilogue(options);
|
|
693
|
+
}
|
|
681
694
|
}
|
|
682
695
|
catch (error) {
|
|
683
696
|
partial(options, error, error instanceof LifecycleError && error.code === "npm_dependency_failed"
|
|
@@ -722,8 +735,11 @@ async function profileChange(options, request) {
|
|
|
722
735
|
});
|
|
723
736
|
if (options.json)
|
|
724
737
|
json(result);
|
|
725
|
-
else
|
|
738
|
+
else {
|
|
726
739
|
process.stdout.write(renderPlan(result.plan, { applied: true }));
|
|
740
|
+
// After a panel mutation the fresh table closes the loop.
|
|
741
|
+
await criticsEpilogue(options);
|
|
742
|
+
}
|
|
727
743
|
}
|
|
728
744
|
async function uninstall(options) {
|
|
729
745
|
requireApply(options);
|
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.128.g273b5ff20349",
|
|
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.128.g273b5ff20349",
|
|
54
54
|
"commander": "15.0.0",
|
|
55
55
|
"zod": "4.1.8"
|
|
56
56
|
},
|