forgehive 0.7.5 → 0.7.7
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/README.md +47 -8
- package/dist/cli.js +30 -10
- package/docs/superpowers/plans/2026-05-11-nextgen-v04-v05.md +1708 -0
- package/docs/superpowers/plans/2026-05-11-v05-nextgen-gaps.md +2364 -0
- package/docs/superpowers/plans/2026-05-14-sprint-planner-v2.md +1058 -0
- package/docs/superpowers/plans/2026-05-14-v07-nextgen.md +1980 -0
- package/docs/user-guide.md +337 -0
- package/forgehive/commands/fh-docs.md +16 -6
- package/forgehive/commands/full-party.md +9 -4
- package/package.json +21 -6
package/README.md
CHANGED
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
<p align="center">
|
|
15
15
|
<img src="https://img.shields.io/badge/node-%3E%3D18-brightgreen" alt="Node.js ≥ 18">
|
|
16
16
|
<img src="https://img.shields.io/badge/typescript-5.8-blue" alt="TypeScript">
|
|
17
|
-
<img src="https://img.shields.io/badge/tests-
|
|
18
|
-
<img src="https://img.shields.io/badge/bundle-
|
|
17
|
+
<img src="https://img.shields.io/badge/tests-273%20passing-success" alt="273 tests">
|
|
18
|
+
<img src="https://img.shields.io/badge/bundle-259KB-lightgrey" alt="259KB bundle">
|
|
19
19
|
<img src="https://img.shields.io/badge/license-MIT-green" alt="MIT">
|
|
20
20
|
</p>
|
|
21
21
|
|
|
@@ -45,9 +45,9 @@ Claude loses all project knowledge between sessions. forgehive solves this by wr
|
|
|
45
45
|
|
|
46
46
|
---
|
|
47
47
|
|
|
48
|
-
## Status: v0.7 — Stable
|
|
48
|
+
## Status: v0.7.5 — Stable
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
273 passing tests back the commands listed below. The v0.7 feature set has been validated end-to-end.
|
|
51
51
|
|
|
52
52
|
**Stable — use with confidence:**
|
|
53
53
|
|
|
@@ -93,6 +93,15 @@ If you run into issues, please open an issue on GitHub. The most valuable feedba
|
|
|
93
93
|
|
|
94
94
|
---
|
|
95
95
|
|
|
96
|
+
## Documentation
|
|
97
|
+
|
|
98
|
+
| Document | Description |
|
|
99
|
+
|---|---|
|
|
100
|
+
| [User Guide](docs/user-guide.md) | Installation, quick start, all commands with examples, troubleshooting |
|
|
101
|
+
| [TUTORIAL.md](TUTORIAL.md) | Step-by-step walkthrough of a real session |
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
96
105
|
## Installation
|
|
97
106
|
|
|
98
107
|
### From npm (recommended)
|
|
@@ -109,14 +118,14 @@ This makes both `fh` and `forgehive` available globally.
|
|
|
109
118
|
git clone https://github.com/matharnica/forgehive
|
|
110
119
|
cd forgehive
|
|
111
120
|
npm install
|
|
112
|
-
npm run build # compiles to dist/cli.js (~
|
|
121
|
+
npm run build # compiles to dist/cli.js (~259 KB)
|
|
113
122
|
npm link # makes 'fh' available globally
|
|
114
123
|
```
|
|
115
124
|
|
|
116
125
|
Verify the installation:
|
|
117
126
|
|
|
118
127
|
```bash
|
|
119
|
-
fh --version # should print 0.7.
|
|
128
|
+
fh --version # should print 0.7.5
|
|
120
129
|
fh --help # lists all available commands
|
|
121
130
|
```
|
|
122
131
|
|
|
@@ -332,6 +341,23 @@ Parses conventional commits (`feat:`, `fix:`, `chore:`, `docs:`, etc.) and group
|
|
|
332
341
|
|
|
333
342
|
---
|
|
334
343
|
|
|
344
|
+
### Docs
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
fh docs # list existing documentation
|
|
348
|
+
fh docs user [--output path] # generate user guide → docs/user-guide.md
|
|
349
|
+
fh docs api [--output path] # generate API reference → docs/api.md
|
|
350
|
+
fh docs onboard [--output path] # generate onboarding doc → ONBOARDING.md
|
|
351
|
+
fh docs changelog [--since tag] [--output path] # generate changelog → CHANGELOG.md
|
|
352
|
+
fh docs adr "<title>" # create Architecture Decision Record
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Generates documentation from your project's stack, memory, and git history. Each subcommand writes to a default path inside `docs/` (created if missing) or to the path given via `--output`. `fh docs user` and `fh docs api` write to `docs/user-guide.md` and `docs/api.md` respectively. `fh docs adr` creates a numbered ADR file in `.forgehive/memory/adrs/`.
|
|
356
|
+
|
|
357
|
+
> `fh docs onboard` and `fh onboard` both generate onboarding documentation — they share the same generator. `fh docs onboard` allows specifying a custom `--output` path; `fh onboard` writes to stdout by default.
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
335
361
|
### Developer Metrics
|
|
336
362
|
|
|
337
363
|
```bash
|
|
@@ -847,9 +873,9 @@ Global credential store (chmod 600). Managed exclusively via `fh mcp auth` comma
|
|
|
847
873
|
|---|---|
|
|
848
874
|
| Runtime | Node.js ≥ 18, ESM |
|
|
849
875
|
| Language | TypeScript |
|
|
850
|
-
| Build | esbuild -> `dist/cli.js` (~
|
|
876
|
+
| Build | esbuild -> `dist/cli.js` (~259 KB, single bundle) |
|
|
851
877
|
| Type check | `tsc --noEmit` |
|
|
852
|
-
| Tests | `node:test` (native) + tsx ESM loader,
|
|
878
|
+
| Tests | `node:test` (native) + tsx ESM loader, 273 tests |
|
|
853
879
|
| Dependencies | `js-yaml` (sole runtime dependency) |
|
|
854
880
|
|
|
855
881
|
```bash
|
|
@@ -860,6 +886,19 @@ npm test # node --import tsx/esm --test test/*.test.ts
|
|
|
860
886
|
|
|
861
887
|
---
|
|
862
888
|
|
|
889
|
+
## Changelog
|
|
890
|
+
|
|
891
|
+
| Version | What's new |
|
|
892
|
+
|---|---|
|
|
893
|
+
| **0.7.5** | `fh --version` reads from `package.json` (no longer hardcoded) |
|
|
894
|
+
| **0.7.4** | Party slash commands installed by `fh init` (`/party`, `/review-party`, `/design-party`, `/full-party`, `/security-party`) |
|
|
895
|
+
| **0.7.3** | User Docs generation (`fh docs user`, `fh docs api`, `fh docs list`) |
|
|
896
|
+
| **0.7.2** | `fh --help`, `fh init --force`, `fh story sprint`, `fh velocity show` fixes |
|
|
897
|
+
| **0.7.1** | Story Cards, Epics, Velocity tracking |
|
|
898
|
+
| **0.7.0** | CI, Map, Onboard, Changelog, Metrics, Sync, Background agents |
|
|
899
|
+
|
|
900
|
+
---
|
|
901
|
+
|
|
863
902
|
## License
|
|
864
903
|
|
|
865
904
|
MIT
|
package/dist/cli.js
CHANGED
|
@@ -6460,7 +6460,7 @@ import fs30 from "node:fs";
|
|
|
6460
6460
|
import path31 from "node:path";
|
|
6461
6461
|
import { spawnSync as spawnSync11 } from "node:child_process";
|
|
6462
6462
|
var SOURCE_EXTS = [".ts", ".tsx", ".js", ".jsx", ".py", ".go"];
|
|
6463
|
-
var IGNORE_DIRS3 = ["node_modules", ".git", "dist", ".forgehive", "coverage", ".next", "build", "test"];
|
|
6463
|
+
var IGNORE_DIRS3 = ["node_modules", ".git", "dist", ".forgehive", "coverage", ".next", "build", "test", "__tests__", "spec"];
|
|
6464
6464
|
var EXPORT_PATTERNS = [
|
|
6465
6465
|
/^export\s+(?:async\s+)?function\s+(\w+)/gm,
|
|
6466
6466
|
/^export\s+(?:const|let|var)\s+(\w+)/gm,
|
|
@@ -6476,6 +6476,27 @@ function readCapabilities2(forgehiveDir2) {
|
|
|
6476
6476
|
return {};
|
|
6477
6477
|
}
|
|
6478
6478
|
}
|
|
6479
|
+
function extractCapabilityInfo(caps) {
|
|
6480
|
+
if (typeof caps.language === "string") {
|
|
6481
|
+
return {
|
|
6482
|
+
language: caps.language,
|
|
6483
|
+
packageManager: typeof caps.packageManager === "string" ? caps.packageManager : void 0,
|
|
6484
|
+
entryPoints: Array.isArray(caps.entryPoints) ? caps.entryPoints : void 0
|
|
6485
|
+
};
|
|
6486
|
+
}
|
|
6487
|
+
const confirmed = caps.capabilities?.confirmed ?? [];
|
|
6488
|
+
const ids = confirmed.map((c) => c.id ?? "").filter(Boolean);
|
|
6489
|
+
let language;
|
|
6490
|
+
if (ids.includes("typescript")) language = "typescript";
|
|
6491
|
+
else if (ids.includes("javascript")) language = "javascript";
|
|
6492
|
+
else if (ids.includes("python")) language = "python";
|
|
6493
|
+
else if (ids.includes("go")) language = "go";
|
|
6494
|
+
let packageManager;
|
|
6495
|
+
if (ids.includes("pnpm")) packageManager = "pnpm";
|
|
6496
|
+
else if (ids.includes("yarn")) packageManager = "yarn";
|
|
6497
|
+
else if (ids.includes("npm")) packageManager = "npm";
|
|
6498
|
+
return { language, packageManager };
|
|
6499
|
+
}
|
|
6479
6500
|
function readMemoryFiles2(forgehiveDir2) {
|
|
6480
6501
|
const memDir = path31.join(forgehiveDir2, "memory");
|
|
6481
6502
|
if (!fs30.existsSync(memDir)) return {};
|
|
@@ -6518,6 +6539,7 @@ function walkSourceFiles(dir) {
|
|
|
6518
6539
|
function generateUserGuide(projectRoot2, forgehiveDir2) {
|
|
6519
6540
|
const projectName = path31.basename(projectRoot2);
|
|
6520
6541
|
const caps = readCapabilities2(forgehiveDir2);
|
|
6542
|
+
const { language: lang, packageManager, entryPoints } = extractCapabilityInfo(caps);
|
|
6521
6543
|
const memFiles = readMemoryFiles2(forgehiveDir2);
|
|
6522
6544
|
const commits = getRecentCommits2(projectRoot2);
|
|
6523
6545
|
const lines = [];
|
|
@@ -6528,16 +6550,15 @@ function generateUserGuide(projectRoot2, forgehiveDir2) {
|
|
|
6528
6550
|
lines.push("## Overview");
|
|
6529
6551
|
lines.push("");
|
|
6530
6552
|
if (memFiles["project.md"]) {
|
|
6531
|
-
const content = memFiles["project.md"].replace(/^---[\s\S]*?---\n
|
|
6553
|
+
const content = memFiles["project.md"].replace(/^---[\s\S]*?---\n/, "").trim();
|
|
6532
6554
|
lines.push(content);
|
|
6533
6555
|
} else {
|
|
6534
|
-
lines.push(`${projectName} is a ${
|
|
6556
|
+
lines.push(`${projectName} is a ${lang ?? "software"} application.`);
|
|
6535
6557
|
}
|
|
6536
6558
|
lines.push("");
|
|
6537
6559
|
lines.push("## Requirements");
|
|
6538
6560
|
lines.push("");
|
|
6539
|
-
const pm =
|
|
6540
|
-
const lang = caps.language;
|
|
6561
|
+
const pm = packageManager ?? "npm";
|
|
6541
6562
|
if (lang === "typescript" || lang === "javascript") {
|
|
6542
6563
|
lines.push("- **Node.js** \u2265 18");
|
|
6543
6564
|
lines.push(`- **${pm}** (package manager)`);
|
|
@@ -6564,7 +6585,6 @@ function generateUserGuide(projectRoot2, forgehiveDir2) {
|
|
|
6564
6585
|
}
|
|
6565
6586
|
lines.push("```");
|
|
6566
6587
|
lines.push("");
|
|
6567
|
-
const entryPoints = caps.entryPoints;
|
|
6568
6588
|
if (Array.isArray(entryPoints) && entryPoints.length > 0) {
|
|
6569
6589
|
lines.push("## Getting Started");
|
|
6570
6590
|
lines.push("");
|
|
@@ -6576,7 +6596,7 @@ function generateUserGuide(projectRoot2, forgehiveDir2) {
|
|
|
6576
6596
|
if (memFiles["stack.md"]) {
|
|
6577
6597
|
lines.push("## Configuration");
|
|
6578
6598
|
lines.push("");
|
|
6579
|
-
const content = memFiles["stack.md"].replace(/^---[\s\S]*?---\n
|
|
6599
|
+
const content = memFiles["stack.md"].replace(/^---[\s\S]*?---\n/, "").trim();
|
|
6580
6600
|
lines.push(content);
|
|
6581
6601
|
lines.push("");
|
|
6582
6602
|
}
|
|
@@ -7665,8 +7685,8 @@ Setze diese Umgebungsvariablen:`);
|
|
|
7665
7685
|
pkg = JSON.parse(fs31.readFileSync(path32.join(projectRoot, "package.json"), "utf8"));
|
|
7666
7686
|
} catch {
|
|
7667
7687
|
}
|
|
7668
|
-
const
|
|
7669
|
-
const md = formatChangelog(commits,
|
|
7688
|
+
const pkgVersion = pkg.version ?? "unreleased";
|
|
7689
|
+
const md = formatChangelog(commits, pkgVersion);
|
|
7670
7690
|
const outputPath = outputArg ?? path32.join(projectRoot, "CHANGELOG.md");
|
|
7671
7691
|
let existing = "";
|
|
7672
7692
|
if (fs31.existsSync(outputPath)) existing = fs31.readFileSync(outputPath, "utf8");
|
|
@@ -7680,7 +7700,7 @@ Setze diese Umgebungsvariablen:`);
|
|
|
7680
7700
|
}
|
|
7681
7701
|
const adrsDir = path32.join(forgehiveDir, "memory", "adrs");
|
|
7682
7702
|
fs31.mkdirSync(adrsDir, { recursive: true });
|
|
7683
|
-
const existing = fs31.
|
|
7703
|
+
const existing = fs31.readdirSync(adrsDir).filter((f) => f.endsWith(".md")).length;
|
|
7684
7704
|
const adrId = String(existing + 1).padStart(4, "0");
|
|
7685
7705
|
const slug = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
7686
7706
|
const filename = `${adrId}-${slug}.md`;
|