@m8t-stack/cli 0.2.152 → 0.2.154
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/cli.js +143 -20
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1464,7 +1464,7 @@ function installFoundryDnsShim() {
|
|
|
1464
1464
|
}
|
|
1465
1465
|
|
|
1466
1466
|
// src/lib/package-version.ts
|
|
1467
|
-
var CLI_VERSION = "0.2.
|
|
1467
|
+
var CLI_VERSION = "0.2.154";
|
|
1468
1468
|
|
|
1469
1469
|
// src/lib/render-error.ts
|
|
1470
1470
|
init_errors();
|
|
@@ -16106,17 +16106,35 @@ function hydrateAgentContent(content, destRoot, persona) {
|
|
|
16106
16106
|
fs11.rmSync(stage, { recursive: true, force: true });
|
|
16107
16107
|
}
|
|
16108
16108
|
}
|
|
16109
|
-
function
|
|
16110
|
-
|
|
16111
|
-
|
|
16109
|
+
function moveAside(source, backup, ops) {
|
|
16110
|
+
try {
|
|
16111
|
+
ops.renameSync(source, backup);
|
|
16112
|
+
} catch (e) {
|
|
16113
|
+
const err = e;
|
|
16114
|
+
if (err.code !== "EXDEV") throw e;
|
|
16115
|
+
ops.cpSync(source, backup, { recursive: true });
|
|
16116
|
+
ops.rmSync(source, { recursive: true, force: true });
|
|
16117
|
+
}
|
|
16118
|
+
}
|
|
16119
|
+
function swapInto(from, dest, ops = fs11) {
|
|
16120
|
+
if (!ops.existsSync(from)) {
|
|
16121
|
+
ops.rmSync(dest, { recursive: true, force: true });
|
|
16112
16122
|
return;
|
|
16113
16123
|
}
|
|
16114
|
-
|
|
16124
|
+
ops.mkdirSync(path11.dirname(dest), { recursive: true });
|
|
16115
16125
|
const old = `${dest}.old-${process.pid.toString()}`;
|
|
16116
|
-
|
|
16117
|
-
|
|
16118
|
-
|
|
16119
|
-
|
|
16126
|
+
ops.rmSync(old, { recursive: true, force: true });
|
|
16127
|
+
const hadDest = ops.existsSync(dest);
|
|
16128
|
+
if (hadDest) moveAside(dest, old, ops);
|
|
16129
|
+
try {
|
|
16130
|
+
ops.renameSync(from, dest);
|
|
16131
|
+
} catch (e) {
|
|
16132
|
+
if (hadDest && !ops.existsSync(dest) && ops.existsSync(old)) {
|
|
16133
|
+
ops.renameSync(old, dest);
|
|
16134
|
+
}
|
|
16135
|
+
throw e;
|
|
16136
|
+
}
|
|
16137
|
+
ops.rmSync(old, { recursive: true, force: true });
|
|
16120
16138
|
}
|
|
16121
16139
|
async function resolveToken(deps) {
|
|
16122
16140
|
const env = deps.env ?? process.env;
|
|
@@ -17951,6 +17969,42 @@ function personaFoundryTools(persona, frontmatter2) {
|
|
|
17951
17969
|
});
|
|
17952
17970
|
return rawTools;
|
|
17953
17971
|
}
|
|
17972
|
+
function equalJson(a, b) {
|
|
17973
|
+
if (Object.is(a, b)) return true;
|
|
17974
|
+
if (typeof a !== typeof b || a === null || b === null) return false;
|
|
17975
|
+
if (Array.isArray(a) || Array.isArray(b)) {
|
|
17976
|
+
return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((entry, i) => equalJson(entry, b[i]));
|
|
17977
|
+
}
|
|
17978
|
+
if (typeof a === "object" && typeof b === "object") {
|
|
17979
|
+
const ar = a;
|
|
17980
|
+
const br = b;
|
|
17981
|
+
const keys = Object.keys(ar);
|
|
17982
|
+
return keys.length === Object.keys(br).length && keys.every((key2) => Object.prototype.hasOwnProperty.call(br, key2) && equalJson(ar[key2], br[key2]));
|
|
17983
|
+
}
|
|
17984
|
+
return false;
|
|
17985
|
+
}
|
|
17986
|
+
function normalizeFoundryEchoes(value) {
|
|
17987
|
+
if (Array.isArray(value)) return value.map(normalizeFoundryEchoes);
|
|
17988
|
+
if (!value || typeof value !== "object") return value;
|
|
17989
|
+
const source = value;
|
|
17990
|
+
const normalized = Object.fromEntries(
|
|
17991
|
+
Object.entries(source).map(([key2, entry]) => [key2, normalizeFoundryEchoes(entry)])
|
|
17992
|
+
);
|
|
17993
|
+
if (source.type === "function" && source.strict === null) delete normalized.strict;
|
|
17994
|
+
if (source.type === "mcp") {
|
|
17995
|
+
const allowed = source.allowed_tools;
|
|
17996
|
+
if (allowed && typeof allowed === "object" && !Array.isArray(allowed)) {
|
|
17997
|
+
const names = allowed.tool_names;
|
|
17998
|
+
if (Array.isArray(names) && Object.keys(allowed).length === 1) {
|
|
17999
|
+
normalized.allowed_tools = names.map(normalizeFoundryEchoes);
|
|
18000
|
+
}
|
|
18001
|
+
}
|
|
18002
|
+
}
|
|
18003
|
+
return normalized;
|
|
18004
|
+
}
|
|
18005
|
+
function equivalentToolDefinition(a, b) {
|
|
18006
|
+
return equalJson(normalizeFoundryEchoes(a), normalizeFoundryEchoes(b));
|
|
18007
|
+
}
|
|
17954
18008
|
|
|
17955
18009
|
// src/lib/deploy-prompt-advisor.ts
|
|
17956
18010
|
init_esm();
|
|
@@ -19546,11 +19600,11 @@ function fromBuild(raw, fallbackRef) {
|
|
|
19546
19600
|
};
|
|
19547
19601
|
}
|
|
19548
19602
|
var DEV_TAG = "v0.0.0-dev";
|
|
19549
|
-
var PINNED_INSTALLER = fromBuild('{"ref":"ghcr.io/m8t-labs/m8t-installer:v0.1.
|
|
19603
|
+
var PINNED_INSTALLER = fromBuild('{"ref":"ghcr.io/m8t-labs/m8t-installer:v0.1.124","registry":"ghcr.io/m8t-labs","image":"m8t-installer","tag":"v0.1.124"}', "ghcr.io/m8t-labs/m8t-installer");
|
|
19550
19604
|
var PINNED_CODING_AGENT = fromBuild('{"ref":"ghcr.io/m8t-labs/m8t-coding-agent:v0.1.5","registry":"ghcr.io/m8t-labs","image":"m8t-coding-agent","tag":"v0.1.5"}', "ghcr.io/m8t-labs/m8t-coding-agent");
|
|
19551
19605
|
var PINNED_AZURE_EXECUTOR = fromBuild('{"ref":"ghcr.io/m8t-labs/m8t-azure-executor:v0.1.5","registry":"ghcr.io/m8t-labs","image":"m8t-azure-executor","tag":"v0.1.5"}', "ghcr.io/m8t-labs/m8t-azure-executor");
|
|
19552
19606
|
var PINNED_PLATFORM_VERSION = (() => {
|
|
19553
|
-
const raw = "0.8.
|
|
19607
|
+
const raw = "0.8.9";
|
|
19554
19608
|
return /^\d+\.\d+\.\d+$/.test(raw) ? raw : "";
|
|
19555
19609
|
})();
|
|
19556
19610
|
|
|
@@ -21865,6 +21919,16 @@ function adoptedAcrTopologyError(live, adoption) {
|
|
|
21865
21919
|
}
|
|
21866
21920
|
return null;
|
|
21867
21921
|
}
|
|
21922
|
+
async function assertLiveAdoptedGatewayTopology(args) {
|
|
21923
|
+
const live = await readLiveGatewayDeployment(args.gatewayResourceId);
|
|
21924
|
+
const topologyError = adoptedAcrTopologyError(live, args.adoption);
|
|
21925
|
+
if (topologyError) {
|
|
21926
|
+
throw new LocalCliError({
|
|
21927
|
+
code: "PLATFORM_GATEWAY_ADOPTION_DRIFT",
|
|
21928
|
+
message: `Adopted gateway held before infra converge: ${topologyError}.`
|
|
21929
|
+
});
|
|
21930
|
+
}
|
|
21931
|
+
}
|
|
21868
21932
|
async function readAcrDigest(subscriptionId, acrName, image) {
|
|
21869
21933
|
try {
|
|
21870
21934
|
const value = (await runAz(["acr", "repository", "show", "--subscription", subscriptionId, "-n", acrName, "--image", image, "--query", "digest", "-o", "tsv"])).trim();
|
|
@@ -22551,22 +22615,41 @@ async function applyAgentImage(a, ctx, opts) {
|
|
|
22551
22615
|
const digest = a.component === "codingAgent" ? ctx.manifest.components.codingAgent.digest : ctx.manifest.components.azureExecutor.digest;
|
|
22552
22616
|
return { tag: a.to, digest };
|
|
22553
22617
|
}
|
|
22554
|
-
function
|
|
22618
|
+
function readPersonaFrontmatter(personaPath) {
|
|
22555
22619
|
let raw;
|
|
22556
22620
|
try {
|
|
22557
22621
|
raw = fs26.readFileSync(personaPath, "utf8");
|
|
22558
22622
|
} catch {
|
|
22559
|
-
return
|
|
22623
|
+
return null;
|
|
22560
22624
|
}
|
|
22561
22625
|
const fmMatch = /^---\r?\n([\s\S]*?)\r?\n---/.exec(raw);
|
|
22562
|
-
if (!fmMatch) return
|
|
22626
|
+
if (!fmMatch) return null;
|
|
22563
22627
|
try {
|
|
22564
|
-
|
|
22565
|
-
return fm["fillable-fields"] ?? [];
|
|
22628
|
+
return parseYaml11(fmMatch[1]) ?? {};
|
|
22566
22629
|
} catch {
|
|
22567
|
-
return
|
|
22630
|
+
return null;
|
|
22568
22631
|
}
|
|
22569
22632
|
}
|
|
22633
|
+
function isRuntimePersonaTool(tool) {
|
|
22634
|
+
if (tool.type !== "mcp") return false;
|
|
22635
|
+
const label = tool.server_label;
|
|
22636
|
+
return label === "brain" || label === "a2a";
|
|
22637
|
+
}
|
|
22638
|
+
function convergePersonaTools(currentTools, declaredTools) {
|
|
22639
|
+
const personaTools = (declaredTools ?? []).map((tool) => tool).filter((tool) => !isRuntimePersonaTool(tool));
|
|
22640
|
+
const runtimeTools = (currentTools ?? []).filter(isRuntimePersonaTool);
|
|
22641
|
+
return [...personaTools, ...runtimeTools];
|
|
22642
|
+
}
|
|
22643
|
+
function personaPostCreateMismatches(candidate2, actual, expectedVersion) {
|
|
22644
|
+
const mismatches = [];
|
|
22645
|
+
if (actual.version !== expectedVersion) mismatches.push("version");
|
|
22646
|
+
const { tools: expectedTools, ...expectedDefinition } = candidate2.definition;
|
|
22647
|
+
const { tools: actualTools, ...actualDefinition } = actual.definition;
|
|
22648
|
+
if (!equivalentToolDefinition(actualDefinition, expectedDefinition)) mismatches.push("definition");
|
|
22649
|
+
if (!equivalentToolDefinition(actualTools ?? [], expectedTools ?? [])) mismatches.push("tools");
|
|
22650
|
+
if (!equivalentToolDefinition(actual.metadata ?? {}, candidate2.metadata)) mismatches.push("metadata");
|
|
22651
|
+
return mismatches;
|
|
22652
|
+
}
|
|
22570
22653
|
function defaultsOf(declared) {
|
|
22571
22654
|
const out = {};
|
|
22572
22655
|
for (const f of declared) {
|
|
@@ -22600,7 +22683,12 @@ async function applyPersona(a, ctx, opts) {
|
|
|
22600
22683
|
const personaPath = path27.join(opts.personaDir, "persona.md");
|
|
22601
22684
|
const yamlValues = readAgentYaml(opts.agentName)?.fillableFieldValues ?? null;
|
|
22602
22685
|
const values = resolveFillableValues(current, yamlValues);
|
|
22603
|
-
const
|
|
22686
|
+
const frontmatter2 = readPersonaFrontmatter(personaPath);
|
|
22687
|
+
const declared = frontmatter2?.["fillable-fields"] ?? [];
|
|
22688
|
+
const tools = convergePersonaTools(
|
|
22689
|
+
current.definition.tools,
|
|
22690
|
+
personaFoundryTools(a.personaName ?? opts.agentName, frontmatter2 ?? {})
|
|
22691
|
+
);
|
|
22604
22692
|
if (declared.length > 0 && values === null) {
|
|
22605
22693
|
const defaultBody = injectAndRender(personaPath, defaultsOf(declared), opts.agentName);
|
|
22606
22694
|
const candidateInstructions = composeInstructions({
|
|
@@ -22639,7 +22727,9 @@ async function applyPersona(a, ctx, opts) {
|
|
|
22639
22727
|
productVisibility: productVisibilityFor(opts.agentName),
|
|
22640
22728
|
...values ? { fillableFieldValues: JSON.stringify(values) } : {}
|
|
22641
22729
|
};
|
|
22642
|
-
|
|
22730
|
+
if (frontmatter2?.version === void 0) delete metadata.personaVersion;
|
|
22731
|
+
else metadata.personaVersion = String(frontmatter2.version);
|
|
22732
|
+
const candidate2 = { definition: { ...current.definition, instructions, tools }, metadata };
|
|
22643
22733
|
if (isNoop(candidate2, current)) return "noop";
|
|
22644
22734
|
const foundryVersion = await createAgentVersion({
|
|
22645
22735
|
credential: ctx.credential,
|
|
@@ -22648,6 +22738,19 @@ async function applyPersona(a, ctx, opts) {
|
|
|
22648
22738
|
definition: candidate2.definition,
|
|
22649
22739
|
metadata
|
|
22650
22740
|
});
|
|
22741
|
+
const applied = await getAgentVersion({
|
|
22742
|
+
credential: ctx.credential,
|
|
22743
|
+
projectEndpoint: opts.project.endpoint,
|
|
22744
|
+
agentName: opts.agentName
|
|
22745
|
+
});
|
|
22746
|
+
const mismatches = personaPostCreateMismatches(candidate2, applied, foundryVersion);
|
|
22747
|
+
if (mismatches.length > 0) {
|
|
22748
|
+
throw new LocalCliError({
|
|
22749
|
+
code: "PLATFORM_PERSONA_VERIFY_FAILED",
|
|
22750
|
+
message: `Foundry did not persist the converged persona '${a.personaName ?? opts.agentName}' exactly (mismatch: ${mismatches.join(", ")}); refusing to stamp tree ${a.to}.`,
|
|
22751
|
+
hint: "Re-run the converge after Foundry reports the created version as latest; persistent mismatch requires platform investigation."
|
|
22752
|
+
});
|
|
22753
|
+
}
|
|
22651
22754
|
return { treeSha: a.to, foundryVersion };
|
|
22652
22755
|
}
|
|
22653
22756
|
|
|
@@ -23259,7 +23362,7 @@ function bindRepoApi(token, repo) {
|
|
|
23259
23362
|
}
|
|
23260
23363
|
async function runSeedRefresh(args) {
|
|
23261
23364
|
const targetCommit = args.manifest.platform.commit;
|
|
23262
|
-
const theirsRoot = await resolveReleaseContentWithAgents(args.manifest, {});
|
|
23365
|
+
const theirsRoot = await resolveReleaseContentWithAgents(args.manifest, { contentDir: args.contentDir });
|
|
23263
23366
|
const repos = dedupeBrainRepos(args.agents);
|
|
23264
23367
|
const results = [];
|
|
23265
23368
|
let delivered = 0;
|
|
@@ -23456,6 +23559,19 @@ async function buildConvergeDeps(args) {
|
|
|
23456
23559
|
async applyInfra(a, ctx) {
|
|
23457
23560
|
const target = infraTargetSha(ctx.manifest, args.tree);
|
|
23458
23561
|
if (a.reason !== "forced") return applyInfraDeploy(a, ctx, target);
|
|
23562
|
+
const stampOutcome = await readStampOutcome({
|
|
23563
|
+
credential: args.credential,
|
|
23564
|
+
subscriptionId: args.subscriptionId,
|
|
23565
|
+
resourceGroup: args.resourceGroup
|
|
23566
|
+
}).catch(() => ({ source: "unreadable" }));
|
|
23567
|
+
if (stampOutcome.source === "unreadable") {
|
|
23568
|
+
throw new LocalCliError({
|
|
23569
|
+
code: "PLATFORM_GATEWAY_ADOPTION_STAMP_UNREADABLE",
|
|
23570
|
+
message: "Forced infra held before deployment because the platform stamp could not be read, so gateway adoption authority is unknown.",
|
|
23571
|
+
hint: "Restore access to the platform stamp, then let the next converge retry."
|
|
23572
|
+
});
|
|
23573
|
+
}
|
|
23574
|
+
const adoption = stampOutcome.source === "explicit" ? stampOutcome.stamp.components.gateway.adoption : void 0;
|
|
23459
23575
|
const infraTable = await openInfraParamsTable({ credential: args.credential, subscriptionId: args.subscriptionId, resourceGroup: args.resourceGroup });
|
|
23460
23576
|
const stamped = (await readInfraParams(infraTable))?.bicep;
|
|
23461
23577
|
if (!stamped) {
|
|
@@ -23501,6 +23617,12 @@ async function buildConvergeDeps(args) {
|
|
|
23501
23617
|
...stamped.location ? { location: stamped.location } : {},
|
|
23502
23618
|
...voiceInternalSecret ? { voiceInternalSecret } : {}
|
|
23503
23619
|
};
|
|
23620
|
+
if (adoption) {
|
|
23621
|
+
await assertLiveAdoptedGatewayTopology({
|
|
23622
|
+
gatewayResourceId: args.gatewayResourceId,
|
|
23623
|
+
adoption
|
|
23624
|
+
});
|
|
23625
|
+
}
|
|
23504
23626
|
return applyInfraDeploy(a, ctx, target, opts);
|
|
23505
23627
|
},
|
|
23506
23628
|
async healthGate(_ctx, applied) {
|
|
@@ -23587,6 +23709,7 @@ async function buildConvergeDeps(args) {
|
|
|
23587
23709
|
const { delivered, noop: noop2, failed } = await runSeedRefresh({
|
|
23588
23710
|
credential: args.credential,
|
|
23589
23711
|
kvUri,
|
|
23712
|
+
contentDir: ctx.contentDir,
|
|
23590
23713
|
manifest: ctx.manifest,
|
|
23591
23714
|
agents: discoveredAgents,
|
|
23592
23715
|
version: ctx.manifest.platform.version,
|