@lifesavertech/archguard-guidance 2.0.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 +9 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +102 -0
- package/package.json +45 -0
package/README.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# @lifesavertech/archguard-guidance
|
|
2
|
+
|
|
3
|
+
Generates `AGENTS.md` and `.archguard/ARCHITECTURE_RULES.md` from `architecture.yaml`.
|
|
4
|
+
|
|
5
|
+
Most users should install `@lifesavertech/archguard-cli` rather than depending on this package directly.
|
|
6
|
+
|
|
7
|
+
v2.2 will add `archguard sync` to keep guidance files aligned with config.
|
|
8
|
+
|
|
9
|
+
Documentation: [github.com/lindseystead/ArchGuard](https://github.com/lindseystead/ArchGuard)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Generates project-facing guidance files from the architecture config. */
|
|
2
|
+
import { ArchitectureConfig } from "@lifesavertech/archguard-core";
|
|
3
|
+
export declare function generateEditorGuide(architecture: ArchitectureConfig): string;
|
|
4
|
+
export declare function generateAgentsGuide(architecture: ArchitectureConfig): string;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/** Generates project-facing guidance files from the architecture config. */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.generateEditorGuide = generateEditorGuide;
|
|
5
|
+
exports.generateAgentsGuide = generateAgentsGuide;
|
|
6
|
+
const archguard_core_1 = require("@lifesavertech/archguard-core");
|
|
7
|
+
function generateEditorGuide(architecture) {
|
|
8
|
+
const layerDescriptions = buildLayerDescriptions(architecture);
|
|
9
|
+
const rules = buildRuleDescriptions(architecture);
|
|
10
|
+
return `# Architecture Rules
|
|
11
|
+
|
|
12
|
+
This repository uses ArchGuard to enforce architectural boundaries. Treat these rules as hard constraints.
|
|
13
|
+
|
|
14
|
+
## Layer Structure
|
|
15
|
+
|
|
16
|
+
${layerDescriptions}
|
|
17
|
+
|
|
18
|
+
${buildUiLayerDescription(architecture)}
|
|
19
|
+
|
|
20
|
+
## Rules
|
|
21
|
+
|
|
22
|
+
${rules.join("\n")}
|
|
23
|
+
|
|
24
|
+
## General Guidelines
|
|
25
|
+
|
|
26
|
+
- **Do not create new folders** without explicit justification
|
|
27
|
+
- **Do not merge layers** or blur boundaries
|
|
28
|
+
- **Refactor violating code** instead of suppressing the rule
|
|
29
|
+
- **Escalate architecture questions** before introducing a new dependency shape
|
|
30
|
+
|
|
31
|
+
## When a Proposed Change Violates the Rules
|
|
32
|
+
|
|
33
|
+
If a proposed change violates these rules:
|
|
34
|
+
1. Read the violation message carefully.
|
|
35
|
+
2. Move the logic or dependency to the correct layer.
|
|
36
|
+
3. Avoid suppressing or bypassing the rule.
|
|
37
|
+
4. Document any intentional exception before changing the architecture.
|
|
38
|
+
|
|
39
|
+
Code should conform to the existing architecture unless the architecture is explicitly revised.
|
|
40
|
+
`;
|
|
41
|
+
}
|
|
42
|
+
function generateAgentsGuide(architecture) {
|
|
43
|
+
const layerDescriptions = buildLayerDescriptions(architecture);
|
|
44
|
+
const rules = buildRuleDescriptions(architecture);
|
|
45
|
+
return `# AGENTS.md
|
|
46
|
+
|
|
47
|
+
This repository uses ArchGuard for architecture enforcement. Follow these constraints when proposing or editing code.
|
|
48
|
+
|
|
49
|
+
## Architecture
|
|
50
|
+
|
|
51
|
+
${layerDescriptions}
|
|
52
|
+
|
|
53
|
+
${buildUiLayerDescription(architecture)}
|
|
54
|
+
|
|
55
|
+
## Required Constraints
|
|
56
|
+
|
|
57
|
+
${rules.join("\n")}
|
|
58
|
+
|
|
59
|
+
## Working Rules
|
|
60
|
+
|
|
61
|
+
- Keep the existing folder structure unless a structural change is explicitly requested.
|
|
62
|
+
- Do not bypass architectural violations by moving logic into a disallowed layer.
|
|
63
|
+
- Prefer refactoring code into an allowed layer over introducing exceptions.
|
|
64
|
+
- If the architecture needs to change, update \`architecture.yaml\` first and then regenerate supporting documents.
|
|
65
|
+
|
|
66
|
+
## Enforcement
|
|
67
|
+
|
|
68
|
+
These instructions are reference material for tooling and contributors. The enforceable source of truth is \`architecture.yaml\`, and validation happens through the ArchGuard CLI.
|
|
69
|
+
`;
|
|
70
|
+
}
|
|
71
|
+
function buildLayerDescriptions(architecture) {
|
|
72
|
+
return Object.keys(architecture.layers)
|
|
73
|
+
.map((layer) => {
|
|
74
|
+
const config = architecture.layers[layer];
|
|
75
|
+
const allowed = config.allowedImports.length > 0 ? config.allowedImports.join(", ") : "none";
|
|
76
|
+
return `- **${layer}**: Can import from: ${allowed}`;
|
|
77
|
+
})
|
|
78
|
+
.join("\n");
|
|
79
|
+
}
|
|
80
|
+
function buildRuleDescriptions(architecture) {
|
|
81
|
+
const rules = [];
|
|
82
|
+
if (architecture.rules.noBusinessLogicInComponents) {
|
|
83
|
+
rules.push("- **No business logic in components**: React components must not contain loops, complex conditionals, calculations, or data transformations. Extract these to the feature or domain layer.");
|
|
84
|
+
}
|
|
85
|
+
if (architecture.rules.noDataFetchingInUI) {
|
|
86
|
+
rules.push("- **No data fetching in UI**: UI layer components must not call fetch/axios/query hooks directly or invoke imported domain/data-access helpers. Move data access to the features layer.");
|
|
87
|
+
}
|
|
88
|
+
if ((0, archguard_core_1.isLayerBoundaryEnforcementEnabled)(architecture.rules)) {
|
|
89
|
+
rules.push("- **Enforce layer boundaries**: Respect the layer import rules. Do not create imports that violate the defined architecture.");
|
|
90
|
+
}
|
|
91
|
+
if (architecture.rules.noCircularLayerDeps) {
|
|
92
|
+
rules.push("- **No circular dependencies**: Do not create circular dependencies between layers.");
|
|
93
|
+
}
|
|
94
|
+
return rules;
|
|
95
|
+
}
|
|
96
|
+
function buildUiLayerDescription(architecture) {
|
|
97
|
+
const uiLayers = Array.from((0, archguard_core_1.resolveUiLayers)(architecture));
|
|
98
|
+
if (uiLayers.length === 0) {
|
|
99
|
+
return "";
|
|
100
|
+
}
|
|
101
|
+
return `## UI Layers\n\nReact UI behavior rules apply to files in: ${uiLayers.join(", ")}.\n`;
|
|
102
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lifesavertech/archguard-guidance",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Project guidance document generator for ArchGuard",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"engines": {
|
|
11
|
+
"node": ">=20"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"archguard",
|
|
15
|
+
"architecture",
|
|
16
|
+
"guidance"
|
|
17
|
+
],
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && tsc -b --force",
|
|
23
|
+
"prepack": "npm run build",
|
|
24
|
+
"build:test": "node -e \"require('fs').rmSync('dist-test',{recursive:true,force:true})\" && tsc -p tsconfig.test.json",
|
|
25
|
+
"test": "npm run build:test && node --test dist-test/index.test.js"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@lifesavertech/archguard-core": "2.0.0",
|
|
29
|
+
"yaml": "^2.3.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/node": "^20.0.0"
|
|
33
|
+
},
|
|
34
|
+
"author": "Lindsey Stead",
|
|
35
|
+
"homepage": "https://github.com/lindseystead/ArchGuard#readme",
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/lindseystead/ArchGuard/issues"
|
|
38
|
+
},
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "https://github.com/lindseystead/ArchGuard.git",
|
|
43
|
+
"directory": "packages/guidance"
|
|
44
|
+
}
|
|
45
|
+
}
|