@haus-tech/haus-workflow 0.16.3 → 0.17.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.17.0](https://github.com/WeAreHausTech/haus-workflow/compare/v0.16.3...v0.17.0) (2026-06-09)
4
+
5
+ ### Features
6
+
7
+ - **catalog:** support curated superpowers skills and commands ([#80](https://github.com/WeAreHausTech/haus-workflow/issues/80)) ([2e49c80](https://github.com/WeAreHausTech/haus-workflow/commit/2e49c80d6780e8ff753536f2d4042b4ce7fa2ae8))
8
+
3
9
  ## [0.16.3](https://github.com/WeAreHausTech/haus-workflow/compare/v0.16.2...v0.16.3) (2026-06-09)
4
10
 
5
11
  ### Bug Fixes
package/dist/cli.js CHANGED
@@ -137,7 +137,7 @@ async function syncRemoteCatalog() {
137
137
  let unchanged = 0;
138
138
  const failed = [];
139
139
  for (const item of items) {
140
- if (item.type !== "skill" && item.type !== "agent" && item.type !== "template" || !item.path)
140
+ if (item.type !== "skill" && item.type !== "agent" && item.type !== "template" && item.type !== "command" || !item.path)
141
141
  continue;
142
142
  if (!isSafeCatalogPath(item.path)) {
143
143
  warn(`Skipping ${item.id}: invalid path "${item.path}"`);
@@ -1240,7 +1240,7 @@ async function writeClaudeFiles(root, dryRun, selectedIds, opts = {}) {
1240
1240
  }
1241
1241
  }
1242
1242
  const sourcePath = catalogItemContentPath(contentRoot, manifestItem);
1243
- const target = item.type === "agent" ? "agents" : item.type === "template" ? "templates" : "skills";
1243
+ const target = item.type === "agent" ? "agents" : item.type === "template" ? "templates" : item.type === "command" ? "commands" : "skills";
1244
1244
  const destination = claudePath(root, target, path12.basename(sourcePath));
1245
1245
  if (await fs10.pathExists(sourcePath)) {
1246
1246
  if (dryRun) {
@@ -1549,7 +1549,8 @@ var validation_rules_default = {
1549
1549
  "baseline",
1550
1550
  "project-instructions"
1551
1551
  ],
1552
- patternTagSuffixes: ["-patterns"]
1552
+ patternTagSuffixes: ["-patterns"],
1553
+ skillSectionExemptSources: ["curated"]
1553
1554
  };
1554
1555
 
1555
1556
  // src/catalog/validation-rules.ts
@@ -1557,6 +1558,10 @@ var toRegExp = (r) => new RegExp(r.source, r.flags);
1557
1558
  var FORBIDDEN_TAGS = validation_rules_default.forbiddenTags;
1558
1559
  var BANNED_AGENT_PHRASES = validation_rules_default.bannedAgentPhrases;
1559
1560
  var REQUIRED_SKILL_SECTIONS = validation_rules_default.requiredSkillSections;
1561
+ var SKILL_SECTION_EXEMPT_SOURCES = validation_rules_default.skillSectionExemptSources;
1562
+ function isVerbatimSuperpowersMarkdownPath(rel) {
1563
+ return rel.replace(/\\/g, "/").includes("/superpowers/");
1564
+ }
1560
1565
  var REQUIRED_AGENT_SECTIONS = validation_rules_default.requiredAgentSections;
1561
1566
  var RISKY_INSTALL_PATTERNS = validation_rules_default.riskyInstallPatterns.map(toRegExp);
1562
1567
  var ALLOWED_NPX_PATTERN = toRegExp(validation_rules_default.allowedNpxPattern);
@@ -4130,7 +4135,7 @@ function auditManifestStructure(items) {
4130
4135
  } else {
4131
4136
  seenIds.set(item.id, i);
4132
4137
  }
4133
- if (item.type === "skill" || item.type === "agent" || item.type === "template") {
4138
+ if (item.type === "skill" || item.type === "agent" || item.type === "template" || item.type === "command") {
4134
4139
  if (!item.path) {
4135
4140
  failures.push(`${item.id}: missing path`);
4136
4141
  } else {
@@ -4168,8 +4173,11 @@ function auditShippedFiles(manifestDir, items) {
4168
4173
  continue;
4169
4174
  }
4170
4175
  const text = fs18.readFileSync(skillMd, "utf8");
4171
- for (const section of REQUIRED_SKILL_SECTIONS) {
4172
- if (!text.includes(section)) failures.push(`${item.id}: SKILL.md missing ${section}`);
4176
+ const skillSectionExempt = SKILL_SECTION_EXEMPT_SOURCES.includes(item.source) && item.whenToUse && item.whenNotToUse;
4177
+ if (!skillSectionExempt) {
4178
+ for (const section of REQUIRED_SKILL_SECTIONS) {
4179
+ if (!text.includes(section)) failures.push(`${item.id}: SKILL.md missing ${section}`);
4180
+ }
4173
4181
  }
4174
4182
  failures.push(
4175
4183
  ...auditForbiddenTagsInText(text, `${item.id}: ${path26.relative(manifestDir, skillMd)}`)
@@ -4198,6 +4206,12 @@ function auditShippedFiles(manifestDir, items) {
4198
4206
  continue;
4199
4207
  }
4200
4208
  failures.push(...auditTemplateContent(manifestDir, absPath, item.id));
4209
+ } else if (item.type === "command") {
4210
+ if (!fs18.existsSync(absPath)) {
4211
+ failures.push(`${item.id}: missing command file ${item.path}`);
4212
+ continue;
4213
+ }
4214
+ failures.push(...auditTemplateContent(manifestDir, absPath, item.id));
4201
4215
  }
4202
4216
  }
4203
4217
  return failures;
@@ -4224,13 +4238,14 @@ function auditTemplateContent(manifestDir, absPath, itemId) {
4224
4238
  }
4225
4239
  function auditMarkdownContent(manifestDir) {
4226
4240
  const failures = [];
4227
- const dirs = ["skills", "agents", "templates"];
4241
+ const dirs = ["skills", "agents", "templates", "commands"];
4228
4242
  for (const dir of dirs) {
4229
4243
  const abs = path26.join(manifestDir, dir);
4230
4244
  if (!fs18.existsSync(abs)) continue;
4231
4245
  walkMd(abs, (file) => {
4232
4246
  const text = fs18.readFileSync(file, "utf8");
4233
4247
  const rel = path26.relative(manifestDir, file);
4248
+ if (isVerbatimSuperpowersMarkdownPath(rel)) return;
4234
4249
  const lines = text.split(/\r?\n/);
4235
4250
  for (let i = 0; i < lines.length; i++) {
4236
4251
  const line2 = lines[i] ?? "";
@@ -142,5 +142,6 @@
142
142
  "baseline",
143
143
  "project-instructions"
144
144
  ],
145
- "patternTagSuffixes": ["-patterns"]
145
+ "patternTagSuffixes": ["-patterns"],
146
+ "skillSectionExemptSources": ["curated"]
146
147
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haus-tech/haus-workflow",
3
- "version": "0.16.3",
3
+ "version": "0.17.0",
4
4
  "description": "Haus AI workflow CLI for Claude Code.",
5
5
  "type": "module",
6
6
  "bin": {