forgehive 0.6.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/README.md +631 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +6265 -0
- package/dist/confirm.d.ts +1 -0
- package/dist/confirm.js +15 -0
- package/dist/fulfillment-catalog.d.ts +10 -0
- package/dist/fulfillment-catalog.js +119 -0
- package/dist/lookup-table.d.ts +16 -0
- package/dist/lookup-table.js +128 -0
- package/dist/rollback.d.ts +1 -0
- package/dist/rollback.js +9 -0
- package/dist/scanner.d.ts +2 -0
- package/dist/scanner.js +87 -0
- package/dist/types.d.ts +13 -0
- package/dist/types.js +1 -0
- package/dist/update.d.ts +7 -0
- package/dist/update.js +42 -0
- package/dist/writer.d.ts +3 -0
- package/dist/writer.js +63 -0
- package/forgehive/agents/eli.yaml +8 -0
- package/forgehive/agents/kai.yaml +8 -0
- package/forgehive/agents/nora.yaml +8 -0
- package/forgehive/agents/remy.yaml +8 -0
- package/forgehive/agents/sam.yaml +8 -0
- package/forgehive/agents/suki.yaml +8 -0
- package/forgehive/agents/vera.yaml +24 -0
- package/forgehive/agents/viktor.yaml +8 -0
- package/forgehive/commands/fh-hotfix.md +16 -0
- package/forgehive/commands/fh-review.md +16 -0
- package/forgehive/commands/fh-ship.md +18 -0
- package/forgehive/commands/fh-start-task.md +13 -0
- package/forgehive/hooks/guardrails.sh +17 -0
- package/forgehive/party/defaults.yaml +21 -0
- package/forgehive/skills/INDEX.yaml +64 -0
- package/forgehive/skills/expert/.gitkeep +0 -0
- package/forgehive/skills/expert/api-design.md +77 -0
- package/forgehive/skills/expert/auth-security.md +80 -0
- package/forgehive/skills/expert/clean-architecture.md +83 -0
- package/forgehive/skills/expert/code-review.md +81 -0
- package/forgehive/skills/expert/database-patterns.md +81 -0
- package/forgehive/skills/expert/error-handling.md +90 -0
- package/forgehive/skills/expert/gdpr-compliance.md +64 -0
- package/forgehive/skills/expert/git-conventions.md +84 -0
- package/forgehive/skills/expert/monorepo-patterns.md +91 -0
- package/forgehive/skills/expert/observability.md +98 -0
- package/forgehive/skills/expert/owasp-top10.md +153 -0
- package/forgehive/skills/expert/performance-patterns.md +79 -0
- package/forgehive/skills/expert/security-checklist.md +70 -0
- package/forgehive/skills/expert/testing-strategies.md +74 -0
- package/forgehive/skills/expert/typescript-patterns.md +62 -0
- package/forgehive/skills/templates/.gitkeep +0 -0
- package/forgehive/templates/claude-md.block.md +62 -0
- package/package.json +30 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Testing Strategies
|
|
2
|
+
|
|
3
|
+
## Core Principle: Test Behavior, Not Implementation
|
|
4
|
+
|
|
5
|
+
Tests should verify what a unit does, not how it does it. If a refactor breaks tests without changing behavior, the tests are wrong.
|
|
6
|
+
|
|
7
|
+
## Test Structure (AAA)
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
it("returns null for unknown user", async () => {
|
|
11
|
+
// Arrange
|
|
12
|
+
const repo = new UserRepository(testDb);
|
|
13
|
+
|
|
14
|
+
// Act
|
|
15
|
+
const result = await repo.findById("nonexistent-id");
|
|
16
|
+
|
|
17
|
+
// Assert
|
|
18
|
+
assert.equal(result, null);
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Test Naming
|
|
23
|
+
|
|
24
|
+
Format: **`[unit] [condition] [expected outcome]`**
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
✅ "findById returns null for unknown id"
|
|
28
|
+
✅ "parseConfig throws when port is negative"
|
|
29
|
+
❌ "test findById"
|
|
30
|
+
❌ "should work correctly"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## What to Test
|
|
34
|
+
|
|
35
|
+
| Test | What |
|
|
36
|
+
|---|---|
|
|
37
|
+
| Unit | Pure functions, transformations, business logic |
|
|
38
|
+
| Integration | DB queries, file I/O, external API clients |
|
|
39
|
+
| Contract | API response shapes, event schemas |
|
|
40
|
+
|
|
41
|
+
**Don't test:** framework behavior, library internals, private methods via backdoor.
|
|
42
|
+
|
|
43
|
+
## Test Isolation
|
|
44
|
+
|
|
45
|
+
- Each test owns its state — no shared mutable variables between tests
|
|
46
|
+
- `beforeEach` creates fresh instances, `afterEach` cleans up
|
|
47
|
+
- Integration tests use real dependencies (test DB, temp files) — not mocks
|
|
48
|
+
- Mock only things you don't own (3rd party APIs, time, random)
|
|
49
|
+
|
|
50
|
+
## Edge Cases to Always Cover
|
|
51
|
+
|
|
52
|
+
1. Empty / zero / null input
|
|
53
|
+
2. Single item (off-by-one)
|
|
54
|
+
3. Concurrent/duplicate calls (idempotency)
|
|
55
|
+
4. Error paths (not just happy path)
|
|
56
|
+
|
|
57
|
+
## TDD Cycle
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
Red → write failing test
|
|
61
|
+
Green → minimal code to pass
|
|
62
|
+
Refactor → clean up, tests still green
|
|
63
|
+
Commit → tests are the safety net
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Anti-Patterns
|
|
67
|
+
|
|
68
|
+
| Avoid | Why |
|
|
69
|
+
|---|---|
|
|
70
|
+
| Mocking internal modules | Couples tests to implementation |
|
|
71
|
+
| `expect(x).toBeDefined()` only | Doesn't verify actual value |
|
|
72
|
+
| Tests that only pass in sequence | Hidden shared state |
|
|
73
|
+
| Snapshot tests for logic | Fragile, hides intent |
|
|
74
|
+
| Testing mocks | You're testing the mock, not the code |
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# TypeScript Patterns
|
|
2
|
+
|
|
3
|
+
## Type System
|
|
4
|
+
|
|
5
|
+
**Prefer `interface` for object shapes, `type` for everything else:**
|
|
6
|
+
```typescript
|
|
7
|
+
interface UserRepository { findById(id: string): Promise<User>; }
|
|
8
|
+
type UserId = string;
|
|
9
|
+
type Result<T> = { data: T; error: null } | { data: null; error: Error };
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
**Avoid `any` — use `unknown` then narrow:**
|
|
13
|
+
```typescript
|
|
14
|
+
function parse(raw: unknown): Config {
|
|
15
|
+
if (typeof raw !== "object" || raw === null) throw new Error("invalid");
|
|
16
|
+
return raw as Config; // after structural check
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**`satisfies` for validation without widening:**
|
|
21
|
+
```typescript
|
|
22
|
+
const config = { port: 3000, host: "localhost" } satisfies ServerConfig;
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Functions
|
|
26
|
+
|
|
27
|
+
- Explicit return types on public/exported functions
|
|
28
|
+
- Arrow functions for callbacks, function declarations for top-level
|
|
29
|
+
- Overloads only when return type changes by input type — otherwise use union
|
|
30
|
+
|
|
31
|
+
## Async
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
// Always await — never fire-and-forget without void
|
|
35
|
+
void sendAnalytics(event); // intentional: mark explicitly
|
|
36
|
+
|
|
37
|
+
// Prefer explicit Promise<T> when body is trivially async
|
|
38
|
+
function getUser(id: string): Promise<User> {
|
|
39
|
+
return db.users.findUnique({ where: { id } });
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Modules (ESM)
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
// Named exports > default exports (better tree-shaking + renaming)
|
|
47
|
+
export function parseConfig() {}
|
|
48
|
+
export type { Config };
|
|
49
|
+
|
|
50
|
+
// Always include .ts extension in ESM imports
|
|
51
|
+
import { parseConfig } from "./config.ts";
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Anti-Patterns
|
|
55
|
+
|
|
56
|
+
| Avoid | Use instead |
|
|
57
|
+
|---|---|
|
|
58
|
+
| `value!` non-null assertion | Narrow: `if (value == null) throw` |
|
|
59
|
+
| `value as Type` cast | Runtime check + type guard |
|
|
60
|
+
| `// @ts-ignore` | Fix the underlying issue |
|
|
61
|
+
| Nested ternaries | `if/else` or early return |
|
|
62
|
+
| `enum` | `const` object + `keyof typeof` |
|
|
File without changes
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
## forgehive
|
|
2
|
+
|
|
3
|
+
This project uses **forgehive** for structured AI-assisted development.
|
|
4
|
+
|
|
5
|
+
### Session Start (Required)
|
|
6
|
+
|
|
7
|
+
1. Read `.forgehive/capabilities.yaml`
|
|
8
|
+
- If `status: draft` → tell the user: "Run `fh confirm` to activate capabilities."
|
|
9
|
+
- If `status: confirmed` → load silently and apply throughout the session
|
|
10
|
+
2. Read `.forgehive/memory/MEMORY.md` — follow the index links to load project context
|
|
11
|
+
3. Run `fh scan --check` to verify the stack snapshot is current
|
|
12
|
+
|
|
13
|
+
### During the Session
|
|
14
|
+
|
|
15
|
+
- Only suggest tools and libraries listed in `capabilities.yaml`
|
|
16
|
+
- If a capability has a `check` field: verify it before use
|
|
17
|
+
- If a capability has a `fulfill` field and the check fails: fulfill it
|
|
18
|
+
- At session end: append brief notes to `.forgehive/state/YYYY-MM-DD.md`
|
|
19
|
+
- If you learn something non-obvious about the project, offer to persist it to memory
|
|
20
|
+
|
|
21
|
+
### Skills — Progressive Loading
|
|
22
|
+
|
|
23
|
+
Before starting a technical task, read `.forgehive/skills/INDEX.yaml` to find relevant skills.
|
|
24
|
+
Load only the skills matching your current task — not all skills at once.
|
|
25
|
+
|
|
26
|
+
Examples:
|
|
27
|
+
- Working with TypeScript types → load `expert/typescript-patterns.md`
|
|
28
|
+
- Database migration → load `expert/database-patterns.md`
|
|
29
|
+
- Reviewing a PR → load `expert/code-review.md`
|
|
30
|
+
- Security review → load `expert/security-checklist.md`
|
|
31
|
+
- Performance issue → load `expert/performance-patterns.md`
|
|
32
|
+
|
|
33
|
+
### Workflow Commands
|
|
34
|
+
|
|
35
|
+
ForgeHive installs slash commands in `.claude/commands/`:
|
|
36
|
+
- `/fh-start-task` — start a new feature branch with full context loaded
|
|
37
|
+
- `/fh-ship` — pre-ship checklist: tests, diff review, PR draft
|
|
38
|
+
- `/fh-review` — structured code review using the review skill
|
|
39
|
+
- `/fh-hotfix` — minimal hotfix protocol (< 50 lines rule)
|
|
40
|
+
|
|
41
|
+
### Agent Memory
|
|
42
|
+
|
|
43
|
+
Each agent has persistent memory in `.forgehive/agents/memory/<name>.md`.
|
|
44
|
+
Before activating a party set, read the relevant agent memory files.
|
|
45
|
+
Update memory files when agents make significant decisions.
|
|
46
|
+
Format: `[YYYY-MM-DD] <decision or learned context>`
|
|
47
|
+
|
|
48
|
+
### Party Mode
|
|
49
|
+
|
|
50
|
+
Slash commands auto-configured by forgehive:
|
|
51
|
+
- `/party` — activate build agents (Viktor + Kai + Sam)
|
|
52
|
+
- `/design-party` — activate design agents (Suki + Viktor)
|
|
53
|
+
- `/review-party` — activate review agents (Kai + Sam + Eli)
|
|
54
|
+
- `/full-party` — activate all agents
|
|
55
|
+
|
|
56
|
+
### Prohibited
|
|
57
|
+
|
|
58
|
+
- Writing to paths outside the project root
|
|
59
|
+
- Modifying `.forgehive/scan-result.yaml` manually
|
|
60
|
+
- Skipping the session-start capability and memory check
|
|
61
|
+
- Suggesting tools not in `capabilities.yaml` without explicitly noting the deviation
|
|
62
|
+
- Activating party agents without reading their memory files first
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "forgehive",
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "Context-aware AI development environment — one binary, your stack.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"forgehive": "./dist/cli.js",
|
|
8
|
+
"fh": "./dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"files": ["dist/", "forgehive/"],
|
|
11
|
+
"keywords": ["claude", "claude-code", "ai", "mcp", "agents", "context", "forgehive", "development"],
|
|
12
|
+
"engines": { "node": ">=18" },
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "esbuild src/cli.ts --bundle --platform=node --format=esm --banner:js='#!/usr/bin/env node' --outfile=dist/cli.js && chmod +x dist/cli.js",
|
|
15
|
+
"prepublishOnly": "npm run build",
|
|
16
|
+
"typecheck": "tsc",
|
|
17
|
+
"test": "node --import tsx/esm --test test/*.test.ts",
|
|
18
|
+
"test:watch": "node --import tsx/esm --test --watch test/*.test.ts"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/js-yaml": "^4.0.9",
|
|
22
|
+
"@types/node": "^25.6.2",
|
|
23
|
+
"esbuild": "^0.27.7",
|
|
24
|
+
"tsx": "^4.19.2",
|
|
25
|
+
"typescript": "^5.8.3"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"js-yaml": "^4.1.0"
|
|
29
|
+
}
|
|
30
|
+
}
|