forge-dev-framework 1.0.1 → 1.2.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/.claude/commands/forge/README.md +281 -0
- package/.claude/commands/forge/add-phase.md +90 -0
- package/.claude/commands/forge/complete-milestone.md +130 -0
- package/.claude/commands/forge/config.md +115 -0
- package/.claude/commands/forge/convert.md +31 -0
- package/.claude/commands/forge/debug.md +31 -0
- package/.claude/commands/forge/discuss.md +78 -0
- package/.claude/commands/forge/execute.md +85 -0
- package/.claude/commands/forge/generate.md +21 -0
- package/.claude/commands/forge/help.md +18 -0
- package/.claude/commands/forge/init.md +21 -0
- package/.claude/commands/forge/insert-phase.md +99 -0
- package/.claude/commands/forge/new-milestone.md +114 -0
- package/.claude/commands/forge/new-project.md +24 -0
- package/.claude/commands/forge/pause-work.md +111 -0
- package/.claude/commands/forge/plan.md +129 -0
- package/.claude/commands/forge/quick.md +41 -0
- package/.claude/commands/forge/remove-phase.md +92 -0
- package/.claude/commands/forge/resume.md +22 -0
- package/.claude/commands/forge/status.md +87 -0
- package/.claude/commands/forge/team-add.md +24 -0
- package/.claude/commands/forge/team-create.md +22 -0
- package/.claude/commands/forge/team-remove.md +24 -0
- package/.claude/commands/forge/team-start.md +22 -0
- package/.claude/commands/forge/team-view.md +18 -0
- package/.claude/commands/forge/verify.md +95 -0
- package/.claude/hooks/forge-context-cleanup.cjs +79 -0
- package/.claude/hooks/forge-event-guard.cjs +36 -0
- package/.claude/hooks/forge-size-guard.cjs +55 -0
- package/.claude/rules/api-patterns.md +13 -98
- package/.claude/rules/context-efficiency.md +10 -0
- package/.claude/rules/security-baseline.md +18 -204
- package/.claude/rules/testing-standards.md +16 -177
- package/.claude/rules/ui-conventions.md +17 -142
- package/README.md +1 -0
- package/bin/forge.js +5 -3
- package/dist/bin/forge.js +5 -3
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +15 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/convert.d.ts +6 -0
- package/dist/commands/convert.d.ts.map +1 -0
- package/dist/commands/convert.js +132 -0
- package/dist/commands/convert.js.map +1 -0
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +3 -2
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/index.d.ts +4 -4
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +4 -4
- package/dist/commands/index.js.map +1 -1
- package/dist/generators/gsd-converter.d.ts +100 -0
- package/dist/generators/gsd-converter.d.ts.map +1 -0
- package/dist/generators/gsd-converter.js +335 -0
- package/dist/generators/gsd-converter.js.map +1 -0
- package/dist/templates/.claude/rules/api-patterns.md.template +212 -0
- package/dist/templates/.claude/rules/security-baseline.md.template +322 -0
- package/dist/templates/.claude/rules/testing-standards.md.template +280 -0
- package/dist/templates/.claude/rules/ui-conventions.md.template +264 -0
- package/dist/templates/.planning/forge.config.json.template +75 -0
- package/dist/templates/CLAUDE.md.template +161 -0
- package/dist/templates/PLAN.md.template +177 -0
- package/dist/templates/PROJECT.md.template +156 -0
- package/dist/templates/REQUIREMENTS.md.template +221 -0
- package/dist/templates/ROADMAP.md.template +130 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -2
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +5 -5
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +5 -5
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/template-client.d.ts.map +1 -1
- package/dist/utils/template-client.js +3 -2
- package/dist/utils/template-client.js.map +1 -1
- package/package.json +6 -4
- package/dist/git/__tests__/worktree.test.d.ts +0 -5
- package/dist/git/__tests__/worktree.test.d.ts.map +0 -1
- package/dist/git/__tests__/worktree.test.js +0 -121
- package/dist/git/__tests__/worktree.test.js.map +0 -1
- package/dist/git/codeowners.d.ts +0 -101
- package/dist/git/codeowners.d.ts.map +0 -1
- package/dist/git/codeowners.js +0 -216
- package/dist/git/codeowners.js.map +0 -1
- package/dist/git/commit.d.ts +0 -135
- package/dist/git/commit.d.ts.map +0 -1
- package/dist/git/commit.js +0 -223
- package/dist/git/commit.js.map +0 -1
- package/dist/git/hooks/commit-msg.d.ts +0 -8
- package/dist/git/hooks/commit-msg.d.ts.map +0 -1
- package/dist/git/hooks/commit-msg.js +0 -34
- package/dist/git/hooks/commit-msg.js.map +0 -1
- package/dist/git/hooks/pre-commit.d.ts +0 -8
- package/dist/git/hooks/pre-commit.d.ts.map +0 -1
- package/dist/git/hooks/pre-commit.js +0 -34
- package/dist/git/hooks/pre-commit.js.map +0 -1
- package/dist/git/pre-commit-hooks.d.ts +0 -117
- package/dist/git/pre-commit-hooks.d.ts.map +0 -1
- package/dist/git/pre-commit-hooks.js +0 -270
- package/dist/git/pre-commit-hooks.js.map +0 -1
- package/dist/git/wipe-protocol.d.ts +0 -281
- package/dist/git/wipe-protocol.d.ts.map +0 -1
- package/dist/git/wipe-protocol.js +0 -237
- package/dist/git/wipe-protocol.js.map +0 -1
- package/dist/git/worktree.d.ts +0 -69
- package/dist/git/worktree.d.ts.map +0 -1
- package/dist/git/worktree.js +0 -202
- package/dist/git/worktree.js.map +0 -1
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for Git Worktree Management
|
|
3
|
-
*/
|
|
4
|
-
import { describe, it, before, after } from "node:test";
|
|
5
|
-
import assert from "node/assert";
|
|
6
|
-
import { execa } from "execa";
|
|
7
|
-
import { createWorktree, getWorktree, mergeWorktree, cleanupWorktree, listWorktrees, WorktreeError, } from "../worktree.js";
|
|
8
|
-
describe("Git Worktree Management", () => {
|
|
9
|
-
const testTaskId = "test-task-001";
|
|
10
|
-
const testBaseBranch = "main";
|
|
11
|
-
before(async () => {
|
|
12
|
-
// Initialize a test git repository if needed
|
|
13
|
-
try {
|
|
14
|
-
await execa("git", ["status"]);
|
|
15
|
-
}
|
|
16
|
-
catch {
|
|
17
|
-
// Not in a git repo, skip tests
|
|
18
|
-
console.log("Not in a git repository, skipping worktree tests");
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
describe("createWorktree", () => {
|
|
22
|
-
it("should create a new worktree with branch forge/{taskId}", async () => {
|
|
23
|
-
const result = await createWorktree({ taskId: testTaskId });
|
|
24
|
-
assert.ok(result.includes(".worktrees"));
|
|
25
|
-
assert.ok(result.includes(testTaskId));
|
|
26
|
-
});
|
|
27
|
-
it("should use custom branch name if provided", async () => {
|
|
28
|
-
const customBranch = "custom-branch";
|
|
29
|
-
const result = await createWorktree({
|
|
30
|
-
taskId: "custom-task",
|
|
31
|
-
branchName: customBranch,
|
|
32
|
-
});
|
|
33
|
-
assert.ok(result.includes("custom-task"));
|
|
34
|
-
});
|
|
35
|
-
it("should throw WorktreeError on failure", async () => {
|
|
36
|
-
try {
|
|
37
|
-
// Try to create duplicate worktree
|
|
38
|
-
await createWorktree({ taskId: testTaskId });
|
|
39
|
-
assert.fail("Should have thrown WorktreeError");
|
|
40
|
-
}
|
|
41
|
-
catch (error) {
|
|
42
|
-
assert.ok(error instanceof WorktreeError);
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
describe("getWorktree", () => {
|
|
47
|
-
it("should return worktree info for existing task", async () => {
|
|
48
|
-
const info = await getWorktree(testTaskId);
|
|
49
|
-
assert.ok(info);
|
|
50
|
-
assert.equal(info.taskId, testTaskId);
|
|
51
|
-
assert.ok(info.branchName);
|
|
52
|
-
assert.ok(info.path);
|
|
53
|
-
assert.ok(info.commit);
|
|
54
|
-
});
|
|
55
|
-
it("should return null for non-existent task", async () => {
|
|
56
|
-
const info = await getWorktree("non-existent-task");
|
|
57
|
-
assert.equal(info, null);
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
describe("listWorktrees", () => {
|
|
61
|
-
it("should return array of worktree info", async () => {
|
|
62
|
-
const worktrees = await listWorktrees();
|
|
63
|
-
assert.ok(Array.isArray(worktrees));
|
|
64
|
-
assert.ok(worktrees.length > 0);
|
|
65
|
-
assert.ok(worktrees.some((w) => w.taskId === testTaskId));
|
|
66
|
-
});
|
|
67
|
-
it("should only include FORGE worktrees (.worktrees/)", async () => {
|
|
68
|
-
const worktrees = await listWorktrees();
|
|
69
|
-
for (const worktree of worktrees) {
|
|
70
|
-
assert.ok(worktree.path.includes(".worktrees"));
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
describe("cleanupWorktree", () => {
|
|
75
|
-
it("should remove an existing worktree", async () => {
|
|
76
|
-
await cleanupWorktree(testTaskId);
|
|
77
|
-
const info = await getWorktree(testTaskId);
|
|
78
|
-
assert.equal(info, null);
|
|
79
|
-
});
|
|
80
|
-
it("should not error when cleaning up non-existent worktree", async () => {
|
|
81
|
-
// Should not throw
|
|
82
|
-
await cleanupWorktree("non-existent-task");
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
describe("mergeWorktree", () => {
|
|
86
|
-
it("should merge worktree branch into target branch", async () => {
|
|
87
|
-
// Create a test worktree
|
|
88
|
-
const taskId = "merge-test-001";
|
|
89
|
-
await createWorktree({ taskId });
|
|
90
|
-
// Make a change in the worktree
|
|
91
|
-
// (This would require file operations, simplified here)
|
|
92
|
-
// Merge the worktree
|
|
93
|
-
try {
|
|
94
|
-
await mergeWorktree(taskId, "main");
|
|
95
|
-
}
|
|
96
|
-
catch (error) {
|
|
97
|
-
// Merge might fail if no changes or conflicts, that's ok for test
|
|
98
|
-
assert.ok(error instanceof WorktreeError);
|
|
99
|
-
}
|
|
100
|
-
// Cleanup
|
|
101
|
-
await cleanupWorktree(taskId);
|
|
102
|
-
});
|
|
103
|
-
it("should throw WorktreeError for non-existent worktree", async () => {
|
|
104
|
-
try {
|
|
105
|
-
await mergeWorktree("non-existent-task");
|
|
106
|
-
assert.fail("Should have thrown WorktreeError");
|
|
107
|
-
}
|
|
108
|
-
catch (error) {
|
|
109
|
-
assert.ok(error instanceof WorktreeError);
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
after(async () => {
|
|
114
|
-
// Clean up test worktrees
|
|
115
|
-
try {
|
|
116
|
-
await cleanupWorktree(testTaskId);
|
|
117
|
-
}
|
|
118
|
-
catch { }
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
//# sourceMappingURL=worktree.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"worktree.test.js","sourceRoot":"","sources":["../../../src/git/__tests__/worktree.test.ts"],"names":[],"mappings":"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"}
|
package/dist/git/codeowners.d.ts
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generate .github/CODEOWNERS from task ownership maps.
|
|
3
|
-
*
|
|
4
|
-
* The CODEOWNERS file defines canonical ownership for code paths.
|
|
5
|
-
* GitHub enforces this at merge time - changes require owner approval.
|
|
6
|
-
*
|
|
7
|
-
* Generated format:
|
|
8
|
-
* # Auto-generated by FORGE
|
|
9
|
-
* src/api/** @backend-agent
|
|
10
|
-
* src/ui/** @frontend-agent
|
|
11
|
-
* src/tests/** @qa-agent
|
|
12
|
-
* docs/** @docs-agent
|
|
13
|
-
*/
|
|
14
|
-
export interface TaskOwnership {
|
|
15
|
-
id: string;
|
|
16
|
-
ownerRole: string;
|
|
17
|
-
allowedPaths: string[];
|
|
18
|
-
}
|
|
19
|
-
export interface StateForCodeowners {
|
|
20
|
-
tasks: TaskOwnership[];
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Generate CODEOWNERS content from task ownership.
|
|
24
|
-
*
|
|
25
|
-
* Aggregates allowedPaths by owner role and formats for GitHub.
|
|
26
|
-
*
|
|
27
|
-
* @param state - FORGE state with task ownership
|
|
28
|
-
* @returns CODEOWNERS file content
|
|
29
|
-
*/
|
|
30
|
-
export declare function generateCodeownersContent(state: StateForCodeowners): string;
|
|
31
|
-
/**
|
|
32
|
-
* Write CODEOWNERS file to disk.
|
|
33
|
-
*
|
|
34
|
-
* @param state - FORGE state with task ownership
|
|
35
|
-
* @param basePath - Root of the FORGE project
|
|
36
|
-
* @param forceOverwrite - Whether to overwrite existing file
|
|
37
|
-
* @throws Error if file exists and forceOverwrite is false
|
|
38
|
-
*/
|
|
39
|
-
export declare function writeCodeowners(state: StateForCodeowners, basePath?: string, forceOverwrite?: boolean): Promise<void>;
|
|
40
|
-
/**
|
|
41
|
-
* Parse existing CODEOWNERS file.
|
|
42
|
-
*
|
|
43
|
-
* Useful for validating or diffing against generated content.
|
|
44
|
-
*
|
|
45
|
-
* @param content - CODEOWNERS file content
|
|
46
|
-
* @returns Parsed entries
|
|
47
|
-
*/
|
|
48
|
-
export interface CodeownersEntry {
|
|
49
|
-
pattern: string;
|
|
50
|
-
owner: string;
|
|
51
|
-
}
|
|
52
|
-
export declare function parseCodeowners(content: string): CodeownersEntry[];
|
|
53
|
-
/**
|
|
54
|
-
* Validate CODEOWNERS entries.
|
|
55
|
-
*
|
|
56
|
-
* Checks for:
|
|
57
|
-
* - Overlapping patterns (conflicting ownership)
|
|
58
|
-
* - Invalid patterns
|
|
59
|
-
* - Missing owners
|
|
60
|
-
*
|
|
61
|
-
* @param entries - Parsed CODEOWNERS entries
|
|
62
|
-
* @returns Validation result with errors
|
|
63
|
-
*/
|
|
64
|
-
export interface ValidationError {
|
|
65
|
-
type: "overlap" | "invalid-pattern" | "missing-owner";
|
|
66
|
-
message: string;
|
|
67
|
-
entries?: CodeownersEntry[];
|
|
68
|
-
}
|
|
69
|
-
export declare function validateCodeowners(entries: CodeownersEntry[]): {
|
|
70
|
-
isValid: boolean;
|
|
71
|
-
errors: ValidationError[];
|
|
72
|
-
};
|
|
73
|
-
/**
|
|
74
|
-
* Diff two CODEOWNERS configurations.
|
|
75
|
-
*
|
|
76
|
-
* Useful for showing what would change before regenerating.
|
|
77
|
-
*
|
|
78
|
-
* @param current - Current CODEOWNERS content
|
|
79
|
-
* @param proposed - Proposed CODEOWNERS content
|
|
80
|
-
* @returns Diff with additions, removals, and changes
|
|
81
|
-
*/
|
|
82
|
-
export interface CodeownersDiff {
|
|
83
|
-
added: CodeownersEntry[];
|
|
84
|
-
removed: CodeownersEntry[];
|
|
85
|
-
changed: Array<{
|
|
86
|
-
from: CodeownersEntry;
|
|
87
|
-
to: CodeownersEntry;
|
|
88
|
-
}>;
|
|
89
|
-
}
|
|
90
|
-
export declare function diffCodeowners(current: string, proposed: string): CodeownersDiff;
|
|
91
|
-
/**
|
|
92
|
-
* Generate CODEOWNERS from STATE.json file.
|
|
93
|
-
*
|
|
94
|
-
* This is the main entry point for CODEOWNERS generation.
|
|
95
|
-
*
|
|
96
|
-
* @param stateJsonPath - Path to STATE.json
|
|
97
|
-
* @param basePath - Root of the FORGE project
|
|
98
|
-
* @param forceOverwrite - Whether to overwrite existing file
|
|
99
|
-
*/
|
|
100
|
-
export declare function generateCodeownersFromState(stateJsonPath: string, basePath?: string, forceOverwrite?: boolean): Promise<void>;
|
|
101
|
-
//# sourceMappingURL=codeowners.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"codeowners.d.ts","sourceRoot":"","sources":["../../src/git/codeowners.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB;AAcD;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,CA+C3E;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,kBAAkB,EACzB,QAAQ,GAAE,MAAoC,EAC9C,cAAc,GAAE,OAAe,GAC9B,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,EAAE,CAqBlE;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,GAAG,iBAAiB,GAAG,eAAe,CAAC;IACtD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG;IAC9D,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B,CA8CA;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,eAAe,CAAC;QAAC,EAAE,EAAE,eAAe,CAAA;KAAE,CAAC,CAAC;CAChE;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,CAuDhF;AAED;;;;;;;;GAQG;AACH,wBAAsB,2BAA2B,CAC/C,aAAa,EAAE,MAAM,EACrB,QAAQ,GAAE,MAAoC,EAC9C,cAAc,GAAE,OAAe,GAC9B,OAAO,CAAC,IAAI,CAAC,CAMf"}
|
package/dist/git/codeowners.js
DELETED
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generate .github/CODEOWNERS from task ownership maps.
|
|
3
|
-
*
|
|
4
|
-
* The CODEOWNERS file defines canonical ownership for code paths.
|
|
5
|
-
* GitHub enforces this at merge time - changes require owner approval.
|
|
6
|
-
*
|
|
7
|
-
* Generated format:
|
|
8
|
-
* # Auto-generated by FORGE
|
|
9
|
-
* src/api/** @backend-agent
|
|
10
|
-
* src/ui/** @frontend-agent
|
|
11
|
-
* src/tests/** @qa-agent
|
|
12
|
-
* docs/** @docs-agent
|
|
13
|
-
*/
|
|
14
|
-
import { writeFile, mkdir } from "node:fs/promises";
|
|
15
|
-
import { join } from "node:path";
|
|
16
|
-
// Role to GitHub username/team mapping
|
|
17
|
-
// In production, this would come from config
|
|
18
|
-
const ROLE_TO_OWNER = {
|
|
19
|
-
backend: "@backend-agent",
|
|
20
|
-
frontend: "@frontend-agent",
|
|
21
|
-
qa: "@qa-agent",
|
|
22
|
-
docs: "@docs-agent",
|
|
23
|
-
devops: "@devops-agent",
|
|
24
|
-
architect: "@architect",
|
|
25
|
-
"team-lead": "@team-lead",
|
|
26
|
-
};
|
|
27
|
-
/**
|
|
28
|
-
* Generate CODEOWNERS content from task ownership.
|
|
29
|
-
*
|
|
30
|
-
* Aggregates allowedPaths by owner role and formats for GitHub.
|
|
31
|
-
*
|
|
32
|
-
* @param state - FORGE state with task ownership
|
|
33
|
-
* @returns CODEOWNERS file content
|
|
34
|
-
*/
|
|
35
|
-
export function generateCodeownersContent(state) {
|
|
36
|
-
const lines = [];
|
|
37
|
-
// Header
|
|
38
|
-
lines.push("# Auto-generated by FORGE");
|
|
39
|
-
lines.push("# DO NOT EDIT MANually - Regenerate with forge generate-codeowners");
|
|
40
|
-
lines.push("");
|
|
41
|
-
// Aggregate paths by owner role
|
|
42
|
-
const pathsByOwner = new Map();
|
|
43
|
-
for (const task of state.tasks) {
|
|
44
|
-
const owner = ROLE_TO_OWNER[task.ownerRole] || `@${task.ownerRole}`;
|
|
45
|
-
if (!pathsByOwner.has(owner)) {
|
|
46
|
-
pathsByOwner.set(owner, new Set());
|
|
47
|
-
}
|
|
48
|
-
const ownerPaths = pathsByOwner.get(owner);
|
|
49
|
-
for (const path of task.allowedPaths) {
|
|
50
|
-
ownerPaths.add(path);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
// Format: sorted by owner, then by path
|
|
54
|
-
const sortedOwners = Array.from(pathsByOwner.entries()).sort((a, b) => a[0].localeCompare(b[0]));
|
|
55
|
-
for (const [owner, paths] of sortedOwners) {
|
|
56
|
-
// Sort paths for consistency
|
|
57
|
-
const sortedPaths = Array.from(paths).sort();
|
|
58
|
-
for (const path of sortedPaths) {
|
|
59
|
-
// Ensure path is in gitignore-style format
|
|
60
|
-
const gitPath = path.startsWith("/") ? path.slice(1) : path;
|
|
61
|
-
lines.push(`${gitPath} ${owner}`);
|
|
62
|
-
}
|
|
63
|
-
lines.push(""); // Blank line between owners
|
|
64
|
-
}
|
|
65
|
-
// Add default fallback (team-lead owns everything else)
|
|
66
|
-
lines.push(`# Default fallback`);
|
|
67
|
-
lines.push(`* ${ROLE_TO_OWNER["team-lead"] || "@team-lead"}`);
|
|
68
|
-
return lines.join("\n");
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Write CODEOWNERS file to disk.
|
|
72
|
-
*
|
|
73
|
-
* @param state - FORGE state with task ownership
|
|
74
|
-
* @param basePath - Root of the FORGE project
|
|
75
|
-
* @param forceOverwrite - Whether to overwrite existing file
|
|
76
|
-
* @throws Error if file exists and forceOverwrite is false
|
|
77
|
-
*/
|
|
78
|
-
export async function writeCodeowners(state, basePath = "/home/parz/projects/forge", forceOverwrite = false) {
|
|
79
|
-
const codeownersPath = join(basePath, ".github", "CODEOWNERS");
|
|
80
|
-
// Check if file exists
|
|
81
|
-
try {
|
|
82
|
-
await writeFile(codeownersPath, "", { flag: "rx" });
|
|
83
|
-
if (!forceOverwrite) {
|
|
84
|
-
throw new Error("CODEOWNERS file already exists. Use forceOverwrite=true to replace it.");
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
catch {
|
|
88
|
-
// File doesn't exist, which is fine
|
|
89
|
-
}
|
|
90
|
-
// Ensure .github directory exists
|
|
91
|
-
await mkdir(join(basePath, ".github"), { recursive: true });
|
|
92
|
-
// Generate content
|
|
93
|
-
const content = generateCodeownersContent(state);
|
|
94
|
-
// Write file
|
|
95
|
-
await writeFile(codeownersPath, content, "utf-8");
|
|
96
|
-
}
|
|
97
|
-
export function parseCodeowners(content) {
|
|
98
|
-
const entries = [];
|
|
99
|
-
const lines = content.split("\n");
|
|
100
|
-
for (const line of lines) {
|
|
101
|
-
const trimmed = line.trim();
|
|
102
|
-
// Skip comments and empty lines
|
|
103
|
-
if (!trimmed || trimmed.startsWith("#")) {
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
// Parse "pattern owner"
|
|
107
|
-
const parts = trimmed.split(/\s+/);
|
|
108
|
-
if (parts.length >= 2) {
|
|
109
|
-
const [pattern, owner] = parts;
|
|
110
|
-
entries.push({ pattern, owner });
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return entries;
|
|
114
|
-
}
|
|
115
|
-
export function validateCodeowners(entries) {
|
|
116
|
-
const errors = [];
|
|
117
|
-
// Check for invalid patterns (basic validation)
|
|
118
|
-
for (const entry of entries) {
|
|
119
|
-
try {
|
|
120
|
-
// Convert gitignore pattern to regex for basic validation
|
|
121
|
-
const regexPattern = entry.pattern
|
|
122
|
-
.replace(/\*\*/g, ".*")
|
|
123
|
-
.replace(/\*/g, "[^/]*")
|
|
124
|
-
.replace(/\?/g, "[^/]");
|
|
125
|
-
new RegExp(regexPattern);
|
|
126
|
-
}
|
|
127
|
-
catch {
|
|
128
|
-
errors.push({
|
|
129
|
-
type: "invalid-pattern",
|
|
130
|
-
message: `Invalid pattern: ${entry.pattern}`,
|
|
131
|
-
entries: [entry],
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
// Check for missing owner
|
|
135
|
-
if (!entry.owner || !entry.owner.startsWith("@")) {
|
|
136
|
-
errors.push({
|
|
137
|
-
type: "missing-owner",
|
|
138
|
-
message: `Missing or invalid owner for pattern: ${entry.pattern}`,
|
|
139
|
-
entries: [entry],
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
// Check for overlapping patterns (same file owned by different roles)
|
|
144
|
-
// This is a simplified check - real validation would need path matching
|
|
145
|
-
const byOwner = new Map();
|
|
146
|
-
for (const entry of entries) {
|
|
147
|
-
if (!byOwner.has(entry.owner)) {
|
|
148
|
-
byOwner.set(entry.owner, []);
|
|
149
|
-
}
|
|
150
|
-
byOwner.get(entry.owner).push(entry.pattern);
|
|
151
|
-
}
|
|
152
|
-
// TODO: Add sophisticated overlap detection
|
|
153
|
-
return {
|
|
154
|
-
isValid: errors.length === 0,
|
|
155
|
-
errors,
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
export function diffCodeowners(current, proposed) {
|
|
159
|
-
const currentEntries = parseCodeowners(current);
|
|
160
|
-
const proposedEntries = parseCodeowners(proposed);
|
|
161
|
-
// Create maps for easy comparison
|
|
162
|
-
const currentMap = new Map();
|
|
163
|
-
const proposedMap = new Map();
|
|
164
|
-
for (const entry of currentEntries) {
|
|
165
|
-
const key = `${entry.pattern}|${entry.owner}`;
|
|
166
|
-
currentMap.set(key, entry);
|
|
167
|
-
}
|
|
168
|
-
for (const entry of proposedEntries) {
|
|
169
|
-
const key = `${entry.pattern}|${entry.owner}`;
|
|
170
|
-
proposedMap.set(key, entry);
|
|
171
|
-
}
|
|
172
|
-
// Find differences
|
|
173
|
-
const added = [];
|
|
174
|
-
const removed = [];
|
|
175
|
-
const changed = [];
|
|
176
|
-
// Check for removed and changed entries
|
|
177
|
-
for (const [key, entry] of currentMap) {
|
|
178
|
-
const pattern = entry.pattern;
|
|
179
|
-
// Find if this pattern exists in proposed with different owner
|
|
180
|
-
const proposedWithSamePattern = Array.from(proposedMap.values()).find((e) => e.pattern === pattern);
|
|
181
|
-
if (!proposedWithSamePattern) {
|
|
182
|
-
removed.push(entry);
|
|
183
|
-
}
|
|
184
|
-
else if (proposedWithSamePattern.owner !== entry.owner) {
|
|
185
|
-
changed.push({ from: entry, to: proposedWithSamePattern });
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
// Check for added entries
|
|
189
|
-
for (const [key, entry] of proposedMap) {
|
|
190
|
-
if (!currentMap.has(key)) {
|
|
191
|
-
const pattern = entry.pattern;
|
|
192
|
-
const currentWithSamePattern = Array.from(currentMap.values()).find((e) => e.pattern === pattern);
|
|
193
|
-
// Only add if it's truly new, not a change (already captured above)
|
|
194
|
-
if (!currentWithSamePattern) {
|
|
195
|
-
added.push(entry);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
return { added, removed, changed };
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Generate CODEOWNERS from STATE.json file.
|
|
203
|
-
*
|
|
204
|
-
* This is the main entry point for CODEOWNERS generation.
|
|
205
|
-
*
|
|
206
|
-
* @param stateJsonPath - Path to STATE.json
|
|
207
|
-
* @param basePath - Root of the FORGE project
|
|
208
|
-
* @param forceOverwrite - Whether to overwrite existing file
|
|
209
|
-
*/
|
|
210
|
-
export async function generateCodeownersFromState(stateJsonPath, basePath = "/home/parz/projects/forge", forceOverwrite = false) {
|
|
211
|
-
const { readFile } = await import("node:fs/promises");
|
|
212
|
-
const stateRaw = await readFile(stateJsonPath, "utf-8");
|
|
213
|
-
const state = JSON.parse(stateRaw);
|
|
214
|
-
await writeCodeowners(state, basePath, forceOverwrite);
|
|
215
|
-
}
|
|
216
|
-
//# sourceMappingURL=codeowners.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"codeowners.js","sourceRoot":"","sources":["../../src/git/codeowners.ts"],"names":[],"mappings":"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"}
|
package/dist/git/commit.d.ts
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Atomic Commit Enforcement for FORGE
|
|
3
|
-
*
|
|
4
|
-
* Enforces conventional commit format with task ID in scope:
|
|
5
|
-
* type(scope): description
|
|
6
|
-
*
|
|
7
|
-
* Examples:
|
|
8
|
-
* - feat(api-003): implement session authentication
|
|
9
|
-
* - fix(ui-002): resolve login form validation bug
|
|
10
|
-
* - test(core-001): add database integration tests
|
|
11
|
-
* - docs(readme): update installation instructions
|
|
12
|
-
*
|
|
13
|
-
* Rules:
|
|
14
|
-
* - Every task = one commit
|
|
15
|
-
* - Commit message MUST include task ID in scope
|
|
16
|
-
* - Pre-commit hooks validate format
|
|
17
|
-
* - Reject commits that don't match pattern
|
|
18
|
-
*/
|
|
19
|
-
import { z } from "zod";
|
|
20
|
-
export declare const CommitType: z.ZodEnum<["feat", "fix", "docs", "style", "refactor", "perf", "test", "chore", "revert"]>;
|
|
21
|
-
export type CommitType = z.infer<typeof CommitType>;
|
|
22
|
-
export declare class CommitFormatError extends Error {
|
|
23
|
-
readonly commitMessage: string;
|
|
24
|
-
constructor(message: string, commitMessage: string);
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Parsed commit message components.
|
|
28
|
-
*/
|
|
29
|
-
export interface ParsedCommit {
|
|
30
|
-
type: CommitType;
|
|
31
|
-
scope: string;
|
|
32
|
-
description: string;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Parse a commit message into its components.
|
|
36
|
-
*
|
|
37
|
-
* @param message - The commit message to parse
|
|
38
|
-
* @returns Parsed commit components
|
|
39
|
-
* @throws CommitFormatError if format is invalid
|
|
40
|
-
*/
|
|
41
|
-
export declare function parseCommitMessage(message: string): ParsedCommit;
|
|
42
|
-
/**
|
|
43
|
-
* Format a commit message from components.
|
|
44
|
-
*
|
|
45
|
-
* @param type - Commit type
|
|
46
|
-
* @param scope - Task ID (e.g., api-003)
|
|
47
|
-
* @param description - Commit description
|
|
48
|
-
* @returns Formatted commit message
|
|
49
|
-
*/
|
|
50
|
-
export declare function formatCommitMessage(type: CommitType, scope: string, description: string): string;
|
|
51
|
-
/**
|
|
52
|
-
* Validate a commit message against FORGE standards.
|
|
53
|
-
*
|
|
54
|
-
* @param message - The commit message to validate
|
|
55
|
-
* @returns True if valid
|
|
56
|
-
* @throws CommitFormatError if invalid
|
|
57
|
-
*/
|
|
58
|
-
export declare function validateCommitMessage(message: string): boolean;
|
|
59
|
-
/**
|
|
60
|
-
* Check if a commit message is for a specific task.
|
|
61
|
-
*
|
|
62
|
-
* @param message - The commit message
|
|
63
|
-
* @param taskId - The task ID to check
|
|
64
|
-
* @returns True if the commit is for the specified task
|
|
65
|
-
*/
|
|
66
|
-
export declare function isCommitForTask(message: string, taskId: string): boolean;
|
|
67
|
-
/**
|
|
68
|
-
* Extract task ID from a commit message.
|
|
69
|
-
*
|
|
70
|
-
* @param message - The commit message
|
|
71
|
-
* @returns Task ID or null if format is invalid
|
|
72
|
-
*/
|
|
73
|
-
export declare function extractTaskId(message: string): string | null;
|
|
74
|
-
/**
|
|
75
|
-
* Commit message options for formatting.
|
|
76
|
-
*/
|
|
77
|
-
export interface CommitMessageOptions {
|
|
78
|
-
type: CommitType;
|
|
79
|
-
taskId: string;
|
|
80
|
-
description: string;
|
|
81
|
-
body?: string;
|
|
82
|
-
footer?: string;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Create a full commit message with optional body and footer.
|
|
86
|
-
*
|
|
87
|
-
* @param options - Commit message components
|
|
88
|
-
* @returns Formatted commit message
|
|
89
|
-
*/
|
|
90
|
-
export declare function createCommitMessage(options: CommitMessageOptions): string;
|
|
91
|
-
/**
|
|
92
|
-
* Batch validate multiple commit messages.
|
|
93
|
-
*
|
|
94
|
-
* Useful for pre-commit hooks that check all staged commits.
|
|
95
|
-
*
|
|
96
|
-
* @param messages - Array of commit messages
|
|
97
|
-
* @returns Object with validation results
|
|
98
|
-
*/
|
|
99
|
-
export declare function validateCommitMessages(messages: string[]): {
|
|
100
|
-
valid: boolean;
|
|
101
|
-
errors: Array<{
|
|
102
|
-
message: string;
|
|
103
|
-
error: string;
|
|
104
|
-
}>;
|
|
105
|
-
};
|
|
106
|
-
/**
|
|
107
|
-
* Generate a commit message from task information.
|
|
108
|
-
*
|
|
109
|
-
* This is a helper for agents to generate properly formatted commits.
|
|
110
|
-
*
|
|
111
|
-
* @param taskId - The task ID
|
|
112
|
-
* @param taskTitle - The task title (will be converted to description)
|
|
113
|
-
* @param type - Commit type (defaults to "feat")
|
|
114
|
-
* @returns Formatted commit message
|
|
115
|
-
*/
|
|
116
|
-
export declare function generateCommitFromTask(taskId: string, taskTitle: string, type?: CommitType): string;
|
|
117
|
-
/**
|
|
118
|
-
* Commit validation result for pre-commit hooks.
|
|
119
|
-
*/
|
|
120
|
-
export interface CommitValidationResult {
|
|
121
|
-
isValid: boolean;
|
|
122
|
-
taskId: string | null;
|
|
123
|
-
errors: string[];
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Validate a commit for pre-commit hook usage.
|
|
127
|
-
*
|
|
128
|
-
* This is the main entry point for pre-commit hooks.
|
|
129
|
-
*
|
|
130
|
-
* @param message - The commit message to validate
|
|
131
|
-
* @param expectedTaskId - Optional expected task ID
|
|
132
|
-
* @returns Validation result
|
|
133
|
-
*/
|
|
134
|
-
export declare function validateForPreCommit(message: string, expectedTaskId?: string): CommitValidationResult;
|
|
135
|
-
//# sourceMappingURL=commit.d.ts.map
|
package/dist/git/commit.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"commit.d.ts","sourceRoot":"","sources":["../../src/git/commit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,UAAU,4FAUrB,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAMpD,qBAAa,iBAAkB,SAAQ,KAAK;aACG,aAAa,EAAE,MAAM;gBAAtD,OAAO,EAAE,MAAM,EAAkB,aAAa,EAAE,MAAM;CAInE;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAuChE;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAClB,MAAM,CAER;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAG9D;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAOxE;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAO5D;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAczE;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG;IAC1D,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnD,CAoBA;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,UAAmB,GACxB,MAAM,CAMR;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,cAAc,CAAC,EAAE,MAAM,GACtB,sBAAsB,CA2BxB"}
|