hstack 0.7.1 → 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.
Files changed (131) hide show
  1. package/CHANGELOG.md +308 -0
  2. package/README.md +90 -154
  3. package/VERSION +1 -1
  4. package/dist/commands/doctor.js +69 -9
  5. package/dist/commands/doctor.js.map +1 -1
  6. package/dist/commands/init.js +7 -3
  7. package/dist/commands/init.js.map +1 -1
  8. package/dist/commands/update.js +17 -4
  9. package/dist/commands/update.js.map +1 -1
  10. package/dist/lib/descriptions.js +160 -0
  11. package/dist/lib/descriptions.js.map +1 -0
  12. package/dist/lib/diff.js +1 -1
  13. package/dist/lib/git.js +16 -0
  14. package/dist/lib/git.js.map +1 -1
  15. package/dist/lib/wire.js +274 -142
  16. package/dist/lib/wire.js.map +1 -1
  17. package/dist/manifest.js +49 -22
  18. package/dist/manifest.js.map +1 -1
  19. package/package.json +4 -3
  20. package/template/.claude/agents/adversarial-reviewer.md +42 -98
  21. package/template/.claude/agents/app-architect.md +44 -133
  22. package/template/.claude/agents/data-architect.md +46 -127
  23. package/template/.claude/agents/test-strategist.md +39 -109
  24. package/template/.claude/skills/hstack-adr-new/SKILL.md +23 -100
  25. package/template/.claude/skills/hstack-adversarial-review/SKILL.md +47 -174
  26. package/template/.claude/skills/hstack-adversarial-review/references/finding-categories.md +134 -0
  27. package/template/.claude/skills/hstack-app-architecture/SKILL.md +43 -95
  28. package/template/.claude/skills/hstack-commit/SKILL.md +28 -97
  29. package/template/.claude/skills/hstack-data-architecture/SKILL.md +34 -82
  30. package/template/.claude/skills/hstack-promote/SKILL.md +55 -0
  31. package/template/.claude/skills/hstack-story/SKILL.md +58 -0
  32. package/template/.claude/skills/hstack-test-audit/SKILL.md +64 -0
  33. package/template/.claude/skills/hstack-wrap/SKILL.md +48 -0
  34. package/template/.claude/skills/hstack-wrap/references/pr-description.md +45 -0
  35. package/template/KERNEL.md +167 -0
  36. package/template/templates/adr.md +9 -18
  37. package/template/templates/app-architecture.md +38 -50
  38. package/template/templates/data-architecture.md +39 -93
  39. package/template/templates/infrastructure.md +54 -148
  40. package/template/templates/roadmap.md +35 -0
  41. package/template/templates/story.md +7 -13
  42. package/template/templates/tech-debt.md +2 -37
  43. package/template/templates/tech-stack.md +2 -12
  44. package/template/.claude/agents/data-specialist.md +0 -126
  45. package/template/.claude/agents/implementer.md +0 -154
  46. package/template/.claude/agents/kernel-fit-analyst.md +0 -190
  47. package/template/.claude/agents/planner.md +0 -110
  48. package/template/.claude/agents/product-discovery.md +0 -165
  49. package/template/.claude/agents/product-manager.md +0 -111
  50. package/template/.claude/agents/researcher.md +0 -123
  51. package/template/.claude/agents/security-reviewer.md +0 -123
  52. package/template/.claude/agents/spec-author.md +0 -123
  53. package/template/.claude/agents/stack-architect.md +0 -137
  54. package/template/.claude/agents/ui-ux-briefer.md +0 -105
  55. package/template/.claude/agents/verifier.md +0 -113
  56. package/template/.claude/skills/hstack-branch/SKILL.md +0 -103
  57. package/template/.claude/skills/hstack-brownfield-init/SKILL.md +0 -158
  58. package/template/.claude/skills/hstack-change-new/SKILL.md +0 -111
  59. package/template/.claude/skills/hstack-change-plan/SKILL.md +0 -119
  60. package/template/.claude/skills/hstack-configure/SKILL.md +0 -126
  61. package/template/.claude/skills/hstack-coord/SKILL.md +0 -131
  62. package/template/.claude/skills/hstack-data-review/SKILL.md +0 -132
  63. package/template/.claude/skills/hstack-finalize/SKILL.md +0 -159
  64. package/template/.claude/skills/hstack-flag/SKILL.md +0 -138
  65. package/template/.claude/skills/hstack-greenfield-init/SKILL.md +0 -175
  66. package/template/.claude/skills/hstack-help/SKILL.md +0 -179
  67. package/template/.claude/skills/hstack-implement/SKILL.md +0 -185
  68. package/template/.claude/skills/hstack-kernel-fit-promote/SKILL.md +0 -164
  69. package/template/.claude/skills/hstack-kernel-fit-scan/SKILL.md +0 -197
  70. package/template/.claude/skills/hstack-kernel-fit-triage/SKILL.md +0 -159
  71. package/template/.claude/skills/hstack-module-spec/SKILL.md +0 -105
  72. package/template/.claude/skills/hstack-product-discovery/SKILL.md +0 -101
  73. package/template/.claude/skills/hstack-research/SKILL.md +0 -145
  74. package/template/.claude/skills/hstack-scaffold/SKILL.md +0 -140
  75. package/template/.claude/skills/hstack-security-review/SKILL.md +0 -133
  76. package/template/.claude/skills/hstack-ship/SKILL.md +0 -129
  77. package/template/.claude/skills/hstack-stack-decide/SKILL.md +0 -108
  78. package/template/.claude/skills/hstack-story-draft/SKILL.md +0 -119
  79. package/template/.claude/skills/hstack-tech-debt-new/SKILL.md +0 -122
  80. package/template/.claude/skills/hstack-tech-debt-resolve/SKILL.md +0 -158
  81. package/template/.claude/skills/hstack-tech-debt-stale/SKILL.md +0 -113
  82. package/template/.claude/skills/hstack-tech-debt-wontfix/SKILL.md +0 -104
  83. package/template/.claude/skills/hstack-telemetry/SKILL.md +0 -98
  84. package/template/.claude/skills/hstack-test-plan/SKILL.md +0 -182
  85. package/template/.claude/skills/hstack-ui-brief/SKILL.md +0 -108
  86. package/template/.claude/skills/hstack-verify/SKILL.md +0 -150
  87. package/template/CLAUDE.md +0 -443
  88. package/template/scripts/coord/coord_scan.py +0 -681
  89. package/template/scripts/telemetry/__init__.py +0 -6
  90. package/template/scripts/telemetry/insights/__init__.py +0 -0
  91. package/template/scripts/telemetry/insights/contract_drift.py +0 -137
  92. package/template/scripts/telemetry/insights/kernel_fit.py +0 -438
  93. package/template/scripts/telemetry/insights/overengineering.py +0 -115
  94. package/template/scripts/telemetry/insights/quality_outcomes.py +0 -131
  95. package/template/scripts/telemetry/insights/token_economics.py +0 -129
  96. package/template/scripts/telemetry/insights/workflow_shape.py +0 -198
  97. package/template/scripts/telemetry/parsers/__init__.py +0 -0
  98. package/template/scripts/telemetry/parsers/bodies.py +0 -87
  99. package/template/scripts/telemetry/parsers/commits.py +0 -219
  100. package/template/scripts/telemetry/parsers/frontmatter.py +0 -322
  101. package/template/scripts/telemetry/parsers/transcripts.py +0 -181
  102. package/template/scripts/telemetry/render.py +0 -395
  103. package/template/scripts/telemetry/report.py +0 -138
  104. package/template/scripts/telemetry/run_kernel_fit.py +0 -91
  105. package/template/templates/adversarial-review.md +0 -54
  106. package/template/templates/bootstrap.md +0 -105
  107. package/template/templates/change-spec.md +0 -82
  108. package/template/templates/ci-cd.md +0 -27
  109. package/template/templates/coord-message.md +0 -55
  110. package/template/templates/data-review.md +0 -54
  111. package/template/templates/discovery/brainstorm.md +0 -69
  112. package/template/templates/discovery/forcing-questions.md +0 -76
  113. package/template/templates/discovery/project-brief.md +0 -53
  114. package/template/templates/figma-handoff.md +0 -38
  115. package/template/templates/glossary.md +0 -20
  116. package/template/templates/hardening-checklist.md +0 -73
  117. package/template/templates/incident-runbook.md +0 -57
  118. package/template/templates/kernel-fit-finding.md +0 -63
  119. package/template/templates/kernel-fit-flag.md +0 -52
  120. package/template/templates/module-spec.md +0 -49
  121. package/template/templates/mvp-scope.md +0 -34
  122. package/template/templates/persona.md +0 -38
  123. package/template/templates/plan.md +0 -49
  124. package/template/templates/product-brief.md +0 -56
  125. package/template/templates/security-review.md +0 -63
  126. package/template/templates/telemetry-sidecar.md +0 -184
  127. package/template/templates/test-plan.md +0 -119
  128. package/template/templates/threat-model.md +0 -54
  129. package/template/templates/ui-brief.md +0 -49
  130. package/template/templates/verification.md +0 -63
  131. package/template/templates/vision.md +0 -34
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Description-budget scanner — ADR-0011's Option F.
3
+ *
4
+ * A Skill or subagent `description` is a routing trigger, not documentation:
5
+ * it is injected into every session, unconditionally, for every installed
6
+ * Skill and subagent, whether or not anything invokes it. ADR-0011 cut the 52
7
+ * descriptions from 19,234 words to one-sentence triggers under a 40-word
8
+ * budget, and deliberately left the enforcement out of that PR — "a linter for
9
+ * a size that no file currently respects would flag 52 findings on day one,
10
+ * and the rule should be established by the rewrite before it is enforced by a
11
+ * tool". The rewrite shipped in v0.14.0. This is the tool.
12
+ *
13
+ * It scans the PACKAGE's `template/` tree, not the consumer's `hstack/`. The
14
+ * consumer's copies are framework files that `hstack update` overwrites and
15
+ * that `doctor` already diffs against the template — a budget finding there
16
+ * would be a second report of the same drift. The regression this guards
17
+ * against is one made in this repo, so this repo is where it is measured.
18
+ */
19
+ import { readFileSync, readdirSync, statSync } from "node:fs";
20
+ import { join } from "node:path";
21
+ /**
22
+ * ADR-0011: "Budget: ≤ 40 words / ~250 characters per description."
23
+ *
24
+ * Words are the budget. The character figure carries a tilde in the ADR — it
25
+ * is the size 40 words implies, not a second independent limit — so it is
26
+ * enforced at the next round number above it. Three descriptions in the
27
+ * current template sit at 253 characters inside a 29–37 word trigger; those
28
+ * are the shape the ADR asked for, not the regression it guards against.
29
+ */
30
+ export const WORD_BUDGET = 40;
31
+ export const CHAR_BUDGET = 300;
32
+ /**
33
+ * Named carve-outs. Empty since v0.17.
34
+ *
35
+ * ADR-0011 § Named carve-outs grants three, and only one ever needed a larger
36
+ * budget: `hstack-coord`, the single description that routed with no human
37
+ * typing anything — ADR-0007's hooks injected `HSTACK-COORD: N unread …` and
38
+ * the model had to invoke `check` mode on sight. v0.17 removed coord, and with
39
+ * it the only description that could argue for the exemption. The other two
40
+ * carve-outs (confusable families, status preconditions stated as triggers)
41
+ * always bought a clause rather than a budget: every file in those families is
42
+ * under 40 words.
43
+ *
44
+ * An entry here is a decision with a reason, not a snooze. Adding one means
45
+ * arguing that the description does routing work no body can do.
46
+ */
47
+ export const BUDGET_CARVE_OUTS = new Map();
48
+ /**
49
+ * Pull the `description:` value out of a frontmatter block.
50
+ *
51
+ * Deliberately not the full YAML subset `validate-spec.mjs` parses: this reads
52
+ * one known scalar out of a framework file whose shape this repo controls. It
53
+ * handles the two forms that occur — a single-line scalar (quoted or not) and
54
+ * a folded/literal block scalar — and returns null for anything else rather
55
+ * than guessing.
56
+ */
57
+ export function extractDescription(text) {
58
+ const lines = text.split("\n");
59
+ if (lines[0]?.trim() !== "---")
60
+ return null;
61
+ let end = -1;
62
+ for (let i = 1; i < lines.length; i++) {
63
+ const t = lines[i].trim();
64
+ if (t === "---" || t === "...") {
65
+ end = i;
66
+ break;
67
+ }
68
+ }
69
+ if (end === -1)
70
+ return null;
71
+ for (let i = 1; i < end; i++) {
72
+ const m = /^description:(.*)$/.exec(lines[i]);
73
+ if (!m)
74
+ continue;
75
+ const rest = m[1].trim();
76
+ if (rest === ">" || rest === "|" || /^[|>][-+]?$/.test(rest)) {
77
+ const out = [];
78
+ for (let j = i + 1; j < end; j++) {
79
+ const line = lines[j];
80
+ if (line.trim() === "") {
81
+ out.push("");
82
+ continue;
83
+ }
84
+ if (!/^\s/.test(line))
85
+ break;
86
+ out.push(line.trim());
87
+ }
88
+ return out.join(" ").trim();
89
+ }
90
+ const unquoted = rest.replace(/^(["'])([\s\S]*)\1$/, "$2");
91
+ return unquoted.trim();
92
+ }
93
+ return null;
94
+ }
95
+ export function wordCount(s) {
96
+ return s.trim().split(/\s+/).filter(Boolean).length;
97
+ }
98
+ /** Every Skill and subagent description in the package template, measured. */
99
+ export function measureDescriptions(templateDir) {
100
+ const out = [];
101
+ const push = (name, relpath, kind, abs) => {
102
+ let text;
103
+ try {
104
+ text = readFileSync(abs, "utf8");
105
+ }
106
+ catch {
107
+ return;
108
+ }
109
+ const desc = extractDescription(text);
110
+ if (desc === null)
111
+ return;
112
+ out.push({
113
+ name,
114
+ relpath,
115
+ kind,
116
+ words: wordCount(desc),
117
+ chars: desc.length,
118
+ carveOut: BUDGET_CARVE_OUTS.get(name) ?? null,
119
+ });
120
+ };
121
+ const skillsDir = join(templateDir, ".claude", "skills");
122
+ for (const entry of safeReaddir(skillsDir)) {
123
+ const abs = join(skillsDir, entry, "SKILL.md");
124
+ try {
125
+ if (!statSync(abs).isFile())
126
+ continue;
127
+ }
128
+ catch {
129
+ continue;
130
+ }
131
+ push(entry, `.claude/skills/${entry}/SKILL.md`, "skill", abs);
132
+ }
133
+ const agentsDir = join(templateDir, ".claude", "agents");
134
+ for (const entry of safeReaddir(agentsDir)) {
135
+ if (!entry.endsWith(".md"))
136
+ continue;
137
+ const name = entry.replace(/\.md$/, "");
138
+ push(name, `.claude/agents/${entry}`, "agent", join(agentsDir, entry));
139
+ }
140
+ out.sort((a, b) => b.words - a.words || a.name.localeCompare(b.name));
141
+ return out;
142
+ }
143
+ /**
144
+ * The descriptions over budget, carve-outs removed. Empty is the healthy
145
+ * state — and is what the current template produces.
146
+ */
147
+ export function descriptionsOverBudget(templateDir) {
148
+ return measureDescriptions(templateDir)
149
+ .filter((d) => d.carveOut === null && (d.words > WORD_BUDGET || d.chars > CHAR_BUDGET))
150
+ .map(({ carveOut: _carveOut, ...rest }) => rest);
151
+ }
152
+ function safeReaddir(dir) {
153
+ try {
154
+ return readdirSync(dir).sort();
155
+ }
156
+ catch {
157
+ return [];
158
+ }
159
+ }
160
+ //# sourceMappingURL=descriptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"descriptions.js","sourceRoot":"","sources":["../../src/lib/descriptions.ts"],"names":[],"mappings":"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"}
package/dist/lib/diff.js CHANGED
@@ -39,7 +39,7 @@ export async function filesEqual(a, b) {
39
39
  * Only paths under FRAMEWORK_PATHS are considered.
40
40
  *
41
41
  * `frameworkPaths` is the list of framework subpaths (relative to template root
42
- * and to consumer hstack root). Both top-level files (e.g., "CLAUDE.md") and
42
+ * and to consumer hstack root). Both top-level files (e.g., "KERNEL.md") and
43
43
  * directories (e.g., "templates/") are supported.
44
44
  */
45
45
  export async function diffFramework(templateDir, consumerHstackDir, frameworkPaths) {
package/dist/lib/git.js CHANGED
@@ -13,6 +13,22 @@ export async function findGitRoot(start) {
13
13
  dir = parent;
14
14
  }
15
15
  }
16
+ /**
17
+ * Move a repo-relative path with `git mv`, falling back to a plain rename when
18
+ * git refuses (file untracked, or no git available). Returns true when git
19
+ * recorded the rename — which is what keeps `git log --follow` working across
20
+ * the ADR-0010 kernel rename and lands the move already staged.
21
+ */
22
+ export async function gitMove(cwd, from, to) {
23
+ try {
24
+ await execa("git", ["mv", from, to], { cwd });
25
+ return true;
26
+ }
27
+ catch {
28
+ await fs.move(resolve(cwd, from), resolve(cwd, to));
29
+ return false;
30
+ }
31
+ }
16
32
  /** True if working tree has no uncommitted changes (staged or unstaged). */
17
33
  export async function isWorkingTreeClean(cwd) {
18
34
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,MAAM,UAAU,CAAC;AAE1B,uGAAuG;AACvG,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAa;IAC7C,IAAI,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACzB,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC;QAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QAChC,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,GAAW;IAClD,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QAC1E,OAAO,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,MAAM,UAAU,CAAC;AAE1B,uGAAuG;AACvG,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAa;IAC7C,IAAI,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACzB,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC;QAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QAChC,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,GAAW,EACX,IAAY,EACZ,EAAU;IAEV,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;QACpD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,GAAW;IAClD,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QAC1E,OAAO,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}