forgehive 0.7.5 → 0.7.6
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 +38 -8
- package/dist/cli.js +30 -10
- package/forgehive/commands/fh-docs.md +16 -6
- package/forgehive/commands/full-party.md +9 -4
- package/package.json +20 -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
|
|
|
@@ -109,14 +109,14 @@ This makes both `fh` and `forgehive` available globally.
|
|
|
109
109
|
git clone https://github.com/matharnica/forgehive
|
|
110
110
|
cd forgehive
|
|
111
111
|
npm install
|
|
112
|
-
npm run build # compiles to dist/cli.js (~
|
|
112
|
+
npm run build # compiles to dist/cli.js (~259 KB)
|
|
113
113
|
npm link # makes 'fh' available globally
|
|
114
114
|
```
|
|
115
115
|
|
|
116
116
|
Verify the installation:
|
|
117
117
|
|
|
118
118
|
```bash
|
|
119
|
-
fh --version # should print 0.7.
|
|
119
|
+
fh --version # should print 0.7.5
|
|
120
120
|
fh --help # lists all available commands
|
|
121
121
|
```
|
|
122
122
|
|
|
@@ -332,6 +332,23 @@ Parses conventional commits (`feat:`, `fix:`, `chore:`, `docs:`, etc.) and group
|
|
|
332
332
|
|
|
333
333
|
---
|
|
334
334
|
|
|
335
|
+
### Docs
|
|
336
|
+
|
|
337
|
+
```bash
|
|
338
|
+
fh docs # list existing documentation
|
|
339
|
+
fh docs user [--output path] # generate user guide → docs/user-guide.md
|
|
340
|
+
fh docs api [--output path] # generate API reference → docs/api.md
|
|
341
|
+
fh docs onboard [--output path] # generate onboarding doc → ONBOARDING.md
|
|
342
|
+
fh docs changelog [--since tag] [--output path] # generate changelog → CHANGELOG.md
|
|
343
|
+
fh docs adr "<title>" # create Architecture Decision Record
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
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/`.
|
|
347
|
+
|
|
348
|
+
> `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.
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
335
352
|
### Developer Metrics
|
|
336
353
|
|
|
337
354
|
```bash
|
|
@@ -847,9 +864,9 @@ Global credential store (chmod 600). Managed exclusively via `fh mcp auth` comma
|
|
|
847
864
|
|---|---|
|
|
848
865
|
| Runtime | Node.js ≥ 18, ESM |
|
|
849
866
|
| Language | TypeScript |
|
|
850
|
-
| Build | esbuild -> `dist/cli.js` (~
|
|
867
|
+
| Build | esbuild -> `dist/cli.js` (~259 KB, single bundle) |
|
|
851
868
|
| Type check | `tsc --noEmit` |
|
|
852
|
-
| Tests | `node:test` (native) + tsx ESM loader,
|
|
869
|
+
| Tests | `node:test` (native) + tsx ESM loader, 273 tests |
|
|
853
870
|
| Dependencies | `js-yaml` (sole runtime dependency) |
|
|
854
871
|
|
|
855
872
|
```bash
|
|
@@ -860,6 +877,19 @@ npm test # node --import tsx/esm --test test/*.test.ts
|
|
|
860
877
|
|
|
861
878
|
---
|
|
862
879
|
|
|
880
|
+
## Changelog
|
|
881
|
+
|
|
882
|
+
| Version | What's new |
|
|
883
|
+
|---|---|
|
|
884
|
+
| **0.7.5** | `fh --version` reads from `package.json` (no longer hardcoded) |
|
|
885
|
+
| **0.7.4** | Party slash commands installed by `fh init` (`/party`, `/review-party`, `/design-party`, `/full-party`, `/security-party`) |
|
|
886
|
+
| **0.7.3** | User Docs generation (`fh docs user`, `fh docs api`, `fh docs list`) |
|
|
887
|
+
| **0.7.2** | `fh --help`, `fh init --force`, `fh story sprint`, `fh velocity show` fixes |
|
|
888
|
+
| **0.7.1** | Story Cards, Epics, Velocity tracking |
|
|
889
|
+
| **0.7.0** | CI, Map, Onboard, Changelog, Metrics, Sync, Background agents |
|
|
890
|
+
|
|
891
|
+
---
|
|
892
|
+
|
|
863
893
|
## License
|
|
864
894
|
|
|
865
895
|
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`;
|
|
@@ -20,12 +20,22 @@ For interactive generation with editing, continue below.
|
|
|
20
20
|
Ask the user: **"Was soll ich dokumentieren?"**
|
|
21
21
|
|
|
22
22
|
Options:
|
|
23
|
-
1. **
|
|
24
|
-
2. **
|
|
25
|
-
3. **
|
|
26
|
-
4. **
|
|
27
|
-
5. **
|
|
28
|
-
6. **
|
|
23
|
+
1. **User Guide** — write or update `docs/user-guide.md` for end users
|
|
24
|
+
2. **README update** — reflect recent features/changes
|
|
25
|
+
3. **API reference** — document endpoints or exported functions (`docs/api.md`)
|
|
26
|
+
4. **CHANGELOG** — run `fh docs changelog` and review the output
|
|
27
|
+
5. **ADR** — document an architecture decision (`fh docs adr "<title>"`)
|
|
28
|
+
6. **Inline docs** — add JSDoc/docstrings to changed functions
|
|
29
|
+
7. **ONBOARDING** — run `fh docs onboard` and review
|
|
30
|
+
|
|
31
|
+
### For User Guide
|
|
32
|
+
|
|
33
|
+
1. Run `fh docs user` to generate a baseline → `docs/user-guide.md`
|
|
34
|
+
2. Read the generated file
|
|
35
|
+
3. Read `.forgehive/memory/project.md` for additional context
|
|
36
|
+
4. Expand sections that are thin: add real usage examples, explain non-obvious behavior, describe common workflows
|
|
37
|
+
5. Remove or correct any placeholder text or auto-generated boilerplate that doesn't match the actual project
|
|
38
|
+
6. Ensure the guide covers: installation, first run, core commands, configuration, troubleshooting
|
|
29
39
|
|
|
30
40
|
### For README updates
|
|
31
41
|
|
|
@@ -2,11 +2,11 @@ You are running a Full Party using ForgeHive.
|
|
|
2
2
|
|
|
3
3
|
## Full Party
|
|
4
4
|
|
|
5
|
-
**Agents:** Nora (Senior Research Analyst), Eli (Documentation Architect), Remy (Product Strategist), Suki (Experience Designer), Viktor (Systems Architect), Kai (Principal Engineer), Sam (Quality Architect)
|
|
5
|
+
**Agents:** Nora (Senior Research Analyst), Eli (Documentation Architect), Remy (Product Strategist), Suki (Experience Designer), Viktor (Systems Architect), Kai (Principal Engineer), Sam (Quality Architect), Vera (Security Architect)
|
|
6
6
|
|
|
7
|
-
**Mission:** Comprehensive multi-discipline review of a major feature or release — all
|
|
7
|
+
**Mission:** Comprehensive multi-discipline review of a major feature or release — all eight specialists working in parallel on their domain.
|
|
8
8
|
|
|
9
|
-
> **Warning:** This party spins up
|
|
9
|
+
> **Warning:** This party spins up 8 worktrees simultaneously. Reserve this for major milestones, release candidates, and significant architectural changes. For smaller reviews, use `/review-party` or `/design-party` instead.
|
|
10
10
|
|
|
11
11
|
## Protocol
|
|
12
12
|
|
|
@@ -17,7 +17,7 @@ Run:
|
|
|
17
17
|
fh party run --set full
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
This spins up isolated worktrees for all
|
|
20
|
+
This spins up isolated worktrees for all 8 agents. Each works their specialization in parallel.
|
|
21
21
|
|
|
22
22
|
### Step 2: Define the milestone
|
|
23
23
|
|
|
@@ -63,6 +63,11 @@ Before the party starts, describe what is being reviewed — be specific:
|
|
|
63
63
|
- Identifies high-risk paths with insufficient coverage
|
|
64
64
|
- Produces: a test coverage and risk report
|
|
65
65
|
|
|
66
|
+
**Vera** (Security Architect) — threat modeling, attack surface analysis:
|
|
67
|
+
- Reviews authentication, authorization, and input handling
|
|
68
|
+
- Flags injection risks, insecure defaults, and data exposure
|
|
69
|
+
- Produces: a security review with severity-labeled findings
|
|
70
|
+
|
|
66
71
|
### Step 4: Check status
|
|
67
72
|
|
|
68
73
|
After all agents complete:
|
package/package.json
CHANGED
|
@@ -1,15 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "forgehive",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.6",
|
|
4
4
|
"description": "Context-aware AI development environment — one binary, your stack.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"forgehive": "
|
|
8
|
-
"fh": "
|
|
7
|
+
"forgehive": "dist/cli.js",
|
|
8
|
+
"fh": "dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist/",
|
|
12
|
+
"forgehive/"
|
|
13
|
+
],
|
|
14
|
+
"keywords": [
|
|
15
|
+
"claude",
|
|
16
|
+
"claude-code",
|
|
17
|
+
"ai",
|
|
18
|
+
"mcp",
|
|
19
|
+
"agents",
|
|
20
|
+
"context",
|
|
21
|
+
"forgehive",
|
|
22
|
+
"development"
|
|
23
|
+
],
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=18"
|
|
9
26
|
},
|
|
10
|
-
"files": ["dist/", "forgehive/"],
|
|
11
|
-
"keywords": ["claude", "claude-code", "ai", "mcp", "agents", "context", "forgehive", "development"],
|
|
12
|
-
"engines": { "node": ">=18" },
|
|
13
27
|
"scripts": {
|
|
14
28
|
"build": "esbuild src/cli.ts --bundle --platform=node --format=esm --outfile=dist/cli.js && chmod +x dist/cli.js",
|
|
15
29
|
"prepublishOnly": "npm run build",
|