@wairon/cli 5.1.1-dev.57 → 5.1.1-dev.58
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 +139 -118
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +101 -83
- 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.58";
|
|
69
69
|
GITHUB_REPO = "SYW-Apps/Waffle-AIron";
|
|
70
70
|
SUPPORTED_ALIASES = ["wai"];
|
|
71
71
|
SCAN_EXCLUDE_DIRS = /* @__PURE__ */ new Set([
|
|
@@ -546,6 +546,21 @@ var init_yaml = __esm({
|
|
|
546
546
|
});
|
|
547
547
|
|
|
548
548
|
// src/models/execution.ts
|
|
549
|
+
function summarize(budget, profile) {
|
|
550
|
+
const lines = [
|
|
551
|
+
`- **Work shape**: ${profile.breadth} breadth, ${profile.reasoningDepth} reasoning${profile.writes ? "" : ", read-only"}${profile.delegates ? ", delegating" : ""}`,
|
|
552
|
+
`- **Why**: ${profile.rationale}`
|
|
553
|
+
];
|
|
554
|
+
if (budget.modelTier) lines.push(`- **Capability tier**: ${budget.modelTier}`);
|
|
555
|
+
if (budget.effort) lines.push(`- **Effort**: ${budget.effort}`);
|
|
556
|
+
if (budget.maxTurns !== void 0) {
|
|
557
|
+
lines.push(`- **Turn ceiling**: ${budget.maxTurns} (a circuit breaker \u2014 hitting it should read as a scoping error, not a limit to work up to)`);
|
|
558
|
+
}
|
|
559
|
+
lines.push(`- **Tool grant**: ${budget.toolClass}`);
|
|
560
|
+
lines.push(`- **May delegate further**: ${budget.allowNestedDelegation ? "yes" : "no"}`);
|
|
561
|
+
lines.push(`- **MCP access**: ${budget.mcp}`);
|
|
562
|
+
return lines;
|
|
563
|
+
}
|
|
549
564
|
var import_zod, WorkBreadthSchema, ReasoningDepthSchema, ExecutionProfileSchema, ModelTierSchema, EffortTierSchema, ToolClassSchema, McpAccessSchema, ExecutionBudgetSchema, BudgetTierSchema, BUDGET_TIER_DESCRIPTIONS, ExecutionConfigSchema;
|
|
550
565
|
var init_execution = __esm({
|
|
551
566
|
"src/models/execution.ts"() {
|
|
@@ -14256,12 +14271,109 @@ var init_carried_debt = __esm({
|
|
|
14256
14271
|
}
|
|
14257
14272
|
});
|
|
14258
14273
|
|
|
14274
|
+
// src/core/rules/heuristic/method-cohesion.ts
|
|
14275
|
+
function groupsSharingCollaborators(calledBy) {
|
|
14276
|
+
const parent = /* @__PURE__ */ new Map();
|
|
14277
|
+
const find = (m) => {
|
|
14278
|
+
let root = m;
|
|
14279
|
+
while (parent.get(root) !== root) root = parent.get(root);
|
|
14280
|
+
return root;
|
|
14281
|
+
};
|
|
14282
|
+
const union = (a, b) => {
|
|
14283
|
+
const [ra, rb] = [find(a), find(b)];
|
|
14284
|
+
if (ra !== rb) parent.set(ra, rb);
|
|
14285
|
+
};
|
|
14286
|
+
const methods = [...calledBy.keys()];
|
|
14287
|
+
for (const m of methods) parent.set(m, m);
|
|
14288
|
+
for (let i = 0; i < methods.length; i++) {
|
|
14289
|
+
for (let j = i + 1; j < methods.length; j++) {
|
|
14290
|
+
const shares = [...calledBy.get(methods[i])].some((c) => calledBy.get(methods[j])?.has(c));
|
|
14291
|
+
if (shares) union(methods[i], methods[j]);
|
|
14292
|
+
}
|
|
14293
|
+
}
|
|
14294
|
+
const groups = /* @__PURE__ */ new Map();
|
|
14295
|
+
for (const m of methods) {
|
|
14296
|
+
const root = find(m);
|
|
14297
|
+
groups.set(root, [...groups.get(root) ?? [], m]);
|
|
14298
|
+
}
|
|
14299
|
+
return [...groups.values()];
|
|
14300
|
+
}
|
|
14301
|
+
function isForwardingMethod(narrative) {
|
|
14302
|
+
let handoffs = 0;
|
|
14303
|
+
for (const step of narrative) {
|
|
14304
|
+
if (step.type === "call" || step.type === "dispatch") handoffs++;
|
|
14305
|
+
else if (step.type !== "return") return false;
|
|
14306
|
+
}
|
|
14307
|
+
return handoffs === 1;
|
|
14308
|
+
}
|
|
14309
|
+
function isPureForwarder(methods) {
|
|
14310
|
+
const narrated = methods.filter((m) => (m.narrative ?? []).length > 0);
|
|
14311
|
+
return narrated.length > 0 && narrated.every((m) => isForwardingMethod(m.narrative ?? []));
|
|
14312
|
+
}
|
|
14313
|
+
function pureForwarderComponents(ctx) {
|
|
14314
|
+
const realized = /* @__PURE__ */ new Map();
|
|
14315
|
+
for (const impl of ctx.implementations) {
|
|
14316
|
+
const intf = ctx.interfaceMap.get(impl.contract);
|
|
14317
|
+
if (!intf) continue;
|
|
14318
|
+
realized.set(intf.component, [...realized.get(intf.component) ?? [], ...impl.methods]);
|
|
14319
|
+
}
|
|
14320
|
+
return new Set([...realized].filter(([, methods]) => isPureForwarder(methods)).map(([id]) => id));
|
|
14321
|
+
}
|
|
14322
|
+
var methodCohesionRule;
|
|
14323
|
+
var init_method_cohesion = __esm({
|
|
14324
|
+
"src/core/rules/heuristic/method-cohesion.ts"() {
|
|
14325
|
+
"use strict";
|
|
14326
|
+
methodCohesionRule = {
|
|
14327
|
+
name: "method-cohesion",
|
|
14328
|
+
description: "An Orchestrator's methods share collaborators; when they split into groups that call no component in common, the component holds more than one responsibility. Reported only where two or more groups each hold two or more methods, so a single specialized method is not a finding \u2014 and never on a pure forwarder, whose every narrated method is a single hand-off and whose responsibility therefore lives in what it forwards to.",
|
|
14329
|
+
codes: [
|
|
14330
|
+
{ code: "INCOHESIVE_METHODS", defaultSeverity: "warning", summary: "Orchestrator's methods form two or more groups of two or more that share no called component" }
|
|
14331
|
+
],
|
|
14332
|
+
check(ctx) {
|
|
14333
|
+
const subjects = [];
|
|
14334
|
+
for (const impl of ctx.implementations) {
|
|
14335
|
+
const intf = ctx.interfaceMap.get(impl.contract);
|
|
14336
|
+
const comp = intf ? ctx.componentMap.get(intf.component) : void 0;
|
|
14337
|
+
if (!comp || comp.componentType !== "Orchestrator") continue;
|
|
14338
|
+
if (isPureForwarder(impl.methods)) continue;
|
|
14339
|
+
const calledBy = /* @__PURE__ */ new Map();
|
|
14340
|
+
for (const method2 of impl.methods) {
|
|
14341
|
+
const reached = /* @__PURE__ */ new Set();
|
|
14342
|
+
for (const step of method2.narrative ?? []) {
|
|
14343
|
+
if ((step.type === "call" || step.type === "dispatch") && step.targetComponent) reached.add(step.targetComponent);
|
|
14344
|
+
}
|
|
14345
|
+
if (reached.size > 0) calledBy.set(method2.name, reached);
|
|
14346
|
+
}
|
|
14347
|
+
subjects.push({ implementation: impl, component: comp, calledBy });
|
|
14348
|
+
}
|
|
14349
|
+
for (const { component, calledBy } of subjects) {
|
|
14350
|
+
if (calledBy.size < 2) continue;
|
|
14351
|
+
const groups = groupsSharingCollaborators(calledBy).filter((g) => g.length >= 2);
|
|
14352
|
+
if (groups.length < 2) continue;
|
|
14353
|
+
const described = groups.map((g) => {
|
|
14354
|
+
const collaborators = [...new Set(g.flatMap((m) => [...calledBy.get(m)]))].sort();
|
|
14355
|
+
return `${g.join(", ")} (calling ${collaborators.join(", ")})`;
|
|
14356
|
+
}).join("; ");
|
|
14357
|
+
ctx.addIssue(
|
|
14358
|
+
"warning",
|
|
14359
|
+
"INCOHESIVE_METHODS",
|
|
14360
|
+
`Orchestrator "${component.id}" holds ${groups.length} groups of methods that share no called component: ${described}. Split it along those groups, move the logic out until every method is a single hand-off (a pure forwarder is exempt), or acknowledge a deliberate facade with a reasoned lint.allow for INCOHESIVE_METHODS.`,
|
|
14361
|
+
component.id,
|
|
14362
|
+
ctx.isComponentDraft(component.id)
|
|
14363
|
+
);
|
|
14364
|
+
}
|
|
14365
|
+
}
|
|
14366
|
+
};
|
|
14367
|
+
}
|
|
14368
|
+
});
|
|
14369
|
+
|
|
14259
14370
|
// src/core/rules/heuristic/coupling-health.ts
|
|
14260
14371
|
var DEFAULT_GOD_COMPONENT_THRESHOLD, couplingRule;
|
|
14261
14372
|
var init_coupling_health = __esm({
|
|
14262
14373
|
"src/core/rules/heuristic/coupling-health.ts"() {
|
|
14263
14374
|
"use strict";
|
|
14264
14375
|
init_models();
|
|
14376
|
+
init_method_cohesion();
|
|
14265
14377
|
DEFAULT_GOD_COMPONENT_THRESHOLD = 8;
|
|
14266
14378
|
couplingRule = {
|
|
14267
14379
|
name: "coupling-health",
|
|
@@ -14270,7 +14382,7 @@ var init_coupling_health = __esm({
|
|
|
14270
14382
|
{ code: "MUTUAL_SUBSYSTEM_DEPENDENCY", defaultSeverity: "warning", summary: "Subsystems depend on each other without a declared trusted link" },
|
|
14271
14383
|
{ code: "INVALID_TRUSTED_LINK", defaultSeverity: "error", summary: "trustedLinks references a non-existent subsystem" },
|
|
14272
14384
|
{ code: "UNUSED_TRUSTED_LINK", defaultSeverity: "warning", summary: "trustedLinks declares a peer no dependency actually reaches" },
|
|
14273
|
-
{ code: "GOD_COMPONENT", defaultSeverity: "warning", summary: "Component with excessive dependency fan-out" }
|
|
14385
|
+
{ code: "GOD_COMPONENT", defaultSeverity: "warning", summary: "Component with excessive dependency fan-out; not reported on a pure forwarder, whose every narrated method is a single hand-off" }
|
|
14274
14386
|
],
|
|
14275
14387
|
check(ctx) {
|
|
14276
14388
|
const subsystemDeps = /* @__PURE__ */ new Map();
|
|
@@ -14342,9 +14454,10 @@ var init_coupling_health = __esm({
|
|
|
14342
14454
|
);
|
|
14343
14455
|
}
|
|
14344
14456
|
}
|
|
14457
|
+
const forwarders = pureForwarderComponents(ctx);
|
|
14345
14458
|
for (const comp of ctx.components) {
|
|
14346
14459
|
const threshold = ctx.complexityConfigFor(comp.subsystem)?.maxComponentDependencies ?? DEFAULT_GOD_COMPONENT_THRESHOLD;
|
|
14347
|
-
if (comp.dependsOn.length > threshold) {
|
|
14460
|
+
if (comp.dependsOn.length > threshold && !forwarders.has(comp.id)) {
|
|
14348
14461
|
ctx.addIssue(
|
|
14349
14462
|
"warning",
|
|
14350
14463
|
"GOD_COMPONENT",
|
|
@@ -14968,6 +15081,7 @@ var init_complexity_and_metadata = __esm({
|
|
|
14968
15081
|
"src/core/rules/heuristic/complexity-and-metadata.ts"() {
|
|
14969
15082
|
"use strict";
|
|
14970
15083
|
init_models();
|
|
15084
|
+
init_method_cohesion();
|
|
14971
15085
|
complexityRule = {
|
|
14972
15086
|
name: "complexity-and-metadata",
|
|
14973
15087
|
description: "Enforces metadata documentation completeness (checking if descriptions are missing or too short) and structural complexity caps (limits on methods per interface, parameters per method, dependencies per component, and components per subsystem) configured globally or in architectural profiles. A narrative's own length and shape are judged by narrative-complexity.",
|
|
@@ -14976,7 +15090,7 @@ var init_complexity_and_metadata = __esm({
|
|
|
14976
15090
|
{ code: "DESCRIPTION_TOO_SHORT", defaultSeverity: "warning", summary: "Description is shorter than the configured minimum length" },
|
|
14977
15091
|
{ code: "EXCESSIVE_METHODS", defaultSeverity: "warning", summary: "Interface declares more methods than the configured limit" },
|
|
14978
15092
|
{ code: "EXCESSIVE_METHOD_PARAMS", defaultSeverity: "warning", summary: "Interface method declares more parameters than the configured limit" },
|
|
14979
|
-
{ code: "EXCESSIVE_DEPENDENCIES", defaultSeverity: "warning", summary: "Component has more dependencies than the configured limit" },
|
|
15093
|
+
{ code: "EXCESSIVE_DEPENDENCIES", defaultSeverity: "warning", summary: "Component has more dependencies than the configured limit; not reported on a pure forwarder, whose fan-out is a routing table rather than knowledge" },
|
|
14980
15094
|
{ code: "EXCESSIVE_SUBSYSTEM_COMPONENTS", defaultSeverity: "warning", summary: "Subsystem has more direct components than the configured limit" }
|
|
14981
15095
|
],
|
|
14982
15096
|
check(ctx) {
|
|
@@ -14996,6 +15110,7 @@ var init_complexity_and_metadata = __esm({
|
|
|
14996
15110
|
);
|
|
14997
15111
|
}
|
|
14998
15112
|
}
|
|
15113
|
+
const forwarders = pureForwarderComponents(ctx);
|
|
14999
15114
|
for (const comp of ctx.components) {
|
|
15000
15115
|
const docConfig = ctx.documentationConfigFor(comp.subsystem);
|
|
15001
15116
|
const complexityConfig = ctx.complexityConfigFor(comp.subsystem);
|
|
@@ -15009,7 +15124,7 @@ var init_complexity_and_metadata = __esm({
|
|
|
15009
15124
|
"Component",
|
|
15010
15125
|
isDraft
|
|
15011
15126
|
);
|
|
15012
|
-
if (complexityConfig?.maxComponentDependencies !== void 0 && comp.dependsOn.length > complexityConfig.maxComponentDependencies) {
|
|
15127
|
+
if (complexityConfig?.maxComponentDependencies !== void 0 && comp.dependsOn.length > complexityConfig.maxComponentDependencies && !forwarders.has(comp.id)) {
|
|
15013
15128
|
ctx.addIssue(
|
|
15014
15129
|
"warning",
|
|
15015
15130
|
"EXCESSIVE_DEPENDENCIES",
|
|
@@ -15308,90 +15423,6 @@ var init_naming_discipline = __esm({
|
|
|
15308
15423
|
}
|
|
15309
15424
|
});
|
|
15310
15425
|
|
|
15311
|
-
// src/core/rules/heuristic/method-cohesion.ts
|
|
15312
|
-
function groupsSharingCollaborators(calledBy) {
|
|
15313
|
-
const parent = /* @__PURE__ */ new Map();
|
|
15314
|
-
const find = (m) => {
|
|
15315
|
-
let root = m;
|
|
15316
|
-
while (parent.get(root) !== root) root = parent.get(root);
|
|
15317
|
-
return root;
|
|
15318
|
-
};
|
|
15319
|
-
const union = (a, b) => {
|
|
15320
|
-
const [ra, rb] = [find(a), find(b)];
|
|
15321
|
-
if (ra !== rb) parent.set(ra, rb);
|
|
15322
|
-
};
|
|
15323
|
-
const methods = [...calledBy.keys()];
|
|
15324
|
-
for (const m of methods) parent.set(m, m);
|
|
15325
|
-
for (let i = 0; i < methods.length; i++) {
|
|
15326
|
-
for (let j = i + 1; j < methods.length; j++) {
|
|
15327
|
-
const shares = [...calledBy.get(methods[i])].some((c) => calledBy.get(methods[j])?.has(c));
|
|
15328
|
-
if (shares) union(methods[i], methods[j]);
|
|
15329
|
-
}
|
|
15330
|
-
}
|
|
15331
|
-
const groups = /* @__PURE__ */ new Map();
|
|
15332
|
-
for (const m of methods) {
|
|
15333
|
-
const root = find(m);
|
|
15334
|
-
groups.set(root, [...groups.get(root) ?? [], m]);
|
|
15335
|
-
}
|
|
15336
|
-
return [...groups.values()];
|
|
15337
|
-
}
|
|
15338
|
-
function isForwardingMethod(narrative) {
|
|
15339
|
-
let handoffs = 0;
|
|
15340
|
-
for (const step of narrative) {
|
|
15341
|
-
if (step.type === "call" || step.type === "dispatch") handoffs++;
|
|
15342
|
-
else if (step.type !== "return") return false;
|
|
15343
|
-
}
|
|
15344
|
-
return handoffs === 1;
|
|
15345
|
-
}
|
|
15346
|
-
var methodCohesionRule;
|
|
15347
|
-
var init_method_cohesion = __esm({
|
|
15348
|
-
"src/core/rules/heuristic/method-cohesion.ts"() {
|
|
15349
|
-
"use strict";
|
|
15350
|
-
methodCohesionRule = {
|
|
15351
|
-
name: "method-cohesion",
|
|
15352
|
-
description: "An Orchestrator's methods share collaborators; when they split into groups that call no component in common, the component holds more than one responsibility. Reported only where two or more groups each hold two or more methods, so a single specialized method is not a finding \u2014 and never on a pure forwarder, whose every narrated method is a single hand-off and whose responsibility therefore lives in what it forwards to.",
|
|
15353
|
-
codes: [
|
|
15354
|
-
{ code: "INCOHESIVE_METHODS", defaultSeverity: "warning", summary: "Orchestrator's methods form two or more groups of two or more that share no called component" }
|
|
15355
|
-
],
|
|
15356
|
-
check(ctx) {
|
|
15357
|
-
const subjects = [];
|
|
15358
|
-
for (const impl of ctx.implementations) {
|
|
15359
|
-
const intf = ctx.interfaceMap.get(impl.contract);
|
|
15360
|
-
const comp = intf ? ctx.componentMap.get(intf.component) : void 0;
|
|
15361
|
-
if (!comp || comp.componentType !== "Orchestrator") continue;
|
|
15362
|
-
const narrated = impl.methods.filter((m) => (m.narrative ?? []).length > 0);
|
|
15363
|
-
if (narrated.length > 0 && narrated.every((m) => isForwardingMethod(m.narrative ?? []))) continue;
|
|
15364
|
-
const calledBy = /* @__PURE__ */ new Map();
|
|
15365
|
-
for (const method2 of impl.methods) {
|
|
15366
|
-
const reached = /* @__PURE__ */ new Set();
|
|
15367
|
-
for (const step of method2.narrative ?? []) {
|
|
15368
|
-
if ((step.type === "call" || step.type === "dispatch") && step.targetComponent) reached.add(step.targetComponent);
|
|
15369
|
-
}
|
|
15370
|
-
if (reached.size > 0) calledBy.set(method2.name, reached);
|
|
15371
|
-
}
|
|
15372
|
-
subjects.push({ implementation: impl, component: comp, calledBy });
|
|
15373
|
-
}
|
|
15374
|
-
for (const { component, calledBy } of subjects) {
|
|
15375
|
-
if (calledBy.size < 2) continue;
|
|
15376
|
-
const groups = groupsSharingCollaborators(calledBy).filter((g) => g.length >= 2);
|
|
15377
|
-
if (groups.length < 2) continue;
|
|
15378
|
-
const described = groups.map((g) => {
|
|
15379
|
-
const collaborators = [...new Set(g.flatMap((m) => [...calledBy.get(m)]))].sort();
|
|
15380
|
-
return `${g.join(", ")} (calling ${collaborators.join(", ")})`;
|
|
15381
|
-
}).join("; ");
|
|
15382
|
-
ctx.addIssue(
|
|
15383
|
-
"warning",
|
|
15384
|
-
"INCOHESIVE_METHODS",
|
|
15385
|
-
`Orchestrator "${component.id}" holds ${groups.length} groups of methods that share no called component: ${described}. Split it along those groups, move the logic out until every method is a single hand-off (a pure forwarder is exempt), or acknowledge a deliberate facade with a reasoned lint.allow for INCOHESIVE_METHODS.`,
|
|
15386
|
-
component.id,
|
|
15387
|
-
ctx.isComponentDraft(component.id)
|
|
15388
|
-
);
|
|
15389
|
-
}
|
|
15390
|
-
}
|
|
15391
|
-
};
|
|
15392
|
-
}
|
|
15393
|
-
});
|
|
15394
|
-
|
|
15395
15426
|
// src/core/rules/repository.ts
|
|
15396
15427
|
function addRule(rule) {
|
|
15397
15428
|
ruleSet.push(rule);
|
|
@@ -23251,21 +23282,6 @@ function resolveBudget(profile, config, agentId) {
|
|
|
23251
23282
|
const override = config.overrides[agentId];
|
|
23252
23283
|
return override ? { ...budget, ...override } : budget;
|
|
23253
23284
|
}
|
|
23254
|
-
function describeBudget(profile, budget) {
|
|
23255
|
-
const lines = [
|
|
23256
|
-
`- **Work shape**: ${profile.breadth} breadth, ${profile.reasoningDepth} reasoning${profile.writes ? "" : ", read-only"}${profile.delegates ? ", delegating" : ""}`,
|
|
23257
|
-
`- **Why**: ${profile.rationale}`
|
|
23258
|
-
];
|
|
23259
|
-
if (budget.modelTier) lines.push(`- **Capability tier**: ${budget.modelTier}`);
|
|
23260
|
-
if (budget.effort) lines.push(`- **Effort**: ${budget.effort}`);
|
|
23261
|
-
if (budget.maxTurns !== void 0) {
|
|
23262
|
-
lines.push(`- **Turn ceiling**: ${budget.maxTurns} (a circuit breaker \u2014 hitting it should read as a scoping error, not a limit to work up to)`);
|
|
23263
|
-
}
|
|
23264
|
-
lines.push(`- **Tool grant**: ${budget.toolClass}`);
|
|
23265
|
-
lines.push(`- **May delegate further**: ${budget.allowNestedDelegation ? "yes" : "no"}`);
|
|
23266
|
-
lines.push(`- **MCP access**: ${budget.mcp}`);
|
|
23267
|
-
return lines;
|
|
23268
|
-
}
|
|
23269
23285
|
var TIER_ORDER, TIER_STEPS;
|
|
23270
23286
|
var init_budget_policy = __esm({
|
|
23271
23287
|
"src/core/budget_policy.ts"() {
|
|
@@ -23406,7 +23422,7 @@ function inferSourcePathForComponent(comp, subsystems) {
|
|
|
23406
23422
|
return null;
|
|
23407
23423
|
}
|
|
23408
23424
|
}
|
|
23409
|
-
function
|
|
23425
|
+
function summarize2(text2, max = 140) {
|
|
23410
23426
|
const clean = text2.replace(/\s+/g, " ").trim();
|
|
23411
23427
|
const period = clean.indexOf(". ");
|
|
23412
23428
|
const firstSentence = period > 0 ? clean.slice(0, period + 1) : clean;
|
|
@@ -23433,7 +23449,7 @@ function resolveAgentTopology() {
|
|
|
23433
23449
|
agents.push({
|
|
23434
23450
|
id: "system-architect",
|
|
23435
23451
|
name: `${system.name} Architect`,
|
|
23436
|
-
description: `Global architect for ${system.name} \u2014 owns the spec tree and topology. ${
|
|
23452
|
+
description: `Global architect for ${system.name} \u2014 owns the spec tree and topology. ${summarize2(system.vision)}`,
|
|
23437
23453
|
template: "architect",
|
|
23438
23454
|
creationReason: "Automatically inferred from L0 system spec",
|
|
23439
23455
|
ownedPaths: [".wai/specs/**"],
|
|
@@ -23513,7 +23529,7 @@ function resolveAgentTopology() {
|
|
|
23513
23529
|
agents.push({
|
|
23514
23530
|
id: `${sub.id}-owner`,
|
|
23515
23531
|
name: `${sub.name} Owner`,
|
|
23516
|
-
description: `Owns the ${sub.id} subsystem. ${
|
|
23532
|
+
description: `Owns the ${sub.id} subsystem. ${summarize2(sub.description)}`,
|
|
23517
23533
|
template: "domain-owner",
|
|
23518
23534
|
creationReason: `Automatically inferred from L1 subsystem spec: ${sub.id}`,
|
|
23519
23535
|
domainRoot: sub.id,
|
|
@@ -23578,7 +23594,7 @@ function resolveAgentTopology() {
|
|
|
23578
23594
|
agents.push({
|
|
23579
23595
|
id: `${dom.id}-owner`,
|
|
23580
23596
|
name: `${dom.name ?? dom.id} Owner`,
|
|
23581
|
-
description: dom.description ?
|
|
23597
|
+
description: dom.description ? summarize2(dom.description) : `Owner agent for the free-standing "${dom.id}" domain.`,
|
|
23582
23598
|
template: "domain-owner",
|
|
23583
23599
|
creationReason: "Inferred from a free-standing domain in .wai/topology.yaml",
|
|
23584
23600
|
domainRoot: dom.id,
|
|
@@ -28257,6 +28273,8 @@ var init_core = __esm({
|
|
|
28257
28273
|
init_approver();
|
|
28258
28274
|
init_specs2();
|
|
28259
28275
|
init_project_config();
|
|
28276
|
+
init_execution_profile();
|
|
28277
|
+
init_budget_policy();
|
|
28260
28278
|
}
|
|
28261
28279
|
});
|
|
28262
28280
|
|
|
@@ -28958,7 +28976,7 @@ function renderAgentBriefMarkdown(brief) {
|
|
|
28958
28976
|
"",
|
|
28959
28977
|
"## Execution budget",
|
|
28960
28978
|
"",
|
|
28961
|
-
...
|
|
28979
|
+
...summarize(brief.budget, brief.profile),
|
|
28962
28980
|
"",
|
|
28963
28981
|
"Advisory \u2014 apply these when spawning. Map the capability tier onto your host tool's models; a tool that cannot express a field should ignore it rather than approximate it."
|
|
28964
28982
|
);
|
|
@@ -30346,7 +30364,7 @@ var init_server = __esm({
|
|
|
30346
30364
|
init_variants();
|
|
30347
30365
|
init_agent_resolver();
|
|
30348
30366
|
init_core();
|
|
30349
|
-
|
|
30367
|
+
init_execution();
|
|
30350
30368
|
init_surfaces();
|
|
30351
30369
|
TYPE_REF_GRAMMAR = (what) => `${what}: a primitive/builtin or a defined type id (qualified across subsystems, e.g. "billing.Invoice" or "billing::Invoice"). Generics, arrays and UNIONS are all read, at any depth: "Invoice | null" (the commonest shape there is), "Invoice | undefined", "Invoice | Receipt", "Promise<Invoice | null>", "Map<string, Invoice | null>", "Invoice[] | null", "(Invoice | null)[]". Every identifier the string names must resolve \u2014 a union of two defined types means BOTH must exist. A union of string literals ("read" | "write") names no type and resolves to nothing.`;
|
|
30352
30370
|
staleServerOutput = {
|
|
@@ -31116,6 +31134,12 @@ function removeDomain2(id) {
|
|
|
31116
31134
|
function detectDomainCandidates2(projectRoot2, trackedPaths, trackedIds) {
|
|
31117
31135
|
return detectDomainCandidates(projectRoot2, trackedPaths, trackedIds);
|
|
31118
31136
|
}
|
|
31137
|
+
function deriveExecutionProfile2(agent) {
|
|
31138
|
+
return deriveExecutionProfile(agent);
|
|
31139
|
+
}
|
|
31140
|
+
function resolveBudget2(profile, config, agentId) {
|
|
31141
|
+
return resolveBudget(profile, config, agentId);
|
|
31142
|
+
}
|
|
31119
31143
|
async function runSubsystemAdd(id, options = {}) {
|
|
31120
31144
|
logger.header("wairon subsystem add");
|
|
31121
31145
|
if (!projectConfigExists2()) {
|
|
@@ -48372,15 +48396,12 @@ function report(outcome) {
|
|
|
48372
48396
|
}
|
|
48373
48397
|
|
|
48374
48398
|
// src/cli/index.ts
|
|
48375
|
-
|
|
48399
|
+
init_execution();
|
|
48376
48400
|
|
|
48377
48401
|
// src/commands/execution.ts
|
|
48378
48402
|
var import_chalk21 = __toESM(require("chalk"));
|
|
48379
48403
|
init_logger();
|
|
48380
48404
|
init_errors();
|
|
48381
|
-
init_agent_resolver();
|
|
48382
|
-
init_execution_profile();
|
|
48383
|
-
init_budget_policy();
|
|
48384
48405
|
init_execution();
|
|
48385
48406
|
function assertInitialized() {
|
|
48386
48407
|
if (!projectConfigExists2()) {
|
|
@@ -48408,7 +48429,7 @@ async function showExecution() {
|
|
|
48408
48429
|
logger.info(`Enable with ${import_chalk21.default.bold("wairon execution set-tier default")}.`);
|
|
48409
48430
|
return;
|
|
48410
48431
|
}
|
|
48411
|
-
const agents =
|
|
48432
|
+
const agents = resolveAgentTopology2();
|
|
48412
48433
|
if (agents.length === 0) {
|
|
48413
48434
|
logger.blank();
|
|
48414
48435
|
logger.warn("No agents in the topology yet \u2014 nothing to budget.");
|
|
@@ -48416,8 +48437,8 @@ async function showExecution() {
|
|
|
48416
48437
|
}
|
|
48417
48438
|
logger.blank();
|
|
48418
48439
|
const rows = agents.map((agent) => {
|
|
48419
|
-
const profile =
|
|
48420
|
-
const budget =
|
|
48440
|
+
const profile = deriveExecutionProfile2(agent);
|
|
48441
|
+
const budget = resolveBudget2(profile, config.execution, agent.id);
|
|
48421
48442
|
return { agent, profile, budget };
|
|
48422
48443
|
});
|
|
48423
48444
|
const idWidth = Math.max(...rows.map((r) => r.agent.id.length));
|
|
@@ -48752,7 +48773,7 @@ async function runAgent(action, id) {
|
|
|
48752
48773
|
if (brief.budget && brief.profile) {
|
|
48753
48774
|
logger.blank();
|
|
48754
48775
|
logger.info("Execution budget (advisory \u2014 apply when spawning):");
|
|
48755
|
-
for (const line2 of
|
|
48776
|
+
for (const line2 of summarize(brief.budget, brief.profile)) {
|
|
48756
48777
|
logger.info(` ${line2.replace(/^- \*\*(.+?)\*\*: /, "$1: ")}`);
|
|
48757
48778
|
}
|
|
48758
48779
|
}
|