@haus-tech/haus-workflow 1.5.5 → 1.5.8
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 +14 -0
- package/dist/cli.js +89 -23
- package/library/catalog/manifest.json +13 -13
- package/library/catalog/validation-rules.json +0 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.5.8](https://github.com/WeAreHausTech/haus-workflow/compare/v1.5.7...v1.5.8) (2026-08-12)
|
|
4
|
+
|
|
5
|
+
## [1.5.7](https://github.com/WeAreHausTech/haus-workflow/compare/v1.5.6...v1.5.7) (2026-08-12)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- **catalog:** un-gate platform words android/swift ([#271](https://github.com/WeAreHausTech/haus-workflow/issues/271)) ([#273](https://github.com/WeAreHausTech/haus-workflow/issues/273)) ([b6c1734](https://github.com/WeAreHausTech/haus-workflow/commit/b6c17343c48b32dbd72938b952a947e42bc9bb91)), closes [BP#1](https://github.com/WeAreHausTech/BP/issues/1)
|
|
10
|
+
|
|
11
|
+
## [1.5.6](https://github.com/WeAreHausTech/haus-workflow/compare/v1.5.5...v1.5.6) (2026-08-12)
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
- cross-repo manifest validator parity (--include vs catalog) ([#269](https://github.com/WeAreHausTech/haus-workflow/issues/269)) ([84269e6](https://github.com/WeAreHausTech/haus-workflow/commit/84269e67ab5e5cb28efdfaaea537c1d2d1459c08)), closes [haus-workflow-catalog#76](https://github.com/WeAreHausTech/haus-workflow-catalog/issues/76) [#227](https://github.com/WeAreHausTech/haus-workflow/issues/227) [#228](https://github.com/WeAreHausTech/haus-workflow/issues/228) [#227](https://github.com/WeAreHausTech/haus-workflow/issues/227) [#227](https://github.com/WeAreHausTech/haus-workflow/issues/227) [#228](https://github.com/WeAreHausTech/haus-workflow/issues/228)
|
|
16
|
+
|
|
3
17
|
## [1.5.5](https://github.com/WeAreHausTech/haus-workflow/compare/v1.5.4...v1.5.5) (2026-08-11)
|
|
4
18
|
|
|
5
19
|
### Bug Fixes
|
package/dist/cli.js
CHANGED
|
@@ -693,10 +693,17 @@ function validateReferences(itemId, references) {
|
|
|
693
693
|
if (references === void 0) return null;
|
|
694
694
|
if (!isStringArray(references)) return `${itemId}: references must be a string array`;
|
|
695
695
|
for (const ref of references) {
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
696
|
+
let parsed;
|
|
697
|
+
try {
|
|
698
|
+
parsed = new URL(ref);
|
|
699
|
+
} catch {
|
|
700
|
+
return `${itemId}: reference is not a valid URL: ${ref}`;
|
|
701
|
+
}
|
|
702
|
+
if (parsed.protocol === "http:") {
|
|
703
|
+
return `${itemId}: reference uses insecure http:// URL: ${ref}`;
|
|
704
|
+
}
|
|
705
|
+
if (parsed.protocol !== "https:") {
|
|
706
|
+
return `${itemId}: reference must be https:// URL: ${ref}`;
|
|
700
707
|
}
|
|
701
708
|
}
|
|
702
709
|
return null;
|
|
@@ -751,16 +758,29 @@ function validateCuratedProvenance(item) {
|
|
|
751
758
|
if (!RISK_LEVELS.has(item.riskLevel)) {
|
|
752
759
|
return `${item.id}: invalid riskLevel "${item.riskLevel}"`;
|
|
753
760
|
}
|
|
754
|
-
if (
|
|
761
|
+
if (!isNonEmptyString(item.originSourceId)) {
|
|
762
|
+
return `${item.id}: curated item missing originSourceId`;
|
|
763
|
+
}
|
|
764
|
+
if (!isNonEmptyString(item.originUrl)) {
|
|
765
|
+
return `${item.id}: curated item missing originUrl`;
|
|
766
|
+
}
|
|
767
|
+
if (!isNonEmptyString(item.useMode)) {
|
|
768
|
+
return `${item.id}: curated item missing useMode`;
|
|
769
|
+
}
|
|
770
|
+
if (!USE_MODES.has(item.useMode)) {
|
|
755
771
|
return `${item.id}: invalid useMode "${item.useMode}"`;
|
|
756
772
|
}
|
|
757
|
-
if (
|
|
773
|
+
if (!isNonEmptyString(item.license)) {
|
|
774
|
+
return `${item.id}: curated item missing license`;
|
|
775
|
+
}
|
|
776
|
+
if (!isNonEmptyString(item.licenseConfidence)) {
|
|
777
|
+
return `${item.id}: curated item missing licenseConfidence`;
|
|
778
|
+
}
|
|
779
|
+
if (!LICENSE_CONFIDENCES.has(item.licenseConfidence)) {
|
|
758
780
|
return `${item.id}: invalid licenseConfidence "${item.licenseConfidence}"`;
|
|
759
781
|
}
|
|
760
|
-
if (item.originUrl !==
|
|
761
|
-
|
|
762
|
-
return `${item.id}: originUrl must be an https:// URL`;
|
|
763
|
-
}
|
|
782
|
+
if (typeof item.originUrl !== "string" || !item.originUrl.startsWith("https://")) {
|
|
783
|
+
return `${item.id}: originUrl must be an https:// URL`;
|
|
764
784
|
}
|
|
765
785
|
return null;
|
|
766
786
|
}
|
|
@@ -782,9 +802,6 @@ function isRequiresAnyClause(value) {
|
|
|
782
802
|
if (!REQUIRES_ANY_KEYS.includes(key)) return false;
|
|
783
803
|
return typeof value[key] === "string";
|
|
784
804
|
}
|
|
785
|
-
function isRequiresAnyArray(value) {
|
|
786
|
-
return Array.isArray(value) && value.every(isRequiresAnyClause);
|
|
787
|
-
}
|
|
788
805
|
function safeParse(json) {
|
|
789
806
|
return JSON.parse(json, (key, value) => {
|
|
790
807
|
if (POLLUTION_KEYS.has(key)) return void 0;
|
|
@@ -811,6 +828,7 @@ function parseManifest(json) {
|
|
|
811
828
|
const items = [];
|
|
812
829
|
const seenIds = /* @__PURE__ */ new Set();
|
|
813
830
|
const seenPaths = /* @__PURE__ */ new Set();
|
|
831
|
+
const warnings = [];
|
|
814
832
|
for (let i = 0; i < root.items.length; i++) {
|
|
815
833
|
const raw = root.items[i];
|
|
816
834
|
if (!raw || typeof raw !== "object") {
|
|
@@ -845,8 +863,21 @@ function parseManifest(json) {
|
|
|
845
863
|
if (!isStringArray2(item.repoRoles)) {
|
|
846
864
|
return { ok: false, error: `${item.id}: repoRoles must be a string array` };
|
|
847
865
|
}
|
|
848
|
-
if (item.requiresAny !== void 0
|
|
849
|
-
|
|
866
|
+
if (item.requiresAny !== void 0) {
|
|
867
|
+
if (!Array.isArray(item.requiresAny)) {
|
|
868
|
+
return { ok: false, error: `${item.id}: requiresAny must be an array of clause objects` };
|
|
869
|
+
}
|
|
870
|
+
const kept = [];
|
|
871
|
+
for (const clause of item.requiresAny) {
|
|
872
|
+
if (isRequiresAnyClause(clause)) {
|
|
873
|
+
kept.push(clause);
|
|
874
|
+
} else {
|
|
875
|
+
warnings.push(
|
|
876
|
+
`${item.id}: dropping unrecognized requiresAny clause (catalog schema evolved ahead of this CLI version) \u2014 ${JSON.stringify(clause)}`
|
|
877
|
+
);
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
item.requiresAny = kept;
|
|
850
881
|
}
|
|
851
882
|
if (typeof item.tokenEstimate !== "number" || !Number.isFinite(item.tokenEstimate)) {
|
|
852
883
|
return { ok: false, error: `${item.id}: tokenEstimate must be a finite number` };
|
|
@@ -863,7 +894,7 @@ function parseManifest(json) {
|
|
|
863
894
|
if (formerIdFailures.length > 0) {
|
|
864
895
|
return { ok: false, error: formerIdFailures[0] };
|
|
865
896
|
}
|
|
866
|
-
return { ok: true, manifest: { version: root.version, items } };
|
|
897
|
+
return { ok: true, manifest: { version: root.version, items }, warnings };
|
|
867
898
|
}
|
|
868
899
|
|
|
869
900
|
// src/catalog/remote-catalog/manifest.ts
|
|
@@ -876,6 +907,7 @@ async function fetchRemoteManifest() {
|
|
|
876
907
|
warn(`Remote manifest failed schema validation: ${parsed.error}`);
|
|
877
908
|
return null;
|
|
878
909
|
}
|
|
910
|
+
for (const warning of parsed.warnings) warn(warning);
|
|
879
911
|
if (!parsed.manifest.items.length) return null;
|
|
880
912
|
return parsed.manifest;
|
|
881
913
|
}
|
|
@@ -912,8 +944,6 @@ var validation_rules_default = {
|
|
|
912
944
|
"java",
|
|
913
945
|
"spring",
|
|
914
946
|
"kotlin",
|
|
915
|
-
"swift",
|
|
916
|
-
"android",
|
|
917
947
|
"flutter",
|
|
918
948
|
"dart",
|
|
919
949
|
"c++",
|
|
@@ -1135,6 +1165,16 @@ function extractUseWhenSection(text) {
|
|
|
1135
1165
|
const next = tail.search(/\n##\s+/);
|
|
1136
1166
|
return next < 0 ? tail : tail.slice(0, next);
|
|
1137
1167
|
}
|
|
1168
|
+
function indentedContinuationLines(lines, idx) {
|
|
1169
|
+
const out = [];
|
|
1170
|
+
for (let j = idx + 1; j < lines.length; j++) {
|
|
1171
|
+
const line2 = lines[j];
|
|
1172
|
+
if (line2.trim() === "") continue;
|
|
1173
|
+
if (!/^\s+\S/.test(line2)) break;
|
|
1174
|
+
out.push(line2.trim());
|
|
1175
|
+
}
|
|
1176
|
+
return out;
|
|
1177
|
+
}
|
|
1138
1178
|
function isYamlBlockScalarHeader(rest) {
|
|
1139
1179
|
return /^[>|][-+]?(\d+)?(?:\s+#.*)?$/.test(rest);
|
|
1140
1180
|
}
|
|
@@ -1148,7 +1188,7 @@ function extractFrontmatterValue(text, key) {
|
|
|
1148
1188
|
const rest = lines[idx].replace(keyRe, "").trim();
|
|
1149
1189
|
if (!rest) return "";
|
|
1150
1190
|
if (!isYamlBlockScalarHeader(rest)) {
|
|
1151
|
-
return rest.replace(/^["']|["']$/g, "").trim();
|
|
1191
|
+
return [rest, ...indentedContinuationLines(lines, idx)].join(" ").replace(/\s+/g, " ").replace(/^["']|["']$/g, "").trim();
|
|
1152
1192
|
}
|
|
1153
1193
|
const body = [];
|
|
1154
1194
|
for (let j = idx + 1; j < lines.length; j++) {
|
|
@@ -1160,11 +1200,20 @@ function extractFrontmatterValue(text, key) {
|
|
|
1160
1200
|
}
|
|
1161
1201
|
return body.join(" ").replace(/\s+/g, " ").trim();
|
|
1162
1202
|
}
|
|
1163
|
-
function
|
|
1164
|
-
|
|
1203
|
+
function frontmatterDescriptionRegion(text) {
|
|
1204
|
+
const m = text.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
1205
|
+
if (!m) return "";
|
|
1206
|
+
const lines = m[1].split(/\r?\n/);
|
|
1207
|
+
const idx = lines.findIndex((l) => /^description:[ \t]*/.test(l));
|
|
1208
|
+
if (idx < 0) return "";
|
|
1209
|
+
const region = [
|
|
1210
|
+
lines[idx].replace(/^description:[ \t]*/, ""),
|
|
1211
|
+
...indentedContinuationLines(lines, idx)
|
|
1212
|
+
];
|
|
1213
|
+
return region.join(" ").replace(/\s+/g, " ").trim();
|
|
1165
1214
|
}
|
|
1166
1215
|
function auditForbiddenTagsInText(text, label) {
|
|
1167
|
-
const body = `${
|
|
1216
|
+
const body = `${frontmatterDescriptionRegion(text)}
|
|
1168
1217
|
${extractUseWhenSection(text)}`;
|
|
1169
1218
|
if (!body.trim()) return [];
|
|
1170
1219
|
const failures = [];
|
|
@@ -7137,11 +7186,28 @@ import fs33 from "fs-extra";
|
|
|
7137
7186
|
// src/recommender/git-signal.ts
|
|
7138
7187
|
init_exec();
|
|
7139
7188
|
async function runGitLines(root, args) {
|
|
7189
|
+
const started = Date.now();
|
|
7140
7190
|
try {
|
|
7141
7191
|
const result = await runGit(args, { cwd: root, timeout: 3e3 });
|
|
7192
|
+
if (process.env.HAUS_DEBUG_GITSIG) {
|
|
7193
|
+
const { appendFileSync } = await import("node:fs");
|
|
7194
|
+
appendFileSync(
|
|
7195
|
+
process.env.HAUS_DEBUG_GITSIG,
|
|
7196
|
+
`GITSIG ok git ${args.join(" ")} cwd=${root} ms=${Date.now() - started} exit=${result.exitCode} stdout=${JSON.stringify(result.stdout.slice(0, 200))} stderr=${JSON.stringify(result.stderr.slice(0, 200))}
|
|
7197
|
+
`
|
|
7198
|
+
);
|
|
7199
|
+
}
|
|
7142
7200
|
if (result.exitCode !== 0) return [];
|
|
7143
7201
|
return result.stdout.split("\n").map((x) => x.trim()).filter(Boolean);
|
|
7144
|
-
} catch {
|
|
7202
|
+
} catch (err) {
|
|
7203
|
+
if (process.env.HAUS_DEBUG_GITSIG) {
|
|
7204
|
+
const { appendFileSync } = await import("node:fs");
|
|
7205
|
+
appendFileSync(
|
|
7206
|
+
process.env.HAUS_DEBUG_GITSIG,
|
|
7207
|
+
`GITSIG threw git ${args.join(" ")} cwd=${root} ms=${Date.now() - started} err=${JSON.stringify(String(err).slice(0, 300))}
|
|
7208
|
+
`
|
|
7209
|
+
);
|
|
7210
|
+
}
|
|
7145
7211
|
return [];
|
|
7146
7212
|
}
|
|
7147
7213
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "4.
|
|
2
|
+
"version": "4.4.0",
|
|
3
3
|
"items": [
|
|
4
4
|
{
|
|
5
5
|
"id": "haus.agentic-workflow-standard",
|
|
@@ -365,7 +365,7 @@
|
|
|
365
365
|
"useMode": "copy",
|
|
366
366
|
"license": "MIT",
|
|
367
367
|
"licenseConfidence": "high",
|
|
368
|
-
"originSourceId": "ecc",
|
|
368
|
+
"originSourceId": "ecc-affaanm",
|
|
369
369
|
"originUrl": "https://github.com/affaan-m/ECC/blob/ec92b528471df708c2384ebbcc82b390b60f535a/skills/csharp-testing/SKILL.md",
|
|
370
370
|
"pinnedRef": "ec92b528471df708c2384ebbcc82b390b60f535a",
|
|
371
371
|
"ecosystem": "dotnet",
|
|
@@ -466,7 +466,7 @@
|
|
|
466
466
|
"useMode": "copy",
|
|
467
467
|
"license": "MIT",
|
|
468
468
|
"licenseConfidence": "high",
|
|
469
|
-
"originSourceId": "ecc",
|
|
469
|
+
"originSourceId": "ecc-affaanm",
|
|
470
470
|
"originUrl": "https://github.com/affaan-m/ECC/blob/71d22d0a77b7e0684f4e51cba03749b788993cdb/skills/dotnet-patterns/SKILL.md",
|
|
471
471
|
"pinnedRef": "71d22d0a77b7e0684f4e51cba03749b788993cdb",
|
|
472
472
|
"ecosystem": "dotnet",
|
|
@@ -531,7 +531,7 @@
|
|
|
531
531
|
"useMode": "copy",
|
|
532
532
|
"license": "MIT",
|
|
533
533
|
"licenseConfidence": "high",
|
|
534
|
-
"originSourceId": "ecc",
|
|
534
|
+
"originSourceId": "ecc-affaanm",
|
|
535
535
|
"originUrl": "https://github.com/affaan-m/ECC/blob/71d22d0a77b7e0684f4e51cba03749b788993cdb/skills/e2e-testing/SKILL.md",
|
|
536
536
|
"pinnedRef": "71d22d0a77b7e0684f4e51cba03749b788993cdb",
|
|
537
537
|
"ecosystem": "playwright",
|
|
@@ -565,7 +565,7 @@
|
|
|
565
565
|
"useMode": "copy",
|
|
566
566
|
"license": "MIT",
|
|
567
567
|
"licenseConfidence": "high",
|
|
568
|
-
"originSourceId": "ecc",
|
|
568
|
+
"originSourceId": "ecc-affaanm",
|
|
569
569
|
"originUrl": "https://github.com/affaan-m/ECC/blob/ec92b528471df708c2384ebbcc82b390b60f535a/skills/frontend-patterns/SKILL.md",
|
|
570
570
|
"pinnedRef": "ec92b528471df708c2384ebbcc82b390b60f535a",
|
|
571
571
|
"ecosystem": "react",
|
|
@@ -601,7 +601,7 @@
|
|
|
601
601
|
"useMode": "copy",
|
|
602
602
|
"license": "MIT",
|
|
603
603
|
"licenseConfidence": "high",
|
|
604
|
-
"originSourceId": "ecc",
|
|
604
|
+
"originSourceId": "ecc-affaanm",
|
|
605
605
|
"originUrl": "https://github.com/affaan-m/ECC/blob/ec92b528471df708c2384ebbcc82b390b60f535a/skills/laravel-patterns/SKILL.md",
|
|
606
606
|
"pinnedRef": "ec92b528471df708c2384ebbcc82b390b60f535a",
|
|
607
607
|
"ecosystem": "laravel",
|
|
@@ -703,7 +703,7 @@
|
|
|
703
703
|
"useMode": "copy",
|
|
704
704
|
"license": "MIT",
|
|
705
705
|
"licenseConfidence": "high",
|
|
706
|
-
"originSourceId": "ecc",
|
|
706
|
+
"originSourceId": "ecc-affaanm",
|
|
707
707
|
"originUrl": "https://github.com/affaan-m/ECC/blob/ec92b528471df708c2384ebbcc82b390b60f535a/skills/laravel-plugin-discovery/SKILL.md",
|
|
708
708
|
"pinnedRef": "ec92b528471df708c2384ebbcc82b390b60f535a",
|
|
709
709
|
"ecosystem": "laravel",
|
|
@@ -774,7 +774,7 @@
|
|
|
774
774
|
"useMode": "copy",
|
|
775
775
|
"license": "MIT",
|
|
776
776
|
"licenseConfidence": "high",
|
|
777
|
-
"originSourceId": "ecc",
|
|
777
|
+
"originSourceId": "ecc-affaanm",
|
|
778
778
|
"originUrl": "https://github.com/affaan-m/ECC/blob/ec92b528471df708c2384ebbcc82b390b60f535a/skills/laravel-verification/SKILL.md",
|
|
779
779
|
"pinnedRef": "ec92b528471df708c2384ebbcc82b390b60f535a",
|
|
780
780
|
"ecosystem": "laravel",
|
|
@@ -807,7 +807,7 @@
|
|
|
807
807
|
"useMode": "copy",
|
|
808
808
|
"license": "MIT",
|
|
809
809
|
"licenseConfidence": "high",
|
|
810
|
-
"originSourceId": "ecc",
|
|
810
|
+
"originSourceId": "ecc-affaanm",
|
|
811
811
|
"originUrl": "https://github.com/affaan-m/ECC/blob/ec92b528471df708c2384ebbcc82b390b60f535a/skills/nestjs-patterns/SKILL.md",
|
|
812
812
|
"pinnedRef": "ec92b528471df708c2384ebbcc82b390b60f535a",
|
|
813
813
|
"ecosystem": "nestjs",
|
|
@@ -901,7 +901,7 @@
|
|
|
901
901
|
"useMode": "copy",
|
|
902
902
|
"license": "MIT",
|
|
903
903
|
"licenseConfidence": "high",
|
|
904
|
-
"originSourceId": "ecc",
|
|
904
|
+
"originSourceId": "ecc-affaanm",
|
|
905
905
|
"originUrl": "https://github.com/affaan-m/ECC/blob/81af40761939056ab3dc54732fd4f562a27309d0/skills/prisma-patterns/SKILL.md",
|
|
906
906
|
"pinnedRef": "81af40761939056ab3dc54732fd4f562a27309d0",
|
|
907
907
|
"ecosystem": "database",
|
|
@@ -1002,7 +1002,7 @@
|
|
|
1002
1002
|
"useMode": "copy",
|
|
1003
1003
|
"license": "MIT",
|
|
1004
1004
|
"licenseConfidence": "high",
|
|
1005
|
-
"originSourceId": "ecc",
|
|
1005
|
+
"originSourceId": "ecc-affaanm",
|
|
1006
1006
|
"originUrl": "https://github.com/affaan-m/ECC/blob/71d22d0a77b7e0684f4e51cba03749b788993cdb/skills/react-testing/SKILL.md",
|
|
1007
1007
|
"pinnedRef": "71d22d0a77b7e0684f4e51cba03749b788993cdb",
|
|
1008
1008
|
"ecosystem": "testing",
|
|
@@ -1172,7 +1172,7 @@
|
|
|
1172
1172
|
"useMode": "copy",
|
|
1173
1173
|
"license": "MIT",
|
|
1174
1174
|
"licenseConfidence": "high",
|
|
1175
|
-
"originSourceId": "ecc",
|
|
1175
|
+
"originSourceId": "ecc-affaanm",
|
|
1176
1176
|
"originUrl": "https://github.com/affaan-m/ECC/blob/ec92b528471df708c2384ebbcc82b390b60f535a/skills/vite-patterns/SKILL.md",
|
|
1177
1177
|
"pinnedRef": "ec92b528471df708c2384ebbcc82b390b60f535a",
|
|
1178
1178
|
"ecosystem": "vite",
|
|
@@ -1205,7 +1205,7 @@
|
|
|
1205
1205
|
"useMode": "copy",
|
|
1206
1206
|
"license": "MIT",
|
|
1207
1207
|
"licenseConfidence": "high",
|
|
1208
|
-
"originSourceId": "ecc",
|
|
1208
|
+
"originSourceId": "ecc-affaanm",
|
|
1209
1209
|
"originUrl": "https://github.com/affaan-m/ECC/blob/71d22d0a77b7e0684f4e51cba03749b788993cdb/skills/vue-patterns/SKILL.md",
|
|
1210
1210
|
"pinnedRef": "71d22d0a77b7e0684f4e51cba03749b788993cdb",
|
|
1211
1211
|
"ecosystem": "vue",
|