@wairon/cli 5.1.1-dev.93 → 5.1.1-dev.94

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/index.js CHANGED
@@ -3580,6 +3580,7 @@ __export(src_exports, {
3580
3580
  deregisterPackRef: () => deregisterPackRef,
3581
3581
  deriveExecutionProfile: () => deriveExecutionProfile,
3582
3582
  derivedDocPaths: () => derivedDocPaths,
3583
+ describeProject: () => describeProject,
3583
3584
  detectDomainCandidates: () => detectDomainCandidates,
3584
3585
  diagnoseProjectPacks: () => diagnoseProjectPacks,
3585
3586
  diagramSetIndex: () => diagramSetIndex,
@@ -4149,21 +4150,6 @@ var ExecutionBudgetSchema = import_zod.z.object({
4149
4150
  allowNestedDelegation: import_zod.z.boolean(),
4150
4151
  mcp: McpAccessSchema
4151
4152
  });
4152
- function summarize(budget, profile) {
4153
- const lines = [
4154
- `- **Work shape**: ${profile.breadth} breadth, ${profile.reasoningDepth} reasoning${profile.writes ? "" : ", read-only"}${profile.delegates ? ", delegating" : ""}`,
4155
- `- **Why**: ${profile.rationale}`
4156
- ];
4157
- if (budget.modelTier) lines.push(`- **Capability tier**: ${budget.modelTier}`);
4158
- if (budget.effort) lines.push(`- **Effort**: ${budget.effort}`);
4159
- if (budget.maxTurns !== void 0) {
4160
- 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)`);
4161
- }
4162
- lines.push(`- **Tool grant**: ${budget.toolClass}`);
4163
- lines.push(`- **May delegate further**: ${budget.allowNestedDelegation ? "yes" : "no"}`);
4164
- lines.push(`- **MCP access**: ${budget.mcp}`);
4165
- return lines;
4166
- }
4167
4153
  var BudgetTierSchema = import_zod.z.enum(["off", "free", "default", "trade", "aggressive"]);
4168
4154
  var ExecutionConfigSchema = import_zod.z.object({
4169
4155
  /**
@@ -4841,16 +4827,6 @@ var ProjectConfigSchema = import_zod3.z.object({
4841
4827
  * Can also be set via WAIRON_TEMPLATES_DIR environment variable.
4842
4828
  */
4843
4829
  globalTemplatesDir: import_zod3.z.string().optional(),
4844
- /**
4845
- * Tracks whether the wairon usage guide has been injected into each target's
4846
- * AI tool configuration files so the tool knows how to use wairon.
4847
- */
4848
- aiGuide: import_zod3.z.object({
4849
- claudeGlobal: import_zod3.z.boolean().default(false),
4850
- claudeLocal: import_zod3.z.boolean().default(false),
4851
- geminiGlobal: import_zod3.z.boolean().default(false),
4852
- geminiLocal: import_zod3.z.boolean().default(false)
4853
- }).optional(),
4854
4830
  /** Created by wairon at init time */
4855
4831
  createdAt: import_zod3.z.string().datetime(),
4856
4832
  updatedAt: import_zod3.z.string().datetime()
@@ -5714,6 +5690,9 @@ function registryOver(store, root) {
5714
5690
  setProjectType(projectType) {
5715
5691
  save({ ...current2(), projectType });
5716
5692
  },
5693
+ describeProject(name, description) {
5694
+ save({ ...current2(), name, ...description !== void 0 ? { description } : {} });
5695
+ },
5717
5696
  recordProfileSelection(selection) {
5718
5697
  save({ ...current2(), profileSelection: selection });
5719
5698
  },
@@ -6079,6 +6058,9 @@ function projectConfigRepositoryOver(adapter, rootDir) {
6079
6058
  setProjectType(projectType) {
6080
6059
  registry.setProjectType(projectType);
6081
6060
  },
6061
+ describeProject(name, description) {
6062
+ registry.describeProject(name, description);
6063
+ },
6082
6064
  recordProfileSelection(selection) {
6083
6065
  registry.recordProfileSelection(selection);
6084
6066
  },
@@ -6141,7 +6123,10 @@ function projectConfigRepositoryOver(adapter, rootDir) {
6141
6123
  function projectConfigRepositoryAt(rootDir) {
6142
6124
  return projectConfigRepositoryOver(projectConfigFsAdapterAt(rootDir), rootDir);
6143
6125
  }
6144
- var bound = () => projectConfigRepositoryAt(getProjectRoot());
6126
+ var bound = () => {
6127
+ const rootDir = getProjectRoot();
6128
+ return projectConfigRepositoryOver(projectConfigFsAdapterAt(rootDir), rootDir);
6129
+ };
6145
6130
  var projectConfigRepository = {
6146
6131
  load() {
6147
6132
  return bound().load();
@@ -6167,6 +6152,9 @@ var projectConfigRepository = {
6167
6152
  setProjectType(projectType) {
6168
6153
  bound().setProjectType(projectType);
6169
6154
  },
6155
+ describeProject(name, description) {
6156
+ bound().describeProject(name, description);
6157
+ },
6170
6158
  recordProfileSelection(selection) {
6171
6159
  bound().recordProfileSelection(selection);
6172
6160
  },
@@ -6434,19 +6422,19 @@ function withSortedMaps(record) {
6434
6422
  var fs5 = __toESM(require("fs"));
6435
6423
  var path7 = __toESM(require("path"));
6436
6424
  var SPEC_FILE_EXTENSION = ".yaml";
6437
- function readSpecFile(filePath) {
6438
- return readYamlFile(filePath);
6425
+ function readSpecFile(specPath) {
6426
+ return readYamlFile(specPath);
6439
6427
  }
6440
- function writeSpecFile(filePath, document) {
6441
- writeYamlFile(filePath, document);
6428
+ function writeSpecFile(specPath, document) {
6429
+ writeYamlFile(specPath, document);
6442
6430
  }
6443
6431
  function listSpecFiles(specsDir) {
6444
6432
  return listFilesRecursive(specsDir, SPEC_FILE_EXTENSION);
6445
6433
  }
6446
- function removeSpecFile(filePath, specsRoot) {
6447
- if (!fs5.existsSync(filePath)) return false;
6448
- fs5.unlinkSync(filePath);
6449
- pruneEmptyDirs(path7.dirname(filePath), path7.resolve(specsRoot));
6434
+ function removeSpecFile(specPath, specsRoot) {
6435
+ if (!fs5.existsSync(specPath)) return false;
6436
+ fs5.unlinkSync(specPath);
6437
+ pruneEmptyDirs(path7.dirname(specPath), path7.resolve(specsRoot));
6450
6438
  return true;
6451
6439
  }
6452
6440
  function pruneEmptyDirs(dir, specsRoot) {
@@ -14041,8 +14029,8 @@ function canonicalReferences(snapshot) {
14041
14029
  types: snapshot.types.map((def) => ({ ...def, fields: def.fields.map((f) => ({ ...f, type: canon(f.type) })) }))
14042
14030
  };
14043
14031
  }
14044
- function listSnapshots(rootDir = getProjectRoot()) {
14045
- const dir = surfacesDir(rootDir);
14032
+ function listSnapshots() {
14033
+ const dir = surfacesDir(getProjectRoot());
14046
14034
  if (!fs9.existsSync(dir)) return [];
14047
14035
  const out = [];
14048
14036
  for (const file of fs9.readdirSync(dir)) {
@@ -14057,8 +14045,8 @@ function listSnapshots(rootDir = getProjectRoot()) {
14057
14045
  function snapshotFilename(projectName) {
14058
14046
  return `${safeFilenamePart(projectName)}.yaml`;
14059
14047
  }
14060
- function removeSnapshot(projectName, rootDir = getProjectRoot()) {
14061
- const dir = surfacesDir(rootDir);
14048
+ function removeSnapshot(projectName) {
14049
+ const dir = surfacesDir(getProjectRoot());
14062
14050
  const direct = path13.join(dir, snapshotFilename(projectName));
14063
14051
  if (fs9.existsSync(direct)) {
14064
14052
  fs9.unlinkSync(direct);
@@ -14378,11 +14366,11 @@ function listExternals() {
14378
14366
  }
14379
14367
 
14380
14368
  // src/core/surface-portal.ts
14381
- function listSnapshots2(rootDir) {
14382
- return listSnapshots(rootDir);
14369
+ function listSnapshots2() {
14370
+ return listSnapshots();
14383
14371
  }
14384
- function removeSnapshot2(projectName, rootDir) {
14385
- return removeSnapshot(projectName, rootDir);
14372
+ function removeSnapshot2(projectName) {
14373
+ return removeSnapshot(projectName);
14386
14374
  }
14387
14375
  function listFamilyPins2() {
14388
14376
  return listFamilyPins();
@@ -15097,7 +15085,7 @@ function defaultTargetConfig(type) {
15097
15085
  enabled: true
15098
15086
  };
15099
15087
  }
15100
- var WAIRON_VERSION = "5.1.1-dev.93";
15088
+ var WAIRON_VERSION = "5.1.1-dev.94";
15101
15089
  var GITHUB_REPO = "SYW-Apps/Waffle-AIron";
15102
15090
  var ARCHITECT_AGENT_ID = "agent-architect";
15103
15091
  var ARCHITECT_TEMPLATE_ID = "architect";
@@ -15544,13 +15532,13 @@ function resolvePackRef(ref, projectRoot) {
15544
15532
  }
15545
15533
  return resolved;
15546
15534
  }
15547
- function readManifest(target, projectRoot) {
15535
+ function readManifest(target, resolveFrom) {
15548
15536
  if (isYamlPath(target)) {
15549
15537
  const raw = readYamlFile(target);
15550
15538
  if (raw == null) throw new Error("file not found or empty");
15551
15539
  return { ...DeclarativePackSchema.parse(raw), rules: [] };
15552
15540
  }
15553
- const req = (0, import_module.createRequire)(path17.join(projectRoot, "package.json"));
15541
+ const req = (0, import_module.createRequire)(path17.join(resolveFrom, "package.json"));
15554
15542
  const modRaw = req(target);
15555
15543
  const mod = modRaw?.default ?? modRaw;
15556
15544
  const parsed = DeclarativePackSchema.parse({
@@ -18870,7 +18858,9 @@ var facadeForwardingRule = {
18870
18858
  "FACADE_FORWARDING",
18871
18859
  `Facade method "${method.name}" of ${comp.componentType} "${comp.id}" (implementation "${impl.id}") must be pure 1:1 forwarding \u2014 exactly one call step to an owned member (${comp.owns.join(", ") || "none declared"}) \u2014 but its narrative ${problem}. Move the logic into a member block, or lint.allow a deliberate exception.`,
18872
18860
  impl.id,
18873
- isDraftCtx
18861
+ isDraftCtx,
18862
+ void 0,
18863
+ { at: method.name }
18874
18864
  );
18875
18865
  }
18876
18866
  }
@@ -21766,11 +21756,31 @@ var exportConformanceRule = {
21766
21756
  );
21767
21757
  }
21768
21758
  }
21759
+ const typeMethodsAt = /* @__PURE__ */ new Map();
21769
21760
  for (const type of ctx.types) {
21770
21761
  if (!type.sourcePath) continue;
21771
21762
  promise(type.sourcePath, type.symbol ?? type.name);
21772
21763
  for (const method of type.methods ?? []) {
21773
- promise(method.sourcePath ?? type.sourcePath, method.symbol ?? method.name);
21764
+ const at = pathKey(method.sourcePath ?? type.sourcePath);
21765
+ const name = method.symbol ?? method.name;
21766
+ promise(at, name);
21767
+ let names = typeMethodsAt.get(at);
21768
+ if (!names) typeMethodsAt.set(at, names = /* @__PURE__ */ new Set());
21769
+ names.add(name);
21770
+ }
21771
+ }
21772
+ for (const file of realization.paths) {
21773
+ const facts = code.factsAt(file);
21774
+ if (!facts || facts.status !== "analyzed" || facts.analysisGrade !== "exact") continue;
21775
+ for (const binding of facts.reexportBindings ?? []) {
21776
+ const target = resolveImport(file, binding.from, code.paths);
21777
+ const methods = target ? typeMethodsAt.get(target) : void 0;
21778
+ if (!methods) continue;
21779
+ if (binding.local === "*") {
21780
+ for (const name of methods) promise(file, name);
21781
+ } else if (methods.has(binding.local)) {
21782
+ promise(file, binding.exported);
21783
+ }
21774
21784
  }
21775
21785
  }
21776
21786
  const takenFrom = /* @__PURE__ */ new Map();
@@ -24172,7 +24182,7 @@ function publishesFrom(module2, name, target, symbol, readReexports, visited = /
24172
24182
  }
24173
24183
  return false;
24174
24184
  }
24175
- function findTestsReferencing(methods, projectRoot, testRoots = []) {
24185
+ function findTestsReferencing(methods, projectRoot, testRoots) {
24176
24186
  const scanned = readTestFiles(testRoots, projectRoot);
24177
24187
  if (scanned.length === 0) return [];
24178
24188
  const indiscriminateAbove = scanned.length / 10;
@@ -25163,7 +25173,7 @@ function boundProjectIdentity() {
25163
25173
  const lockedProjectId = readLockRecord()?.projectId;
25164
25174
  return projectIdentity(config, lockedProjectId);
25165
25175
  }
25166
- function findTestsReferencing2(methods, projectRoot, testRoots = []) {
25176
+ function findTestsReferencing2(methods, projectRoot, testRoots) {
25167
25177
  return findTestsReferencing(methods, projectRoot, testRoots);
25168
25178
  }
25169
25179
  function issue(severity, code, message, agentId, specId) {
@@ -31646,6 +31656,9 @@ function removePackSelection(packName) {
31646
31656
  function setProjectType(projectType) {
31647
31657
  projectConfigRepository.setProjectType(projectType);
31648
31658
  }
31659
+ function describeProject(name, description) {
31660
+ projectConfigRepository.describeProject(name, description);
31661
+ }
31649
31662
  function recordProfileSelection(selection) {
31650
31663
  projectConfigRepository.recordProfileSelection(selection);
31651
31664
  }
@@ -33957,16 +33970,16 @@ var path28 = __toESM(require("path"));
33957
33970
  function builtinTemplatesDir() {
33958
33971
  return path28.resolve(__dirname, "..", "templates");
33959
33972
  }
33960
- function loadTemplate(id, globalOverride) {
33961
- const dirs = templateSearchDirs(globalOverride);
33973
+ function loadTemplate(templateName, globalTemplatesDir2) {
33974
+ const dirs = templateSearchDirs(globalTemplatesDir2);
33962
33975
  for (const dir of dirs) {
33963
- const filePath = path28.join(dir, `${id}.yaml`);
33976
+ const filePath = path28.join(dir, `${templateName}.yaml`);
33964
33977
  if (pathExists(filePath)) {
33965
33978
  const raw = readYamlFile(filePath);
33966
- return { ...TemplateSchema.parse(raw), templateName: id };
33979
+ return { ...TemplateSchema.parse(raw), templateName };
33967
33980
  }
33968
33981
  }
33969
- throw new TemplateNotFoundError(id);
33982
+ throw new TemplateNotFoundError(templateName);
33970
33983
  }
33971
33984
  function loadAgentOverride(agentId) {
33972
33985
  const filePath = path28.join(AI_PATHS.root(), "agents", `${agentId}.md`);
@@ -34249,7 +34262,7 @@ function inferSourcePathForComponent(comp, subsystems) {
34249
34262
  return null;
34250
34263
  }
34251
34264
  }
34252
- function summarize2(text3, max = 140) {
34265
+ function summarize(text3, max = 140) {
34253
34266
  const clean = text3.replace(/\s+/g, " ").trim();
34254
34267
  const period = clean.indexOf(". ");
34255
34268
  const firstSentence = period > 0 ? clean.slice(0, period + 1) : clean;
@@ -34304,7 +34317,7 @@ function resolveLayer(delegate) {
34304
34317
  agents.push({
34305
34318
  id: "system-architect",
34306
34319
  name: `${system.name} Architect`,
34307
- description: `Global architect for ${system.name} \u2014 owns the spec tree and topology. ${summarize2(system.vision)}`,
34320
+ description: `Global architect for ${system.name} \u2014 owns the spec tree and topology. ${summarize(system.vision)}`,
34308
34321
  template: "architect",
34309
34322
  creationReason: "Automatically inferred from L0 system spec",
34310
34323
  ownedPaths: [".wai/specs/**"],
@@ -34388,7 +34401,7 @@ function resolveLayer(delegate) {
34388
34401
  agents.push({
34389
34402
  id: `${sub.id}-owner`,
34390
34403
  name: `${sub.name} Owner`,
34391
- description: `Owns the ${sub.id} subsystem. ${summarize2(sub.description)}${partNote ? ` ${partNote}` : ""}`,
34404
+ description: `Owns the ${sub.id} subsystem. ${summarize(sub.description)}${partNote ? ` ${partNote}` : ""}`,
34392
34405
  template: "domain-owner",
34393
34406
  creationReason: `Automatically inferred from L1 subsystem spec: ${sub.id}`,
34394
34407
  domainRoot: sub.id,
@@ -34453,7 +34466,7 @@ function resolveLayer(delegate) {
34453
34466
  agents.push({
34454
34467
  id: `${dom.id}-owner`,
34455
34468
  name: `${dom.name ?? dom.id} Owner`,
34456
- description: dom.description ? summarize2(dom.description) : `Owner agent for the free-standing "${dom.id}" domain.`,
34469
+ description: dom.description ? summarize(dom.description) : `Owner agent for the free-standing "${dom.id}" domain.`,
34457
34470
  template: "domain-owner",
34458
34471
  creationReason: "Inferred from a free-standing domain in .wai/topology.yaml",
34459
34472
  domainRoot: dom.id,
@@ -35320,8 +35333,11 @@ function localGuideFilePath(projectRoot, targetType) {
35320
35333
  if (targetType === "gemini" || targetType === "agy") return path36.join(projectRoot, ".gemini", "GEMINI.md");
35321
35334
  return null;
35322
35335
  }
35336
+ function guideBody(scope) {
35337
+ return scope === "global" ? GLOBAL_GUIDE_BODY : LOCAL_GUIDE_BODY;
35338
+ }
35323
35339
  function injectGuide(filePath, scope) {
35324
- const body = scope === "global" ? GLOBAL_GUIDE_BODY : LOCAL_GUIDE_BODY;
35340
+ const body = guideBody(scope);
35325
35341
  const section = `
35326
35342
 
35327
35343
  ${GUIDE_MARKER_START}
@@ -35530,7 +35546,7 @@ function renderWaironGuide() {
35530
35546
  lines.push("---");
35531
35547
  lines.push("");
35532
35548
  }
35533
- lines.push(GLOBAL_GUIDE_BODY);
35549
+ lines.push(guideBody("global"));
35534
35550
  lines.push("");
35535
35551
  return lines.join("\n");
35536
35552
  }
@@ -35991,22 +36007,6 @@ function packSkillId(skill) {
35991
36007
  function packNamespace(pack) {
35992
36008
  return pack.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
35993
36009
  }
35994
- function extensionsFor(builtin, packSkills) {
35995
- return packSkills.filter((s) => s.extends === builtin && fs22.existsSync(s.sourcePath));
35996
- }
35997
- function composeBuiltinSkill(name, packSkills) {
35998
- const srcPath = skillTemplatePath(name);
35999
- const base = fs22.existsSync(srcPath) ? fs22.readFileSync(srcPath, "utf-8") : "";
36000
- const sections = extensionsFor(name, packSkills);
36001
- if (sections.length === 0) return base;
36002
- const parts = [base.trimEnd()];
36003
- for (const section of sections) {
36004
- const body = fs22.readFileSync(section.sourcePath, "utf-8").replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/, "");
36005
- parts.push(`## Platform: ${section.pack}`, body.trim());
36006
- }
36007
- return `${parts.join("\n\n")}
36008
- `;
36009
- }
36010
36010
  function readFrontmatter(raw, fallbackName) {
36011
36011
  const match2 = /^---\r?\n([\s\S]*?)\r?\n---/.exec(raw);
36012
36012
  const block2 = match2 ? match2[1] : "";
@@ -36029,12 +36029,6 @@ function activeTargetTypes2() {
36029
36029
  }
36030
36030
  var SKILL_RESOURCE_SCHEME = "wairon-skill";
36031
36031
  var RESOURCE_SKILL_IDS = [...SKILL_NAMES].sort();
36032
- var SkillResourceNotFoundError = class extends Error {
36033
- constructor(resourceId) {
36034
- super(`Unknown SDD skill resource id: "${resourceId}".`);
36035
- this.name = "SkillResourceNotFoundError";
36036
- }
36037
- };
36038
36032
  function readSkillFrontmatter(name) {
36039
36033
  return readFrontmatter(fs22.readFileSync(skillTemplatePath(name), "utf-8"), name);
36040
36034
  }
@@ -36064,24 +36058,9 @@ function listSkillResources() {
36064
36058
  });
36065
36059
  return [...builtin, ...pack];
36066
36060
  }
36067
- function readSkillResource(resourceId) {
36068
- const packSkills = loadProjectExtensions().skills;
36069
- if (SKILL_NAMES.includes(resourceId)) return composeBuiltinSkill(resourceId, packSkills);
36070
- const packSkill = packSkills.find((s) => s.extends === void 0 && packSkillId(s) === resourceId);
36071
- if (packSkill) return fs22.readFileSync(packSkill.sourcePath, "utf-8");
36072
- return fs22.readFileSync(skillTemplatePath(resourceId), "utf-8");
36073
- }
36074
- function listResources() {
36075
- return listSkillResources();
36076
- }
36077
36061
  function buildServerInstructions2() {
36078
36062
  return buildServerInstructions();
36079
36063
  }
36080
- function readResource(resourceId) {
36081
- const known = listSkillResources().some((d) => d.id === resourceId);
36082
- if (!known) throw new SkillResourceNotFoundError(resourceId);
36083
- return readSkillResource(resourceId);
36084
- }
36085
36064
 
36086
36065
  // src/mcp/server.ts
36087
36066
  var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
@@ -40280,7 +40259,7 @@ function schemaFingerprint() {
40280
40259
  implementation: schemaShape(ImplementationSpecSchema),
40281
40260
  type: schemaShape(TypeSpecSchema)
40282
40261
  };
40283
- const registered = createMcpServer()._registeredTools;
40262
+ const registered = createBareMcpServer()._registeredTools;
40284
40263
  const tools = [...SPEC_WRITE_TOOLS].sort().map((name) => [name, schemaShape(registered[name]?.inputSchema)]);
40285
40264
  runningFingerprint = crypto10.createHash("sha256").update(JSON.stringify({ version: FINGERPRINT_VERSION, specs, tools })).digest("hex");
40286
40265
  return runningFingerprint;
@@ -40384,113 +40363,7 @@ function reg(server, name, config, cb) {
40384
40363
  var statusInput = import_zod11.z.enum(STATUS_VALUES).optional().describe(
40385
40364
  "The spec's lifecycle status. Omitted means draft for a NEW spec and the status already stored for a re-authoring, so a restatement never reopens a frozen spec. State it to author straight at design or complete instead of promoting afterwards. A status that would LOWER the stored one is refused \u2014 reopening a spec for revision is sdd_update_spec's job, which sets the demotion deliberately."
40386
40365
  );
40387
- var SKILL_RESOURCE_MIME = "text/markdown";
40388
- function skillIdFromResourceUri(uri) {
40389
- try {
40390
- const u = new URL(uri);
40391
- return u.host || u.pathname.replace(/^\/+/, "") || uri;
40392
- } catch {
40393
- return uri;
40394
- }
40395
- }
40396
- var AGENT_BRIEF_SCHEME = "wairon-agent://";
40397
- function listAgentBriefResources() {
40398
- try {
40399
- return resolveAgentTopology().map((a) => ({
40400
- uri: `${AGENT_BRIEF_SCHEME}${a.id}`,
40401
- name: a.name,
40402
- description: a.description,
40403
- mimeType: SKILL_RESOURCE_MIME
40404
- }));
40405
- } catch {
40406
- return [];
40407
- }
40408
- }
40409
- function renderAgentBriefMarkdown(brief) {
40410
- const lines = [
40411
- `# Agent brief: ${brief.agentId}`,
40412
- "",
40413
- `- **Name**: ${brief.name}`,
40414
- `- **Template**: ${brief.template}`,
40415
- ...brief.domainRoot ? [`- **Domain root**: ${brief.domainRoot}`] : [],
40416
- `- **Owned paths**: ${brief.ownedPaths.join(", ")}`,
40417
- ...brief.readPaths?.length ? [`- **Read paths**: ${brief.readPaths.join(", ")}`] : [],
40418
- "",
40419
- "## Instructions",
40420
- "",
40421
- brief.instructions
40422
- ];
40423
- if (brief.variantGuidance && !brief.instructions.includes(brief.variantGuidance)) {
40424
- lines.push("", "## Variant guidance", "", brief.variantGuidance);
40425
- }
40426
- if (brief.budget && brief.profile) {
40427
- lines.push(
40428
- "",
40429
- "## Execution budget",
40430
- "",
40431
- ...summarize(brief.budget, brief.profile),
40432
- "",
40433
- "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."
40434
- );
40435
- }
40436
- return `${lines.join("\n")}
40437
- `;
40438
- }
40439
- function registerSkillResources(server, listChanged) {
40440
- server.server.registerCapabilities({ resources: listChanged ? { listChanged: true } : {} });
40441
- server.server.setRequestHandler(import_types12.ListResourcesRequestSchema, () => ({
40442
- resources: [
40443
- ...listResources().map((d) => ({
40444
- uri: d.resourceUri,
40445
- name: d.name,
40446
- description: d.description,
40447
- mimeType: SKILL_RESOURCE_MIME
40448
- })),
40449
- ...listAgentBriefResources()
40450
- ]
40451
- }));
40452
- server.server.setRequestHandler(import_types12.ReadResourceRequestSchema, (request) => {
40453
- const uri = request.params.uri;
40454
- if (uri.startsWith(AGENT_BRIEF_SCHEME)) {
40455
- try {
40456
- const brief = composeAgentBrief(uri.slice(AGENT_BRIEF_SCHEME.length));
40457
- return { contents: [{ uri, mimeType: SKILL_RESOURCE_MIME, text: renderAgentBriefMarkdown(brief) }] };
40458
- } catch (e) {
40459
- throw new import_types12.McpError(import_types12.ErrorCode.InvalidParams, e instanceof Error ? e.message : String(e));
40460
- }
40461
- }
40462
- try {
40463
- const content = readResource(skillIdFromResourceUri(uri));
40464
- return { contents: [{ uri, mimeType: SKILL_RESOURCE_MIME, text: content }] };
40465
- } catch (e) {
40466
- const message = e instanceof Error ? e.message : String(e);
40467
- throw new import_types12.McpError(import_types12.ErrorCode.InvalidParams, message);
40468
- }
40469
- });
40470
- }
40471
- function registerSkillPrompts(server, listChanged) {
40472
- server.server.registerCapabilities({ prompts: listChanged ? { listChanged: true } : {} });
40473
- server.server.setRequestHandler(import_types12.ListPromptsRequestSchema, () => ({
40474
- prompts: listResources().map((d) => ({
40475
- name: d.id,
40476
- title: d.name,
40477
- description: d.description
40478
- }))
40479
- }));
40480
- server.server.setRequestHandler(import_types12.GetPromptRequestSchema, (request) => {
40481
- const name = request.params.name;
40482
- try {
40483
- const content = readResource(name);
40484
- return {
40485
- description: `The wairon "${name}" skill.`,
40486
- messages: [{ role: "user", content: { type: "text", text: content } }]
40487
- };
40488
- } catch (e) {
40489
- throw new import_types12.McpError(import_types12.ErrorCode.InvalidParams, e instanceof Error ? e.message : String(e));
40490
- }
40491
- });
40492
- }
40493
- function createMcpServer(options = {}) {
40366
+ function createBareMcpServer(options = {}) {
40494
40367
  const server = new import_mcp.McpServer({
40495
40368
  name: "wairon",
40496
40369
  version: WAIRON_VERSION
@@ -41670,8 +41543,6 @@ ${testsBlock}` : ""}`, deletion);
41670
41543
  }
41671
41544
  }
41672
41545
  );
41673
- registerSkillResources(server, !options.hostedTools);
41674
- registerSkillPrompts(server, !options.hostedTools);
41675
41546
  try {
41676
41547
  const chainingParent = resolveChainingParent();
41677
41548
  if (chainingParent) {
@@ -41682,105 +41553,8 @@ ${testsBlock}` : ""}`, deletion);
41682
41553
  }
41683
41554
  } catch {
41684
41555
  }
41685
- advertiseHostedTools(server, options);
41686
41556
  return server;
41687
41557
  }
41688
- function advertiseHostedTools(server, options) {
41689
- if (options.hostedTools) {
41690
- const hostedStub = () => errText("This hosted tool is dispatched by the hosting data plane before reaching the MCP server; it is unavailable outside a hosted request.");
41691
- reg(server, "sdd_host_lock_project", {
41692
- description: "Hosted project lifecycle (execute-primary): LOCK the bound project (validate-as-complete gate + commit-scoped lock record). Executes directly when your resolved permission is yes and returns the completed outcome; when it is approval, a pending approval request is created instead (await it with sdd_host_await_approval).",
41693
- inputSchema: {}
41694
- }, hostedStub);
41695
- reg(server, "sdd_host_initialize_project", {
41696
- description: "Hosted project lifecycle (execute-primary): initialize a new hosted project into its REQUIRED owner organization unit (with an optional profile selection). Executes directly when your resolved permission is yes; when it is approval, a pending approval request is created instead.",
41697
- inputSchema: {
41698
- id: import_zod11.z.string().describe("Requested project id"),
41699
- displayName: import_zod11.z.string().optional(),
41700
- description: import_zod11.z.string().optional(),
41701
- ownerUnitId: import_zod11.z.string().describe("REQUIRED organization unit that owns the new project (every project is placed at creation)"),
41702
- environment: import_zod11.z.string().optional()
41703
- }
41704
- }, hostedStub);
41705
- reg(server, "sdd_host_get_approval_status", {
41706
- description: "Hosted project lifecycle: read the status of one of your approval requests.",
41707
- inputSchema: { requestId: import_zod11.z.string() }
41708
- }, hostedStub);
41709
- reg(server, "sdd_host_await_approval", {
41710
- description: "Hosted project lifecycle: long-poll one of YOUR approval requests until it is decided (approved requests auto-execute, so an approval resolves as completed) or the timeout elapses. Returns the request in its current state.",
41711
- inputSchema: {
41712
- requestId: import_zod11.z.string(),
41713
- timeoutSeconds: import_zod11.z.number().optional().describe("How long to wait server-side (clamped; 0 returns the current state immediately)")
41714
- }
41715
- }, hostedStub);
41716
- reg(server, "sdd_landscape_list_reachable_projects", {
41717
- description: "Hosted landscape: the projects reachable from the BOUND project through ACTIVE cross-project relations (directional, relations-only), each with the relation ids/kinds and target public interface ids.",
41718
- inputSchema: {}
41719
- }, hostedStub);
41720
- reg(server, "sdd_landscape_list_reachable_project_interfaces", {
41721
- description: "Hosted landscape: redacted, audience-filtered public interface summaries of one reachable target project (Forbidden outside the reachable set; private by default).",
41722
- inputSchema: { projectId: import_zod11.z.string().describe("The reachable target project id") }
41723
- }, hostedStub);
41724
- reg(server, "sdd_landscape_list_visible_surfaces", {
41725
- description: "Hosted landscape: the visibility-resolved discovery catalog for the BOUND project \u2014 every target the organization unit graph exposes to it (open-within-tenant, closed groups hidden, exposeTo grants honored), with audience distance and audience-filtered summaries. No relation required.",
41726
- inputSchema: {}
41727
- }, hostedStub);
41728
- reg(server, "sdd_landscape_get_project_surface", {
41729
- description: `Hosted landscape: fetch a visible target project's CONTRACT-GRADE surface snapshot (full method contracts, dispatch tables, type closure) at your audience-distance ceiling, origin "exchanged" \u2014 save it under .wai/surfaces/ (wairon surface import) so your adapters validate against the declared contract.`,
41730
- inputSchema: { projectId: import_zod11.z.string().describe("The visible target project id") }
41731
- }, hostedStub);
41732
- reg(server, "sdd_host_pack_list", {
41733
- description: "Hosted project ops: list the BOUND project's registered extension packs (requires project:read over it).",
41734
- inputSchema: {}
41735
- }, hostedStub);
41736
- reg(server, "sdd_host_pack_install", {
41737
- description: "Hosted project ops: install a DECLARATIVE extension pack (profiles + language/platform tables \u2014 never rule/code packs) into the BOUND project (requires project:admin over it).",
41738
- inputSchema: {
41739
- name: import_zod11.z.string().describe("Pack name (letters, digits, dot, underscore, hyphen)"),
41740
- content: import_zod11.z.string().describe("The declarative pack YAML content")
41741
- }
41742
- }, hostedStub);
41743
- reg(server, "sdd_host_pack_impact", {
41744
- description: "Hosted project ops: measure, writing nothing, what installing a DECLARATIVE pack (content given) or adopting the server-global pack of that name (content omitted) would change on the BOUND project \u2014 the pack's doctrine against wairon's defaults (rules loosened, raised, turned off or added; profiles and concepts added, redefined or removed), which of its profiles would govern, and the findings that change. Show it to your human before sdd_host_pack_install, which applies without it. Nothing in it is a finding: packs exist to adjust wairon's checks. Requires project:read over the project.",
41745
- inputSchema: {
41746
- name: import_zod11.z.string().describe("Pack name (letters, digits, dot, underscore, hyphen); the server-global pack to adopt when content is omitted"),
41747
- content: import_zod11.z.string().optional().describe("The declarative pack YAML an install would upload; omitted, the server-global pack an adoption would vendor")
41748
- }
41749
- }, hostedStub);
41750
- reg(server, "sdd_host_policy_evaluate", {
41751
- description: "Hosted project ops: evaluate the BOUND project's packs and profile selection against the instance pack policy \u2014 compliance without side effects (requires project:write over it).",
41752
- inputSchema: {}
41753
- }, hostedStub);
41754
- reg(server, "sdd_host_policy_reconcile", {
41755
- description: "Hosted project ops: reconcile the BOUND project against the instance pack policy \u2014 under auto_reconcile enforcement the missing required/default declarative packs are applied (requires project:write over it).",
41756
- inputSchema: {}
41757
- }, hostedStub);
41758
- reg(server, "sdd_host_produce", {
41759
- description: "Hosted project ops: run a configured producer projection (Notion/Miro) of the BOUND project to the named target (requires project:admin over it).",
41760
- inputSchema: { target: import_zod11.z.string().describe("The configured producer target (e.g. notion, miro)") }
41761
- }, hostedStub);
41762
- reg(server, "sdd_host_commit_project", {
41763
- description: "Hosted project ops: publish a DELIBERATE, .wai/-scoped commit+push of the BOUND project's specs to its bound repository (commit = local save, push = the actual backup; a clean scope publishes nothing). The data plane binds ONE project, so there is no project argument. Requires project:write over it.",
41764
- inputSchema: {
41765
- subsystem: import_zod11.z.string().optional().describe("Narrow staging to .wai/specs/<subsystem>/ (a convenience \u2014 git history stays per-repo)"),
41766
- message: import_zod11.z.string().optional().describe("Commit message; defaults to a timestamped wairon message")
41767
- }
41768
- }, hostedStub);
41769
- reg(server, "sdd_host_export_tree", {
41770
- description: "Hosted spec-tree transfer: pack the BOUND project's WHOLE spec tree \u2014 its own .wai plus every chained subproject \u2014 into a .waitree archive, returned as base64 with its roots, file count and state id. The migration counterpart of an import: use it to take a hosted project local, or to move it to another instance. Requires project:read over the project. Bounded by the data-plane body cap; a very large tree exports through the web download route instead. Refuses when a chained mount cannot be packed (escaping, missing, cyclic, too deep, or holding no .wai), naming every one and why, unless allowPartial is set \u2014 then the archive is built anyway and the result lists what was skipped.",
41771
- inputSchema: {
41772
- allowPartial: import_zod11.z.boolean().optional().describe("Build the archive even when some members cannot be packed, listing them as skipped; default false (refuse and name them)")
41773
- }
41774
- }, hostedStub);
41775
- reg(server, "sdd_host_import_tree", {
41776
- description: "Hosted spec-tree transfer: REPLACE the BOUND project's spec tree from a base64 .waitree archive. Requires project:admin over the project (strictly above project:write \u2014 this replaces the whole design, not one spec). Refuses an occupied destination unless replaceExisting is set, always refuses executable entries (rule/code packs install only through the trusted filesystem), and moves the previous tree aside to a backup whose path is returned.",
41777
- inputSchema: {
41778
- archiveBase64: import_zod11.z.string().describe("The .waitree archive bytes, base64-encoded"),
41779
- replaceExisting: import_zod11.z.boolean().optional().describe("Replace a tree already present (backed up first); without it an occupied destination is refused")
41780
- }
41781
- }, hostedStub);
41782
- }
41783
- }
41784
41558
 
41785
41559
  // src/index.ts
41786
41560
  function loadProjectConfig3() {
@@ -41985,6 +41759,7 @@ function loadProjectConfig3() {
41985
41759
  deregisterPackRef,
41986
41760
  deriveExecutionProfile,
41987
41761
  derivedDocPaths,
41762
+ describeProject,
41988
41763
  detectDomainCandidates,
41989
41764
  diagnoseProjectPacks,
41990
41765
  diagramSetIndex,