agents-united 0.10.0 → 0.12.0

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.
Files changed (179) hide show
  1. package/README.md +30 -3
  2. package/dist/cli.js +515 -56
  3. package/dist/cli.js.map +1 -1
  4. package/package.json +1 -1
  5. package/registry/agents/orchestrator-business.md +19 -6
  6. package/registry/agents/orchestrator-design.md +21 -6
  7. package/registry/agents/orchestrator-digital-agency.md +22 -3
  8. package/registry/agents/orchestrator-engineering.md +88 -29
  9. package/registry/agents/orchestrator-marketing.md +21 -7
  10. package/registry/agents/orchestrator-research.md +18 -4
  11. package/registry/agents/orchestrator-security.md +20 -8
  12. package/registry/agents/orchestrator-system-architecture.md +20 -6
  13. package/registry/agents/orchestrator-universal.md +17 -1
  14. package/registry/agents/subagent-accessibility-lead.md +8 -0
  15. package/registry/agents/subagent-ai-model-architect.md +8 -0
  16. package/registry/agents/subagent-android-architect.md +9 -0
  17. package/registry/agents/subagent-appsec-penetration-tester.md +7 -0
  18. package/registry/agents/subagent-backend-architect.md +22 -1
  19. package/registry/agents/subagent-business-panel-experts.md +8 -0
  20. package/registry/agents/subagent-cloud-infrastructure-architect.md +9 -0
  21. package/registry/agents/subagent-cloud-security-architect.md +8 -0
  22. package/registry/agents/subagent-code-reviewer.md +11 -2
  23. package/registry/agents/subagent-compliance-grc-specialist.md +8 -0
  24. package/registry/agents/subagent-cross-platform-specialist.md +10 -0
  25. package/registry/agents/subagent-data-engineer.md +8 -0
  26. package/registry/agents/subagent-database-administrator.md +8 -0
  27. package/registry/agents/subagent-deep-research.md +9 -0
  28. package/registry/agents/subagent-design-ops-lead.md +9 -0
  29. package/registry/agents/subagent-design-researcher.md +8 -0
  30. package/registry/agents/subagent-design-systems-architect.md +9 -0
  31. package/registry/agents/subagent-designer-toolkit-expert.md +9 -0
  32. package/registry/agents/subagent-devops-engineer.md +9 -0
  33. package/registry/agents/subagent-distributed-systems-architect.md +10 -0
  34. package/registry/agents/subagent-e2e-tester.md +9 -0
  35. package/registry/agents/subagent-financial-analyst.md +10 -2
  36. package/registry/agents/subagent-finops-cost-engineer.md +7 -0
  37. package/registry/agents/subagent-frontend-architect.md +23 -0
  38. package/registry/agents/subagent-interaction-designer.md +10 -0
  39. package/registry/agents/subagent-ios-architect.md +9 -0
  40. package/registry/agents/subagent-legal-contract-analyst.md +13 -5
  41. package/registry/agents/subagent-lifecycle-email-specialist.md +8 -0
  42. package/registry/agents/subagent-literature-patent-analyst.md +15 -5
  43. package/registry/agents/subagent-market-intelligence-analyst.md +13 -3
  44. package/registry/agents/subagent-marketing-campaign-specialist.md +8 -0
  45. package/registry/agents/subagent-marketing-content-strategist.md +9 -0
  46. package/registry/agents/subagent-marketing-conversion-specialist.md +10 -0
  47. package/registry/agents/subagent-marketing-creative-designer.md +15 -2
  48. package/registry/agents/subagent-marketing-growth-strategist.md +8 -0
  49. package/registry/agents/subagent-ml-platform-engineer.md +8 -0
  50. package/registry/agents/subagent-operations-strategist.md +11 -2
  51. package/registry/agents/subagent-paid-acquisition-specialist.md +8 -0
  52. package/registry/agents/subagent-plg-strategist.md +8 -0
  53. package/registry/agents/subagent-prototype-tester.md +8 -0
  54. package/registry/agents/subagent-qa-automation-lead.md +10 -0
  55. package/registry/agents/subagent-repo-index.md +8 -2
  56. package/registry/agents/subagent-security-engineer.md +6 -0
  57. package/registry/agents/subagent-seo-specialist.md +10 -0
  58. package/registry/agents/subagent-socratic-mentor.md +7 -0
  59. package/registry/agents/subagent-statistical-analyst.md +6 -0
  60. package/registry/agents/subagent-sysops-sre-lead.md +8 -0
  61. package/registry/agents/subagent-system-architect.md +9 -0
  62. package/registry/agents/subagent-ui-designer.md +12 -0
  63. package/registry/agents/subagent-ux-strategist.md +10 -0
  64. package/registry/bundles.json +216 -275
  65. package/registry/skills/a11y-debugging/SKILL.md +98 -0
  66. package/registry/skills/a11y-debugging/references/a11y-snippets.md +92 -0
  67. package/registry/skills/ab-test-setup/SKILL.md +1 -1
  68. package/registry/skills/accessibility-audit/SKILL.md +1 -1
  69. package/registry/skills/clickable-prototype-spec/SKILL.md +1 -1
  70. package/registry/skills/component-library-management/SKILL.md +1 -1
  71. package/registry/skills/component-playground-setup/SKILL.md +1 -1
  72. package/registry/skills/content-calendar-strategy/SKILL.md +1 -1
  73. package/registry/skills/conversion-funnel-optimization/SKILL.md +1 -1
  74. package/registry/skills/copywriting-frameworks/SKILL.md +1 -1
  75. package/registry/skills/debug-optimize-lcp/SKILL.md +133 -0
  76. package/registry/skills/debug-optimize-lcp/references/elements-and-size.md +27 -0
  77. package/registry/skills/debug-optimize-lcp/references/lcp-breakdown.md +23 -0
  78. package/registry/skills/debug-optimize-lcp/references/lcp-snippets.md +79 -0
  79. package/registry/skills/debug-optimize-lcp/references/optimization-strategies.md +38 -0
  80. package/registry/skills/design-handoff-spec/SKILL.md +1 -1
  81. package/registry/skills/design-ops-workflow/SKILL.md +1 -1
  82. package/registry/skills/design-system-governance/SKILL.md +1 -1
  83. package/registry/skills/design-system-tokens/SKILL.md +1 -1
  84. package/registry/skills/design-tokens-management/SKILL.md +1 -1
  85. package/registry/skills/design-version-control/SKILL.md +1 -1
  86. package/registry/skills/email-marketing-automation/SKILL.md +1 -1
  87. package/registry/skills/finishing-a-development-branch/SKILL.md +1 -1
  88. package/registry/skills/frontend-design/LICENSE.txt +177 -0
  89. package/registry/skills/frontend-design/SKILL.md +64 -0
  90. package/registry/skills/generative_ui/SKILL.md +131 -0
  91. package/registry/skills/growth-experiment-design/SKILL.md +1 -1
  92. package/registry/skills/interaction-pattern-library/SKILL.md +1 -1
  93. package/registry/skills/interactive-prototype-builder/SKILL.md +1 -1
  94. package/registry/skills/mcp-setup/SKILL.md +22 -7
  95. package/registry/skills/micro-interaction-design/SKILL.md +1 -1
  96. package/registry/skills/mobile-first-design/SKILL.md +1 -1
  97. package/registry/skills/modern-web-guidance/SKILL.md +139 -0
  98. package/registry/skills/product-launch-playbook/SKILL.md +1 -1
  99. package/registry/skills/responsive-design-audit/SKILL.md +1 -1
  100. package/registry/skills/seo-audit/SKILL.md +1 -1
  101. package/registry/skills/signup-flow-cro/SKILL.md +1 -1
  102. package/registry/skills/social-media-campaign/SKILL.md +1 -1
  103. package/registry/skills/state-driven-ui-animation/SKILL.md +1 -1
  104. package/registry/skills/stitch-design-taste/DESIGN.md +121 -0
  105. package/registry/skills/stitch-design-taste/SKILL.md +194 -0
  106. package/registry/skills/subagent-driven-development/SKILL.md +1 -1
  107. package/registry/skills/ui-component-spec/SKILL.md +1 -1
  108. package/registry/skills/usability-testing-protocol/SKILL.md +1 -1
  109. package/registry/skills/user-flow-mapping/SKILL.md +1 -1
  110. package/registry/skills/user-journey-mapping/SKILL.md +1 -1
  111. package/registry/{workflows/workflow-agency-ad-creative-sprint.md → skills/workflow-agency-ad-creative-sprint/SKILL.md} +14 -7
  112. package/registry/{workflows/workflow-agency-brand-design-system.md → skills/workflow-agency-brand-design-system/SKILL.md} +14 -7
  113. package/registry/{workflows/workflow-agency-client-pitch-proposal.md → skills/workflow-agency-client-pitch-proposal/SKILL.md} +14 -7
  114. package/registry/{workflows/workflow-agency-cro-funnel-teardown.md → skills/workflow-agency-cro-funnel-teardown/SKILL.md} +14 -7
  115. package/registry/{workflows/workflow-agency-full-campaign.md → skills/workflow-agency-full-campaign/SKILL.md} +14 -7
  116. package/registry/{workflows/workflow-agency-seo-content-engine.md → skills/workflow-agency-seo-content-engine/SKILL.md} +14 -7
  117. package/registry/{workflows/workflow-analyze.md → skills/workflow-analyze/SKILL.md} +13 -6
  118. package/registry/{workflows/workflow-api-contract-design.md → skills/workflow-api-contract-design/SKILL.md} +11 -4
  119. package/registry/{workflows/workflow-app-store-release.md → skills/workflow-app-store-release/SKILL.md} +11 -4
  120. package/registry/{workflows/workflow-brainstorm.md → skills/workflow-brainstorm/SKILL.md} +14 -7
  121. package/registry/{workflows/workflow-build.md → skills/workflow-build/SKILL.md} +14 -7
  122. package/registry/{workflows/workflow-business-panel.md → skills/workflow-business-panel/SKILL.md} +14 -7
  123. package/registry/{workflows/workflow-cleanup.md → skills/workflow-cleanup/SKILL.md} +14 -8
  124. package/registry/{workflows/workflow-deploy-staging.md → skills/workflow-deploy-staging/SKILL.md} +11 -4
  125. package/registry/{workflows/workflow-design-code.md → skills/workflow-design-code/SKILL.md} +14 -7
  126. package/registry/{workflows/workflow-design-ops--handoff.md → skills/workflow-design-ops-handoff/SKILL.md} +14 -7
  127. package/registry/{workflows/workflow-design-ops--plan-sprint.md → skills/workflow-design-ops-plan-sprint/SKILL.md} +14 -7
  128. package/registry/{workflows/workflow-design-ops--setup-workflow.md → skills/workflow-design-ops-setup-workflow/SKILL.md} +14 -7
  129. package/registry/{workflows/workflow-design-orchestrate.md → skills/workflow-design-orchestrate/SKILL.md} +14 -7
  130. package/registry/{workflows/workflow-design-systems--audit-system.md → skills/workflow-design-systems-audit-system/SKILL.md} +14 -7
  131. package/registry/{workflows/workflow-design-systems--create-component.md → skills/workflow-design-systems-create-component/SKILL.md} +13 -7
  132. package/registry/{workflows/workflow-design-systems--tokenize.md → skills/workflow-design-systems-tokenize/SKILL.md} +14 -7
  133. package/registry/{workflows/workflow-diagnose.md → skills/workflow-diagnose/SKILL.md} +11 -4
  134. package/registry/{workflows/workflow-e2e-testing.md → skills/workflow-e2e-testing/SKILL.md} +11 -4
  135. package/registry/{workflows/workflow-email-drip-sequence.md → skills/workflow-email-drip-sequence/SKILL.md} +14 -7
  136. package/registry/{workflows/workflow-estimate.md → skills/workflow-estimate/SKILL.md} +14 -7
  137. package/registry/{workflows/workflow-explain.md → skills/workflow-explain/SKILL.md} +14 -7
  138. package/registry/{workflows/workflow-frontend-audit.md → skills/workflow-frontend-audit/SKILL.md} +11 -4
  139. package/registry/{workflows/workflow-git.md → skills/workflow-git/SKILL.md} +12 -5
  140. package/registry/{workflows/workflow-grill.md → skills/workflow-grill/SKILL.md} +11 -4
  141. package/registry/{workflows/workflow-implement.md → skills/workflow-implement/SKILL.md} +15 -8
  142. package/registry/{workflows/workflow-incident-triage.md → skills/workflow-incident-triage/SKILL.md} +11 -4
  143. package/registry/{workflows/workflow-interaction-design--design-interaction.md → skills/workflow-interaction-design-design-interaction/SKILL.md} +14 -7
  144. package/registry/{workflows/workflow-interaction-design--error-flow.md → skills/workflow-interaction-design-error-flow/SKILL.md} +14 -7
  145. package/registry/{workflows/workflow-interaction-design--map-states.md → skills/workflow-interaction-design-map-states/SKILL.md} +14 -7
  146. package/registry/{workflows/workflow-marketing-audit.md → skills/workflow-marketing-audit/SKILL.md} +14 -7
  147. package/registry/{workflows/workflow-marketing-campaign-builder.md → skills/workflow-marketing-campaign-builder/SKILL.md} +14 -7
  148. package/registry/{workflows/workflow-marketing-content-pipeline.md → skills/workflow-marketing-content-pipeline/SKILL.md} +13 -7
  149. package/registry/{workflows/workflow-marketing-growth-experiment.md → skills/workflow-marketing-growth-experiment/SKILL.md} +14 -7
  150. package/registry/{workflows/workflow-marketing-launch.md → skills/workflow-marketing-launch/SKILL.md} +14 -7
  151. package/registry/{workflows/workflow-marketing-panel.md → skills/workflow-marketing-panel/SKILL.md} +14 -7
  152. package/registry/{workflows/workflow-ml-eval.md → skills/workflow-ml-eval/SKILL.md} +14 -7
  153. package/registry/{workflows/workflow-mobile-build.md → skills/workflow-mobile-build/SKILL.md} +13 -6
  154. package/registry/{workflows/workflow-onboarding-funnel-cro.md → skills/workflow-onboarding-funnel-cro/SKILL.md} +14 -7
  155. package/registry/{workflows/workflow-paid-acquisition-campaign.md → skills/workflow-paid-acquisition-campaign/SKILL.md} +14 -7
  156. package/registry/{workflows/workflow-paid-campaign-launch.md → skills/workflow-paid-campaign-launch/SKILL.md} +14 -7
  157. package/registry/{workflows/workflow-plan.md → skills/workflow-plan/SKILL.md} +14 -7
  158. package/registry/{workflows/workflow-prototyping-testing--evaluate.md → skills/workflow-prototyping-testing-evaluate/SKILL.md} +14 -7
  159. package/registry/{workflows/workflow-prototyping-testing--experiment.md → skills/workflow-prototyping-testing-experiment/SKILL.md} +14 -7
  160. package/registry/{workflows/workflow-prototyping-testing--prototype-plan.md → skills/workflow-prototyping-testing-prototype-plan/SKILL.md} +14 -7
  161. package/registry/{workflows/workflow-prototyping-testing--test-plan.md → skills/workflow-prototyping-testing-test-plan/SKILL.md} +14 -7
  162. package/registry/{workflows/workflow-rag-pipeline-deploy.md → skills/workflow-rag-pipeline-deploy/SKILL.md} +14 -7
  163. package/registry/{workflows/workflow-recommend.md → skills/workflow-recommend/SKILL.md} +14 -7
  164. package/registry/{workflows/workflow-research.md → skills/workflow-research/SKILL.md} +14 -7
  165. package/registry/{workflows/workflow-review.md → skills/workflow-review/SKILL.md} +13 -6
  166. package/registry/{workflows/workflow-seo-audit-pipeline.md → skills/workflow-seo-audit-pipeline/SKILL.md} +14 -7
  167. package/registry/{workflows/workflow-seo-content-pipeline.md → skills/workflow-seo-content-pipeline/SKILL.md} +14 -7
  168. package/registry/{workflows/workflow-serverless-gpu-deploy.md → skills/workflow-serverless-gpu-deploy/SKILL.md} +14 -7
  169. package/registry/{workflows/workflow-spec.md → skills/workflow-spec/SKILL.md} +11 -4
  170. package/registry/{workflows/workflow-spec-panel.md → skills/workflow-spec-panel/SKILL.md} +14 -7
  171. package/registry/{workflows/workflow-test.md → skills/workflow-test/SKILL.md} +15 -8
  172. package/registry/{workflows/workflow-troubleshoot.md → skills/workflow-troubleshoot/SKILL.md} +14 -7
  173. package/registry/{workflows/workflow-ui-design--color-palette.md → skills/workflow-ui-design-color-palette/SKILL.md} +13 -7
  174. package/registry/{workflows/workflow-ui-design--design-screen.md → skills/workflow-ui-design-design-screen/SKILL.md} +13 -7
  175. package/registry/{workflows/workflow-ui-design--responsive-audit.md → skills/workflow-ui-design-responsive-audit/SKILL.md} +14 -7
  176. package/registry/{workflows/workflow-ui-design--type-system.md → skills/workflow-ui-design-type-system/SKILL.md} +14 -7
  177. package/registry/{workflows/workflow-ux-strategy--benchmark.md → skills/workflow-ux-strategy-benchmark/SKILL.md} +14 -7
  178. package/registry/{workflows/workflow-ux-strategy--frame-problem.md → skills/workflow-ux-strategy-frame-problem/SKILL.md} +14 -7
  179. package/registry/{workflows/workflow-ux-strategy--strategize.md → skills/workflow-ux-strategy-strategize/SKILL.md} +14 -7
package/dist/cli.js CHANGED
@@ -10,12 +10,21 @@ import path14 from "path";
10
10
  // src/core/registry.ts
11
11
  import path from "path";
12
12
  import fs from "fs-extra";
13
+ import yaml from "yaml";
13
14
  import { fileURLToPath } from "url";
14
15
  var __filename = fileURLToPath(import.meta.url);
15
16
  var __dirname = path.dirname(__filename);
16
- var RegistryResolver = class {
17
+ var RegistryResolver = class _RegistryResolver {
18
+ /**
19
+ * Host entrypoint rules (Plan 015 §0/C7). `GEMINI.md` is always resolved so
20
+ * Antigravity-family hosts keep their entrypoint; it is never declared in an
21
+ * agent's frontmatter.
22
+ */
23
+ static BASELINE_RULES = ["GEMINI.md"];
17
24
  registryDir;
18
25
  bundlesManifest = null;
26
+ /** Memoized agent file -> declared rules (Plan 015 §0/C6). */
27
+ agentRuleCache = /* @__PURE__ */ new Map();
19
28
  constructor(customRegistryDir) {
20
29
  if (customRegistryDir) {
21
30
  this.registryDir = path.resolve(customRegistryDir);
@@ -71,18 +80,20 @@ var RegistryResolver = class {
71
80
  const agents = /* @__PURE__ */ new Set();
72
81
  const skills = /* @__PURE__ */ new Set();
73
82
  const workflows = /* @__PURE__ */ new Set();
83
+ const rules = new Set(_RegistryResolver.BASELINE_RULES);
74
84
  for (const b of domainBundles) {
75
85
  const resolved = await this.resolve(b.name);
76
86
  resolved.agents.forEach((a) => agents.add(a));
77
87
  resolved.skills.forEach((s) => skills.add(s));
78
88
  resolved.workflows.forEach((w) => workflows.add(w));
89
+ resolved.rules.forEach((r) => rules.add(r));
79
90
  }
80
91
  return {
81
92
  targetBundle: `domain:${domainName}`,
82
93
  agents: Array.from(agents),
83
94
  skills: Array.from(skills),
84
95
  workflows: Array.from(workflows),
85
- rules: ["GEMINI.md"]
96
+ rules: Array.from(rules).sort()
86
97
  };
87
98
  }
88
99
  }
@@ -91,7 +102,8 @@ var RegistryResolver = class {
91
102
  const agents = /* @__PURE__ */ new Set();
92
103
  const skills = new Set(bundle.skills || []);
93
104
  const workflows = new Set(bundle.workflows || []);
94
- const rules = ["GEMINI.md"];
105
+ const rules = new Set(_RegistryResolver.BASELINE_RULES);
106
+ (bundle.rules || []).forEach((r) => rules.add(r));
95
107
  if (bundle.parentBundle) {
96
108
  const parent = await this.getBundle(bundle.parentBundle);
97
109
  if (parent) {
@@ -99,16 +111,24 @@ var RegistryResolver = class {
99
111
  if (parent.agents) parent.agents.forEach((a) => agents.add(a));
100
112
  if (parent.skills) parent.skills.forEach((s) => skills.add(s));
101
113
  if (parent.workflows) parent.workflows.forEach((w) => workflows.add(w));
114
+ (parent.rules || []).forEach((r) => rules.add(r));
102
115
  }
103
116
  }
104
117
  if (bundle.orchestrator) agents.add(bundle.orchestrator);
105
118
  if (bundle.agents) bundle.agents.forEach((a) => agents.add(a));
119
+ for (const agentFile of agents) {
120
+ for (const rule of await this.extractRulesFromAgent(agentFile)) {
121
+ rules.add(rule);
122
+ }
123
+ }
124
+ const sortedRules = Array.from(rules).sort();
125
+ this.assertRulesExist(sortedRules, `bundle "${bundle.name}"`);
106
126
  return {
107
127
  targetBundle: bundle.name,
108
128
  agents: Array.from(agents),
109
129
  skills: Array.from(skills),
110
130
  workflows: Array.from(workflows),
111
- rules
131
+ rules: sortedRules
112
132
  };
113
133
  }
114
134
  const agentPath = path.join(this.registryDir, "agents", identifier.endsWith(".md") ? identifier : `${identifier}.md`);
@@ -120,7 +140,9 @@ var RegistryResolver = class {
120
140
  rules: []
121
141
  };
122
142
  }
143
+ const sanitizedSkillId = identifier.replace(/\.md$/, "").replace(/--/g, "-");
123
144
  const skillPath = path.join(this.registryDir, "skills", identifier);
145
+ const sanitizedSkillPath = path.join(this.registryDir, "skills", sanitizedSkillId);
124
146
  if (await fs.pathExists(skillPath)) {
125
147
  return {
126
148
  agents: [],
@@ -128,6 +150,22 @@ var RegistryResolver = class {
128
150
  workflows: [],
129
151
  rules: []
130
152
  };
153
+ } else if (await fs.pathExists(sanitizedSkillPath)) {
154
+ return {
155
+ agents: [],
156
+ skills: [sanitizedSkillId],
157
+ workflows: [],
158
+ rules: []
159
+ };
160
+ }
161
+ const workflowSkillPath = path.join(this.registryDir, "skills", `workflow-${sanitizedSkillId}`);
162
+ if (await fs.pathExists(workflowSkillPath)) {
163
+ return {
164
+ agents: [],
165
+ skills: [`workflow-${sanitizedSkillId}`],
166
+ workflows: [],
167
+ rules: []
168
+ };
131
169
  }
132
170
  const workflowFileName = identifier.startsWith("workflow-") ? `${identifier}.md` : `workflow-${identifier}.md`;
133
171
  const workflowPath = path.join(this.registryDir, "workflows", workflowFileName);
@@ -167,7 +205,7 @@ var RegistryResolver = class {
167
205
  }
168
206
  const skillsDir = path.join(this.registryDir, "skills");
169
207
  let matchedSkills = [];
170
- if (!options?.type || options.type === "skill") {
208
+ if (!options?.type || options.type === "skill" || options.type === "workflow") {
171
209
  if (await fs.pathExists(skillsDir)) {
172
210
  const dirs = await fs.readdir(skillsDir);
173
211
  matchedSkills = dirs.filter((d) => {
@@ -176,15 +214,19 @@ var RegistryResolver = class {
176
214
  });
177
215
  }
178
216
  }
179
- const workflowsDir = path.join(this.registryDir, "workflows");
180
217
  let matchedWorkflows = [];
181
218
  if (!options?.type || options.type === "workflow") {
219
+ matchedWorkflows = matchedSkills.filter((s) => s.startsWith("workflow-"));
220
+ const workflowsDir = path.join(this.registryDir, "workflows");
182
221
  if (await fs.pathExists(workflowsDir)) {
183
222
  const files = await fs.readdir(workflowsDir);
184
- matchedWorkflows = files.filter((f) => f.endsWith(".md")).filter((f) => {
223
+ const legacyMatches = files.filter((f) => f.endsWith(".md")).filter((f) => {
185
224
  if (!q) return true;
186
225
  return f.toLowerCase().includes(q);
187
226
  });
227
+ legacyMatches.forEach((f) => {
228
+ if (!matchedWorkflows.includes(f)) matchedWorkflows.push(f);
229
+ });
188
230
  }
189
231
  }
190
232
  return {
@@ -194,6 +236,55 @@ var RegistryResolver = class {
194
236
  workflows: matchedWorkflows
195
237
  };
196
238
  }
239
+ /**
240
+ * Plan 015 Step 1 / §0/C6 — extract the `rules:` binding from an agent's YAML
241
+ * frontmatter. Rules are declared as a BLOCK SEQUENCE:
242
+ * rules:
243
+ * - git-guardrails.md
244
+ * Never regex for an inline `rules: [a, b]`. Returns `[]` (never throws) when
245
+ * the file is missing, has no frontmatter, or the YAML is unparsable so that
246
+ * resolution stays resilient; existence of the referenced rule files is
247
+ * enforced separately by `assertRulesExist`.
248
+ */
249
+ async extractRulesFromAgent(agentFileName) {
250
+ const cached = this.agentRuleCache.get(agentFileName);
251
+ if (cached) {
252
+ return cached;
253
+ }
254
+ let declared = [];
255
+ const agentPath = path.join(this.registryDir, "agents", agentFileName);
256
+ if (await fs.pathExists(agentPath)) {
257
+ const content = await fs.readFile(agentPath, "utf8");
258
+ const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
259
+ if (match) {
260
+ try {
261
+ const meta = yaml.parse(match[1]) ?? {};
262
+ if (Array.isArray(meta.rules)) {
263
+ declared = meta.rules.filter((r) => typeof r === "string");
264
+ }
265
+ } catch {
266
+ declared = [];
267
+ }
268
+ }
269
+ }
270
+ this.agentRuleCache.set(agentFileName, declared);
271
+ return declared;
272
+ }
273
+ /**
274
+ * Plan 015 §0/D2 — a declared rule binding that cannot be satisfied is a
275
+ * configuration defect, not something to skip silently: installer.ts guards
276
+ * its copy loop with `pathExists`, so a typo would otherwise deploy no rule at
277
+ * all with no error surfaced anywhere.
278
+ */
279
+ assertRulesExist(rules, context) {
280
+ for (const rule of rules) {
281
+ if (!fs.existsSync(path.join(this.registryDir, "rules", rule))) {
282
+ throw new Error(
283
+ `Registry validation error: ${context} references rule "${rule}" which does not exist in registry/rules/.`
284
+ );
285
+ }
286
+ }
287
+ }
197
288
  /**
198
289
  * ADR 0015 — fail-fast validation of planningLoop configuration.
199
290
  * @throws if any bundle violates planner-orchestrator invariants.
@@ -201,6 +292,15 @@ var RegistryResolver = class {
201
292
  validateBundles(manifest) {
202
293
  const validModes = ["subagent-first", "planner-orchestrator"];
203
294
  for (const [name, bundle] of Object.entries(manifest.bundles)) {
295
+ if (Array.isArray(bundle.rules)) {
296
+ for (const rule of bundle.rules) {
297
+ if (!fs.existsSync(path.join(this.registryDir, "rules", rule))) {
298
+ throw new Error(
299
+ `Registry validation error: bundle "${name}" references rule "${rule}" which does not exist in registry/rules/.`
300
+ );
301
+ }
302
+ }
303
+ }
204
304
  const pl = bundle.planningLoop;
205
305
  if (!pl || !pl.enabled) continue;
206
306
  const mode = pl.mode ?? "subagent-first";
@@ -367,10 +467,10 @@ var AgentHostAdapter = class {
367
467
  import YAML from "yaml";
368
468
 
369
469
  // src/core/cline-projector.ts
370
- import yaml from "yaml";
470
+ import yaml2 from "yaml";
371
471
  import path4 from "path";
372
472
  import fs2 from "fs-extra";
373
- var ClineProjector = class {
473
+ var ClineProjector = class _ClineProjector {
374
474
  /**
375
475
  * Managed marker inserted after YAML frontmatter in every rendered artifact.
376
476
  */
@@ -411,7 +511,7 @@ complete the role in the main session.`;
411
511
  }
412
512
  let parsed = {};
413
513
  try {
414
- parsed = yaml.parse(match[1]) || {};
514
+ parsed = yaml2.parse(match[1]) || {};
415
515
  } catch {
416
516
  parsed = {};
417
517
  }
@@ -428,7 +528,7 @@ complete the role in the main session.`;
428
528
  } else if (typeof defaultMaxIterations === "number") {
429
529
  cleanFrontmatter.maxIterations = defaultMaxIterations;
430
530
  }
431
- const frontmatterStr = yaml.stringify(cleanFrontmatter).trim();
531
+ const frontmatterStr = yaml2.stringify(cleanFrontmatter).trim();
432
532
  const bodyStr = match[2].trim();
433
533
  return `---
434
534
  ${frontmatterStr}
@@ -450,7 +550,7 @@ ${bodyStr}
450
550
  let humanName;
451
551
  if (match) {
452
552
  try {
453
- const parsed = yaml.parse(match[1]) || {};
553
+ const parsed = yaml2.parse(match[1]) || {};
454
554
  if (typeof parsed.name === "string" && parsed.name.trim().length > 0) {
455
555
  humanName = parsed.name.trim();
456
556
  }
@@ -471,7 +571,7 @@ ${bodyStr}
471
571
  let description;
472
572
  if (match) {
473
573
  try {
474
- const parsed = yaml.parse(match[1]) || {};
574
+ const parsed = yaml2.parse(match[1]) || {};
475
575
  if (typeof parsed.description === "string" && parsed.description.trim().length > 0) {
476
576
  description = parsed.description.trim();
477
577
  }
@@ -480,7 +580,7 @@ ${bodyStr}
480
580
  }
481
581
  const cleanFrontmatter = { name: slug };
482
582
  if (description) cleanFrontmatter.description = description;
483
- const frontmatterStr = yaml.stringify(cleanFrontmatter).trim();
583
+ const frontmatterStr = yaml2.stringify(cleanFrontmatter).trim();
484
584
  const bodyStr = match ? match[2].trim() : canonicalContent.trim();
485
585
  return `---
486
586
  ${frontmatterStr}
@@ -506,11 +606,11 @@ ${canonicalContent.trim()}`;
506
606
  const rawBody = match[2];
507
607
  let parsed = {};
508
608
  try {
509
- parsed = yaml.parse(rawYaml) || {};
609
+ parsed = yaml2.parse(rawYaml) || {};
510
610
  } catch {
511
611
  parsed = {};
512
612
  }
513
- const frontmatterStr = yaml.stringify(parsed).trim();
613
+ const frontmatterStr = yaml2.stringify(parsed).trim();
514
614
  const bodyStr = rawBody.trim();
515
615
  return `---
516
616
  ${frontmatterStr}
@@ -534,7 +634,8 @@ ${bodyStr}
534
634
  canonicalPath: `agents/${agentFile}`
535
635
  }));
536
636
  const sortedSkills = [...bundle.skills || []].sort();
537
- const sortedWorkflows = [...bundle.workflows || []].sort();
637
+ const rawWorkflows = bundle.workflows && bundle.workflows.length > 0 ? bundle.workflows : (bundle.skills || []).filter((s) => s.startsWith("workflow-"));
638
+ const sortedWorkflows = [...rawWorkflows].sort();
538
639
  const recommendedAddons = (bundle.recommendedAddons || []).filter((a) => !excludeAddons.includes(a));
539
640
  const manifest = {
540
641
  schemaVersion: 1,
@@ -566,7 +667,7 @@ ${bodyStr}
566
667
  manifest.personas = Object.entries(bundle.personaAliases).map(([persona, role]) => ({ persona, role }));
567
668
  }
568
669
  }
569
- return yaml.stringify(manifest);
670
+ return yaml2.stringify(manifest);
570
671
  }
571
672
  /**
572
673
  * Render the coordinator rule file (.agents/plugins/<bundle>/rules/agents-united-<bundle>.md).
@@ -583,6 +684,15 @@ ${bodyStr}
583
684
  const name = agentFile.replace(/\.md$/, "");
584
685
  return `- **${name}**: \`.agents/agents/${agentFile}\``;
585
686
  });
687
+ const rawWorkflows = [
688
+ ...(bundle.workflows || []).map((w) => w.replace(/\.md$/i, "")),
689
+ ...(bundle.skills || []).filter((s) => s.startsWith("workflow-"))
690
+ ];
691
+ const uniqueWorkflows = Array.from(new Set(rawWorkflows)).sort();
692
+ const workflowSection = uniqueWorkflows.length > 0 ? `
693
+ ### Installed Workflows & Workflow Skills
694
+ Execute multi-step engineering procedures by consulting the corresponding workflow skill runbook (\`.agents/skills/<name>/SKILL.md\`) or triggering its slash command (\`/<name>\`):
695
+ ` + uniqueWorkflows.map((w) => `- **${w}**: \`.cline/workflows/${w}.md\` | \`.agents/skills/${w}/SKILL.md\``).join("\n") + "\n" : "";
586
696
  const addons = (bundle.recommendedAddons || []).filter((a) => !excludeAddons.includes(a));
587
697
  const addonSection = addons.length > 0 ? `
588
698
  ### Recommended Addon Policy
@@ -617,7 +727,7 @@ ${planningSection}${personaSection}
617
727
  ${specialistLines.length > 0 ? `
618
728
  ### Installed Specialist Roles
619
729
  ${specialistLines.join("\n")}` : ""}
620
- ${addonSection}
730
+ ${workflowSection}${addonSection}
621
731
  `;
622
732
  }
623
733
  /**
@@ -694,7 +804,24 @@ ${addonSection}
694
804
  }
695
805
  }
696
806
  }
697
- for (const workflowFile of resolved.workflows) {
807
+ const workflowSkillNames = resolved.skills.filter((s) => s.startsWith("workflow-"));
808
+ for (const skillName of workflowSkillNames) {
809
+ const canonicalRel = `skills/${skillName}/SKILL.md`;
810
+ const skillFilePath = path4.join(registryDir, "skills", skillName, "SKILL.md");
811
+ if (await fs2.pathExists(skillFilePath)) {
812
+ const content = await fs2.readFile(skillFilePath, "utf8");
813
+ const slug = skillName;
814
+ const rendered = this.renderWorkflowProjection(content, canonicalRel);
815
+ artifacts.push({
816
+ kind: "workflow",
817
+ canonical: canonicalRel,
818
+ relPath: `.cline/workflows/${slug}.md`.replace(/\\/g, "/"),
819
+ content: rendered,
820
+ managedMarker: true
821
+ });
822
+ }
823
+ }
824
+ for (const workflowFile of resolved.workflows || []) {
698
825
  const canonicalRel = `workflows/${workflowFile}`;
699
826
  const srcPath = path4.join(registryDir, "workflows", workflowFile);
700
827
  if (await fs2.pathExists(srcPath)) {
@@ -717,6 +844,24 @@ ${addonSection}
717
844
  content: ruleContent,
718
845
  managedMarker: true
719
846
  });
847
+ const hostEntrypointRules = /* @__PURE__ */ new Set(["GEMINI.md", "AGENTS.md", "CLAUDE.md", "CURSOR.md"]);
848
+ for (const ruleFile of [...resolved.rules || []].sort()) {
849
+ if (hostEntrypointRules.has(ruleFile)) continue;
850
+ const ruleSrcPath = path4.join(registryDir, "rules", ruleFile);
851
+ if (await fs2.pathExists(ruleSrcPath)) {
852
+ const ruleFileContent = await fs2.readFile(ruleSrcPath, "utf8");
853
+ artifacts.push({
854
+ kind: "rule",
855
+ canonical: `rules/${ruleFile}`,
856
+ relPath: `.cline/rules/${ruleFile}`.replace(/\\/g, "/"),
857
+ content: `${_ClineProjector.marker(`rules/${ruleFile}`)}
858
+
859
+ ${ruleFileContent.trim()}
860
+ `,
861
+ managedMarker: true
862
+ });
863
+ }
864
+ }
720
865
  const manifestContent = this.renderTeamManifest(bundle, scope, excludeAddons);
721
866
  artifacts.push({
722
867
  kind: "team-manifest",
@@ -921,6 +1066,7 @@ ${normalizedBody}`;
921
1066
  };
922
1067
 
923
1068
  // src/core/installer.ts
1069
+ import YAML2 from "yaml";
924
1070
  var InstallEngine = class _InstallEngine {
925
1071
  registry;
926
1072
  constructor(registry2) {
@@ -1054,6 +1200,70 @@ var InstallEngine = class _InstallEngine {
1054
1200
  }
1055
1201
  }
1056
1202
  }
1203
+ /**
1204
+ * Plan 015c / §5.7 — host-scoped projection namespaces.
1205
+ *
1206
+ * A re-projection run is authoritative only for the paths it produces inside
1207
+ * its own host namespace. Bundle-scoped lanes (`.agents/plugins/<bundle>/`) are
1208
+ * additionally narrowed to the bundle that owns them, so re-projecting bundle A
1209
+ * never drops bundle B's plugin-lane entries.
1210
+ */
1211
+ static projectionNamespacePrefixes(host, bundleName) {
1212
+ switch (host) {
1213
+ case "cline":
1214
+ return [".cline/", `.agents/plugins/${bundleName}/`];
1215
+ case "claude":
1216
+ return [".claude/"];
1217
+ case "cursor":
1218
+ return [".cursor/"];
1219
+ case "gemini":
1220
+ return [".gemini/"];
1221
+ case "opencode":
1222
+ return [".opencode/"];
1223
+ case "codex":
1224
+ return ["AGENTS.md"];
1225
+ default:
1226
+ return [];
1227
+ }
1228
+ }
1229
+ /**
1230
+ * Plan 015c / §5.7 — reconcile `projectedTo` instead of only appending.
1231
+ *
1232
+ * `recordProjectedTo()` appends and is never told when a projection *path*
1233
+ * changes (e.g. the ADR 0016 workflow slug rename from
1234
+ * `.cline/workflows/implement-feature-or-fix.md` to
1235
+ * `.cline/workflows/workflow-implement.md`). The obsolete-projection cleanup
1236
+ * iterates `lockfile.projections`, which no longer contains the legacy path, so
1237
+ * the stale pointer in `files[canonical].projectedTo` survived forever and
1238
+ * `agents doctor` warned "Missing projection ... Re-run: agents add ... --fanout"
1239
+ * — a remediation that provably cannot clear it.
1240
+ *
1241
+ * For every canonical this run actually produced projections for, drop the
1242
+ * entries inside this run's namespace that the current plan did not produce.
1243
+ * Entries for other hosts and for other bundles survive untouched.
1244
+ */
1245
+ reconcileProjectedTo(lockfile, host, bundleName, producedByCanonical) {
1246
+ const prefixes = _InstallEngine.projectionNamespacePrefixes(host, bundleName);
1247
+ if (prefixes.length === 0 || producedByCanonical.size === 0) return;
1248
+ for (const [canonical, producedPaths] of producedByCanonical) {
1249
+ const posixKey = canonical.replace(/\\/g, "/");
1250
+ const sysKey = canonical.replace(/\//g, path5.sep);
1251
+ const targetKey = lockfile.files[posixKey] ? posixKey : lockfile.files[sysKey] ? sysKey : null;
1252
+ if (!targetKey) continue;
1253
+ const asset = lockfile.files[targetKey];
1254
+ if (!asset.projectedTo || asset.projectedTo.length === 0) continue;
1255
+ const produced = new Set(producedPaths.map((p) => this.toPosix(p)));
1256
+ const kept = asset.projectedTo.filter(
1257
+ (p) => !(prefixes.some((prefix) => p.startsWith(prefix)) && !produced.has(p))
1258
+ );
1259
+ if (kept.length === asset.projectedTo.length) continue;
1260
+ if (kept.length === 0) {
1261
+ delete asset.projectedTo;
1262
+ } else {
1263
+ asset.projectedTo = kept;
1264
+ }
1265
+ }
1266
+ }
1057
1267
  async removeEmptyProjectionDirs(workspaceRoot, projPath) {
1058
1268
  let dir = path5.dirname(path5.join(workspaceRoot, projPath));
1059
1269
  while (dir !== workspaceRoot && dir.startsWith(workspaceRoot)) {
@@ -1067,6 +1277,97 @@ var InstallEngine = class _InstallEngine {
1067
1277
  dir = path5.dirname(dir);
1068
1278
  }
1069
1279
  }
1280
+ // ADR 0016: Silent auto-migration of legacy .agents/workflows/*.md into
1281
+ // .agents/skills/workflow-<name>/SKILL.md, synchronizing lockfiles and pruning empty dirs.
1282
+ async migrateLegacyWorkspaceWorkflows(targetDir, lockfile) {
1283
+ const subPaths = AgentHostAdapter.getSubPaths(targetDir);
1284
+ let migratedCount = 0;
1285
+ let targetLockfile = lockfile;
1286
+ let lockfileLoadedFromDisk = false;
1287
+ if (!targetLockfile && await fs3.pathExists(subPaths.lockfile)) {
1288
+ try {
1289
+ targetLockfile = await fs3.readJson(subPaths.lockfile);
1290
+ lockfileLoadedFromDisk = true;
1291
+ } catch {
1292
+ }
1293
+ }
1294
+ if (await fs3.pathExists(subPaths.workflowsDir)) {
1295
+ const entries = await fs3.readdir(subPaths.workflowsDir).catch(() => []);
1296
+ for (const entry of entries) {
1297
+ if (entry.endsWith(".md")) {
1298
+ const legacyPath = path5.join(subPaths.workflowsDir, entry);
1299
+ let skillName = entry.replace(/\.md$/, "").replace(/--/g, "-");
1300
+ if (!skillName.startsWith("workflow-")) {
1301
+ skillName = `workflow-${skillName}`;
1302
+ }
1303
+ const targetSkillDir = path5.join(subPaths.skillsDir, skillName);
1304
+ const targetSkillFile = path5.join(targetSkillDir, "SKILL.md");
1305
+ if (!await fs3.pathExists(targetSkillFile)) {
1306
+ await fs3.ensureDir(targetSkillDir);
1307
+ const legacyContent = await fs3.readFile(legacyPath, "utf8");
1308
+ let skillContent = legacyContent;
1309
+ const fmMatch = legacyContent.match(/^---\r?\n([\s\S]+?)\r?\n---/);
1310
+ if (fmMatch) {
1311
+ try {
1312
+ const meta = YAML2.parse(fmMatch[1]) || {};
1313
+ meta.name = skillName;
1314
+ if (!meta.metadata) {
1315
+ meta.metadata = {
1316
+ author: "Agents United",
1317
+ version: "1.0.0",
1318
+ icon: "\u{1F504}"
1319
+ };
1320
+ }
1321
+ const rest = legacyContent.replace(/^---\r?\n[\s\S]+?\r?\n---/, "");
1322
+ skillContent = `---
1323
+ ${YAML2.stringify(meta).trim()}
1324
+ ---${rest}`;
1325
+ } catch {
1326
+ }
1327
+ }
1328
+ await fs3.writeFile(targetSkillFile, skillContent, "utf8");
1329
+ }
1330
+ await fs3.remove(legacyPath).catch(() => {
1331
+ });
1332
+ migratedCount++;
1333
+ if (targetLockfile) {
1334
+ const legacyRel = this.toPosix(path5.relative(targetDir, legacyPath));
1335
+ const newRel = this.toPosix(path5.relative(targetDir, targetSkillFile));
1336
+ if (targetLockfile.files && targetLockfile.files[legacyRel]) {
1337
+ targetLockfile.files[newRel] = targetLockfile.files[legacyRel];
1338
+ delete targetLockfile.files[legacyRel];
1339
+ }
1340
+ if (targetLockfile.installed && targetLockfile.installed.skills) {
1341
+ if (!targetLockfile.installed.skills.includes(skillName)) {
1342
+ targetLockfile.installed.skills.push(skillName);
1343
+ }
1344
+ }
1345
+ }
1346
+ }
1347
+ }
1348
+ const remaining = await fs3.readdir(subPaths.workflowsDir).catch(() => []);
1349
+ if (remaining.length === 0) {
1350
+ await fs3.remove(subPaths.workflowsDir).catch(() => {
1351
+ });
1352
+ }
1353
+ }
1354
+ if (targetLockfile && targetLockfile.installed && targetLockfile.installed.workflows && targetLockfile.installed.workflows.length > 0) {
1355
+ for (const w of targetLockfile.installed.workflows) {
1356
+ let skillName = w.replace(/\.md$/, "").replace(/--/g, "-");
1357
+ if (!skillName.startsWith("workflow-")) {
1358
+ skillName = `workflow-${skillName}`;
1359
+ }
1360
+ if (targetLockfile.installed.skills && !targetLockfile.installed.skills.includes(skillName)) {
1361
+ targetLockfile.installed.skills.push(skillName);
1362
+ }
1363
+ }
1364
+ targetLockfile.installed.workflows = [];
1365
+ }
1366
+ if (targetLockfile && (lockfileLoadedFromDisk || await fs3.pathExists(subPaths.lockfile))) {
1367
+ await fs3.writeJson(subPaths.lockfile, targetLockfile, { spaces: 2 });
1368
+ }
1369
+ return migratedCount;
1370
+ }
1070
1371
  /**
1071
1372
  * Dry-run: compute the projection plan (paths + warnings) without writing anything.
1072
1373
  */
@@ -1206,6 +1507,17 @@ var InstallEngine = class _InstallEngine {
1206
1507
  this.recordProjectedTo(lockfile, artifact.canonical, artifact.relPath);
1207
1508
  }
1208
1509
  }
1510
+ const producedByCanonical = /* @__PURE__ */ new Map();
1511
+ for (const artifact of artifacts) {
1512
+ if (!artifact.canonical) continue;
1513
+ const producedPaths = producedByCanonical.get(artifact.canonical);
1514
+ if (producedPaths) {
1515
+ producedPaths.push(artifact.relPath);
1516
+ } else {
1517
+ producedByCanonical.set(artifact.canonical, [artifact.relPath]);
1518
+ }
1519
+ }
1520
+ this.reconcileProjectedTo(lockfile, "cline", bundleDef.name, producedByCanonical);
1209
1521
  if (bundleDef.parentBundle) {
1210
1522
  const parentDef = await this.registry.getBundle(bundleDef.parentBundle);
1211
1523
  if (parentDef) {
@@ -1249,6 +1561,10 @@ var InstallEngine = class _InstallEngine {
1249
1561
  const res = HostProjector.projectAgent(content, HOST_REGISTRY[host].profile, canonicalRel);
1250
1562
  const projName = host === "cline" ? `${agentFile.replace(/\.md$/i, "").replace(/^subagent-/, "")}.yml` : agentFile;
1251
1563
  const dest = path5.join(base, subdir, projName);
1564
+ const projPath = this.toPosix(path5.relative(root, dest));
1565
+ if (host === "cline" && lockfile.projections?.[projPath]?.kind === "role") {
1566
+ continue;
1567
+ }
1252
1568
  if (await fs3.pathExists(dest) && !options.force) {
1253
1569
  const existing = await fs3.readFile(dest, "utf8");
1254
1570
  if (!HostProjector.hasManagedMarker(existing)) {
@@ -1258,9 +1574,20 @@ var InstallEngine = class _InstallEngine {
1258
1574
  }
1259
1575
  }
1260
1576
  await this.deployProjection(dest, res.content);
1261
- const projPath = this.toPosix(path5.relative(root, dest));
1262
1577
  projections.push({ host, path: projPath, kind: "role", warnings: res.warnings });
1263
1578
  this.recordProjectedTo(lockfile, this.lockRel("agents", agentFile), projPath);
1579
+ if (host === "cline") {
1580
+ lockfile.projections = lockfile.projections || {};
1581
+ lockfile.projections[projPath] = {
1582
+ host,
1583
+ kind: "role",
1584
+ canonical: canonicalRel,
1585
+ owners: resolved.targetBundle ? [resolved.targetBundle] : [],
1586
+ hash: await this.calculateHash(dest),
1587
+ installedAt: lockfile.projections[projPath]?.installedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
1588
+ managedMarker: true
1589
+ };
1590
+ }
1264
1591
  }
1265
1592
  }
1266
1593
  }
@@ -1295,9 +1622,12 @@ var InstallEngine = class _InstallEngine {
1295
1622
  const subPaths = AgentHostAdapter.getSubPaths(targetDir);
1296
1623
  await fs3.ensureDir(subPaths.agentsDir);
1297
1624
  await fs3.ensureDir(subPaths.skillsDir);
1298
- await fs3.ensureDir(subPaths.workflowsDir);
1625
+ if (resolved.workflows && resolved.workflows.length > 0) {
1626
+ await fs3.ensureDir(subPaths.workflowsDir);
1627
+ }
1299
1628
  await fs3.ensureDir(subPaths.rulesDir);
1300
1629
  const lockfile = await this.readLockfile(subPaths.lockfile);
1630
+ await this.migrateLegacyWorkspaceWorkflows(targetDir, lockfile);
1301
1631
  lockfile.scope = scope;
1302
1632
  lockfile.method = method;
1303
1633
  lockfile.hosts = hosts;
@@ -1387,6 +1717,7 @@ var InstallEngine = class _InstallEngine {
1387
1717
  installedAt: existing?.installedAt ?? now,
1388
1718
  ...existing?.projectedTo ? { projectedTo: existing.projectedTo } : {}
1389
1719
  };
1720
+ lockfile.installed.workflows = lockfile.installed.workflows || [];
1390
1721
  if (!lockfile.installed.workflows.includes(workflowFile)) {
1391
1722
  lockfile.installed.workflows.push(workflowFile);
1392
1723
  }
@@ -1673,7 +2004,9 @@ var UninstallEngine = class {
1673
2004
  }
1674
2005
  lockfile.installed.agents = lockfile.installed.agents.filter((a) => survival.has(`agents/${a}`));
1675
2006
  lockfile.installed.skills = lockfile.installed.skills.filter((s) => survival.has(`skills/${s}/SKILL.md`));
1676
- lockfile.installed.workflows = lockfile.installed.workflows.filter((w) => survival.has(`workflows/${w}`));
2007
+ if (lockfile.installed.workflows) {
2008
+ lockfile.installed.workflows = lockfile.installed.workflows.filter((w) => survival.has(`workflows/${w}`));
2009
+ }
1677
2010
  await this.refreshParentCoordination(bundleName, workspaceRoot, lockfile, scope);
1678
2011
  await fs4.writeJson(subPaths.lockfile, lockfile, { spaces: 2 });
1679
2012
  } else {
@@ -2175,7 +2508,8 @@ var UpdateEngine = class {
2175
2508
  // src/core/doctor.ts
2176
2509
  import path10 from "path";
2177
2510
  import fs8 from "fs-extra";
2178
- import YAML2 from "yaml";
2511
+ import crypto4 from "crypto";
2512
+ import YAML3 from "yaml";
2179
2513
 
2180
2514
  // src/core/cline-capabilities.ts
2181
2515
  import path9 from "path";
@@ -2377,6 +2711,56 @@ var DoctorEngine = class {
2377
2711
  }
2378
2712
  return HostProjector.hasManagedMarker(content);
2379
2713
  }
2714
+ /**
2715
+ * ADR 0017 — re-render the compound projections owned by the installed bundles so
2716
+ * doctor can compare what is on disk with what the current renderer produces.
2717
+ *
2718
+ * Returns projection path -> acceptable content variants, or `null` when the registry
2719
+ * is unavailable (the freshness check is then skipped rather than guessed).
2720
+ *
2721
+ * Two variants are produced per path on purpose: the coordinator rule and team manifest
2722
+ * legitimately render either with or without the installed-bundle addon exclusions
2723
+ * (installer primary path vs parent-bundle refresh path). Matching *either* means the
2724
+ * projection is fresh, which keeps the check false-positive free while still catching
2725
+ * content that matches neither.
2726
+ */
2727
+ static async renderProjectionVariants(owners, installedBundles) {
2728
+ if (owners.size === 0) return null;
2729
+ let resolver;
2730
+ try {
2731
+ resolver = new RegistryResolver();
2732
+ await resolver.loadBundles();
2733
+ } catch {
2734
+ return null;
2735
+ }
2736
+ const registryDir = resolver.getRegistryDir();
2737
+ const variants = /* @__PURE__ */ new Map();
2738
+ for (const owner of owners) {
2739
+ try {
2740
+ const bundleDef = await resolver.getBundle(owner);
2741
+ if (!bundleDef) continue;
2742
+ const resolved = await resolver.resolve(bundleDef.name);
2743
+ for (const excludeAddons of [void 0, installedBundles]) {
2744
+ const artifacts = await ClineProjector.planCompoundProjection(
2745
+ bundleDef,
2746
+ "project",
2747
+ resolved,
2748
+ registryDir,
2749
+ excludeAddons
2750
+ );
2751
+ for (const artifact of artifacts) {
2752
+ if (artifact.content === void 0) continue;
2753
+ const list = variants.get(artifact.relPath) ?? [];
2754
+ if (!list.includes(artifact.content)) list.push(artifact.content);
2755
+ variants.set(artifact.relPath, list);
2756
+ }
2757
+ }
2758
+ } catch {
2759
+ continue;
2760
+ }
2761
+ }
2762
+ return variants;
2763
+ }
2380
2764
  static async runDoctor(targetDir, host) {
2381
2765
  const root = AgentHostAdapter.resolveHostDir("project", "agents", targetDir);
2382
2766
  const subPaths = AgentHostAdapter.getSubPaths(root);
@@ -2396,7 +2780,9 @@ var DoctorEngine = class {
2396
2780
  manifest = parsed;
2397
2781
  agentsCount = parsed.installed?.agents?.length || 0;
2398
2782
  skillsCount = parsed.installed?.skills?.length || 0;
2399
- workflowsCount = parsed.installed?.workflows?.length || 0;
2783
+ const legacyWorkflows = parsed.installed?.workflows?.length || 0;
2784
+ const workflowSkillCount = (parsed.installed?.skills || []).filter((s) => String(s).startsWith("workflow-")).length;
2785
+ workflowsCount = legacyWorkflows + workflowSkillCount;
2400
2786
  isInitialized = true;
2401
2787
  } catch (err) {
2402
2788
  issues.push(`Corrupt lockfile at ${subPaths.lockfile}: ${err.message}`);
@@ -2414,7 +2800,7 @@ var DoctorEngine = class {
2414
2800
  warnings.push(`Agent ${file} is missing YAML frontmatter.`);
2415
2801
  } else {
2416
2802
  try {
2417
- const meta = YAML2.parse(frontmatterMatch[1]);
2803
+ const meta = YAML3.parse(frontmatterMatch[1]);
2418
2804
  if (!meta.name) issues.push(`Agent ${file} missing 'name' in frontmatter.`);
2419
2805
  if (!meta.description) warnings.push(`Agent ${file} missing 'description'.`);
2420
2806
  if (!meta.model) warnings.push(`Agent ${file} missing 'model' definition.`);
@@ -2425,6 +2811,12 @@ var DoctorEngine = class {
2425
2811
  }
2426
2812
  }
2427
2813
  }
2814
+ if (await fs8.pathExists(subPaths.workflowsDir)) {
2815
+ const remainingWorkflowFiles = (await fs8.readdir(subPaths.workflowsDir)).filter((f) => f.endsWith(".md"));
2816
+ if (remainingWorkflowFiles.length > 0) {
2817
+ warnings.push(`Detected ${remainingWorkflowFiles.length} legacy workflows in ${subPaths.workflowsDir}. Run 'agents update' to automatically migrate them to modern skills.`);
2818
+ }
2819
+ }
2428
2820
  if (manifest) {
2429
2821
  const workspaceRoot = path10.resolve(path10.dirname(root));
2430
2822
  for (const [relPath, assetMeta] of Object.entries(manifest.files)) {
@@ -2433,9 +2825,24 @@ var DoctorEngine = class {
2433
2825
  for (const projPath of projectedTo) {
2434
2826
  const absProjection = path10.join(workspaceRoot, projPath);
2435
2827
  if (!await fs8.pathExists(absProjection)) {
2436
- warnings.push(
2437
- `Missing projection ${projPath} for canonical ${relPath}. Re-run: agents add ... --fanout`
2438
- );
2828
+ let superseding = null;
2829
+ for (const [projRelPath, proj] of Object.entries(manifest.projections ?? {})) {
2830
+ if (projRelPath === projPath) continue;
2831
+ if (proj.canonical !== relPath) continue;
2832
+ if (!await fs8.pathExists(path10.join(workspaceRoot, projRelPath))) continue;
2833
+ superseding = { relPath: projRelPath, host: proj.host, owners: proj.owners ?? [] };
2834
+ break;
2835
+ }
2836
+ if (superseding) {
2837
+ const owner = superseding.owners[0];
2838
+ warnings.push(
2839
+ `Stale projection ${projPath} for canonical ${relPath} (superseded by ${superseding.relPath}).` + (owner ? ` Run: agents update ${owner} --fanout ${superseding.host} to reconcile.` : "")
2840
+ );
2841
+ } else {
2842
+ warnings.push(
2843
+ `Missing projection ${projPath} for canonical ${relPath}. Re-run: agents add ... --fanout`
2844
+ );
2845
+ }
2439
2846
  continue;
2440
2847
  }
2441
2848
  const managed = await this.isManagedProjection(absProjection, projPath === "AGENTS.md");
@@ -2459,6 +2866,41 @@ var DoctorEngine = class {
2459
2866
  }
2460
2867
  }
2461
2868
  }
2869
+ if (manifest.projections && manifest.installed) {
2870
+ const ownerNames = /* @__PURE__ */ new Set();
2871
+ for (const proj of Object.values(manifest.projections)) {
2872
+ for (const owner of proj.owners) ownerNames.add(owner);
2873
+ }
2874
+ const expectedVariants = await this.renderProjectionVariants(ownerNames, manifest.installed.bundles ?? []);
2875
+ if (expectedVariants) {
2876
+ for (const [projRelPath, proj] of Object.entries(manifest.projections)) {
2877
+ const absPath = path10.join(workspaceRoot, projRelPath);
2878
+ if (!await fs8.pathExists(absPath)) continue;
2879
+ if (!proj.managedMarker) continue;
2880
+ const content = await fs8.readFile(absPath, "utf8");
2881
+ if (!HostProjector.hasManagedMarker(content)) continue;
2882
+ if (proj.hash) {
2883
+ const diskHash = `sha256:${crypto4.createHash("sha256").update(await fs8.readFile(absPath)).digest("hex")}`;
2884
+ if (diskHash !== proj.hash) {
2885
+ const owner = proj.owners[0];
2886
+ warnings.push(
2887
+ `Content drift ${projRelPath} \u2014 edited after installation (recorded ${proj.hash.slice(0, 16)}\u2026, on disk ${diskHash.slice(0, 16)}\u2026).` + (owner ? ` Run: agents update ${owner} --fanout ${proj.host} to restore it.` : "")
2888
+ );
2889
+ continue;
2890
+ }
2891
+ }
2892
+ const variants = expectedVariants.get(projRelPath);
2893
+ if (!variants || variants.length === 0) continue;
2894
+ const onDisk = content.replace(/\r\n/g, "\n");
2895
+ if (!variants.some((variant) => variant.replace(/\r\n/g, "\n") === onDisk)) {
2896
+ const owner = proj.owners[0];
2897
+ warnings.push(
2898
+ `Outdated projection ${projRelPath} (content differs from the current render).` + (owner ? ` Run: agents update ${owner} --fanout ${proj.host} to refresh it.` : "")
2899
+ );
2900
+ }
2901
+ }
2902
+ }
2903
+ }
2462
2904
  const installedBundles = manifest.installed?.bundles ?? [];
2463
2905
  const fileOwnersOf = (rec) => rec.owners ?? (rec.bundle ? [rec.bundle] : []);
2464
2906
  if (manifest.projections) {
@@ -2508,7 +2950,7 @@ var DoctorEngine = class {
2508
2950
  // src/core/cline-launcher.ts
2509
2951
  import path11 from "path";
2510
2952
  import os3 from "os";
2511
- import crypto4 from "crypto";
2953
+ import crypto5 from "crypto";
2512
2954
  import fs9 from "fs-extra";
2513
2955
  var ClineLauncher = class _ClineLauncher {
2514
2956
  probe;
@@ -2522,7 +2964,7 @@ var ClineLauncher = class _ClineLauncher {
2522
2964
  */
2523
2965
  static generateTeamName(bundleName, workspace) {
2524
2966
  const sanitizedBundle = bundleName.replace(/[^A-Za-z0-9_-]/g, "-");
2525
- const hash = crypto4.createHash("sha256").update(path11.resolve(workspace)).digest("hex").slice(0, 8);
2967
+ const hash = crypto5.createHash("sha256").update(path11.resolve(workspace)).digest("hex").slice(0, 8);
2526
2968
  const prefix = `au-${sanitizedBundle}`;
2527
2969
  const maxPrefixLen = 64 - 9;
2528
2970
  const truncatedPrefix = prefix.slice(0, maxPrefixLen);
@@ -3633,7 +4075,7 @@ var BUNDLE_DISPLAY_NAMES = {
3633
4075
  },
3634
4076
  "full": {
3635
4077
  title: "All-in-One Autonomous Department",
3636
- summary: "Complete suite with all 7 team leads, 38 agents, and all skills & workflows"
4078
+ summary: "Complete suite with all 7 team leads, 38 agents, and all 160 modular skills & workflows"
3637
4079
  }
3638
4080
  };
3639
4081
  cli.command("add [identifier]", "Add a bundle, agent, skill, or workflow to project or global configuration").option("-g, --global", "Install globally into home directory (~/.agents/)").option("-s, --symlink", "Create symbolic links to central registry cache (default / recommended)").option("--copy", "Create independent standalone copies of asset files").option("-t, --target <hosts>", "Which assistants to set up (agents = main library; claude, cursor, cline, opencode, codex get translated copies)", { default: "agents" }).option("--fanout <hosts>", "Also make translated copies for these assistants: claude, cursor, cline, opencode, codex").option("--mode <mode>", "Execution mode for organization bundles (operational | brainstorming)", { default: "operational" }).option("--allow-missing-prereqs", "Proceed with installation even if some prerequisites are missing").option("--allow-under-construction", "Allow installation of bundles marked as under construction").option("-y, --yes", "Skip confirmation prompts").option("-f, --force", "Force overwrite user modified files").option("--start", "Start the installed team in Cline immediately after setup").option("--dry-run", "Simulate installation without writing files").action(async (targetIdentifier, options = {}) => {
@@ -4400,7 +4842,7 @@ function renderBundleDetailTree(bundle) {
4400
4842
  if (bundle.name === "full") {
4401
4843
  const lines2 = [];
4402
4844
  lines2.push(`\u{1F4E6} ${pc.bold(pc.green("full"))} ${pc.cyan("(Universal Autonomous Department)")} ${pc.green("\u2B50 [Recommended]")}`);
4403
- lines2.push(`\u2502 ${pc.white("Complete suite with all 7 lead orchestrators, 38 subagents, 90 skills, and 63 workflows.")}`);
4845
+ lines2.push(`\u2502 ${pc.white("Complete suite with all 7 lead orchestrators, 38 subagents, and 160 modular skills (91 domain skills + 69 workflow playbooks).")}`);
4404
4846
  lines2.push(`\u2502`);
4405
4847
  lines2.push(`\u251C\u2500\u2500 \u{1F916} Lead Orchestrators (7 department domains):`);
4406
4848
  lines2.push(`\u2502 \u251C\u2500\u2500 \u{1F6E0}\uFE0F ${pc.blue("orchestrator-engineering")} ${pc.dim("(Software Engineering & Delivery)")}`);
@@ -4411,8 +4853,8 @@ function renderBundleDetailTree(bundle) {
4411
4853
  lines2.push(`\u2502 \u251C\u2500\u2500 \u{1F52C} ${pc.blue("orchestrator-research")} ${pc.dim("(Deep Technical Research)")}`);
4412
4854
  lines2.push(`\u2502 \u2514\u2500\u2500 \u{1F4BC} ${pc.blue("orchestrator-business")} ${pc.dim("(Business Strategy & Economics)")}`);
4413
4855
  lines2.push(`\u251C\u2500\u2500 \u{1F916} Specialized Sub-Agents: ${pc.blue("38 worker agents across all 8 departments")}`);
4414
- lines2.push(`\u251C\u2500\u2500 \u26A1 Skills: ${pc.yellow("90 modular skills & runbooks")}`);
4415
- lines2.push(`\u251C\u2500\u2500 \u{1F504} Workflows: ${pc.magenta("63 guided multi-step workflows")}`);
4856
+ lines2.push(`\u251C\u2500\u2500 \u26A1 Skills: ${pc.yellow("91 modular domain skills & runbooks")}`);
4857
+ lines2.push(`\u251C\u2500\u2500 \u{1F504} Workflows: ${pc.magenta("69 guided multi-step workflow playbooks")}`);
4416
4858
  lines2.push(`\u251C\u2500\u2500 \u{1F50C} Prerequisites: ${pc.dim("None (Self-contained universal suite)")}`);
4417
4859
  lines2.push(`\u2514\u2500\u2500 \u{1F4A1} Execution Modes: ${pc.green("Operational")}`);
4418
4860
  return lines2.join("\n");
@@ -4457,27 +4899,34 @@ function renderBundleDetailTree(bundle) {
4457
4899
  } else {
4458
4900
  lines.push(`\u251C\u2500\u2500 \u{1F916} Sub-agents: ${pc.dim("None")}`);
4459
4901
  }
4460
- if (bundle.skills && bundle.skills.length > 0) {
4461
- lines.push(`\u251C\u2500\u2500 \u26A1 Skills (${bundle.skills.length}):`);
4462
- if (bundle.skills.length <= 5) {
4463
- lines.push(`\u2502 \u2514\u2500\u2500 ${pc.yellow(bundle.skills.join(", "))}`);
4902
+ const domainSkills = (bundle.skills || []).filter((s) => !s.startsWith("workflow-"));
4903
+ const workflowSkills = [
4904
+ ...(bundle.skills || []).filter((s) => s.startsWith("workflow-")),
4905
+ ...bundle.workflows || []
4906
+ ];
4907
+ if (domainSkills.length > 0) {
4908
+ lines.push(`\u251C\u2500\u2500 \u26A1 Skills (${domainSkills.length}):`);
4909
+ if (domainSkills.length <= 5) {
4910
+ lines.push(`\u2502 \u2514\u2500\u2500 ${pc.yellow(domainSkills.join(", "))}`);
4464
4911
  } else {
4465
- lines.push(`\u2502 \u251C\u2500\u2500 ${pc.yellow(bundle.skills.slice(0, 5).join(", "))}`);
4466
- lines.push(`\u2502 \u2514\u2500\u2500 ${pc.dim(`(+${bundle.skills.length - 5} more: ${bundle.skills.slice(5).join(", ")})`)}`);
4912
+ lines.push(`\u2502 \u251C\u2500\u2500 ${pc.yellow(domainSkills.slice(0, 5).join(", "))}`);
4913
+ lines.push(`\u2502 \u2514\u2500\u2500 ${pc.dim(`(+${domainSkills.length - 5} more: ${domainSkills.slice(5).join(", ")})`)}`);
4467
4914
  }
4468
- } else {
4915
+ } else if (!bundle.parentBundle && workflowSkills.length === 0) {
4916
+ lines.push(`\u251C\u2500\u2500 \u26A1 Skills: ${pc.dim("None")}`);
4917
+ } else if (bundle.parentBundle && domainSkills.length === 0) {
4469
4918
  lines.push(`\u251C\u2500\u2500 \u26A1 Skills: ${pc.dim("Inherited from base bundle")}`);
4470
4919
  }
4471
- if (bundle.workflows && bundle.workflows.length > 0) {
4472
- const wfNames = bundle.workflows.map((w) => w.replace(/^workflow-/, "").replace(/\.md$/, ""));
4473
- lines.push(`\u251C\u2500\u2500 \u{1F504} Workflows (${bundle.workflows.length}):`);
4920
+ if (workflowSkills.length > 0) {
4921
+ const wfNames = workflowSkills.map((w) => w.replace(/^workflow-/, "").replace(/\.md$/, ""));
4922
+ lines.push(`\u251C\u2500\u2500 \u{1F504} Workflows (${workflowSkills.length}):`);
4474
4923
  if (wfNames.length <= 4) {
4475
4924
  lines.push(`\u2502 \u2514\u2500\u2500 ${pc.magenta(wfNames.join(", "))}`);
4476
4925
  } else {
4477
4926
  lines.push(`\u2502 \u251C\u2500\u2500 ${pc.magenta(wfNames.slice(0, 4).join(", "))}`);
4478
4927
  lines.push(`\u2502 \u2514\u2500\u2500 ${pc.dim(`(+${wfNames.length - 4} more: ${wfNames.slice(4).join(", ")})`)}`);
4479
4928
  }
4480
- } else {
4929
+ } else if (bundle.parentBundle) {
4481
4930
  lines.push(`\u251C\u2500\u2500 \u{1F504} Workflows: ${pc.dim("Inherited from base bundle")}`);
4482
4931
  }
4483
4932
  if (bundle.prerequisites) {
@@ -4569,15 +5018,20 @@ ${pc.bold(pc.magenta(header))} ${pc.dim(`(${items.length} bundle${items.length >
4569
5018
  const displaySubs = subNames.length > 3 ? `${subNames.slice(0, 3).join(", ")} (+${subNames.length - 3} more)` : subNames.join(", ");
4570
5019
  console.log(`${subIndent}\u251C\u2500\u2500 \u{1F916} Sub-agents: ${pc.blue(displaySubs)}`);
4571
5020
  }
4572
- if (b.skills && b.skills.length > 0) {
4573
- const displaySkills = b.skills.length > 3 ? `${b.skills.slice(0, 3).join(", ")} (+${b.skills.length - 3} more)` : b.skills.join(", ");
5021
+ const domainSkills = (b.skills || []).filter((s) => !s.startsWith("workflow-"));
5022
+ const workflowSkills = [
5023
+ ...(b.skills || []).filter((s) => s.startsWith("workflow-")),
5024
+ ...b.workflows || []
5025
+ ];
5026
+ if (domainSkills.length > 0) {
5027
+ const displaySkills = domainSkills.length > 3 ? `${domainSkills.slice(0, 3).join(", ")} (+${domainSkills.length - 3} more)` : domainSkills.join(", ");
4574
5028
  console.log(`${subIndent}\u251C\u2500\u2500 \u26A1 Skills: ${pc.yellow(displaySkills)}`);
4575
5029
  }
4576
- if (b.workflows && b.workflows.length > 0) {
4577
- const wfNames = b.workflows.map((w) => w.replace(/^workflow-/, "").replace(/\.md$/, ""));
5030
+ if (workflowSkills.length > 0) {
5031
+ const wfNames = workflowSkills.map((w) => w.replace(/^workflow-/, "").replace(/\.md$/, ""));
4578
5032
  const displayWfs = wfNames.length > 3 ? `${wfNames.slice(0, 3).join(", ")} (+${wfNames.length - 3} more)` : wfNames.join(", ");
4579
5033
  console.log(`${subIndent}\u2514\u2500\u2500 \u{1F504} Workflows: ${pc.magenta(displayWfs)}`);
4580
- } else {
5034
+ } else if (b.parentBundle) {
4581
5035
  console.log(`${subIndent}\u2514\u2500\u2500 \u{1F504} Workflows: ${pc.dim("Inherited from parent")}`);
4582
5036
  }
4583
5037
  if (!isLastBundle) {
@@ -4611,12 +5065,17 @@ ${pc.bold(pc.cyan("\u{1F3E2} Organization Bundles (Experimental / Cross-Functio
4611
5065
  const displaySubs = subNames.length > 3 ? `${subNames.slice(0, 3).join(", ")} (+${subNames.length - 3} more)` : subNames.join(", ");
4612
5066
  console.log(`${subIndent}\u251C\u2500\u2500 \u{1F916} Sub-agents: ${pc.blue(displaySubs)}`);
4613
5067
  }
4614
- if (b.skills && b.skills.length > 0) {
4615
- const displaySkills = b.skills.length > 3 ? `${b.skills.slice(0, 3).join(", ")} (+${b.skills.length - 3} more)` : b.skills.join(", ");
5068
+ const orgDomainSkills = (b.skills || []).filter((s) => !s.startsWith("workflow-"));
5069
+ const orgWorkflowSkills = [
5070
+ ...(b.skills || []).filter((s) => s.startsWith("workflow-")),
5071
+ ...b.workflows || []
5072
+ ];
5073
+ if (orgDomainSkills.length > 0) {
5074
+ const displaySkills = orgDomainSkills.length > 3 ? `${orgDomainSkills.slice(0, 3).join(", ")} (+${orgDomainSkills.length - 3} more)` : orgDomainSkills.join(", ");
4616
5075
  console.log(`${subIndent}\u251C\u2500\u2500 \u26A1 Skills: ${pc.yellow(displaySkills)}`);
4617
5076
  }
4618
- if (b.workflows && b.workflows.length > 0) {
4619
- const wfNames = b.workflows.map((w) => w.replace(/^workflow-/, "").replace(/\.md$/, ""));
5077
+ if (orgWorkflowSkills.length > 0) {
5078
+ const wfNames = orgWorkflowSkills.map((w) => w.replace(/^workflow-/, "").replace(/\.md$/, ""));
4620
5079
  const displayWfs = wfNames.length > 3 ? `${wfNames.slice(0, 3).join(", ")} (+${wfNames.length - 3} more)` : wfNames.join(", ");
4621
5080
  console.log(`${subIndent}\u251C\u2500\u2500 \u{1F504} Workflows: ${pc.magenta(displayWfs)}`);
4622
5081
  }
@@ -5163,7 +5622,7 @@ cli.command("doctor", "Verify health of installed agents, frontmatter schemas, a
5163
5622
  }
5164
5623
  console.log(` \u{1F916} Installed Agents: ${pc.bold(report.agentsCount.toString())}`);
5165
5624
  console.log(` \u26A1 Installed Skills: ${pc.bold(report.skillsCount.toString())}`);
5166
- console.log(` \u{1F504} Installed Workflows: ${pc.bold(report.workflowsCount.toString())}
5625
+ console.log(` \u{1F504} Installed Workflow Skills: ${pc.bold(report.workflowsCount.toString())}
5167
5626
  `);
5168
5627
  if (report.clineCapability) {
5169
5628
  console.log(pc.bold(pc.cyan("Cline Runtime & Native Discovery Audit:")));