@kuznai/inception-engine 0.14.0 → 0.14.1
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/core/deploy.js +57 -133
- package/package.json +1 -1
package/dist/core/deploy.js
CHANGED
|
@@ -4,12 +4,10 @@ import path from "node:path";
|
|
|
4
4
|
import { AGENT_REGISTRY_BY_ID } from "../config/agents.js";
|
|
5
5
|
import { UserError } from "../errors.js";
|
|
6
6
|
import { logger } from "../logger.js";
|
|
7
|
-
import { writeFrontmatterFile } from "./adapters/frontmatter.js";
|
|
8
7
|
import { compileAdapterActions } from "./adapters/index.js";
|
|
9
|
-
import { applyTomlMcpPatch } from "./adapters/toml.js";
|
|
10
8
|
import { lookupDeployment, registerDeployment, verifyDeployment, } from "./ownership.js";
|
|
11
9
|
import { getDeployMethod, resolveAgentSkillPath } from "./resolve.js";
|
|
12
|
-
import {
|
|
10
|
+
import { resolveTargetTemplate } from "./runtime-paths.js";
|
|
13
11
|
import { sourceAccessError, validateSkillDefinitionFile, validateSourceFile, validateSourcePath, } from "./validation.js";
|
|
14
12
|
function isPlainObject(v) {
|
|
15
13
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
@@ -82,28 +80,26 @@ function detectCollisions(actions) {
|
|
|
82
80
|
}
|
|
83
81
|
return warnings;
|
|
84
82
|
}
|
|
85
|
-
function detectAmbiguities(detectedAgents,
|
|
83
|
+
function detectAmbiguities(detectedAgents, manifest) {
|
|
86
84
|
const warnings = [];
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
});
|
|
103
|
-
if (targetsShared) {
|
|
85
|
+
if (!(detectedAgents.includes("gemini-cli") &&
|
|
86
|
+
detectedAgents.includes("antigravity"))) {
|
|
87
|
+
return warnings;
|
|
88
|
+
}
|
|
89
|
+
const bothAgents = (agents) => agents.includes("gemini-cli") && agents.includes("antigravity");
|
|
90
|
+
for (const entry of manifest.agentRules ?? []) {
|
|
91
|
+
if (bothAgents(entry.agents)) {
|
|
92
|
+
warnings.push({
|
|
93
|
+
kind: "ambiguity",
|
|
94
|
+
message: `Both "gemini-cli" and "antigravity" are listed in agentRules entry "${entry.name}". They share a GEMINI.md-backed instruction shared surface — verify that deploying to both does not create conflicting behavior.`,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
for (const entry of manifest.mcpServers ?? []) {
|
|
99
|
+
if (bothAgents(entry.agents)) {
|
|
104
100
|
warnings.push({
|
|
105
101
|
kind: "ambiguity",
|
|
106
|
-
message:
|
|
102
|
+
message: `Both "gemini-cli" and "antigravity" are listed in mcpServers entry "${entry.name}". "gemini-cli" writes to ~/.gemini/settings.json as a shared surface — verify that deploying to both does not produce conflicting MCP server behavior.`,
|
|
107
103
|
});
|
|
108
104
|
}
|
|
109
105
|
}
|
|
@@ -161,7 +157,7 @@ async function planFileWriteActions(manifest, sourceDir, resolvedSourceDir, real
|
|
|
161
157
|
}
|
|
162
158
|
return actions;
|
|
163
159
|
}
|
|
164
|
-
function planConfigPatchActions(manifest, detectedAgents, home
|
|
160
|
+
function planConfigPatchActions(manifest, detectedAgents, home) {
|
|
165
161
|
const actions = [];
|
|
166
162
|
for (const configEntry of manifest.configs ?? []) {
|
|
167
163
|
for (const agentId of configEntry.agents) {
|
|
@@ -174,7 +170,7 @@ function planConfigPatchActions(manifest, detectedAgents, home, repo) {
|
|
|
174
170
|
kind: "config-patch",
|
|
175
171
|
skill: configEntry.name,
|
|
176
172
|
agent: agentId,
|
|
177
|
-
target: resolveTargetTemplate(configEntry.target, home
|
|
173
|
+
target: resolveTargetTemplate(configEntry.target, home),
|
|
178
174
|
patch: configEntry.patch,
|
|
179
175
|
confidence: agent.provenance.skills,
|
|
180
176
|
});
|
|
@@ -194,44 +190,56 @@ export async function planDeploy(manifest, sourceDir, detectedAgents, home) {
|
|
|
194
190
|
const actions = [
|
|
195
191
|
...(await planSkillDirActions(manifest, sourceDir, resolvedSourceDir, realRoot, detectedAgents, home)),
|
|
196
192
|
...(await planFileWriteActions(manifest, sourceDir, resolvedSourceDir, realRoot, detectedAgents, home)),
|
|
197
|
-
...planConfigPatchActions(manifest, detectedAgents, home
|
|
193
|
+
...planConfigPatchActions(manifest, detectedAgents, home),
|
|
198
194
|
];
|
|
199
|
-
const adapterResult = await compileAdapterActions(manifest.mcpServers, manifest.agentRules, sourceDir, resolvedSourceDir, realRoot, detectedAgents, home
|
|
195
|
+
const adapterResult = await compileAdapterActions(manifest.mcpServers, manifest.agentRules, sourceDir, resolvedSourceDir, realRoot, detectedAgents, home);
|
|
200
196
|
actions.push(...adapterResult.actions);
|
|
201
197
|
const warnings = [
|
|
202
|
-
...detectAmbiguities(detectedAgents,
|
|
198
|
+
...detectAmbiguities(detectedAgents, manifest),
|
|
203
199
|
...detectCollisions(actions),
|
|
204
200
|
...adapterResult.warnings,
|
|
205
201
|
];
|
|
206
202
|
return { actions, warnings };
|
|
207
203
|
}
|
|
208
|
-
async function dispatchDeployAction(action, dryRun, verbose, home, planned, deps) {
|
|
209
|
-
switch (action.kind) {
|
|
210
|
-
case "skill-dir":
|
|
211
|
-
return deploySkillDir(action, dryRun, verbose, home, planned, deps);
|
|
212
|
-
case "file-write":
|
|
213
|
-
return deployFileWrite(action, dryRun, verbose, home, planned, deps);
|
|
214
|
-
case "config-patch":
|
|
215
|
-
return deployConfigPatch(action, dryRun, verbose, home, planned, deps);
|
|
216
|
-
case "toml-patch":
|
|
217
|
-
return deployTomlPatch(action, dryRun, verbose, home, planned, deps);
|
|
218
|
-
case "frontmatter-emit":
|
|
219
|
-
return deployFrontmatterEmit(action, dryRun, verbose, home, planned, deps);
|
|
220
|
-
default:
|
|
221
|
-
throw new Error(`Unhandled deploy action kind: ${action.kind}`);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
204
|
export async function executeDeploy(actions, dryRun, verbose, home, deps = {}) {
|
|
225
205
|
let succeeded = 0;
|
|
226
206
|
const failed = [];
|
|
227
207
|
const planned = [];
|
|
228
208
|
for (const action of actions) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
209
|
+
switch (action.kind) {
|
|
210
|
+
case "skill-dir": {
|
|
211
|
+
const result = await deploySkillDir(action, dryRun, verbose, home, planned, deps);
|
|
212
|
+
if (result.error === null) {
|
|
213
|
+
succeeded++;
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
failed.push({ action, error: result.error });
|
|
217
|
+
}
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
case "file-write": {
|
|
221
|
+
const result = await deployFileWrite(action, dryRun, verbose, home, planned, deps);
|
|
222
|
+
if (result.error === null) {
|
|
223
|
+
succeeded++;
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
failed.push({ action, error: result.error });
|
|
227
|
+
}
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
case "config-patch": {
|
|
231
|
+
const result = await deployConfigPatch(action, dryRun, verbose, home, planned, deps);
|
|
232
|
+
if (result.error === null) {
|
|
233
|
+
succeeded++;
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
failed.push({ action, error: result.error });
|
|
237
|
+
}
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
default: {
|
|
241
|
+
throw new Error(`Unhandled deploy action kind: ${action}`);
|
|
242
|
+
}
|
|
235
243
|
}
|
|
236
244
|
}
|
|
237
245
|
return { succeeded, failed, planned };
|
|
@@ -599,87 +607,3 @@ async function backupExisting(targetPath, verbose, home, expected, deps) {
|
|
|
599
607
|
await rename(targetPath, backupPath);
|
|
600
608
|
return backupPath;
|
|
601
609
|
}
|
|
602
|
-
async function deployTomlPatch(action, dryRun, verbose, home, planned, deps) {
|
|
603
|
-
const label = `${action.skill} -> ${action.agent}`;
|
|
604
|
-
if (dryRun) {
|
|
605
|
-
planned.push({
|
|
606
|
-
verb: "patch-toml",
|
|
607
|
-
kind: "toml-patch",
|
|
608
|
-
skill: action.skill,
|
|
609
|
-
agent: action.agent,
|
|
610
|
-
target: action.target,
|
|
611
|
-
confidence: action.confidence,
|
|
612
|
-
});
|
|
613
|
-
return { error: null };
|
|
614
|
-
}
|
|
615
|
-
try {
|
|
616
|
-
// Guard against double-patching by a different skill/agent.
|
|
617
|
-
const existingEntry = await lookupDeployment(home, action.target, deps.registry);
|
|
618
|
-
if (existingEntry &&
|
|
619
|
-
(existingEntry.skill !== action.skill ||
|
|
620
|
-
existingEntry.agent !== action.agent)) {
|
|
621
|
-
throw new Error(`Config "${action.target}" is already patched by skill "${existingEntry.skill}" for agent "${existingEntry.agent}" — refusing to double-patch`);
|
|
622
|
-
}
|
|
623
|
-
await applyTomlMcpPatch(action.target, action.skill, action.config);
|
|
624
|
-
await registerDeployment(home, action.target, {
|
|
625
|
-
kind: "config-patch",
|
|
626
|
-
patch: { mcpServers: { [action.skill]: action.config } },
|
|
627
|
-
undoPatch: { mcpServers: { [action.skill]: null } },
|
|
628
|
-
skill: action.skill,
|
|
629
|
-
agent: action.agent,
|
|
630
|
-
}, deps.registry);
|
|
631
|
-
logger.ok(label);
|
|
632
|
-
if (verbose) {
|
|
633
|
-
logger.detail(`patch-toml: wrote [mcpServers.${action.skill}] to ${action.target}`);
|
|
634
|
-
}
|
|
635
|
-
return { error: null };
|
|
636
|
-
}
|
|
637
|
-
catch (err) {
|
|
638
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
639
|
-
logger.fail(label, msg);
|
|
640
|
-
return { error: msg };
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
async function deployFrontmatterEmit(action, dryRun, verbose, home, planned, deps) {
|
|
644
|
-
const label = `${action.skill} -> ${action.agent}`;
|
|
645
|
-
if (dryRun) {
|
|
646
|
-
planned.push({
|
|
647
|
-
verb: "emit-frontmatter",
|
|
648
|
-
kind: "frontmatter-emit",
|
|
649
|
-
skill: action.skill,
|
|
650
|
-
agent: action.agent,
|
|
651
|
-
target: action.target,
|
|
652
|
-
frontmatter: action.frontmatter,
|
|
653
|
-
confidence: action.confidence,
|
|
654
|
-
});
|
|
655
|
-
return { error: null };
|
|
656
|
-
}
|
|
657
|
-
try {
|
|
658
|
-
// Guard against double-patching by a different skill/agent.
|
|
659
|
-
const existingEntry = await lookupDeployment(home, action.target, deps.registry);
|
|
660
|
-
if (existingEntry &&
|
|
661
|
-
(existingEntry.skill !== action.skill ||
|
|
662
|
-
existingEntry.agent !== action.agent)) {
|
|
663
|
-
throw new Error(`File "${action.target}" is already managed by skill "${existingEntry.skill}" for agent "${existingEntry.agent}" — refusing to overwrite`);
|
|
664
|
-
}
|
|
665
|
-
await writeFrontmatterFile(action.target, action.frontmatter, {
|
|
666
|
-
preserveBody: true,
|
|
667
|
-
});
|
|
668
|
-
await registerDeployment(home, action.target, {
|
|
669
|
-
kind: "file-write",
|
|
670
|
-
source: action.target,
|
|
671
|
-
skill: action.skill,
|
|
672
|
-
agent: action.agent,
|
|
673
|
-
}, deps.registry);
|
|
674
|
-
logger.ok(label);
|
|
675
|
-
if (verbose) {
|
|
676
|
-
logger.detail(`emit-frontmatter: wrote ${action.target}`);
|
|
677
|
-
}
|
|
678
|
-
return { error: null };
|
|
679
|
-
}
|
|
680
|
-
catch (err) {
|
|
681
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
682
|
-
logger.fail(label, msg);
|
|
683
|
-
return { error: msg };
|
|
684
|
-
}
|
|
685
|
-
}
|