@wairon/cli 5.1.1-dev.54 → 5.1.1-dev.55
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/index.js +447 -401
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +282 -233
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -65,7 +65,7 @@ var init_defaults = __esm({
|
|
|
65
65
|
copilot: ".github/prompts",
|
|
66
66
|
codex: ".codex/agents"
|
|
67
67
|
};
|
|
68
|
-
WAIRON_VERSION = "5.1.1-dev.
|
|
68
|
+
WAIRON_VERSION = "5.1.1-dev.55";
|
|
69
69
|
GITHUB_REPO = "SYW-Apps/Waffle-AIron";
|
|
70
70
|
SUPPORTED_ALIASES = ["wai"];
|
|
71
71
|
SCAN_EXCLUDE_DIRS = /* @__PURE__ */ new Set([
|
|
@@ -22768,6 +22768,270 @@ var init_treetransfer = __esm({
|
|
|
22768
22768
|
}
|
|
22769
22769
|
});
|
|
22770
22770
|
|
|
22771
|
+
// src/exporters/claude.ts
|
|
22772
|
+
function toolsFor(budget) {
|
|
22773
|
+
const base = TOOLS_BY_CLASS[budget.toolClass];
|
|
22774
|
+
if (!base) return void 0;
|
|
22775
|
+
if (budget.allowNestedDelegation && !base.includes("Agent")) {
|
|
22776
|
+
return [...base, "Agent"];
|
|
22777
|
+
}
|
|
22778
|
+
if (!budget.allowNestedDelegation) {
|
|
22779
|
+
return base.filter((t) => t !== "Agent");
|
|
22780
|
+
}
|
|
22781
|
+
return base;
|
|
22782
|
+
}
|
|
22783
|
+
function mcpServersFor(access) {
|
|
22784
|
+
return access === "none" ? "[]" : void 0;
|
|
22785
|
+
}
|
|
22786
|
+
function yamlScalar(value) {
|
|
22787
|
+
return /[:#\n]/.test(value) ? `"${value.replace(/"/g, '\\"')}"` : value;
|
|
22788
|
+
}
|
|
22789
|
+
var path22, MODEL_BY_TIER, TOOLS_BY_CLASS, ClaudeExporter;
|
|
22790
|
+
var init_claude = __esm({
|
|
22791
|
+
"src/exporters/claude.ts"() {
|
|
22792
|
+
"use strict";
|
|
22793
|
+
path22 = __toESM(require("path"));
|
|
22794
|
+
init_fs();
|
|
22795
|
+
MODEL_BY_TIER = {
|
|
22796
|
+
small: "haiku",
|
|
22797
|
+
standard: "sonnet",
|
|
22798
|
+
large: "opus",
|
|
22799
|
+
frontier: "fable"
|
|
22800
|
+
};
|
|
22801
|
+
TOOLS_BY_CLASS = {
|
|
22802
|
+
"read-only": ["Read", "Grep", "Glob"],
|
|
22803
|
+
implement: ["Read", "Grep", "Glob", "Edit", "Write", "Bash"],
|
|
22804
|
+
orchestrate: ["Agent", "SendMessage", "TodoWrite"],
|
|
22805
|
+
// `full` means "inherit everything" — expressed by omitting the field.
|
|
22806
|
+
full: void 0
|
|
22807
|
+
};
|
|
22808
|
+
ClaudeExporter = class {
|
|
22809
|
+
constructor(options = {}) {
|
|
22810
|
+
this.options = options;
|
|
22811
|
+
this.targetType = "claude";
|
|
22812
|
+
}
|
|
22813
|
+
outputPath(ctx) {
|
|
22814
|
+
const { agent, target, projectRoot: projectRoot2 } = ctx;
|
|
22815
|
+
const outputDir = "outputDir" in target ? target.outputDir : ".claude/agents";
|
|
22816
|
+
return path22.resolve(projectRoot2, outputDir, `${agent.id.replace(/::/g, "--")}.md`);
|
|
22817
|
+
}
|
|
22818
|
+
export(ctx) {
|
|
22819
|
+
const { agent, renderedInstructions, budget } = ctx;
|
|
22820
|
+
const filePath = this.outputPath(ctx);
|
|
22821
|
+
const frontmatter = [
|
|
22822
|
+
`name: ${agent.name}`,
|
|
22823
|
+
`description: ${yamlScalar(agent.description)}`
|
|
22824
|
+
];
|
|
22825
|
+
if (budget && this.options.emitBudget) {
|
|
22826
|
+
if (budget.modelTier) frontmatter.push(`model: ${MODEL_BY_TIER[budget.modelTier]}`);
|
|
22827
|
+
if (budget.effort) frontmatter.push(`effort: ${budget.effort}`);
|
|
22828
|
+
if (budget.maxTurns !== void 0) frontmatter.push(`maxTurns: ${budget.maxTurns}`);
|
|
22829
|
+
const tools = toolsFor(budget);
|
|
22830
|
+
if (tools) frontmatter.push(`tools: ${tools.join(", ")}`);
|
|
22831
|
+
const servers = mcpServersFor(budget.mcp);
|
|
22832
|
+
if (servers) frontmatter.push(`mcpServers: ${servers}`);
|
|
22833
|
+
}
|
|
22834
|
+
const content = ["---", ...frontmatter, "---", "", renderedInstructions, ""].join("\n");
|
|
22835
|
+
const changed = writeFileIfChanged(filePath, content);
|
|
22836
|
+
return { outputPath: filePath, content, unchanged: !changed };
|
|
22837
|
+
}
|
|
22838
|
+
};
|
|
22839
|
+
}
|
|
22840
|
+
});
|
|
22841
|
+
|
|
22842
|
+
// src/exporters/custom.ts
|
|
22843
|
+
var path23, CustomExporter;
|
|
22844
|
+
var init_custom = __esm({
|
|
22845
|
+
"src/exporters/custom.ts"() {
|
|
22846
|
+
"use strict";
|
|
22847
|
+
path23 = __toESM(require("path"));
|
|
22848
|
+
init_fs();
|
|
22849
|
+
CustomExporter = class {
|
|
22850
|
+
constructor() {
|
|
22851
|
+
this.targetType = "custom";
|
|
22852
|
+
}
|
|
22853
|
+
outputPath(ctx) {
|
|
22854
|
+
const { agent, target, projectRoot: projectRoot2 } = ctx;
|
|
22855
|
+
if (!("outputDir" in target)) {
|
|
22856
|
+
throw new Error("CustomExporter requires target.outputDir");
|
|
22857
|
+
}
|
|
22858
|
+
return path23.resolve(projectRoot2, target.outputDir, `${agent.id.replace(/::/g, "--")}.md`);
|
|
22859
|
+
}
|
|
22860
|
+
export(ctx) {
|
|
22861
|
+
const { agent, target, renderedInstructions } = ctx;
|
|
22862
|
+
const label = "label" in target ? target.label : "Custom";
|
|
22863
|
+
const filePath = this.outputPath(ctx);
|
|
22864
|
+
const content = [
|
|
22865
|
+
"---",
|
|
22866
|
+
`name: ${agent.name}`,
|
|
22867
|
+
`description: ${agent.description}`,
|
|
22868
|
+
`id: ${agent.id}`,
|
|
22869
|
+
`target: ${label}`,
|
|
22870
|
+
"---",
|
|
22871
|
+
"",
|
|
22872
|
+
renderedInstructions,
|
|
22873
|
+
""
|
|
22874
|
+
].join("\n");
|
|
22875
|
+
const changed = writeFileIfChanged(filePath, content);
|
|
22876
|
+
return { outputPath: filePath, content, unchanged: !changed };
|
|
22877
|
+
}
|
|
22878
|
+
};
|
|
22879
|
+
}
|
|
22880
|
+
});
|
|
22881
|
+
|
|
22882
|
+
// src/exporters/gemini.ts
|
|
22883
|
+
function yamlString(value) {
|
|
22884
|
+
if (/[:#\[\]{},&*!|>'"%@`]/.test(value) || value.startsWith(" ") || value.endsWith(" ")) {
|
|
22885
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
22886
|
+
}
|
|
22887
|
+
return value;
|
|
22888
|
+
}
|
|
22889
|
+
var path24, GeminiExporter;
|
|
22890
|
+
var init_gemini = __esm({
|
|
22891
|
+
"src/exporters/gemini.ts"() {
|
|
22892
|
+
"use strict";
|
|
22893
|
+
path24 = __toESM(require("path"));
|
|
22894
|
+
init_fs();
|
|
22895
|
+
GeminiExporter = class {
|
|
22896
|
+
constructor() {
|
|
22897
|
+
this.targetType = "gemini";
|
|
22898
|
+
}
|
|
22899
|
+
outputPath(ctx) {
|
|
22900
|
+
const { agent, target, projectRoot: projectRoot2 } = ctx;
|
|
22901
|
+
const outputDir = "outputDir" in target ? target.outputDir : ".gemini/agents";
|
|
22902
|
+
return path24.resolve(projectRoot2, outputDir, `${agent.id.replace(/::/g, "--")}.yaml`);
|
|
22903
|
+
}
|
|
22904
|
+
export(ctx) {
|
|
22905
|
+
const { agent, renderedInstructions } = ctx;
|
|
22906
|
+
const filePath = this.outputPath(ctx);
|
|
22907
|
+
const indentedInstructions = renderedInstructions.split("\n").map((line2) => line2.length > 0 ? ` ${line2}` : "").join("\n");
|
|
22908
|
+
const content = [
|
|
22909
|
+
`name: ${yamlString(agent.name)}`,
|
|
22910
|
+
`description: ${yamlString(agent.description)}`,
|
|
22911
|
+
`system_prompt: |`,
|
|
22912
|
+
indentedInstructions,
|
|
22913
|
+
""
|
|
22914
|
+
].join("\n");
|
|
22915
|
+
const changed = writeFileIfChanged(filePath, content);
|
|
22916
|
+
return { outputPath: filePath, content, unchanged: !changed };
|
|
22917
|
+
}
|
|
22918
|
+
};
|
|
22919
|
+
}
|
|
22920
|
+
});
|
|
22921
|
+
|
|
22922
|
+
// src/exporters/registry.ts
|
|
22923
|
+
function getExporter(target) {
|
|
22924
|
+
const type = typeof target === "string" ? target : target.type;
|
|
22925
|
+
const exporter = EXPORTERS.get(type);
|
|
22926
|
+
if (!exporter) {
|
|
22927
|
+
throw new WaironError(`No exporter registered for target type: "${type}"`);
|
|
22928
|
+
}
|
|
22929
|
+
return exporter;
|
|
22930
|
+
}
|
|
22931
|
+
var EXPORTERS;
|
|
22932
|
+
var init_registry2 = __esm({
|
|
22933
|
+
"src/exporters/registry.ts"() {
|
|
22934
|
+
"use strict";
|
|
22935
|
+
init_claude();
|
|
22936
|
+
init_custom();
|
|
22937
|
+
init_gemini();
|
|
22938
|
+
init_errors();
|
|
22939
|
+
EXPORTERS = /* @__PURE__ */ new Map([
|
|
22940
|
+
["claude", new ClaudeExporter({ emitBudget: true })],
|
|
22941
|
+
["gemini", new GeminiExporter()],
|
|
22942
|
+
["agy", new GeminiExporter()],
|
|
22943
|
+
["cursor", new ClaudeExporter()],
|
|
22944
|
+
["copilot", new ClaudeExporter()],
|
|
22945
|
+
["codex", new ClaudeExporter()],
|
|
22946
|
+
["custom", new CustomExporter()]
|
|
22947
|
+
]);
|
|
22948
|
+
}
|
|
22949
|
+
});
|
|
22950
|
+
|
|
22951
|
+
// src/exporters/base.ts
|
|
22952
|
+
var WAIRON_MANAGED_MARKER, WAIRON_MANAGED_BANNER;
|
|
22953
|
+
var init_base = __esm({
|
|
22954
|
+
"src/exporters/base.ts"() {
|
|
22955
|
+
"use strict";
|
|
22956
|
+
WAIRON_MANAGED_MARKER = "wairon:managed";
|
|
22957
|
+
WAIRON_MANAGED_BANNER = `<!-- ${WAIRON_MANAGED_MARKER} \u2014 generated by \`wairon generate\`; do not edit, changes are overwritten -->`;
|
|
22958
|
+
}
|
|
22959
|
+
});
|
|
22960
|
+
|
|
22961
|
+
// src/exporters/generate.ts
|
|
22962
|
+
function generateAgent(agent, projectConfig, options = {}) {
|
|
22963
|
+
const projectRoot2 = options.projectRoot ?? getProjectRoot();
|
|
22964
|
+
const template = loadTemplate(agent.template, projectConfig.globalTemplatesDir);
|
|
22965
|
+
const rendered = `${WAIRON_MANAGED_BANNER}
|
|
22966
|
+
${composeAgentBrief(agent.id).instructions}`;
|
|
22967
|
+
const results = [];
|
|
22968
|
+
const budget = resolveBudget(
|
|
22969
|
+
deriveExecutionProfile(agent),
|
|
22970
|
+
projectConfig.execution,
|
|
22971
|
+
agent.id
|
|
22972
|
+
);
|
|
22973
|
+
for (const agentTarget of agent.targets) {
|
|
22974
|
+
const targetConfig = resolveTargetConfig(agentTarget, projectConfig);
|
|
22975
|
+
if (!targetConfig) continue;
|
|
22976
|
+
if (options.filterTargets) {
|
|
22977
|
+
const type = "type" in targetConfig ? targetConfig.type : targetConfig;
|
|
22978
|
+
if (!options.filterTargets.includes(type)) continue;
|
|
22979
|
+
}
|
|
22980
|
+
if (!options.dryRun) {
|
|
22981
|
+
results.push(getExporter(targetConfig).export({
|
|
22982
|
+
agent,
|
|
22983
|
+
template,
|
|
22984
|
+
renderedInstructions: rendered,
|
|
22985
|
+
projectRoot: projectRoot2,
|
|
22986
|
+
target: targetConfig,
|
|
22987
|
+
budget
|
|
22988
|
+
}));
|
|
22989
|
+
}
|
|
22990
|
+
}
|
|
22991
|
+
return { agent, results };
|
|
22992
|
+
}
|
|
22993
|
+
function generateAll(agents, projectConfig, options = {}) {
|
|
22994
|
+
let pool = agents;
|
|
22995
|
+
if (options.filterDomainIds && options.filterDomainIds.length > 0) {
|
|
22996
|
+
const ids = new Set(options.filterDomainIds);
|
|
22997
|
+
pool = agents.filter((a) => ids.has(a.domainRoot ?? "root"));
|
|
22998
|
+
}
|
|
22999
|
+
return pool.map((agent) => generateAgent(agent, projectConfig, options));
|
|
23000
|
+
}
|
|
23001
|
+
function resolveExpectedOutputPaths(agents, projectConfig, projectRoot2 = getProjectRoot()) {
|
|
23002
|
+
const expected = /* @__PURE__ */ new Set();
|
|
23003
|
+
for (const agent of agents) {
|
|
23004
|
+
for (const agentTarget of agent.targets) {
|
|
23005
|
+
const targetConfig = resolveTargetConfig(agentTarget, projectConfig);
|
|
23006
|
+
if (!targetConfig) continue;
|
|
23007
|
+
const ctx = { agent, projectRoot: projectRoot2, target: targetConfig };
|
|
23008
|
+
expected.add(path25.resolve(getExporter(targetConfig).outputPath(ctx)));
|
|
23009
|
+
}
|
|
23010
|
+
}
|
|
23011
|
+
return expected;
|
|
23012
|
+
}
|
|
23013
|
+
function resolveTargetConfig(agentTarget, projectConfig) {
|
|
23014
|
+
const targetType = typeof agentTarget === "string" ? agentTarget : agentTarget.type;
|
|
23015
|
+
return projectConfig.targets.find((t) => {
|
|
23016
|
+
if (typeof t === "string") return t === targetType;
|
|
23017
|
+
return t.type === targetType;
|
|
23018
|
+
});
|
|
23019
|
+
}
|
|
23020
|
+
var path25;
|
|
23021
|
+
var init_generate = __esm({
|
|
23022
|
+
"src/exporters/generate.ts"() {
|
|
23023
|
+
"use strict";
|
|
23024
|
+
path25 = __toESM(require("path"));
|
|
23025
|
+
init_templates();
|
|
23026
|
+
init_agent_resolver();
|
|
23027
|
+
init_execution_profile();
|
|
23028
|
+
init_budget_policy();
|
|
23029
|
+
init_fs();
|
|
23030
|
+
init_registry2();
|
|
23031
|
+
init_base();
|
|
23032
|
+
}
|
|
23033
|
+
});
|
|
23034
|
+
|
|
22771
23035
|
// src/core/stereotype-migration.ts
|
|
22772
23036
|
function retireSpecialists(apply) {
|
|
22773
23037
|
const components = loadComponentSpecs();
|
|
@@ -22924,12 +23188,12 @@ function digest(content) {
|
|
|
22924
23188
|
return crypto3.createHash("sha256").update(normalized, "utf8").digest("hex");
|
|
22925
23189
|
}
|
|
22926
23190
|
function currentSpecDigests(root = getProjectRoot()) {
|
|
22927
|
-
const mountDirs = loadSubsystemSpecs().filter((s) => s.projectPath && !s.id.includes("::")).map((s) => `${
|
|
23191
|
+
const mountDirs = loadSubsystemSpecs().filter((s) => s.projectPath && !s.id.includes("::")).map((s) => `${path26.resolve(root, s.projectPath).split(path26.sep).join("/")}/`);
|
|
22928
23192
|
const out = {};
|
|
22929
23193
|
for (const [abs, content] of snapshotSpecFiles()) {
|
|
22930
|
-
const normalized =
|
|
23194
|
+
const normalized = path26.resolve(abs).split(path26.sep).join("/");
|
|
22931
23195
|
if (mountDirs.some((dir) => normalized.startsWith(dir))) continue;
|
|
22932
|
-
out[
|
|
23196
|
+
out[path26.relative(root, abs).split(path26.sep).join("/")] = digest(content);
|
|
22933
23197
|
}
|
|
22934
23198
|
return out;
|
|
22935
23199
|
}
|
|
@@ -22987,7 +23251,7 @@ function currentChildPins(mounts, root = getProjectRoot()) {
|
|
|
22987
23251
|
const pins = {};
|
|
22988
23252
|
for (const mount of mounts) {
|
|
22989
23253
|
if (!mount.projectPath || mount.id.includes("::")) continue;
|
|
22990
|
-
const child = readLockRecordAt(
|
|
23254
|
+
const child = readLockRecordAt(path26.resolve(root, mount.projectPath));
|
|
22991
23255
|
if (child) pins[mount.id] = pinOf(child.stateId);
|
|
22992
23256
|
}
|
|
22993
23257
|
return pins;
|
|
@@ -23003,12 +23267,12 @@ function movedChildren(mounts, root = getProjectRoot()) {
|
|
|
23003
23267
|
}
|
|
23004
23268
|
return moved;
|
|
23005
23269
|
}
|
|
23006
|
-
var crypto3,
|
|
23270
|
+
var crypto3, path26;
|
|
23007
23271
|
var init_approval = __esm({
|
|
23008
23272
|
"src/core/approval.ts"() {
|
|
23009
23273
|
"use strict";
|
|
23010
23274
|
crypto3 = __toESM(require("crypto"));
|
|
23011
|
-
|
|
23275
|
+
path26 = __toESM(require("path"));
|
|
23012
23276
|
init_fs();
|
|
23013
23277
|
init_specs2();
|
|
23014
23278
|
init_lockfile();
|
|
@@ -23089,6 +23353,7 @@ var init_core = __esm({
|
|
|
23089
23353
|
init_treetransfer();
|
|
23090
23354
|
init_extensions();
|
|
23091
23355
|
init_agent_resolver();
|
|
23356
|
+
init_generate();
|
|
23092
23357
|
init_treetransfer();
|
|
23093
23358
|
init_provision();
|
|
23094
23359
|
init_stereotype_migration();
|
|
@@ -23465,13 +23730,13 @@ function validateSddTree(rulesOrOptions, projectType = "backend") {
|
|
|
23465
23730
|
function resolveThroughParent(boundRoot, treatAllAsComplete, childRules) {
|
|
23466
23731
|
const reach = getRequestParentReach();
|
|
23467
23732
|
if (reach && !reach.parentReach) return null;
|
|
23468
|
-
const ceiling = reach?.topRoot ?
|
|
23733
|
+
const ceiling = reach?.topRoot ? path27.resolve(reach.topRoot) : void 0;
|
|
23469
23734
|
const chain = [];
|
|
23470
|
-
let top =
|
|
23735
|
+
let top = path27.resolve(boundRoot);
|
|
23471
23736
|
while (top !== ceiling) {
|
|
23472
23737
|
const hop = findChainingParent(top, ceiling);
|
|
23473
23738
|
if (!hop) break;
|
|
23474
|
-
const next =
|
|
23739
|
+
const next = path27.resolve(hop.parentRoot);
|
|
23475
23740
|
if (ceiling && !isWithinOrEqual(ceiling, next)) break;
|
|
23476
23741
|
chain.unshift(hop.subsystemId);
|
|
23477
23742
|
top = next;
|
|
@@ -23518,8 +23783,8 @@ function isIdChar(ch) {
|
|
|
23518
23783
|
return ch >= "a" && ch <= "z" || ch >= "A" && ch <= "Z" || ch >= "0" && ch <= "9" || ch === "_" || ch === "-" || ch === "." || ch === ":";
|
|
23519
23784
|
}
|
|
23520
23785
|
function isWithinOrEqual(dir, target) {
|
|
23521
|
-
const rel2 =
|
|
23522
|
-
return rel2 === "" || !rel2.startsWith("..") && !
|
|
23786
|
+
const rel2 = path27.relative(dir, target);
|
|
23787
|
+
return rel2 === "" || !rel2.startsWith("..") && !path27.isAbsolute(rel2);
|
|
23523
23788
|
}
|
|
23524
23789
|
function dedupeIssues(list2) {
|
|
23525
23790
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -23540,7 +23805,7 @@ function settledStatusBearing(loaded) {
|
|
|
23540
23805
|
if (!settled || settled.size === 0) return [];
|
|
23541
23806
|
const root = getProjectRoot();
|
|
23542
23807
|
const index = scanAllSpecs();
|
|
23543
|
-
const rel2 = (abs) =>
|
|
23808
|
+
const rel2 = (abs) => path27.relative(root, abs).split(path27.sep).join("/");
|
|
23544
23809
|
const out = [];
|
|
23545
23810
|
const take = (specs, paths) => {
|
|
23546
23811
|
for (const spec of specs) {
|
|
@@ -23570,7 +23835,7 @@ function computeGateStateId() {
|
|
|
23570
23835
|
registerBuiltinRules();
|
|
23571
23836
|
return computeGateIdentity(content, extensions, ruleSequence(), inputs, gate);
|
|
23572
23837
|
}
|
|
23573
|
-
var
|
|
23838
|
+
var path27, RESOLUTION_FAILURE_CODES, SEVERITY_RANK;
|
|
23574
23839
|
var init_validation = __esm({
|
|
23575
23840
|
"src/core/validation.ts"() {
|
|
23576
23841
|
"use strict";
|
|
@@ -23586,7 +23851,7 @@ var init_validation = __esm({
|
|
|
23586
23851
|
init_source_analysis();
|
|
23587
23852
|
init_specs2();
|
|
23588
23853
|
init_fs();
|
|
23589
|
-
|
|
23854
|
+
path27 = __toESM(require("path"));
|
|
23590
23855
|
init_core();
|
|
23591
23856
|
RESOLUTION_FAILURE_CODES = /* @__PURE__ */ new Set([
|
|
23592
23857
|
"UNDEFINED_TYPE_REFERENCE",
|
|
@@ -24306,42 +24571,42 @@ function rebaseReference(ref, mount, direction, isMoved = () => false) {
|
|
|
24306
24571
|
return relativizeId(travels ? qualifyId(left, to, NO_ROOT_SUBSYSTEMS) : target, to);
|
|
24307
24572
|
}
|
|
24308
24573
|
function isWithin(dir, file) {
|
|
24309
|
-
const d =
|
|
24310
|
-
const f =
|
|
24311
|
-
return f === d || f.startsWith(d +
|
|
24574
|
+
const d = path28.resolve(dir);
|
|
24575
|
+
const f = path28.resolve(file);
|
|
24576
|
+
return f === d || f.startsWith(d + path28.sep);
|
|
24312
24577
|
}
|
|
24313
24578
|
function canonicalPath(target) {
|
|
24314
|
-
let existing =
|
|
24579
|
+
let existing = path28.resolve(target);
|
|
24315
24580
|
const rest = [];
|
|
24316
24581
|
for (; ; ) {
|
|
24317
24582
|
try {
|
|
24318
24583
|
fs18.lstatSync(existing);
|
|
24319
24584
|
break;
|
|
24320
24585
|
} catch {
|
|
24321
|
-
const up =
|
|
24322
|
-
if (up === existing) return
|
|
24323
|
-
rest.unshift(
|
|
24586
|
+
const up = path28.dirname(existing);
|
|
24587
|
+
if (up === existing) return path28.resolve(target);
|
|
24588
|
+
rest.unshift(path28.basename(existing));
|
|
24324
24589
|
existing = up;
|
|
24325
24590
|
}
|
|
24326
24591
|
}
|
|
24327
24592
|
try {
|
|
24328
|
-
return
|
|
24593
|
+
return path28.join(fs18.realpathSync.native(existing), ...rest);
|
|
24329
24594
|
} catch {
|
|
24330
24595
|
return null;
|
|
24331
24596
|
}
|
|
24332
24597
|
}
|
|
24333
24598
|
function chainDirKey(dir) {
|
|
24334
|
-
return canonicalPath(dir) ??
|
|
24599
|
+
return canonicalPath(dir) ?? path28.resolve(dir);
|
|
24335
24600
|
}
|
|
24336
24601
|
function projectPathEscapesRoot(projectRoot2, projectPath, resolvedChildDir) {
|
|
24337
|
-
if (
|
|
24602
|
+
if (path28.isAbsolute(projectPath) || !isWithin(projectRoot2, resolvedChildDir)) return true;
|
|
24338
24603
|
const root = canonicalPath(projectRoot2);
|
|
24339
24604
|
const child = canonicalPath(resolvedChildDir);
|
|
24340
24605
|
return root === null || child === null || !isWithin(root, child);
|
|
24341
24606
|
}
|
|
24342
24607
|
function assertContainedProjectPath(projectRoot2, projectPath) {
|
|
24343
|
-
const root =
|
|
24344
|
-
const resolved =
|
|
24608
|
+
const root = path28.resolve(projectRoot2);
|
|
24609
|
+
const resolved = path28.resolve(root, projectPath);
|
|
24345
24610
|
if (projectPathEscapesRoot(root, projectPath, resolved)) {
|
|
24346
24611
|
throw new Error(
|
|
24347
24612
|
`projectPath "${projectPath}" must resolve within the project root "${root}", but resolves to "${resolved}"; absolute, ../-escaping and link-escaping paths are rejected so a chained subproject is always contained by its parent.`
|
|
@@ -24352,12 +24617,12 @@ function assertContainedProjectPath(projectRoot2, projectPath) {
|
|
|
24352
24617
|
function findChainingParent(childRoot, ceiling) {
|
|
24353
24618
|
let childResolved;
|
|
24354
24619
|
try {
|
|
24355
|
-
childResolved =
|
|
24620
|
+
childResolved = path28.resolve(childRoot);
|
|
24356
24621
|
} catch {
|
|
24357
24622
|
return null;
|
|
24358
24623
|
}
|
|
24359
|
-
const bound2 = ceiling ?
|
|
24360
|
-
let dir =
|
|
24624
|
+
const bound2 = ceiling ? path28.resolve(ceiling) : void 0;
|
|
24625
|
+
let dir = path28.dirname(childResolved);
|
|
24361
24626
|
for (let hops = 0; hops < 32; hops++) {
|
|
24362
24627
|
if (bound2 && !isWithin(bound2, dir)) break;
|
|
24363
24628
|
const specsDir = aiPathsAt(dir).specsDir();
|
|
@@ -24373,7 +24638,7 @@ function findChainingParent(childRoot, ceiling) {
|
|
|
24373
24638
|
const projectPath = raw.projectPath;
|
|
24374
24639
|
if (typeof projectPath === "string" && projectPath.trim() !== "") {
|
|
24375
24640
|
try {
|
|
24376
|
-
const mountDir =
|
|
24641
|
+
const mountDir = path28.resolve(dir, projectPath);
|
|
24377
24642
|
if (mountDir === childResolved && !projectPathEscapesRoot(dir, projectPath, mountDir)) {
|
|
24378
24643
|
const id = raw.id;
|
|
24379
24644
|
return { parentRoot: dir, subsystemId: typeof id === "string" ? id : "?" };
|
|
@@ -24384,14 +24649,14 @@ function findChainingParent(childRoot, ceiling) {
|
|
|
24384
24649
|
}
|
|
24385
24650
|
}
|
|
24386
24651
|
}
|
|
24387
|
-
const up =
|
|
24652
|
+
const up = path28.dirname(dir);
|
|
24388
24653
|
if (up === dir) break;
|
|
24389
24654
|
dir = up;
|
|
24390
24655
|
}
|
|
24391
24656
|
return null;
|
|
24392
24657
|
}
|
|
24393
24658
|
function inspectChainedRoots(rootDir = getProjectRoot()) {
|
|
24394
|
-
const root =
|
|
24659
|
+
const root = path28.resolve(rootDir);
|
|
24395
24660
|
const inspection = { roots: [], skipped: [] };
|
|
24396
24661
|
const listed = /* @__PURE__ */ new Set();
|
|
24397
24662
|
const walk2 = (projectDir, prefix, ancestors, depth) => {
|
|
@@ -24410,7 +24675,7 @@ function inspectChainedRoots(rootDir = getProjectRoot()) {
|
|
|
24410
24675
|
const localId = typeof id === "string" ? id : "?";
|
|
24411
24676
|
let childDir;
|
|
24412
24677
|
try {
|
|
24413
|
-
childDir =
|
|
24678
|
+
childDir = path28.resolve(projectDir, projectPath);
|
|
24414
24679
|
} catch {
|
|
24415
24680
|
continue;
|
|
24416
24681
|
}
|
|
@@ -24427,7 +24692,7 @@ function inspectChainedRoots(rootDir = getProjectRoot()) {
|
|
|
24427
24692
|
const key = chainDirKey(childDir);
|
|
24428
24693
|
if (listed.has(key)) continue;
|
|
24429
24694
|
listed.add(key);
|
|
24430
|
-
inspection.roots.push(
|
|
24695
|
+
inspection.roots.push(path28.relative(root, childDir).split(path28.sep).join("/"));
|
|
24431
24696
|
walk2(childDir, prefix ? `${prefix}::${localId}` : localId, /* @__PURE__ */ new Set([...ancestors, key]), depth + 1);
|
|
24432
24697
|
}
|
|
24433
24698
|
};
|
|
@@ -24513,9 +24778,9 @@ function stripNamespaceFromImplementation(spec, prefix) {
|
|
|
24513
24778
|
}
|
|
24514
24779
|
function childRelativeFilePaths(spec, authoringRoot, childRoot) {
|
|
24515
24780
|
const reexpress = (p) => {
|
|
24516
|
-
if (
|
|
24517
|
-
const rel2 =
|
|
24518
|
-
const inside = rel2 !== "" && rel2 !== ".." && !rel2.startsWith(`..${
|
|
24781
|
+
if (path28.isAbsolute(p)) return p;
|
|
24782
|
+
const rel2 = path28.relative(childRoot, path28.resolve(authoringRoot, p));
|
|
24783
|
+
const inside = rel2 !== "" && rel2 !== ".." && !rel2.startsWith(`..${path28.sep}`) && !path28.isAbsolute(rel2);
|
|
24519
24784
|
return inside ? rel2.replace(/\\/g, "/") : p;
|
|
24520
24785
|
};
|
|
24521
24786
|
return {
|
|
@@ -24550,9 +24815,9 @@ function findOwner(id, components) {
|
|
|
24550
24815
|
}) ?? null;
|
|
24551
24816
|
}
|
|
24552
24817
|
function moveComponentFolder(fromDir, toDir) {
|
|
24553
|
-
if (
|
|
24818
|
+
if (path28.normalize(fromDir) === path28.normalize(toDir)) return false;
|
|
24554
24819
|
if (!fs18.existsSync(fromDir) || fs18.existsSync(toDir)) return false;
|
|
24555
|
-
ensureDir(
|
|
24820
|
+
ensureDir(path28.dirname(toDir));
|
|
24556
24821
|
fs18.renameSync(fromDir, toDir);
|
|
24557
24822
|
return true;
|
|
24558
24823
|
}
|
|
@@ -24968,7 +25233,7 @@ function refusedMoveSummary(from, to, methods, refusals, alternatives) {
|
|
|
24968
25233
|
return `Refused: moving ${namedMethods(methods)} from "${from}" to "${to}" is refused by ${refusals.join(", ")}. Nothing was written. ` + (cheapest ? `The cheapest legal home is "${cheapest.component}" (${cheapest.newDependencies.length} new dependenc${cheapest.newDependencies.length === 1 ? "y" : "ies"}, ${cheapest.dependencyCount} of ${cheapest.dependencyLimit}).` : `No component of this subsystem can take them as they stand \u2014 ${alternatives.length} were weighed.`);
|
|
24969
25234
|
}
|
|
24970
25235
|
function workspaceFor(rootDir) {
|
|
24971
|
-
const key =
|
|
25236
|
+
const key = path28.resolve(rootDir);
|
|
24972
25237
|
let ws = workspaces.get(key);
|
|
24973
25238
|
if (!ws) {
|
|
24974
25239
|
ws = new SpecWorkspace(key);
|
|
@@ -25098,13 +25363,13 @@ function snapshotInputKey(snapshot) {
|
|
|
25098
25363
|
return canonicalize(content);
|
|
25099
25364
|
}
|
|
25100
25365
|
function consumedSurfaceInputsAt(rootDir) {
|
|
25101
|
-
const dir =
|
|
25366
|
+
const dir = path28.join(rootDir, ".wai", "surfaces");
|
|
25102
25367
|
if (!pathExists(dir)) return [];
|
|
25103
25368
|
const keys = [];
|
|
25104
25369
|
for (const file of fs18.readdirSync(dir)) {
|
|
25105
25370
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml")) continue;
|
|
25106
25371
|
try {
|
|
25107
|
-
keys.push(snapshotInputKey(SurfaceSnapshotSchema.parse(readYamlFile(
|
|
25372
|
+
keys.push(snapshotInputKey(SurfaceSnapshotSchema.parse(readYamlFile(path28.join(dir, file)))));
|
|
25108
25373
|
} catch {
|
|
25109
25374
|
}
|
|
25110
25375
|
}
|
|
@@ -25112,7 +25377,7 @@ function consumedSurfaceInputsAt(rootDir) {
|
|
|
25112
25377
|
}
|
|
25113
25378
|
function consumedContractInputs() {
|
|
25114
25379
|
const root = getProjectRoot();
|
|
25115
|
-
const roots = [root, ...listChainedRoots(root).map((rel2) =>
|
|
25380
|
+
const roots = [root, ...listChainedRoots(root).map((rel2) => path28.join(root, rel2))];
|
|
25116
25381
|
return roots.flatMap(consumedSurfaceInputsAt);
|
|
25117
25382
|
}
|
|
25118
25383
|
function readLockState(current2) {
|
|
@@ -25148,7 +25413,7 @@ function markSelectionsBundled(bundled) {
|
|
|
25148
25413
|
projectConfigRepository.markSelectionsBundled(bundled);
|
|
25149
25414
|
}
|
|
25150
25415
|
function computeStateIdAt(root) {
|
|
25151
|
-
const resolved =
|
|
25416
|
+
const resolved = path28.resolve(root);
|
|
25152
25417
|
return runWithProjectRoot(resolved, () => {
|
|
25153
25418
|
workspaceFor(resolved).invalidate();
|
|
25154
25419
|
const system = loadSystemSpec();
|
|
@@ -25198,12 +25463,12 @@ function updateSpec(kind, id, delta, hooks, dryRun) {
|
|
|
25198
25463
|
function moveMethods(from, to, methods, hooks, dryRun) {
|
|
25199
25464
|
return current().moveMethods(from, to, methods, hooks, dryRun);
|
|
25200
25465
|
}
|
|
25201
|
-
var fs18,
|
|
25466
|
+
var fs18, path28, NO_ROOT_SUBSYSTEMS, SIGNATURE_TTL_MS, COMPONENT_AUTH_SOURCE, DELTA_VERBS, JUMP_LABEL_TWINS, LABEL_TWIN_CONTAINERS, SpecWorkspace, DEFAULT_DEPENDENCY_LIMIT, PROSE_FIELDS2, workspaces;
|
|
25202
25467
|
var init_specs2 = __esm({
|
|
25203
25468
|
"src/core/specs.ts"() {
|
|
25204
25469
|
"use strict";
|
|
25205
25470
|
fs18 = __toESM(require("fs"));
|
|
25206
|
-
|
|
25471
|
+
path28 = __toESM(require("path"));
|
|
25207
25472
|
init_loader();
|
|
25208
25473
|
init_project_config();
|
|
25209
25474
|
init_fs();
|
|
@@ -25238,7 +25503,7 @@ var init_specs2 = __esm({
|
|
|
25238
25503
|
this.rootSubsystems = /* @__PURE__ */ new Set();
|
|
25239
25504
|
this.scanVisitedSpecDirs = [];
|
|
25240
25505
|
this.loaderIssues = [];
|
|
25241
|
-
this.rootDir =
|
|
25506
|
+
this.rootDir = path28.resolve(rootDir);
|
|
25242
25507
|
this.paths = aiPathsAt(this.rootDir);
|
|
25243
25508
|
}
|
|
25244
25509
|
invalidate() {
|
|
@@ -25281,8 +25546,8 @@ var init_specs2 = __esm({
|
|
|
25281
25546
|
* qualifies the spec itself — so scoping a validate to a mount keeps it.
|
|
25282
25547
|
*/
|
|
25283
25548
|
loaderIssueSpecId(file, rawId, namespacePrefix) {
|
|
25284
|
-
const stem2 =
|
|
25285
|
-
const local = rawId ?? (stem2.startsWith(".") ?
|
|
25549
|
+
const stem2 = path28.basename(file, ".yaml");
|
|
25550
|
+
const local = rawId ?? (stem2.startsWith(".") ? path28.basename(path28.dirname(file)) : stem2);
|
|
25286
25551
|
return namespacePrefix ? qualifyId(local, namespacePrefix, this.rootSubsystems) : local;
|
|
25287
25552
|
}
|
|
25288
25553
|
scanSpecsForProject(projectDir, namespacePrefix, visitedDirs, maxDepth, currentDepth) {
|
|
@@ -25292,10 +25557,10 @@ var init_specs2 = __esm({
|
|
|
25292
25557
|
this.scanVisitedSpecDirs.push(specsDir);
|
|
25293
25558
|
if (!pathExists(specsDir)) return index;
|
|
25294
25559
|
const files = listSpecFiles(specsDir);
|
|
25295
|
-
const systemYaml =
|
|
25560
|
+
const systemYaml = path28.normalize(projectPaths.specsSystem());
|
|
25296
25561
|
const localSubprojects = [];
|
|
25297
25562
|
for (const file of files) {
|
|
25298
|
-
const normFile =
|
|
25563
|
+
const normFile = path28.normalize(file);
|
|
25299
25564
|
if (normFile === systemYaml) continue;
|
|
25300
25565
|
let detectedType = "spec";
|
|
25301
25566
|
let rawId;
|
|
@@ -25339,7 +25604,7 @@ var init_specs2 = __esm({
|
|
|
25339
25604
|
} else if ("contract" in raw) {
|
|
25340
25605
|
detectedType = "implementation";
|
|
25341
25606
|
const parsed = ImplementationSpecSchema.parse(raw);
|
|
25342
|
-
const normalizeSourcePath = (p) =>
|
|
25607
|
+
const normalizeSourcePath = (p) => path28.relative(projectDir, path28.resolve(projectDir, p)).replace(/\\/g, "/");
|
|
25343
25608
|
if (parsed.sourcePath) parsed.sourcePath = normalizeSourcePath(parsed.sourcePath);
|
|
25344
25609
|
for (const method2 of parsed.methods) {
|
|
25345
25610
|
if (method2.sourcePath) method2.sourcePath = normalizeSourcePath(method2.sourcePath);
|
|
@@ -25465,7 +25730,7 @@ var init_specs2 = __esm({
|
|
|
25465
25730
|
}
|
|
25466
25731
|
if (currentDepth < maxDepth) {
|
|
25467
25732
|
for (const subproj of localSubprojects) {
|
|
25468
|
-
const childDir =
|
|
25733
|
+
const childDir = path28.resolve(projectDir, subproj.projectPath);
|
|
25469
25734
|
const mountId = namespacePrefix ? qualifyDeclaredId(subproj.subsystemId, namespacePrefix, true) : subproj.subsystemId;
|
|
25470
25735
|
if (projectPathEscapesRoot(projectDir, subproj.projectPath, childDir)) {
|
|
25471
25736
|
this.loaderIssues.push({
|
|
@@ -25528,7 +25793,7 @@ var init_specs2 = __esm({
|
|
|
25528
25793
|
const index = this.scanAll();
|
|
25529
25794
|
const sub = index.subsystems.find((s) => s.id === currentPrefix);
|
|
25530
25795
|
if (sub && sub.projectPath) {
|
|
25531
|
-
const nextDir =
|
|
25796
|
+
const nextDir = path28.resolve(currentDir, sub.projectPath);
|
|
25532
25797
|
if (projectPathEscapesRoot(currentDir, sub.projectPath, nextDir)) {
|
|
25533
25798
|
this.loaderIssues.push({
|
|
25534
25799
|
severity: "error",
|
|
@@ -25580,9 +25845,9 @@ var init_specs2 = __esm({
|
|
|
25580
25845
|
return index.paths.subsystem[matches[0]];
|
|
25581
25846
|
}
|
|
25582
25847
|
if (pathExists(this.paths.specsSubsystemsDir()) && listFiles(this.paths.specsSubsystemsDir(), ".yaml").length > 0) {
|
|
25583
|
-
return
|
|
25848
|
+
return path28.join(this.paths.specsSubsystemsDir(), `${id}.yaml`);
|
|
25584
25849
|
}
|
|
25585
|
-
return
|
|
25850
|
+
return path28.join(this.paths.specsDir(), id, ".index.yaml");
|
|
25586
25851
|
}
|
|
25587
25852
|
getComponentPath(id, subsystemId) {
|
|
25588
25853
|
const index = this.scanAll();
|
|
@@ -25602,21 +25867,21 @@ var init_specs2 = __esm({
|
|
|
25602
25867
|
if (owner) {
|
|
25603
25868
|
const ownerPath = index.paths.component[owner.id];
|
|
25604
25869
|
if (ownerPath && ownerPath.endsWith(".index.yaml")) {
|
|
25605
|
-
return
|
|
25870
|
+
return path28.join(path28.dirname(ownerPath), id, ".index.yaml");
|
|
25606
25871
|
}
|
|
25607
25872
|
}
|
|
25608
25873
|
if (subsystemId) {
|
|
25609
25874
|
const subPath = this.getSubsystemPath(subsystemId);
|
|
25610
|
-
const subDir =
|
|
25875
|
+
const subDir = path28.dirname(subPath);
|
|
25611
25876
|
if (subPath.endsWith(".index.yaml")) {
|
|
25612
|
-
return
|
|
25877
|
+
return path28.join(subDir, id, ".index.yaml");
|
|
25613
25878
|
}
|
|
25614
25879
|
}
|
|
25615
25880
|
if (pathExists(this.paths.specsComponentsDir()) && listFiles(this.paths.specsComponentsDir(), ".yaml").length > 0) {
|
|
25616
|
-
return
|
|
25881
|
+
return path28.join(this.paths.specsComponentsDir(), `${id}.yaml`);
|
|
25617
25882
|
}
|
|
25618
25883
|
const targetSubsystem = subsystemId || "default";
|
|
25619
|
-
return
|
|
25884
|
+
return path28.join(this.paths.specsDir(), targetSubsystem, id, ".index.yaml");
|
|
25620
25885
|
}
|
|
25621
25886
|
getInterfacePath(id, componentId) {
|
|
25622
25887
|
const index = this.scanAll();
|
|
@@ -25642,16 +25907,16 @@ var init_specs2 = __esm({
|
|
|
25642
25907
|
}
|
|
25643
25908
|
if (componentId) {
|
|
25644
25909
|
const compPath = this.getComponentPath(componentId);
|
|
25645
|
-
const compDir =
|
|
25910
|
+
const compDir = path28.dirname(compPath);
|
|
25646
25911
|
if (compPath.endsWith(".index.yaml")) {
|
|
25647
|
-
return
|
|
25912
|
+
return path28.join(compDir, ".interface.yaml");
|
|
25648
25913
|
}
|
|
25649
25914
|
}
|
|
25650
25915
|
if (pathExists(this.paths.specsInterfacesDir()) && listFiles(this.paths.specsInterfacesDir(), ".yaml").length > 0) {
|
|
25651
|
-
return
|
|
25916
|
+
return path28.join(this.paths.specsInterfacesDir(), `${id}.yaml`);
|
|
25652
25917
|
}
|
|
25653
25918
|
const targetComponent = componentId || "default";
|
|
25654
|
-
return
|
|
25919
|
+
return path28.join(this.paths.specsDir(), "default", targetComponent, ".interface.yaml");
|
|
25655
25920
|
}
|
|
25656
25921
|
getImplementationPath(id, contractId) {
|
|
25657
25922
|
const index = this.scanAll();
|
|
@@ -25677,16 +25942,16 @@ var init_specs2 = __esm({
|
|
|
25677
25942
|
}
|
|
25678
25943
|
if (contractId) {
|
|
25679
25944
|
const intfPath = this.getInterfacePath(contractId);
|
|
25680
|
-
const intfDir =
|
|
25945
|
+
const intfDir = path28.dirname(intfPath);
|
|
25681
25946
|
if (intfPath.endsWith(".interface.yaml")) {
|
|
25682
|
-
return
|
|
25947
|
+
return path28.join(intfDir, ".implementation.yaml");
|
|
25683
25948
|
}
|
|
25684
25949
|
}
|
|
25685
25950
|
if (pathExists(this.paths.specsImplementationsDir()) && listFiles(this.paths.specsImplementationsDir(), ".yaml").length > 0) {
|
|
25686
|
-
return
|
|
25951
|
+
return path28.join(this.paths.specsImplementationsDir(), `${id}.yaml`);
|
|
25687
25952
|
}
|
|
25688
25953
|
const targetContract = contractId ? contractId.replace(/^i/, "") : "default";
|
|
25689
|
-
return
|
|
25954
|
+
return path28.join(this.paths.specsDir(), "default", targetContract, ".implementation.yaml");
|
|
25690
25955
|
}
|
|
25691
25956
|
getTypePath(id, subsystemId, group) {
|
|
25692
25957
|
const index = this.scanAll();
|
|
@@ -25717,7 +25982,7 @@ var init_specs2 = __esm({
|
|
|
25717
25982
|
const groupPath = index.paths.group[targetGroup] || index.paths.group[plainGroup];
|
|
25718
25983
|
if (groupPath) {
|
|
25719
25984
|
const localId2 = id.split("::").pop();
|
|
25720
|
-
return
|
|
25985
|
+
return path28.join(path28.dirname(groupPath), `${localId2}.yaml`);
|
|
25721
25986
|
}
|
|
25722
25987
|
}
|
|
25723
25988
|
let localId = id;
|
|
@@ -25730,12 +25995,12 @@ var init_specs2 = __esm({
|
|
|
25730
25995
|
}
|
|
25731
25996
|
if (subsystemId) {
|
|
25732
25997
|
const subPath = this.getSubsystemPath(subsystemId);
|
|
25733
|
-
const subDir =
|
|
25998
|
+
const subDir = path28.dirname(subPath);
|
|
25734
25999
|
if (subPath.endsWith(".index.yaml")) {
|
|
25735
|
-
return
|
|
26000
|
+
return path28.join(subDir, "types", `${localId}.yaml`);
|
|
25736
26001
|
}
|
|
25737
26002
|
}
|
|
25738
|
-
return
|
|
26003
|
+
return path28.join(this.paths.specsTypesDir(), `${localId}.yaml`);
|
|
25739
26004
|
}
|
|
25740
26005
|
getGroupPath(id, subsystemId) {
|
|
25741
26006
|
const index = this.scanAll();
|
|
@@ -25769,12 +26034,12 @@ var init_specs2 = __esm({
|
|
|
25769
26034
|
}
|
|
25770
26035
|
if (subsystemId) {
|
|
25771
26036
|
const subPath = this.getSubsystemPath(subsystemId);
|
|
25772
|
-
const subDir =
|
|
26037
|
+
const subDir = path28.dirname(subPath);
|
|
25773
26038
|
if (subPath.endsWith(".index.yaml")) {
|
|
25774
|
-
return
|
|
26039
|
+
return path28.join(subDir, "types", localId, ".index.yaml");
|
|
25775
26040
|
}
|
|
25776
26041
|
}
|
|
25777
|
-
return
|
|
26042
|
+
return path28.join(this.paths.specsTypesDir(), localId, ".index.yaml");
|
|
25778
26043
|
}
|
|
25779
26044
|
// -------------------------------------------------------------------------
|
|
25780
26045
|
// Level 0: System
|
|
@@ -25797,7 +26062,7 @@ var init_specs2 = __esm({
|
|
|
25797
26062
|
}
|
|
25798
26063
|
saveSystemSpec(spec) {
|
|
25799
26064
|
const p = this.paths.specsSystem();
|
|
25800
|
-
ensureDir(
|
|
26065
|
+
ensureDir(path28.dirname(p));
|
|
25801
26066
|
writeSpecFile(p, parseOrThrow(SystemSpecSchema, spec, "system", spec.name));
|
|
25802
26067
|
invalidateSpecCache();
|
|
25803
26068
|
}
|
|
@@ -25919,7 +26184,7 @@ var init_specs2 = __esm({
|
|
|
25919
26184
|
}
|
|
25920
26185
|
saveSubsystemSpec(spec, opts) {
|
|
25921
26186
|
const p = this.getSubsystemPath(spec.id);
|
|
25922
|
-
ensureDir(
|
|
26187
|
+
ensureDir(path28.dirname(p));
|
|
25923
26188
|
const { prefix } = splitNamespace(spec.id);
|
|
25924
26189
|
if (!prefix && spec.projectPath && spec.projectPath.trim() !== "") {
|
|
25925
26190
|
assertContainedProjectPath(this.rootDir, spec.projectPath);
|
|
@@ -25986,7 +26251,7 @@ var init_specs2 = __esm({
|
|
|
25986
26251
|
saveComponentSpec(spec, opts) {
|
|
25987
26252
|
const notices = [];
|
|
25988
26253
|
const p = this.getComponentPath(spec.id, spec.subsystem);
|
|
25989
|
-
ensureDir(
|
|
26254
|
+
ensureDir(path28.dirname(p));
|
|
25990
26255
|
const specToWrite = this.prepareComponentForWrite(spec);
|
|
25991
26256
|
const existing = this.loadComponentSpec(spec.id);
|
|
25992
26257
|
if (existing) {
|
|
@@ -26003,7 +26268,7 @@ var init_specs2 = __esm({
|
|
|
26003
26268
|
const subsystemChanged = existing && existing.subsystem !== spec.subsystem && splitNamespace(existing.subsystem).localId !== splitNamespace(spec.subsystem).localId;
|
|
26004
26269
|
if (subsystemChanged && !p.endsWith(".index.yaml")) {
|
|
26005
26270
|
notices.push(
|
|
26006
|
-
`component "${spec.id}" already exists at ${
|
|
26271
|
+
`component "${spec.id}" already exists at ${path28.relative(this.rootDir, p)} \u2014 the flat layout re-saves in place and never relocates the file. The subsystem field is now "${spec.subsystem}" (was "${existing.subsystem}").`
|
|
26007
26272
|
);
|
|
26008
26273
|
}
|
|
26009
26274
|
specToWrite.updatedAt = opts?.preserveUpdatedAt && existing?.updatedAt ? existing.updatedAt : (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -26027,12 +26292,12 @@ var init_specs2 = __esm({
|
|
|
26027
26292
|
if (owner) {
|
|
26028
26293
|
const ownerPath = index.paths.component[owner.id];
|
|
26029
26294
|
if (ownerPath && ownerPath.endsWith(".index.yaml")) {
|
|
26030
|
-
const ownerSubDir =
|
|
26031
|
-
return
|
|
26295
|
+
const ownerSubDir = path28.dirname(this.getSubsystemPath(owner.subsystem));
|
|
26296
|
+
return path28.join(ownerSubDir, owner.id, comp.id);
|
|
26032
26297
|
}
|
|
26033
26298
|
}
|
|
26034
|
-
const subDir =
|
|
26035
|
-
return
|
|
26299
|
+
const subDir = path28.dirname(this.getSubsystemPath(comp.subsystem));
|
|
26300
|
+
return path28.join(subDir, comp.id);
|
|
26036
26301
|
}
|
|
26037
26302
|
/**
|
|
26038
26303
|
* Move component folders so the physical tree mirrors ownership: each owned
|
|
@@ -26048,7 +26313,7 @@ var init_specs2 = __esm({
|
|
|
26048
26313
|
if (!currentPath) continue;
|
|
26049
26314
|
const desiredDir = this.desiredComponentDir(comp, index);
|
|
26050
26315
|
if (!desiredDir) continue;
|
|
26051
|
-
if (moveComponentFolder(
|
|
26316
|
+
if (moveComponentFolder(path28.dirname(currentPath), desiredDir)) moved.push(comp.id);
|
|
26052
26317
|
}
|
|
26053
26318
|
if (moved.length) invalidateSpecCache();
|
|
26054
26319
|
return moved;
|
|
@@ -26104,7 +26369,7 @@ var init_specs2 = __esm({
|
|
|
26104
26369
|
if (!occupantId) return;
|
|
26105
26370
|
if (occupantId === id || splitNamespace(occupantId).localId === splitNamespace(id).localId) return;
|
|
26106
26371
|
throw new Error(
|
|
26107
|
-
`Cannot write ${kind} "${id}": ${parentLabel} is already ${kind === "interface" ? "served by" : "implemented by"} "${occupantId}" at ${
|
|
26372
|
+
`Cannot write ${kind} "${id}": ${parentLabel} is already ${kind === "interface" ? "served by" : "implemented by"} "${occupantId}" at ${path28.relative(this.rootDir, p)}, and both ids resolve to that one file. Re-author "${occupantId}" instead, or delete it first if you meant to replace it.`
|
|
26108
26373
|
);
|
|
26109
26374
|
}
|
|
26110
26375
|
/** Returns non-fatal placement notices (see saveTypeSpec) — empty when there is nothing to clarify. */
|
|
@@ -26112,12 +26377,12 @@ var init_specs2 = __esm({
|
|
|
26112
26377
|
const notices = [];
|
|
26113
26378
|
const p = this.getInterfacePath(spec.id, spec.component);
|
|
26114
26379
|
this.assertPathHoldsNoOtherSpec(p, spec.id, "interface", `component "${spec.component}"`);
|
|
26115
|
-
ensureDir(
|
|
26380
|
+
ensureDir(path28.dirname(p));
|
|
26116
26381
|
const specToWrite = this.prepareInterfaceForWrite(spec);
|
|
26117
26382
|
const existing = this.loadInterfaceSpec(spec.id);
|
|
26118
26383
|
if (existing && existing.component !== spec.component && splitNamespace(existing.component).localId !== splitNamespace(spec.component).localId) {
|
|
26119
26384
|
notices.push(
|
|
26120
|
-
`interface "${spec.id}" already exists at ${
|
|
26385
|
+
`interface "${spec.id}" already exists at ${path28.relative(this.rootDir, p)} \u2014 re-saving updates the component binding field in place (now "${spec.component}", was "${existing.component}") and never moves the file.`
|
|
26121
26386
|
);
|
|
26122
26387
|
}
|
|
26123
26388
|
if (existing) {
|
|
@@ -26174,12 +26439,12 @@ var init_specs2 = __esm({
|
|
|
26174
26439
|
const notices = [];
|
|
26175
26440
|
const p = this.getImplementationPath(spec.id, spec.contract);
|
|
26176
26441
|
this.assertPathHoldsNoOtherSpec(p, spec.id, "implementation", `contract "${spec.contract}"`);
|
|
26177
|
-
ensureDir(
|
|
26442
|
+
ensureDir(path28.dirname(p));
|
|
26178
26443
|
const specToWrite = this.prepareImplementationForWrite(spec);
|
|
26179
26444
|
const existing = this.loadImplementationSpec(spec.id);
|
|
26180
26445
|
if (existing && existing.contract !== spec.contract && splitNamespace(existing.contract).localId !== splitNamespace(spec.contract).localId) {
|
|
26181
26446
|
notices.push(
|
|
26182
|
-
`implementation "${spec.id}" already exists at ${
|
|
26447
|
+
`implementation "${spec.id}" already exists at ${path28.relative(this.rootDir, p)} \u2014 re-saving updates the contract binding field in place (now "${spec.contract}", was "${existing.contract}") and never moves the file.`
|
|
26183
26448
|
);
|
|
26184
26449
|
}
|
|
26185
26450
|
if (existing) {
|
|
@@ -26220,11 +26485,11 @@ var init_specs2 = __esm({
|
|
|
26220
26485
|
const existing = this.loadTypeSpec(spec.id);
|
|
26221
26486
|
const group = spec.group || (existing ? existing.group : void 0);
|
|
26222
26487
|
const p = this.getTypePath(spec.id, spec.subsystem, group);
|
|
26223
|
-
ensureDir(
|
|
26488
|
+
ensureDir(path28.dirname(p));
|
|
26224
26489
|
const subsystemChanged = existing && (existing.subsystem ?? "") !== (spec.subsystem ?? "") && splitNamespace(existing.subsystem ?? "").localId !== splitNamespace(spec.subsystem ?? "").localId;
|
|
26225
26490
|
if (subsystemChanged) {
|
|
26226
26491
|
notices.push(
|
|
26227
|
-
`type "${spec.id}" already exists at ${
|
|
26492
|
+
`type "${spec.id}" already exists at ${path28.relative(this.rootDir, p)} \u2014 re-saving updates fields in place and never relocates the file. The subsystem field is now "${spec.subsystem ?? "(none)"}" (was "${existing.subsystem ?? "(none)"}").`
|
|
26228
26493
|
);
|
|
26229
26494
|
}
|
|
26230
26495
|
if (spec.subsystem && (!existing || subsystemChanged) && !this.getSubsystemPath(spec.subsystem).endsWith(".index.yaml")) {
|
|
@@ -26262,7 +26527,7 @@ var init_specs2 = __esm({
|
|
|
26262
26527
|
}
|
|
26263
26528
|
saveGroupSpec(spec, opts) {
|
|
26264
26529
|
const p = this.getGroupPath(spec.id);
|
|
26265
|
-
ensureDir(
|
|
26530
|
+
ensureDir(path28.dirname(p));
|
|
26266
26531
|
const specToWrite = this.prepareGroupForWrite(spec);
|
|
26267
26532
|
const existing = this.loadGroupSpec(spec.id);
|
|
26268
26533
|
if (existing) {
|
|
@@ -26340,7 +26605,7 @@ var init_specs2 = __esm({
|
|
|
26340
26605
|
};
|
|
26341
26606
|
const out = /* @__PURE__ */ new Set();
|
|
26342
26607
|
const add = (p) => {
|
|
26343
|
-
if (p) out.add(
|
|
26608
|
+
if (p) out.add(path28.resolve(p));
|
|
26344
26609
|
};
|
|
26345
26610
|
for (const s of this.loadSubsystemSpecs()) {
|
|
26346
26611
|
if (!scopeSubsystem || s.id === scopeSubsystem || s.id.startsWith(`${scopeSubsystem}::`)) {
|
|
@@ -26411,11 +26676,11 @@ var init_specs2 = __esm({
|
|
|
26411
26676
|
const files = /* @__PURE__ */ new Set();
|
|
26412
26677
|
const sysPath = this.paths.specsSystem();
|
|
26413
26678
|
if (pathExists(sysPath)) {
|
|
26414
|
-
files.add(
|
|
26679
|
+
files.add(path28.resolve(sysPath));
|
|
26415
26680
|
}
|
|
26416
26681
|
for (const group of Object.values(index.paths)) {
|
|
26417
26682
|
for (const file of Object.values(group)) {
|
|
26418
|
-
files.add(
|
|
26683
|
+
files.add(path28.resolve(file));
|
|
26419
26684
|
}
|
|
26420
26685
|
}
|
|
26421
26686
|
for (const file of files) {
|
|
@@ -26434,20 +26699,20 @@ var init_specs2 = __esm({
|
|
|
26434
26699
|
const files = listSpecFiles(specsDir);
|
|
26435
26700
|
const legacy = [];
|
|
26436
26701
|
for (const f of files) {
|
|
26437
|
-
const base =
|
|
26438
|
-
const dir =
|
|
26702
|
+
const base = path28.basename(f);
|
|
26703
|
+
const dir = path28.dirname(f);
|
|
26439
26704
|
if (base === "system.yaml") {
|
|
26440
|
-
legacy.push({ path: f, expected:
|
|
26705
|
+
legacy.push({ path: f, expected: path28.join(dir, ".index.yaml") });
|
|
26441
26706
|
} else if (base === "subsystem.yaml") {
|
|
26442
|
-
legacy.push({ path: f, expected:
|
|
26707
|
+
legacy.push({ path: f, expected: path28.join(dir, ".index.yaml") });
|
|
26443
26708
|
} else if (base === "component.yaml") {
|
|
26444
|
-
legacy.push({ path: f, expected:
|
|
26709
|
+
legacy.push({ path: f, expected: path28.join(dir, ".index.yaml") });
|
|
26445
26710
|
} else if (base === "group.yaml") {
|
|
26446
|
-
legacy.push({ path: f, expected:
|
|
26711
|
+
legacy.push({ path: f, expected: path28.join(dir, ".index.yaml") });
|
|
26447
26712
|
} else if (base === "interface.yaml") {
|
|
26448
|
-
legacy.push({ path: f, expected:
|
|
26713
|
+
legacy.push({ path: f, expected: path28.join(dir, ".interface.yaml") });
|
|
26449
26714
|
} else if (base === "implementation.yaml") {
|
|
26450
|
-
legacy.push({ path: f, expected:
|
|
26715
|
+
legacy.push({ path: f, expected: path28.join(dir, ".implementation.yaml") });
|
|
26451
26716
|
}
|
|
26452
26717
|
}
|
|
26453
26718
|
return legacy;
|
|
@@ -27459,7 +27724,7 @@ __export(agent_resolver_exports, {
|
|
|
27459
27724
|
});
|
|
27460
27725
|
function listFilesRecursiveSafe(dirPath, ext) {
|
|
27461
27726
|
if (!fs19.existsSync(dirPath)) return [];
|
|
27462
|
-
const nameLower =
|
|
27727
|
+
const nameLower = path29.basename(dirPath).toLowerCase();
|
|
27463
27728
|
const IGNORED_DIRS = /* @__PURE__ */ new Set([
|
|
27464
27729
|
"node_modules",
|
|
27465
27730
|
"target",
|
|
@@ -27477,7 +27742,7 @@ function listFilesRecursiveSafe(dirPath, ext) {
|
|
|
27477
27742
|
const entries = fs19.readdirSync(dirPath, { withFileTypes: true });
|
|
27478
27743
|
const files = [];
|
|
27479
27744
|
for (const entry of entries) {
|
|
27480
|
-
const fullPath =
|
|
27745
|
+
const fullPath = path29.join(dirPath, entry.name);
|
|
27481
27746
|
if (entry.isDirectory()) {
|
|
27482
27747
|
files.push(...listFilesRecursiveSafe(fullPath, ext));
|
|
27483
27748
|
} else if (entry.isFile() && entry.name.endsWith(ext)) {
|
|
@@ -27490,8 +27755,8 @@ function getProjectFiles(projectDir) {
|
|
|
27490
27755
|
let files = projectFilesCache.get(projectDir);
|
|
27491
27756
|
if (!files) {
|
|
27492
27757
|
files = [];
|
|
27493
|
-
const srcDir =
|
|
27494
|
-
const legacySrcDir =
|
|
27758
|
+
const srcDir = path29.join(projectDir, "src");
|
|
27759
|
+
const legacySrcDir = path29.join(projectDir, "legacy-src");
|
|
27495
27760
|
let searchDir = projectDir;
|
|
27496
27761
|
if (pathExists(srcDir)) {
|
|
27497
27762
|
searchDir = srcDir;
|
|
@@ -27506,7 +27771,7 @@ function getProjectFiles(projectDir) {
|
|
|
27506
27771
|
files.push(...listFilesRecursiveSafe(searchDir, ext));
|
|
27507
27772
|
}
|
|
27508
27773
|
const rootDir = getProjectRoot();
|
|
27509
|
-
files = files.map((f) =>
|
|
27774
|
+
files = files.map((f) => path29.relative(rootDir, f).replace(/\\/g, "/"));
|
|
27510
27775
|
projectFilesCache.set(projectDir, files);
|
|
27511
27776
|
}
|
|
27512
27777
|
return files;
|
|
@@ -27531,8 +27796,8 @@ function inferSourcePathForComponent(comp, subsystems) {
|
|
|
27531
27796
|
let bestFile = null;
|
|
27532
27797
|
let bestScore = -1;
|
|
27533
27798
|
for (const f of files) {
|
|
27534
|
-
const ext =
|
|
27535
|
-
const base =
|
|
27799
|
+
const ext = path29.extname(f);
|
|
27800
|
+
const base = path29.basename(f, ext).toLowerCase();
|
|
27536
27801
|
if (candidates.has(base)) {
|
|
27537
27802
|
let score = 0;
|
|
27538
27803
|
const normalizedPath = f.toLowerCase();
|
|
@@ -27629,7 +27894,7 @@ function resolveAgentTopology() {
|
|
|
27629
27894
|
});
|
|
27630
27895
|
for (const sub of subsystems) {
|
|
27631
27896
|
if (sub.projectPath) {
|
|
27632
|
-
const mountSpecPath =
|
|
27897
|
+
const mountSpecPath = path29.relative(getProjectRoot(), getSubsystemPath(sub.id)).replace(/\\/g, "/");
|
|
27633
27898
|
agents.push({
|
|
27634
27899
|
id: `${sub.id}-owner`,
|
|
27635
27900
|
name: `${sub.name} (chained subproject)`,
|
|
@@ -27651,9 +27916,9 @@ function resolveAgentTopology() {
|
|
|
27651
27916
|
}
|
|
27652
27917
|
const subComponents = components.filter((c) => c.subsystem === sub.id);
|
|
27653
27918
|
const ownedPaths = [];
|
|
27654
|
-
ownedPaths.push(
|
|
27919
|
+
ownedPaths.push(path29.relative(getProjectRoot(), getSubsystemPath(sub.id)).replace(/\\/g, "/"));
|
|
27655
27920
|
for (const c of subComponents) {
|
|
27656
|
-
ownedPaths.push(
|
|
27921
|
+
ownedPaths.push(path29.relative(getProjectRoot(), getComponentPath(c.id, sub.id)).replace(/\\/g, "/"));
|
|
27657
27922
|
}
|
|
27658
27923
|
if (!config.rules.generateComponentImplementers) {
|
|
27659
27924
|
for (const comp of subComponents) {
|
|
@@ -27729,10 +27994,10 @@ function resolveAgentTopology() {
|
|
|
27729
27994
|
}
|
|
27730
27995
|
const dependencies = comp.dependsOn.map((depId) => `${depId}-implementer`);
|
|
27731
27996
|
const readPaths = [
|
|
27732
|
-
|
|
27733
|
-
|
|
27734
|
-
...compInterfaces.map((i) =>
|
|
27735
|
-
...compImpls.map((impl) =>
|
|
27997
|
+
path29.relative(getProjectRoot(), AI_PATHS.specsSystem()).replace(/\\/g, "/"),
|
|
27998
|
+
path29.relative(getProjectRoot(), getComponentPath(comp.id, comp.subsystem)).replace(/\\/g, "/"),
|
|
27999
|
+
...compInterfaces.map((i) => path29.relative(getProjectRoot(), getInterfacePath(i.id, comp.id)).replace(/\\/g, "/")),
|
|
28000
|
+
...compImpls.map((impl) => path29.relative(getProjectRoot(), getImplementationPath(impl.id, impl.contract)).replace(/\\/g, "/"))
|
|
27736
28001
|
];
|
|
27737
28002
|
agents.push({
|
|
27738
28003
|
id: `${comp.id}-implementer`,
|
|
@@ -27821,11 +28086,11 @@ ${guidance.trim()}
|
|
|
27821
28086
|
budget
|
|
27822
28087
|
};
|
|
27823
28088
|
}
|
|
27824
|
-
var
|
|
28089
|
+
var path29, fs19, projectFilesCache, UnknownAgentError;
|
|
27825
28090
|
var init_agent_resolver = __esm({
|
|
27826
28091
|
"src/core/agent_resolver.ts"() {
|
|
27827
28092
|
"use strict";
|
|
27828
|
-
|
|
28093
|
+
path29 = __toESM(require("path"));
|
|
27829
28094
|
fs19 = __toESM(require("fs"));
|
|
27830
28095
|
init_loader();
|
|
27831
28096
|
init_project_config();
|
|
@@ -27859,12 +28124,12 @@ __export(loader_exports, {
|
|
|
27859
28124
|
saveTopologyConfig: () => saveTopologyConfig
|
|
27860
28125
|
});
|
|
27861
28126
|
function aiPathsAt(rootDir) {
|
|
27862
|
-
const resolvedRoot =
|
|
28127
|
+
const resolvedRoot = path30.resolve(rootDir);
|
|
27863
28128
|
const aiDirAt2 = (...segments) => {
|
|
27864
|
-
const waiPath =
|
|
27865
|
-
const waironPath =
|
|
28129
|
+
const waiPath = path30.join(resolvedRoot, ".wai");
|
|
28130
|
+
const waironPath = path30.join(resolvedRoot, ".wairon");
|
|
27866
28131
|
const base = !fs20.existsSync(waiPath) && fs20.existsSync(waironPath) ? waironPath : waiPath;
|
|
27867
|
-
return
|
|
28132
|
+
return path30.join(base, ...segments);
|
|
27868
28133
|
};
|
|
27869
28134
|
const specsDir = () => projectConfigRepositoryAt(resolvedRoot).specsDir();
|
|
27870
28135
|
return {
|
|
@@ -27881,12 +28146,12 @@ function aiPathsAt(rootDir) {
|
|
|
27881
28146
|
contextDomainsMd: () => aiDirAt2("context", "domains.md"),
|
|
27882
28147
|
contextWaironGuideMd: () => aiDirAt2("context", "wairon-guide.md"),
|
|
27883
28148
|
specsDir,
|
|
27884
|
-
specsSystem: () =>
|
|
27885
|
-
specsSubsystemsDir: () =>
|
|
27886
|
-
specsComponentsDir: () =>
|
|
27887
|
-
specsInterfacesDir: () =>
|
|
27888
|
-
specsImplementationsDir: () =>
|
|
27889
|
-
specsTypesDir: () =>
|
|
28149
|
+
specsSystem: () => path30.join(specsDir(), ".index.yaml"),
|
|
28150
|
+
specsSubsystemsDir: () => path30.join(specsDir(), "subsystems"),
|
|
28151
|
+
specsComponentsDir: () => path30.join(specsDir(), "components"),
|
|
28152
|
+
specsInterfacesDir: () => path30.join(specsDir(), "interfaces"),
|
|
28153
|
+
specsImplementationsDir: () => path30.join(specsDir(), "implementations"),
|
|
28154
|
+
specsTypesDir: () => path30.join(specsDir(), "types")
|
|
27890
28155
|
};
|
|
27891
28156
|
}
|
|
27892
28157
|
function isProjectInitialized() {
|
|
@@ -27917,12 +28182,12 @@ function loadTopologyConfig() {
|
|
|
27917
28182
|
function saveTopologyConfig(config) {
|
|
27918
28183
|
writeYamlFile(AI_PATHS.topologyConfig(), config);
|
|
27919
28184
|
}
|
|
27920
|
-
var fs20,
|
|
28185
|
+
var fs20, path30, AI_PATHS;
|
|
27921
28186
|
var init_loader = __esm({
|
|
27922
28187
|
"src/config/loader.ts"() {
|
|
27923
28188
|
"use strict";
|
|
27924
28189
|
fs20 = __toESM(require("fs"));
|
|
27925
|
-
|
|
28190
|
+
path30 = __toESM(require("path"));
|
|
27926
28191
|
init_fs();
|
|
27927
28192
|
init_yaml();
|
|
27928
28193
|
init_errors();
|
|
@@ -29990,7 +30255,7 @@ async function scopeToClientWorkspace(server) {
|
|
|
29990
30255
|
} catch {
|
|
29991
30256
|
dir = null;
|
|
29992
30257
|
}
|
|
29993
|
-
if (dir && (fs21.existsSync(
|
|
30258
|
+
if (dir && (fs21.existsSync(path32.join(dir, ".wai")) || fs21.existsSync(path32.join(dir, ".wairon")))) {
|
|
29994
30259
|
setProjectRoot(dir);
|
|
29995
30260
|
process.stderr.write(`[wairon mcp] scoped to client workspace root: ${dir}
|
|
29996
30261
|
`);
|
|
@@ -30014,7 +30279,7 @@ async function startMcpServer() {
|
|
|
30014
30279
|
} catch {
|
|
30015
30280
|
}
|
|
30016
30281
|
}
|
|
30017
|
-
var import_mcp, import_stdio, import_zod11, import_types3, fs21,
|
|
30282
|
+
var import_mcp, import_stdio, import_zod11, import_types3, fs21, path32, import_url, TYPE_REF_GRAMMAR, staleServerOutput, SPEC_KINDS, STATUS_ORDER, specWriteReceiptOutput, specChangeOutput, specChangeReportOutput, validationIssueOutput, validateTreeOutput, getSpecOutput, SERVER_BUILD_STAMP, STALE_SERVER_WARNING, SPEC_WRITE_TOOLS, listChangedEmitters, STORE_MANAGED_FIELDS, statusInput, ALWAYS_CARRIED_FIELDS, SKILL_RESOURCE_MIME, AGENT_BRIEF_SCHEME;
|
|
30018
30283
|
var init_server = __esm({
|
|
30019
30284
|
"src/mcp/server.ts"() {
|
|
30020
30285
|
"use strict";
|
|
@@ -30023,7 +30288,7 @@ var init_server = __esm({
|
|
|
30023
30288
|
import_zod11 = require("zod");
|
|
30024
30289
|
import_types3 = require("@modelcontextprotocol/sdk/types.js");
|
|
30025
30290
|
fs21 = __toESM(require("fs"));
|
|
30026
|
-
|
|
30291
|
+
path32 = __toESM(require("path"));
|
|
30027
30292
|
import_url = require("url");
|
|
30028
30293
|
init_fs();
|
|
30029
30294
|
init_yaml();
|
|
@@ -30197,18 +30462,18 @@ __export(mcp_exports, {
|
|
|
30197
30462
|
validateConfigDir: () => validateConfigDir
|
|
30198
30463
|
});
|
|
30199
30464
|
function geminiGlobalDir(override) {
|
|
30200
|
-
return override || process.env["GEMINI_CONFIG_DIR"] ||
|
|
30465
|
+
return override || process.env["GEMINI_CONFIG_DIR"] || path33.join(os7.homedir(), ".gemini");
|
|
30201
30466
|
}
|
|
30202
30467
|
function claudeMcpConfigPath(useGlobal, override) {
|
|
30203
|
-
if (!useGlobal) return
|
|
30468
|
+
if (!useGlobal) return path33.join(process.cwd(), ".mcp.json");
|
|
30204
30469
|
const dir = override || process.env["CLAUDE_CONFIG_DIR"];
|
|
30205
|
-
return dir ?
|
|
30470
|
+
return dir ? path33.join(dir, ".claude.json") : path33.join(os7.homedir(), ".claude.json");
|
|
30206
30471
|
}
|
|
30207
30472
|
function validateConfigDir(dir, backend) {
|
|
30208
|
-
const resolved =
|
|
30473
|
+
const resolved = path33.resolve(dir);
|
|
30209
30474
|
const agent = backend === "claude" ? "Claude" : "Gemini/Antigravity";
|
|
30210
30475
|
if (!fs22.existsSync(resolved)) {
|
|
30211
|
-
const parent =
|
|
30476
|
+
const parent = path33.dirname(resolved);
|
|
30212
30477
|
if (!fs22.existsSync(parent)) {
|
|
30213
30478
|
throw new WaironError(`--config-dir "${dir}" does not exist and its parent is missing \u2014 check the path.`);
|
|
30214
30479
|
}
|
|
@@ -30224,7 +30489,7 @@ function validateConfigDir(dir, backend) {
|
|
|
30224
30489
|
logger.warn(`Config dir "${resolved}" is empty; proceeding (treating it as a fresh ${agent} config dir).`);
|
|
30225
30490
|
return;
|
|
30226
30491
|
}
|
|
30227
|
-
if (!markers.some((m) => fs22.existsSync(
|
|
30492
|
+
if (!markers.some((m) => fs22.existsSync(path33.join(resolved, m)))) {
|
|
30228
30493
|
throw new WaironError(
|
|
30229
30494
|
`"${dir}" does not look like a ${agent} config directory (none of ${markers.slice(0, 4).join(", ")} found). Point --config-dir at the agent's config directory.`
|
|
30230
30495
|
);
|
|
@@ -30232,12 +30497,12 @@ function validateConfigDir(dir, backend) {
|
|
|
30232
30497
|
}
|
|
30233
30498
|
async function runMcpServe() {
|
|
30234
30499
|
const { setProjectRoot: setProjectRoot2, getProjectRoot: getProjectRoot2, findProjectRoot: findProjectRoot2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
|
|
30235
|
-
const cwd =
|
|
30500
|
+
const cwd = path33.resolve(process.cwd());
|
|
30236
30501
|
const envDir = process.env["WAIRON_PROJECT_DIR"];
|
|
30237
30502
|
let resolved;
|
|
30238
30503
|
let how;
|
|
30239
|
-
if (envDir && fs22.existsSync(
|
|
30240
|
-
resolved =
|
|
30504
|
+
if (envDir && fs22.existsSync(path33.join(envDir, ".wai"))) {
|
|
30505
|
+
resolved = path33.resolve(envDir);
|
|
30241
30506
|
how = "WAIRON_PROJECT_DIR (pinned at install)";
|
|
30242
30507
|
} else {
|
|
30243
30508
|
const found = findProjectRoot2(cwd);
|
|
@@ -30263,10 +30528,10 @@ async function runMcpServe() {
|
|
|
30263
30528
|
}
|
|
30264
30529
|
function mcpConfigCandidates(cwd) {
|
|
30265
30530
|
return [
|
|
30266
|
-
|
|
30531
|
+
path33.join(cwd, ".mcp.json"),
|
|
30267
30532
|
claudeMcpConfigPath(true),
|
|
30268
|
-
|
|
30269
|
-
|
|
30533
|
+
path33.join(cwd, ".gemini", "settings.json"),
|
|
30534
|
+
path33.join(geminiGlobalDir(), "antigravity-cli", "mcp_config.json")
|
|
30270
30535
|
];
|
|
30271
30536
|
}
|
|
30272
30537
|
function detectHostedMcpSource(cwd = process.cwd()) {
|
|
@@ -30353,15 +30618,15 @@ async function runMcpInstall(options = {}) {
|
|
|
30353
30618
|
let settingsPath;
|
|
30354
30619
|
if (backend === "gemini") {
|
|
30355
30620
|
if (useGlobal) {
|
|
30356
|
-
configBase =
|
|
30357
|
-
settingsPath =
|
|
30621
|
+
configBase = path33.join(geminiGlobalDir(options.configDir), "antigravity-cli");
|
|
30622
|
+
settingsPath = path33.join(configBase, "mcp_config.json");
|
|
30358
30623
|
} else {
|
|
30359
|
-
configBase =
|
|
30360
|
-
settingsPath =
|
|
30624
|
+
configBase = path33.join(process.cwd(), ".gemini");
|
|
30625
|
+
settingsPath = path33.join(configBase, "settings.json");
|
|
30361
30626
|
}
|
|
30362
30627
|
} else {
|
|
30363
30628
|
settingsPath = claudeMcpConfigPath(useGlobal, options.configDir);
|
|
30364
|
-
configBase =
|
|
30629
|
+
configBase = path33.dirname(settingsPath);
|
|
30365
30630
|
}
|
|
30366
30631
|
let settings = {};
|
|
30367
30632
|
if (fs22.existsSync(settingsPath)) {
|
|
@@ -30374,7 +30639,7 @@ async function runMcpInstall(options = {}) {
|
|
|
30374
30639
|
const mcpServers = settings["mcpServers"] ?? {};
|
|
30375
30640
|
const agentLabel = backend === "gemini" ? "Antigravity" : "Claude";
|
|
30376
30641
|
const isPackaged = typeof process.pkg !== "undefined";
|
|
30377
|
-
const scriptPath = process.argv[1] ?
|
|
30642
|
+
const scriptPath = process.argv[1] ? path33.resolve(process.argv[1]).replace(/\\/g, "/") : null;
|
|
30378
30643
|
const useDirectNode = !isPackaged && scriptPath && (scriptPath.endsWith(".js") || scriptPath.endsWith(".ts"));
|
|
30379
30644
|
const env = useGlobal ? {} : { WAIRON_PROJECT_DIR: process.cwd().replace(/\\/g, "/") };
|
|
30380
30645
|
const desiredEntry = options.hostedUrl ? hostedMcpEntry(options) : useDirectNode ? { command: "node", args: [scriptPath, "mcp", "serve"], env } : { command: "wairon", args: ["mcp", "serve"], env };
|
|
@@ -30413,8 +30678,8 @@ async function runMcpStatus() {
|
|
|
30413
30678
|
if (!projectConfig) throw new ProjectNotInitializedError();
|
|
30414
30679
|
const claudeProject = claudeMcpConfigPath(false);
|
|
30415
30680
|
const claudeGlobal = claudeMcpConfigPath(true);
|
|
30416
|
-
const geminiProject =
|
|
30417
|
-
const geminiGlobal =
|
|
30681
|
+
const geminiProject = path33.join(process.cwd(), ".gemini", "settings.json");
|
|
30682
|
+
const geminiGlobal = path33.join(geminiGlobalDir(), "antigravity-cli", "mcp_config.json");
|
|
30418
30683
|
logger.blank();
|
|
30419
30684
|
logger.info(`${import_chalk5.default.bold("wairon MCP Server")}`);
|
|
30420
30685
|
logger.blank();
|
|
@@ -30464,7 +30729,7 @@ function hostedMcpEntry(options) {
|
|
|
30464
30729
|
}
|
|
30465
30730
|
function removeLegacyGlobalPlugin() {
|
|
30466
30731
|
const home = process.env["USERPROFILE"] ?? process.env["HOME"] ?? os7.homedir();
|
|
30467
|
-
const pluginDir =
|
|
30732
|
+
const pluginDir = path33.join(home, ".gemini", "config", "plugins", "wairon");
|
|
30468
30733
|
try {
|
|
30469
30734
|
if (fs22.existsSync(pluginDir)) {
|
|
30470
30735
|
fs22.rmSync(pluginDir, { recursive: true, force: true });
|
|
@@ -30476,13 +30741,13 @@ function removeLegacyGlobalPlugin() {
|
|
|
30476
30741
|
}
|
|
30477
30742
|
return false;
|
|
30478
30743
|
}
|
|
30479
|
-
var fs22, os7,
|
|
30744
|
+
var fs22, os7, path33, import_chalk5;
|
|
30480
30745
|
var init_mcp = __esm({
|
|
30481
30746
|
"src/commands/mcp.ts"() {
|
|
30482
30747
|
"use strict";
|
|
30483
30748
|
fs22 = __toESM(require("fs"));
|
|
30484
30749
|
os7 = __toESM(require("os"));
|
|
30485
|
-
|
|
30750
|
+
path33 = __toESM(require("path"));
|
|
30486
30751
|
import_chalk5 = __toESM(require("chalk"));
|
|
30487
30752
|
init_logger();
|
|
30488
30753
|
init_loader();
|
|
@@ -30726,7 +30991,7 @@ function isSupportedAlias(name) {
|
|
|
30726
30991
|
}
|
|
30727
30992
|
|
|
30728
30993
|
// src/commands/init.ts
|
|
30729
|
-
var
|
|
30994
|
+
var path34 = __toESM(require("path"));
|
|
30730
30995
|
var import_chalk6 = __toESM(require("chalk"));
|
|
30731
30996
|
var import_inquirer = __toESM(require("inquirer"));
|
|
30732
30997
|
init_logger();
|
|
@@ -30737,7 +31002,7 @@ init_yaml();
|
|
|
30737
31002
|
init_loader();
|
|
30738
31003
|
|
|
30739
31004
|
// src/commands/subsystem.ts
|
|
30740
|
-
var
|
|
31005
|
+
var path31 = __toESM(require("path"));
|
|
30741
31006
|
init_logger();
|
|
30742
31007
|
init_errors();
|
|
30743
31008
|
init_fs();
|
|
@@ -30795,6 +31060,12 @@ function readLockState2(current2) {
|
|
|
30795
31060
|
function renderDiagram2(format) {
|
|
30796
31061
|
return renderDiagram(format);
|
|
30797
31062
|
}
|
|
31063
|
+
function generateAll2(agents, config, options) {
|
|
31064
|
+
return generateAll(agents, config, options);
|
|
31065
|
+
}
|
|
31066
|
+
function resolveExpectedOutputPaths2(agents, config) {
|
|
31067
|
+
return resolveExpectedOutputPaths(agents, config);
|
|
31068
|
+
}
|
|
30798
31069
|
async function runSubsystemAdd(id, options = {}) {
|
|
30799
31070
|
logger.header("wairon subsystem add");
|
|
30800
31071
|
if (!projectConfigExists2()) {
|
|
@@ -30824,9 +31095,9 @@ async function runSubsystemAdd(id, options = {}) {
|
|
|
30824
31095
|
updatedAt: now
|
|
30825
31096
|
};
|
|
30826
31097
|
createChainedSubsystem2(subsystem, displayName);
|
|
30827
|
-
const childDir =
|
|
31098
|
+
const childDir = path31.resolve(getProjectRoot(), options.projectPath);
|
|
30828
31099
|
logger.success(`Added external subsystem "${id}" \u2192 ${options.projectPath}`);
|
|
30829
|
-
logger.info(`Scaffolded child project at ${
|
|
31100
|
+
logger.info(`Scaffolded child project at ${path31.relative(process.cwd(), childDir) || "."}`);
|
|
30830
31101
|
logger.info(`Design its spec tree from this parent using namespaced ids (e.g. ${id}::<component>).`);
|
|
30831
31102
|
}
|
|
30832
31103
|
async function runSubsystemMove(id, options = {}) {
|
|
@@ -30849,9 +31120,9 @@ async function runSubsystemExternalize(id, options = {}) {
|
|
|
30849
31120
|
throw new WaironError("--project-path (the subproject destination) is required.");
|
|
30850
31121
|
}
|
|
30851
31122
|
externalizeSubsystem(id, options.projectPath);
|
|
30852
|
-
const childDir =
|
|
31123
|
+
const childDir = path31.resolve(getProjectRoot(), options.projectPath);
|
|
30853
31124
|
logger.success(`Externalized subsystem "${id}" \u2192 ${options.projectPath}`);
|
|
30854
|
-
logger.info(`Moved its specs into ${
|
|
31125
|
+
logger.info(`Moved its specs into ${path31.relative(process.cwd(), childDir) || "."} (now a standalone subproject).`);
|
|
30855
31126
|
logger.info("Move the source code there yourself, then run `wairon validate` to confirm the tree.");
|
|
30856
31127
|
}
|
|
30857
31128
|
async function runSubsystemInternalize(id) {
|
|
@@ -30908,7 +31179,7 @@ async function runInit(options = {}) {
|
|
|
30908
31179
|
logger.header("wairon init");
|
|
30909
31180
|
const cwd = process.cwd();
|
|
30910
31181
|
const ancestorRoot = findSystemRoot(cwd);
|
|
30911
|
-
if (ancestorRoot &&
|
|
31182
|
+
if (ancestorRoot && path34.resolve(ancestorRoot) === path34.resolve(cwd)) {
|
|
30912
31183
|
logger.info("Project already initialized.");
|
|
30913
31184
|
logger.info("Design your spec tree with the SDD architect skill, then run `wairon generate`.");
|
|
30914
31185
|
return;
|
|
@@ -30924,8 +31195,8 @@ async function runInit(options = {}) {
|
|
|
30924
31195
|
await runInitInteractive();
|
|
30925
31196
|
}
|
|
30926
31197
|
async function runInitAsExternalSubsystem(parentRoot, cwd, options) {
|
|
30927
|
-
const relPath =
|
|
30928
|
-
const defaultId =
|
|
31198
|
+
const relPath = path34.relative(parentRoot, cwd) || ".";
|
|
31199
|
+
const defaultId = path34.basename(cwd);
|
|
30929
31200
|
logger.info(`Detected a parent wairon project at ${parentRoot}`);
|
|
30930
31201
|
logger.info(`This directory ("${relPath}") is not yet a wairon project.`);
|
|
30931
31202
|
if (!options.yes) {
|
|
@@ -30985,7 +31256,7 @@ async function runInitAsExternalSubsystem(parentRoot, cwd, options) {
|
|
|
30985
31256
|
}
|
|
30986
31257
|
async function runInitNonInteractive() {
|
|
30987
31258
|
const cwd = process.cwd();
|
|
30988
|
-
const projectName =
|
|
31259
|
+
const projectName = path34.basename(cwd);
|
|
30989
31260
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
30990
31261
|
const targets = [defaultTargetConfig("claude"), defaultTargetConfig("agy")];
|
|
30991
31262
|
const projectConfig = buildProjectConfig(projectName, targets, now, "backend");
|
|
@@ -31005,7 +31276,7 @@ async function runInitNonInteractive() {
|
|
|
31005
31276
|
}
|
|
31006
31277
|
async function runInitInteractive() {
|
|
31007
31278
|
const cwd = process.cwd();
|
|
31008
|
-
const defaultProjectName =
|
|
31279
|
+
const defaultProjectName = path34.basename(cwd);
|
|
31009
31280
|
const { projectName } = await import_inquirer.default.prompt([
|
|
31010
31281
|
{
|
|
31011
31282
|
type: "input",
|
|
@@ -31150,7 +31421,7 @@ async function executeInit(projectName, projectConfig, guidePlan) {
|
|
|
31150
31421
|
if (guidePlan.claudeLocal) {
|
|
31151
31422
|
const p = localGuideFilePath(projectRoot2, "claude");
|
|
31152
31423
|
injectGuide(p, "local");
|
|
31153
|
-
logger.success(`Injected wairon guide into ${
|
|
31424
|
+
logger.success(`Injected wairon guide into ${path34.relative(cwd, p)}`);
|
|
31154
31425
|
writeRootGuideDelegator(projectRoot2, "claude");
|
|
31155
31426
|
logger.success(`Created root CLAUDE.md delegator pointing to .claude/CLAUDE.md`);
|
|
31156
31427
|
}
|
|
@@ -31162,7 +31433,7 @@ async function executeInit(projectName, projectConfig, guidePlan) {
|
|
|
31162
31433
|
if (guidePlan.geminiLocal) {
|
|
31163
31434
|
const p = localGuideFilePath(projectRoot2, "gemini");
|
|
31164
31435
|
injectGuide(p, "local");
|
|
31165
|
-
logger.success(`Injected wairon guide into ${
|
|
31436
|
+
logger.success(`Injected wairon guide into ${path34.relative(cwd, p)}`);
|
|
31166
31437
|
writeRootGuideDelegator(projectRoot2, "gemini");
|
|
31167
31438
|
logger.success(`Created root GEMINI.md delegator pointing to .gemini/GEMINI.md`);
|
|
31168
31439
|
}
|
|
@@ -31382,232 +31653,7 @@ var path35 = __toESM(require("path"));
|
|
|
31382
31653
|
init_logger();
|
|
31383
31654
|
init_loader();
|
|
31384
31655
|
init_errors();
|
|
31385
|
-
|
|
31386
|
-
// src/exporters/generate.ts
|
|
31387
|
-
var path34 = __toESM(require("path"));
|
|
31388
|
-
init_core();
|
|
31389
|
-
init_execution_profile();
|
|
31390
|
-
init_budget_policy();
|
|
31391
|
-
init_fs();
|
|
31392
|
-
|
|
31393
|
-
// src/exporters/claude.ts
|
|
31394
|
-
var path31 = __toESM(require("path"));
|
|
31395
|
-
init_fs();
|
|
31396
|
-
var MODEL_BY_TIER = {
|
|
31397
|
-
small: "haiku",
|
|
31398
|
-
standard: "sonnet",
|
|
31399
|
-
large: "opus",
|
|
31400
|
-
frontier: "fable"
|
|
31401
|
-
};
|
|
31402
|
-
var TOOLS_BY_CLASS = {
|
|
31403
|
-
"read-only": ["Read", "Grep", "Glob"],
|
|
31404
|
-
implement: ["Read", "Grep", "Glob", "Edit", "Write", "Bash"],
|
|
31405
|
-
orchestrate: ["Agent", "SendMessage", "TodoWrite"],
|
|
31406
|
-
// `full` means "inherit everything" — expressed by omitting the field.
|
|
31407
|
-
full: void 0
|
|
31408
|
-
};
|
|
31409
|
-
function toolsFor(budget) {
|
|
31410
|
-
const base = TOOLS_BY_CLASS[budget.toolClass];
|
|
31411
|
-
if (!base) return void 0;
|
|
31412
|
-
if (budget.allowNestedDelegation && !base.includes("Agent")) {
|
|
31413
|
-
return [...base, "Agent"];
|
|
31414
|
-
}
|
|
31415
|
-
if (!budget.allowNestedDelegation) {
|
|
31416
|
-
return base.filter((t) => t !== "Agent");
|
|
31417
|
-
}
|
|
31418
|
-
return base;
|
|
31419
|
-
}
|
|
31420
|
-
function mcpServersFor(access) {
|
|
31421
|
-
return access === "none" ? "[]" : void 0;
|
|
31422
|
-
}
|
|
31423
|
-
function yamlScalar(value) {
|
|
31424
|
-
return /[:#\n]/.test(value) ? `"${value.replace(/"/g, '\\"')}"` : value;
|
|
31425
|
-
}
|
|
31426
|
-
var ClaudeExporter = class {
|
|
31427
|
-
constructor(options = {}) {
|
|
31428
|
-
this.options = options;
|
|
31429
|
-
this.targetType = "claude";
|
|
31430
|
-
}
|
|
31431
|
-
outputPath(ctx) {
|
|
31432
|
-
const { agent, target, projectRoot: projectRoot2 } = ctx;
|
|
31433
|
-
const outputDir = "outputDir" in target ? target.outputDir : ".claude/agents";
|
|
31434
|
-
return path31.resolve(projectRoot2, outputDir, `${agent.id.replace(/::/g, "--")}.md`);
|
|
31435
|
-
}
|
|
31436
|
-
export(ctx) {
|
|
31437
|
-
const { agent, renderedInstructions, budget } = ctx;
|
|
31438
|
-
const filePath = this.outputPath(ctx);
|
|
31439
|
-
const frontmatter = [
|
|
31440
|
-
`name: ${agent.name}`,
|
|
31441
|
-
`description: ${yamlScalar(agent.description)}`
|
|
31442
|
-
];
|
|
31443
|
-
if (budget && this.options.emitBudget) {
|
|
31444
|
-
if (budget.modelTier) frontmatter.push(`model: ${MODEL_BY_TIER[budget.modelTier]}`);
|
|
31445
|
-
if (budget.effort) frontmatter.push(`effort: ${budget.effort}`);
|
|
31446
|
-
if (budget.maxTurns !== void 0) frontmatter.push(`maxTurns: ${budget.maxTurns}`);
|
|
31447
|
-
const tools = toolsFor(budget);
|
|
31448
|
-
if (tools) frontmatter.push(`tools: ${tools.join(", ")}`);
|
|
31449
|
-
const servers = mcpServersFor(budget.mcp);
|
|
31450
|
-
if (servers) frontmatter.push(`mcpServers: ${servers}`);
|
|
31451
|
-
}
|
|
31452
|
-
const content = ["---", ...frontmatter, "---", "", renderedInstructions, ""].join("\n");
|
|
31453
|
-
const changed = writeFileIfChanged(filePath, content);
|
|
31454
|
-
return { outputPath: filePath, content, unchanged: !changed };
|
|
31455
|
-
}
|
|
31456
|
-
};
|
|
31457
|
-
|
|
31458
|
-
// src/exporters/custom.ts
|
|
31459
|
-
var path32 = __toESM(require("path"));
|
|
31460
|
-
init_fs();
|
|
31461
|
-
var CustomExporter = class {
|
|
31462
|
-
constructor() {
|
|
31463
|
-
this.targetType = "custom";
|
|
31464
|
-
}
|
|
31465
|
-
outputPath(ctx) {
|
|
31466
|
-
const { agent, target, projectRoot: projectRoot2 } = ctx;
|
|
31467
|
-
if (!("outputDir" in target)) {
|
|
31468
|
-
throw new Error("CustomExporter requires target.outputDir");
|
|
31469
|
-
}
|
|
31470
|
-
return path32.resolve(projectRoot2, target.outputDir, `${agent.id.replace(/::/g, "--")}.md`);
|
|
31471
|
-
}
|
|
31472
|
-
export(ctx) {
|
|
31473
|
-
const { agent, target, renderedInstructions } = ctx;
|
|
31474
|
-
const label = "label" in target ? target.label : "Custom";
|
|
31475
|
-
const filePath = this.outputPath(ctx);
|
|
31476
|
-
const content = [
|
|
31477
|
-
"---",
|
|
31478
|
-
`name: ${agent.name}`,
|
|
31479
|
-
`description: ${agent.description}`,
|
|
31480
|
-
`id: ${agent.id}`,
|
|
31481
|
-
`target: ${label}`,
|
|
31482
|
-
"---",
|
|
31483
|
-
"",
|
|
31484
|
-
renderedInstructions,
|
|
31485
|
-
""
|
|
31486
|
-
].join("\n");
|
|
31487
|
-
const changed = writeFileIfChanged(filePath, content);
|
|
31488
|
-
return { outputPath: filePath, content, unchanged: !changed };
|
|
31489
|
-
}
|
|
31490
|
-
};
|
|
31491
|
-
|
|
31492
|
-
// src/exporters/gemini.ts
|
|
31493
|
-
var path33 = __toESM(require("path"));
|
|
31494
|
-
init_fs();
|
|
31495
|
-
var GeminiExporter = class {
|
|
31496
|
-
constructor() {
|
|
31497
|
-
this.targetType = "gemini";
|
|
31498
|
-
}
|
|
31499
|
-
outputPath(ctx) {
|
|
31500
|
-
const { agent, target, projectRoot: projectRoot2 } = ctx;
|
|
31501
|
-
const outputDir = "outputDir" in target ? target.outputDir : ".gemini/agents";
|
|
31502
|
-
return path33.resolve(projectRoot2, outputDir, `${agent.id.replace(/::/g, "--")}.yaml`);
|
|
31503
|
-
}
|
|
31504
|
-
export(ctx) {
|
|
31505
|
-
const { agent, renderedInstructions } = ctx;
|
|
31506
|
-
const filePath = this.outputPath(ctx);
|
|
31507
|
-
const indentedInstructions = renderedInstructions.split("\n").map((line2) => line2.length > 0 ? ` ${line2}` : "").join("\n");
|
|
31508
|
-
const content = [
|
|
31509
|
-
`name: ${yamlString(agent.name)}`,
|
|
31510
|
-
`description: ${yamlString(agent.description)}`,
|
|
31511
|
-
`system_prompt: |`,
|
|
31512
|
-
indentedInstructions,
|
|
31513
|
-
""
|
|
31514
|
-
].join("\n");
|
|
31515
|
-
const changed = writeFileIfChanged(filePath, content);
|
|
31516
|
-
return { outputPath: filePath, content, unchanged: !changed };
|
|
31517
|
-
}
|
|
31518
|
-
};
|
|
31519
|
-
function yamlString(value) {
|
|
31520
|
-
if (/[:#\[\]{},&*!|>'"%@`]/.test(value) || value.startsWith(" ") || value.endsWith(" ")) {
|
|
31521
|
-
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
31522
|
-
}
|
|
31523
|
-
return value;
|
|
31524
|
-
}
|
|
31525
|
-
|
|
31526
|
-
// src/exporters/registry.ts
|
|
31527
|
-
init_errors();
|
|
31528
|
-
var EXPORTERS = /* @__PURE__ */ new Map([
|
|
31529
|
-
["claude", new ClaudeExporter({ emitBudget: true })],
|
|
31530
|
-
["gemini", new GeminiExporter()],
|
|
31531
|
-
["agy", new GeminiExporter()],
|
|
31532
|
-
["cursor", new ClaudeExporter()],
|
|
31533
|
-
["copilot", new ClaudeExporter()],
|
|
31534
|
-
["codex", new ClaudeExporter()],
|
|
31535
|
-
["custom", new CustomExporter()]
|
|
31536
|
-
]);
|
|
31537
|
-
function getExporter(target) {
|
|
31538
|
-
const type = typeof target === "string" ? target : target.type;
|
|
31539
|
-
const exporter = EXPORTERS.get(type);
|
|
31540
|
-
if (!exporter) {
|
|
31541
|
-
throw new WaironError(`No exporter registered for target type: "${type}"`);
|
|
31542
|
-
}
|
|
31543
|
-
return exporter;
|
|
31544
|
-
}
|
|
31545
|
-
|
|
31546
|
-
// src/exporters/base.ts
|
|
31547
|
-
var WAIRON_MANAGED_MARKER = "wairon:managed";
|
|
31548
|
-
var WAIRON_MANAGED_BANNER = `<!-- ${WAIRON_MANAGED_MARKER} \u2014 generated by \`wairon generate\`; do not edit, changes are overwritten -->`;
|
|
31549
|
-
|
|
31550
|
-
// src/exporters/generate.ts
|
|
31551
|
-
function generateAgent(agent, projectConfig, options = {}) {
|
|
31552
|
-
const projectRoot2 = options.projectRoot ?? getProjectRoot();
|
|
31553
|
-
const template = loadTemplate(agent.template, projectConfig.globalTemplatesDir);
|
|
31554
|
-
const rendered = `${WAIRON_MANAGED_BANNER}
|
|
31555
|
-
${composeAgentBrief(agent.id).instructions}`;
|
|
31556
|
-
const results = [];
|
|
31557
|
-
const budget = resolveBudget(
|
|
31558
|
-
deriveExecutionProfile(agent),
|
|
31559
|
-
projectConfig.execution,
|
|
31560
|
-
agent.id
|
|
31561
|
-
);
|
|
31562
|
-
for (const agentTarget of agent.targets) {
|
|
31563
|
-
const targetConfig = resolveTargetConfig(agentTarget, projectConfig);
|
|
31564
|
-
if (!targetConfig) continue;
|
|
31565
|
-
if (options.filterTargets) {
|
|
31566
|
-
const type = "type" in targetConfig ? targetConfig.type : targetConfig;
|
|
31567
|
-
if (!options.filterTargets.includes(type)) continue;
|
|
31568
|
-
}
|
|
31569
|
-
if (!options.dryRun) {
|
|
31570
|
-
results.push(getExporter(targetConfig).export({
|
|
31571
|
-
agent,
|
|
31572
|
-
template,
|
|
31573
|
-
renderedInstructions: rendered,
|
|
31574
|
-
projectRoot: projectRoot2,
|
|
31575
|
-
target: targetConfig,
|
|
31576
|
-
budget
|
|
31577
|
-
}));
|
|
31578
|
-
}
|
|
31579
|
-
}
|
|
31580
|
-
return { agent, results };
|
|
31581
|
-
}
|
|
31582
|
-
function generateAll(agents, projectConfig, options = {}) {
|
|
31583
|
-
let pool = agents;
|
|
31584
|
-
if (options.filterDomainIds && options.filterDomainIds.length > 0) {
|
|
31585
|
-
const ids = new Set(options.filterDomainIds);
|
|
31586
|
-
pool = agents.filter((a) => ids.has(a.domainRoot ?? "root"));
|
|
31587
|
-
}
|
|
31588
|
-
return pool.map((agent) => generateAgent(agent, projectConfig, options));
|
|
31589
|
-
}
|
|
31590
|
-
function resolveExpectedOutputPaths(agents, projectConfig, projectRoot2 = getProjectRoot()) {
|
|
31591
|
-
const expected = /* @__PURE__ */ new Set();
|
|
31592
|
-
for (const agent of agents) {
|
|
31593
|
-
for (const agentTarget of agent.targets) {
|
|
31594
|
-
const targetConfig = resolveTargetConfig(agentTarget, projectConfig);
|
|
31595
|
-
if (!targetConfig) continue;
|
|
31596
|
-
const ctx = { agent, projectRoot: projectRoot2, target: targetConfig };
|
|
31597
|
-
expected.add(path34.resolve(getExporter(targetConfig).outputPath(ctx)));
|
|
31598
|
-
}
|
|
31599
|
-
}
|
|
31600
|
-
return expected;
|
|
31601
|
-
}
|
|
31602
|
-
function resolveTargetConfig(agentTarget, projectConfig) {
|
|
31603
|
-
const targetType = typeof agentTarget === "string" ? agentTarget : agentTarget.type;
|
|
31604
|
-
return projectConfig.targets.find((t) => {
|
|
31605
|
-
if (typeof t === "string") return t === targetType;
|
|
31606
|
-
return t.type === targetType;
|
|
31607
|
-
});
|
|
31608
|
-
}
|
|
31609
|
-
|
|
31610
|
-
// src/commands/generate.ts
|
|
31656
|
+
init_base();
|
|
31611
31657
|
init_context();
|
|
31612
31658
|
init_fs();
|
|
31613
31659
|
init_project();
|
|
@@ -31670,7 +31716,7 @@ async function generateLayer(options = {}) {
|
|
|
31670
31716
|
} else if (options.dryRun) {
|
|
31671
31717
|
logger.info("Dry run \u2014 rules.materializeAgentFiles is off: no agent files are written; leftover managed files would be removed.");
|
|
31672
31718
|
} else if (options.prune !== false) {
|
|
31673
|
-
const candidateDirs = [...
|
|
31719
|
+
const candidateDirs = [...resolveExpectedOutputPaths2(agents, projectConfig)].map((p) => path35.dirname(p));
|
|
31674
31720
|
const removed = pruneStaleAgents(/* @__PURE__ */ new Set(), candidateDirs);
|
|
31675
31721
|
if (removed > 0) {
|
|
31676
31722
|
logger.info(`Removed ${removed} previously materialized agent file(s) \u2014 agents are served as live briefs (sdd_get_agent_brief); opt back in with rules.materializeAgentFiles: true.`);
|
|
@@ -31714,7 +31760,7 @@ function materializeAgentLayer(agents, projectConfig, options) {
|
|
|
31714
31760
|
}
|
|
31715
31761
|
logger.info(`Generating ${agentPool.length} agent(s)...`);
|
|
31716
31762
|
logger.blank();
|
|
31717
|
-
const summaries =
|
|
31763
|
+
const summaries = generateAll2(agents, projectConfig, {
|
|
31718
31764
|
filterTargets,
|
|
31719
31765
|
filterDomainIds,
|
|
31720
31766
|
dryRun: options.dryRun
|
|
@@ -31738,7 +31784,7 @@ function materializeAgentLayer(agents, projectConfig, options) {
|
|
|
31738
31784
|
}
|
|
31739
31785
|
let prunedCount = 0;
|
|
31740
31786
|
if (!options.dryRun && options.prune !== false) {
|
|
31741
|
-
prunedCount = pruneStaleAgents(
|
|
31787
|
+
prunedCount = pruneStaleAgents(resolveExpectedOutputPaths2(agents, projectConfig));
|
|
31742
31788
|
}
|
|
31743
31789
|
logger.blank();
|
|
31744
31790
|
if (options.dryRun) {
|