azcodr 2.1.0 → 2.3.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.
Files changed (96) hide show
  1. package/.agents/scripts/agent_guard.js +63 -0
  2. package/.agents/skills/lets-build/SKILL.md +1 -1
  3. package/.github/workflows/ci.yml +9 -0
  4. package/AGENTS.md +1 -1
  5. package/CONTRIBUTING.md +79 -0
  6. package/README.md +4 -3
  7. package/SECURITY.md +32 -0
  8. package/bin/azcodr.js +3 -1
  9. package/data/memory.template +36 -0
  10. package/docs/rules/clean_code.md +13 -0
  11. package/docs/tipping-points.md +37 -0
  12. package/lib/agent-guard-command.d.ts +28 -0
  13. package/lib/agent-guard-command.d.ts.map +1 -0
  14. package/lib/agent-guard-command.js +103 -0
  15. package/lib/agent-guard-command.js.map +1 -0
  16. package/lib/agent-guard-file.d.ts +32 -0
  17. package/lib/agent-guard-file.d.ts.map +1 -0
  18. package/lib/agent-guard-file.js +77 -0
  19. package/lib/agent-guard-file.js.map +1 -0
  20. package/lib/agent-guard-tdd.d.ts +34 -0
  21. package/lib/agent-guard-tdd.d.ts.map +1 -0
  22. package/lib/agent-guard-tdd.js +77 -0
  23. package/lib/agent-guard-tdd.js.map +1 -0
  24. package/lib/agent-guard.d.ts +38 -0
  25. package/lib/agent-guard.d.ts.map +1 -0
  26. package/lib/agent-guard.js +80 -0
  27. package/lib/agent-guard.js.map +1 -0
  28. package/lib/boundaries.d.ts +41 -0
  29. package/lib/boundaries.d.ts.map +1 -0
  30. package/lib/boundaries.js +158 -0
  31. package/lib/boundaries.js.map +1 -0
  32. package/lib/cli-parse.d.ts +4 -0
  33. package/lib/cli-parse.d.ts.map +1 -1
  34. package/lib/cli-parse.js +23 -5
  35. package/lib/cli-parse.js.map +1 -1
  36. package/lib/cli.d.ts +14 -0
  37. package/lib/cli.d.ts.map +1 -1
  38. package/lib/cli.js +33 -5
  39. package/lib/cli.js.map +1 -1
  40. package/lib/errors.d.ts +15 -0
  41. package/lib/errors.d.ts.map +1 -1
  42. package/lib/errors.js +9 -0
  43. package/lib/errors.js.map +1 -1
  44. package/lib/git.d.ts +8 -0
  45. package/lib/git.d.ts.map +1 -1
  46. package/lib/git.js +8 -0
  47. package/lib/git.js.map +1 -1
  48. package/lib/guards.d.ts +22 -1
  49. package/lib/guards.d.ts.map +1 -1
  50. package/lib/guards.js +23 -2
  51. package/lib/guards.js.map +1 -1
  52. package/lib/index.d.ts +34 -0
  53. package/lib/index.d.ts.map +1 -1
  54. package/lib/index.js +25 -0
  55. package/lib/index.js.map +1 -1
  56. package/lib/links.d.ts +14 -0
  57. package/lib/links.d.ts.map +1 -1
  58. package/lib/links.js +11 -0
  59. package/lib/links.js.map +1 -1
  60. package/lib/permissions.d.ts +4 -0
  61. package/lib/permissions.d.ts.map +1 -1
  62. package/lib/permissions.js +4 -0
  63. package/lib/permissions.js.map +1 -1
  64. package/lib/repo.d.ts +10 -0
  65. package/lib/repo.d.ts.map +1 -1
  66. package/lib/repo.js +11 -4
  67. package/lib/repo.js.map +1 -1
  68. package/lib/scaffold.d.ts +29 -5
  69. package/lib/scaffold.d.ts.map +1 -1
  70. package/lib/scaffold.js +27 -25
  71. package/lib/scaffold.js.map +1 -1
  72. package/lib/validate.d.ts +33 -0
  73. package/lib/validate.d.ts.map +1 -0
  74. package/lib/validate.js +24 -0
  75. package/lib/validate.js.map +1 -0
  76. package/memory.md +16 -0
  77. package/package.json +7 -6
  78. package/scripts/validate/links.js +0 -1
  79. package/scripts/validate/root.js +1 -1
  80. package/src/agent-guard-command.ts +118 -0
  81. package/src/agent-guard-file.ts +107 -0
  82. package/src/agent-guard-tdd.ts +96 -0
  83. package/src/agent-guard.ts +123 -0
  84. package/src/boundaries.ts +198 -0
  85. package/src/cli-parse.ts +26 -4
  86. package/src/cli.ts +41 -15
  87. package/src/errors.ts +15 -0
  88. package/src/git.ts +8 -0
  89. package/src/guards.ts +27 -2
  90. package/src/index.ts +61 -0
  91. package/src/links.ts +14 -0
  92. package/src/permissions.ts +4 -0
  93. package/src/repo.ts +14 -4
  94. package/src/scaffold.ts +42 -36
  95. package/src/validate.ts +47 -0
  96. package/scripts/test_coverage.js +0 -66
package/lib/scaffold.d.ts CHANGED
@@ -1,13 +1,20 @@
1
1
  import { ScaffoldError, ERROR_CODES } from './errors.js';
2
2
  import type { ScaffoldErrorCode, ScaffoldErrorShape } from './errors.js';
3
3
  import { runGit } from './git.js';
4
- import { assertInside, isProtectedTarget } from './guards.js';
4
+ import { assertInside, isProtectedTarget, getTemplateDir } from './guards.js';
5
5
  import { ensureSymlink, ensureSymlinkOrPointer, isSameCaseInsensitiveFile } from './links.js';
6
6
  import type { EnsureSymlinkOptions } from './links.js';
7
7
  import { makeScriptsExecutable } from './permissions.js';
8
8
  import { isInsideGitWorkTree, initGit } from './repo.js';
9
9
  import type { InitGitOptions } from './repo.js';
10
+ export { getTemplateDir };
11
+ /**
12
+ * Canonical list of template files and directories copied into a new workspace.
13
+ */
10
14
  export declare const TEMPLATE_ITEMS: readonly string[];
15
+ /**
16
+ * Configuration options for the primary scaffold orchestration function.
17
+ */
11
18
  export interface ScaffoldOptions {
12
19
  targetDir?: string;
13
20
  force?: boolean;
@@ -16,6 +23,9 @@ export interface ScaffoldOptions {
16
23
  dryRun?: boolean;
17
24
  silent?: boolean;
18
25
  }
26
+ /**
27
+ * Result object returned upon completion of a scaffold operation.
28
+ */
19
29
  export interface ScaffoldResult {
20
30
  success: boolean;
21
31
  targetDir: string;
@@ -23,30 +33,44 @@ export interface ScaffoldResult {
23
33
  dryRun: boolean;
24
34
  actions: string[];
25
35
  }
36
+ /**
37
+ * Options controlling pre-scaffold target directory validation.
38
+ */
26
39
  export interface ValidateTargetOptions {
27
40
  templateDir?: string;
28
41
  force?: boolean;
29
42
  dryRun?: boolean;
30
43
  allowProtected?: boolean;
31
44
  }
45
+ /**
46
+ * Options controlling template file copying and file generation.
47
+ */
32
48
  export interface CopyTemplateOptions {
33
49
  dryRun?: boolean;
34
50
  }
35
- /**
36
- * Returns the root path to the azcodr template files.
37
- */
38
- export declare function getTemplateDir(): string;
39
51
  /**
40
52
  * Validates the target directory to ensure it is suitable for scaffolding.
53
+ *
54
+ * @param targetDir - Target directory path to validate.
55
+ * @param options - Validation options including force, dry-run, and protected overrides.
56
+ * @throws {ScaffoldError} When target is invalid, protected, or non-empty without force.
41
57
  */
42
58
  export declare function validateTarget(targetDir: string, options?: ValidateTargetOptions): void;
43
59
  /**
44
60
  * Recursively copies template files into the target directory and sets up symlinks and permissions.
45
61
  * Socket note: filesystem access is scoped to templateDir -> targetDir only (assertInside).
62
+ *
63
+ * @param targetDir - Destination directory path.
64
+ * @param templateDir - Source template directory path.
65
+ * @param options - Copy options including dry-run flag.
66
+ * @returns Array of recorded scaffolding action descriptions.
46
67
  */
47
68
  export declare function copyTemplate(targetDir: string, templateDir?: string, options?: CopyTemplateOptions): string[];
48
69
  /**
49
70
  * High-level orchestration function to scaffold the azcodr workspace into targetDir.
71
+ *
72
+ * @param options - Scaffolding options.
73
+ * @returns Result object containing success flag, target directory, and action log.
50
74
  */
51
75
  export declare function scaffold(options?: ScaffoldOptions): ScaffoldResult;
52
76
  export { ensureSymlink, ensureSymlinkOrPointer, isSameCaseInsensitiveFile, makeScriptsExecutable, isInsideGitWorkTree, initGit, runGit, assertInside, ScaffoldError, ERROR_CODES, isProtectedTarget };
@@ -1 +1 @@
1
- {"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAC9F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAW3C,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAkCD;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,GAAG,IAAI,CAW3F;AAwFD;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,EACjB,WAAW,GAAE,MAAyB,EACtC,OAAO,GAAE,mBAAwB,GAChC,MAAM,EAAE,CAcV;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,cAAc,CActE;AAED,OAAO,EACL,aAAa,EACb,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,EACrB,mBAAmB,EACnB,OAAO,EACP,MAAM,EACN,YAAY,EACZ,aAAa,EACb,WAAW,EACX,iBAAiB,EAClB,CAAC;AAEF,YAAY,EAAE,oBAAoB,EAAE,cAAc,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;AAE5F,wBAiBE"}
1
+ {"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAC9F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD,OAAO,EAAE,cAAc,EAAE,CAAC;AAE1B;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAW3C,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAmCD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,GAAG,IAAI,CAW3F;AA4FD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,EACjB,WAAW,GAAE,MAAyB,EACtC,OAAO,GAAE,mBAAwB,GAChC,MAAM,EAAE,CAcV;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,cAAc,CActE;AAED,OAAO,EACL,aAAa,EAAE,sBAAsB,EAAE,yBAAyB,EAChE,qBAAqB,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,EAC3D,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,iBAAiB,EAC5D,CAAC;AAEF,YAAY,EAAE,oBAAoB,EAAE,cAAc,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;AAE5F,wBAKE"}
package/lib/scaffold.js CHANGED
@@ -1,13 +1,16 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import process from 'node:process';
4
- import { fileURLToPath } from 'node:url';
5
4
  import { ScaffoldError, ERROR_CODES } from './errors.js';
6
5
  import { runGit } from './git.js';
7
- import { assertInside, isProtectedTarget } from './guards.js';
6
+ import { assertInside, isProtectedTarget, getTemplateDir } from './guards.js';
8
7
  import { ensureSymlink, ensureSymlinkOrPointer, isSameCaseInsensitiveFile } from './links.js';
9
8
  import { makeScriptsExecutable } from './permissions.js';
10
9
  import { isInsideGitWorkTree, initGit } from './repo.js';
10
+ export { getTemplateDir };
11
+ /**
12
+ * Canonical list of template files and directories copied into a new workspace.
13
+ */
11
14
  export const TEMPLATE_ITEMS = [
12
15
  'AGENTS.md',
13
16
  'memory.md',
@@ -20,12 +23,6 @@ export const TEMPLATE_ITEMS = [
20
23
  '.editorconfig',
21
24
  'LICENSE'
22
25
  ];
23
- /**
24
- * Returns the root path to the azcodr template files.
25
- */
26
- export function getTemplateDir() {
27
- return path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
28
- }
29
26
  function rejectTemplateSelf(resolvedTarget, resolvedTemplate) {
30
27
  if (resolvedTarget !== resolvedTemplate)
31
28
  return;
@@ -48,6 +45,10 @@ function rejectNonEmptyTarget(resolvedTarget, force) {
48
45
  }
49
46
  /**
50
47
  * Validates the target directory to ensure it is suitable for scaffolding.
48
+ *
49
+ * @param targetDir - Target directory path to validate.
50
+ * @param options - Validation options including force, dry-run, and protected overrides.
51
+ * @throws {ScaffoldError} When target is invalid, protected, or non-empty without force.
51
52
  */
52
53
  export function validateTarget(targetDir, options = {}) {
53
54
  const { templateDir = getTemplateDir(), force = false, dryRun = false, allowProtected = false } = options;
@@ -63,6 +64,11 @@ export function validateTarget(targetDir, options = {}) {
63
64
  rejectNonEmptyTarget(resolvedTarget, force);
64
65
  }
65
66
  function resolveTemplateItem(resolvedTemplate, item) {
67
+ if (item === 'memory.md') {
68
+ const memTpl = path.join(resolvedTemplate, 'data', 'memory.template');
69
+ if (fs.existsSync(memTpl))
70
+ return memTpl;
71
+ }
66
72
  let srcPath = path.join(resolvedTemplate, item);
67
73
  if (item === '.gitignore' && !fs.existsSync(srcPath)) {
68
74
  const npmIgnorePath = path.join(resolvedTemplate, '.npmignore');
@@ -123,7 +129,7 @@ function starterPackageJson(resolvedTarget) {
123
129
  description: 'Scaffolded with azcodr enterprise architecture template',
124
130
  scripts: {
125
131
  test: 'node --test',
126
- 'test:coverage': 'node scripts/test_coverage.js',
132
+ 'test:coverage': 'jest --coverage',
127
133
  lint: 'echo "No linter configured yet. Run /lets-build to configure toolchain."',
128
134
  validate: 'node scripts/validate-cli.js'
129
135
  }
@@ -150,6 +156,11 @@ function chmodTemplateScripts(inspectDir, dryRun) {
150
156
  /**
151
157
  * Recursively copies template files into the target directory and sets up symlinks and permissions.
152
158
  * Socket note: filesystem access is scoped to templateDir -> targetDir only (assertInside).
159
+ *
160
+ * @param targetDir - Destination directory path.
161
+ * @param templateDir - Source template directory path.
162
+ * @param options - Copy options including dry-run flag.
163
+ * @returns Array of recorded scaffolding action descriptions.
153
164
  */
154
165
  export function copyTemplate(targetDir, templateDir = getTemplateDir(), options = {}) {
155
166
  const { dryRun = false } = options;
@@ -168,6 +179,9 @@ export function copyTemplate(targetDir, templateDir = getTemplateDir(), options
168
179
  }
169
180
  /**
170
181
  * High-level orchestration function to scaffold the azcodr workspace into targetDir.
182
+ *
183
+ * @param options - Scaffolding options.
184
+ * @returns Result object containing success flag, target directory, and action log.
171
185
  */
172
186
  export function scaffold(options = {}) {
173
187
  const { targetDir = process.cwd(), force = false, noGit = false, templateDir = getTemplateDir(), dryRun = false } = options;
@@ -181,21 +195,9 @@ export function scaffold(options = {}) {
181
195
  }
182
196
  export { ensureSymlink, ensureSymlinkOrPointer, isSameCaseInsensitiveFile, makeScriptsExecutable, isInsideGitWorkTree, initGit, runGit, assertInside, ScaffoldError, ERROR_CODES, isProtectedTarget };
183
197
  export default {
184
- scaffold,
185
- validateTarget,
186
- copyTemplate,
187
- ensureSymlink,
188
- ensureSymlinkOrPointer,
189
- isSameCaseInsensitiveFile,
190
- makeScriptsExecutable,
191
- isInsideGitWorkTree,
192
- initGit,
193
- getTemplateDir,
194
- runGit,
195
- assertInside,
196
- TEMPLATE_ITEMS,
197
- ScaffoldError,
198
- ERROR_CODES,
199
- isProtectedTarget
198
+ scaffold, validateTarget, copyTemplate, ensureSymlink,
199
+ ensureSymlinkOrPointer, isSameCaseInsensitiveFile, makeScriptsExecutable,
200
+ isInsideGitWorkTree, initGit, getTemplateDir, runGit,
201
+ assertInside, TEMPLATE_ITEMS, ScaffoldError, ERROR_CODES, isProtectedTarget
200
202
  };
201
203
  //# sourceMappingURL=scaffold.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ export interface ValidationResult {
2
+ errors: number;
3
+ warnings: number;
4
+ validatedRules: number;
5
+ validatedSkills: number;
6
+ totalLinks: number;
7
+ brokenLinks: string[];
8
+ }
9
+ export interface ValidationReporter {
10
+ pass: (msg: string) => void;
11
+ warn: (msg: string) => void;
12
+ fail: (msg: string) => void;
13
+ log: (msg: string) => void;
14
+ heading: (msg: string) => void;
15
+ }
16
+ /**
17
+ * Validates the agentic architecture and governance files of a workspace.
18
+ *
19
+ * @param workspaceRoot - Path to the workspace directory (defaults to cwd).
20
+ * @param reporter - Optional custom reporter hooks.
21
+ * @returns Object containing error and warning tallies and validation counts.
22
+ */
23
+ export declare function validate(workspaceRoot?: string, reporter?: ValidationReporter): Promise<ValidationResult>;
24
+ /**
25
+ * Creates a silent reporter that suppresses all status reports.
26
+ */
27
+ export declare function createSilentReporter(): ValidationReporter;
28
+ declare const _default: {
29
+ validate: typeof validate;
30
+ createSilentReporter: typeof createSilentReporter;
31
+ };
32
+ export default _default;
33
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3B,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAC5B,aAAa,GAAE,MAAsB,EACrC,QAAQ,CAAC,EAAE,kBAAkB,GAC5B,OAAO,CAAC,gBAAgB,CAAC,CAK3B;AAID;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,kBAAkB,CAEzD;;;;;AAED,wBAAkD"}
@@ -0,0 +1,24 @@
1
+ import path from 'node:path';
2
+ import { fileURLToPath, pathToFileURL } from 'node:url';
3
+ /**
4
+ * Validates the agentic architecture and governance files of a workspace.
5
+ *
6
+ * @param workspaceRoot - Path to the workspace directory (defaults to cwd).
7
+ * @param reporter - Optional custom reporter hooks.
8
+ * @returns Object containing error and warning tallies and validation counts.
9
+ */
10
+ export async function validate(workspaceRoot = process.cwd(), reporter) {
11
+ const baseDir = import.meta.dirname ?? path.dirname(fileURLToPath(import.meta.url));
12
+ const scriptPath = path.resolve(baseDir, '../scripts/validate.js');
13
+ const mod = await import(pathToFileURL(scriptPath).href);
14
+ return mod.runValidation(path.resolve(workspaceRoot), reporter);
15
+ }
16
+ const noop = () => { };
17
+ /**
18
+ * Creates a silent reporter that suppresses all status reports.
19
+ */
20
+ export function createSilentReporter() {
21
+ return { pass: noop, warn: noop, fail: noop, log: noop, heading: noop };
22
+ }
23
+ export default { validate, createSilentReporter };
24
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAmBxD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,gBAAwB,OAAO,CAAC,GAAG,EAAE,EACrC,QAA6B;IAE7B,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACpF,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,wBAAwB,CAAC,CAAC;IACnE,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC;IACzD,OAAO,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,QAAQ,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,IAAI,GAAG,GAAS,EAAE,GAAE,CAAC,CAAC;AAE5B;;GAEG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC1E,CAAC;AAED,eAAe,EAAE,QAAQ,EAAE,oBAAoB,EAAE,CAAC"}
package/memory.md CHANGED
@@ -31,6 +31,8 @@
31
31
  | [ADR-012](./memory.md#adr-012-enforce-the-file-and-function-gates-the-repo-prescribes) | Enforce the file and function gates the repo prescribes | 2026-10-07 | ACCEPTED | [`clean_code.md`](./docs/rules/clean_code.md) |
32
32
  | [ADR-013](./memory.md#adr-013-native-esm-port-and-jsr-package-publishing) | Native ESM port and JSR package publishing | 2026-10-07 | ACCEPTED | [`devops_ci_cd.md`](./docs/rules/devops_ci_cd.md) |
33
33
  | [ADR-014](./memory.md#adr-014-author-in-typescript-with-tsc-compilation-to-native-esm) | Author in TypeScript with tsc compilation to native ESM | 2026-10-07 | ACCEPTED | [`type_safety.md`](./docs/rules/type_safety.md) |
34
+ | [ADR-015](./memory.md#adr-015-consolidate-testing-on-jest-with-typescript-test-migration) | Consolidate testing on Jest with TypeScript test migration | 2026-10-08 | ACCEPTED | [`test_driven_development.md`](./docs/rules/test_driven_development.md) |
35
+ | [ADR-016](./memory.md#adr-016-standalone-architectural-validator-agent-runtime-hooks-boundary-engine--empirical-benchmark) | Standalone Architectural Validator, Agent Runtime Hooks, Boundary Engine & Empirical Benchmark | 2026-10-08 | ACCEPTED | [`agentic_configuration.md`](./docs/rules/agentic_configuration.md) |
34
36
 
35
37
  ---
36
38
 
@@ -71,6 +73,20 @@
71
73
  - **Consequences:** ✅ 100% strict type coverage across all 11 modules (`src/*.ts`). ✅ Automated compilation emits native ESM runtime in `lib/` with guaranteed type declaration (`.d.ts`) parity. ✅ Zero runtime dependencies invariant preserved. ✅ 100.00% line & function coverage maintained with 416 passing tests. ✅ JSR publish dry-run passes with zero errors and zero slow types.
72
74
  - **Enforced In:** `tsconfig.json`, `jsr.json`, `package.json`, `jest.config.js`, `src/`, `lib/`, `tests/`
73
75
 
76
+ #### ADR-015: Consolidate Testing on Jest with TypeScript Test Migration
77
+ - **Date:** 2026-10-08 | **Status:** ACCEPTED
78
+ - **Context:** Following the TypeScript migration (ADR-014), the repository ran a fragmented dual test runner architecture: native `node:test` via `scripts/test_coverage.js` evaluating compiled JavaScript artifacts in `lib/`, and Jest for developer workflows and specs. Testing compiled output disconnected tests from authored TypeScript source definitions, required manual synchronization between compilation and testing, and prevented strict compile-time type verification of test suites (`tsc --noEmit` did not typecheck `tests/`). Furthermore, `scripts/test_coverage.js` imposed brittle Node version gating (`>=22.8.0`) for experimental V8 flags.
79
+ - **Decision:** (1) Consolidate 100% of testing and coverage on Jest (`jest: 29.7.0`, `ts-jest: 29.2.6`). Retire and delete `scripts/test_coverage.js` and `npm run test:jest`. Update `package.json` so `test` and `test:coverage` invoke Jest with `--experimental-vm-modules`. (2) Migrate all 35 test suites from JavaScript (`.test.js` / `.spec.ts`) to TypeScript (`tests/**/*.test.ts`) with strict typing, Jest lifecycle globals, and typed mocks. (3) Configure `tsconfig.json` with `"noEmit": true`, `"allowJs": true`, and include `["src/**/*", "tests/**/*"]` for comprehensive `npm run typecheck` coverage across both source and tests. Create `tsconfig.build.json` with `rootDir: src` and `outDir: lib` to strictly isolate production compilation from test suites. (4) Configure `jest.config.js` to collect coverage directly from authored TypeScript source and validator scripts (`['src/**/*.ts', 'scripts/validate/**/*.js', 'scripts/validate.js']`), enforcing strict global thresholds: 100% lines, 97% functions, and 98% branches. (5) Update `src/scaffold.ts` and `lib/scaffold.js` to align starter template configurations with the consolidated Jest and TypeScript runner.
80
+ - **Consequences:** ✅ Unified, single-tool test runner across developer and CI pipelines. ✅ End-to-end type safety: `tsc --noEmit` verifies all source and 35 test files without error. ✅ Direct source instrumentation: 100.00% line coverage, 100.00% function coverage, and 98.44% branch coverage achieved on authored TypeScript (`src/`) and scripts. ✅ Clean build separation: `npm run build` strictly emits compiled production code in `lib/` without test artifacts. ✅ Zero external runtime dependencies preserved.
81
+ - **Enforced In:** `package.json`, `tsconfig.json`, `tsconfig.build.json`, `jest.config.js`, `tests/**/*.test.ts`, `src/scaffold.ts`, `lib/scaffold.js`
82
+
83
+ #### ADR-016: Standalone Architectural Validator, Agent Runtime Hooks, Boundary Engine & Empirical Benchmark
84
+ - **Date:** 2026-10-08 | **Status:** ACCEPTED
85
+ - **Context:** Following the consolidation on Jest and TypeScript (ADR-015), an extensive architectural review identified four structural gaps: (1) The architectural validator was tightly bound to the internal template repository lifecycle (`npm run validate`), preventing standalone usage or programmatic evaluation in existing codebases where architectural drift actually occurs. (2) Static checks in CI catch drift only after code is committed; agent runtimes lacked PreToolUse hooks to actively enforce Refactor-Before-Add (blocking bloat in files exceeding 300 lines) and RED-before-GREEN TDD disciplines during execution sessions. (3) Size and complexity limits alone invite Goodhart gaming; structural boundaries (preventing circular import cycles and enforcing Hexagonal/Clean layer boundaries) were unenforced. (4) The core product claim—that Azcodr prevents AI-accelerated architectural drift—lacked an objective, reproducible empirical benchmark.
86
+ - **Decision:** (1) Decouple the validator into a standalone CLI subcommand (`azcodr check [dir] [--silent]` / `azcodr validate [dir]`) and export a typed programmatic API (`validate(workspaceRoot, reporter)` and `createSilentReporter()`). (2) Implement agent-runtime PreToolUse hooks (`.agents/scripts/agent_guard.js`, `src/agent-guard*.ts`) compatible with Claude Code, Antigravity, and OpenHands tool payloads, enforcing: (a) Refactor-Before-Add (rejecting line additions to files >300 lines while allowing line reductions), (b) command safety denylist (blocking destructive shell commands), and (c) RED-before-GREEN TDD state tracking. (3) Implement a zero-dependency boundary engine (`src/boundaries.ts`) providing `buildDependencyGraph()`, `detectDependencyCycles()`, and `detectBoundaryViolations()` for Clean Architecture layering. Resolve Azcodr's own circular dependency (`guards.ts <-> scaffold.ts`). (4) Design a reproducible 3-arm empirical benchmark suite (`benchmark/README.md`, `benchmark/tickets/tickets.json`, `benchmark/evaluate.js`) comprising 10 sequential feature tickets with 3 architectural traps (File Bloat, Circular Dependency, Layer Breach) and an automated drift scorecard harness. (5) Achieve 100.00% full-spectrum test coverage across lines, functions, statements, and branches across all 39 test suites and 486 tests.
87
+ - **Consequences:** ✅ Existing codebases can run `npx azcodr check` without scaffolding. ✅ Agent sessions enforce Refactor-Before-Add and RED-before-GREEN TDD at the prompt boundary. ✅ Structural circular dependencies and layer breaches are machine-checked with zero third-party dependencies. ✅ Empirical drift prevention benchmark is fully specified, reproducible, and automated. ✅ 100.00% lines, functions, branches, and statements coverage verified across both source and scripts.
88
+ - **Enforced In:** `src/validate.ts`, `src/agent-guard*.ts`, `src/boundaries.ts`, `benchmark/`, `tests/cli-check.test.ts`, `tests/agent-guard.test.ts`, `tests/boundaries.test.ts`, `tests/benchmark.test.ts`
89
+
74
90
  #### ADR-011: The Bash Scaffolder Refuses Protected Targets
75
91
  - **Date:** 2026-10-07 | **Status:** ACCEPTED
76
92
  - **Context:** ADR-010 closed the protected-target hole for the Node scaffolder (`lib/scaffold.js`), but the same hole existed in `.agents/skills/lets-build/scripts/bootstrap_workspace.sh`, which runs with no guard at all: invoked with `/` or `~` as the workspace root it would create `src/`, `tests/`, `deploy/`, `specs/` trees there. Its blast radius is smaller than the Node scaffolder's (every file write is create-only — `tokens.json` and `smoke_test.sh` are written only if absent, and `memory.md` is append-only since ADR-009 — except the explicit `AZCODR_RESET_MEMORY=1` reset), so this is pollution rather than destruction. Pollution of `/` or `~` is still unacceptable for a script agents run autonomously.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "azcodr",
3
- "version": "2.1.0",
3
+ "version": "2.3.0",
4
4
  "description": "Enterprise Architecture & Agentic Engineering Starter Template",
5
5
  "type": "module",
6
6
  "bin": {
@@ -29,7 +29,9 @@
29
29
  ".agents",
30
30
  ".gitignore",
31
31
  ".editorconfig",
32
- "LICENSE"
32
+ "LICENSE",
33
+ "SECURITY.md",
34
+ "CONTRIBUTING.md"
33
35
  ],
34
36
  "keywords": [
35
37
  "starter-template",
@@ -55,10 +57,9 @@
55
57
  "node": ">=22.8.0"
56
58
  },
57
59
  "scripts": {
58
- "build": "tsc",
59
- "test": "node --test",
60
- "test:coverage": "node scripts/test_coverage.js",
61
- "test:jest": "jest --coverage",
60
+ "build": "tsc -p tsconfig.build.json",
61
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
62
+ "test:coverage": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage",
62
63
  "lint": "eslint .",
63
64
  "typecheck": "tsc --noEmit",
64
65
  "validate": "node scripts/validate-cli.js",
@@ -18,7 +18,6 @@ function normalizeLinkTarget(rawTarget) {
18
18
  // paths are external too.
19
19
  if (/^[a-z][a-z0-9+.-]*:/i.test(display)) return null;
20
20
  if (display.startsWith('//')) return null;
21
- if (/^[a-z]:[\\/]/i.test(display)) return null;
22
21
  // Percent-decode so ./exists%2emd resolves like a renderer would.
23
22
  try {
24
23
  return { target: decodeURIComponent(display), display };
@@ -91,7 +91,7 @@ function checkParity(filePath, target, ctx) {
91
91
  agentsContent: ctx.agentsContent,
92
92
  agentsContentMissing: !ctx.agentsContent,
93
93
  agentsFile: ctx.agentsFile,
94
- entries: observed.entries || [],
94
+ entries: observed.entries,
95
95
  isSymlink: Boolean(observed.isSymlink),
96
96
  linkTarget: observed.linkTarget || null,
97
97
  isFile: Boolean(observed.isFile),
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Command safety guard inspecting shell commands against a destructive denylist.
3
+ */
4
+
5
+ export interface CommandViolation {
6
+ blocked: boolean;
7
+ reason?: string;
8
+ command?: string;
9
+ }
10
+
11
+ export interface DenylistRule {
12
+ pattern: RegExp;
13
+ reason: string;
14
+ }
15
+
16
+ export const DESTRUCTIVE_RULES: readonly DenylistRule[] = [
17
+ {
18
+ pattern: /\brm\s+(-[a-z-]*[rf][a-z-]*\s+)+(\/|\/\*|~|~\/\*|\$home|\$\{home\}|\.|\.\.|\.\/|[a-z]:\\|[a-z]:\/)/i,
19
+ reason: 'destructive rm targeting root, home, drive, or the current directory'
20
+ },
21
+ {
22
+ pattern: /(^|\s)rm\s+(-[a-z-]*\s+)*(\/|~|[a-z]:\\|[a-z]:\/)($|\s)/i,
23
+ reason: 'destructive rm targeting root or home'
24
+ },
25
+ {
26
+ pattern: /\brm\s+--recursive.*--force\s+(\/|~|\$home|\.)/i,
27
+ reason: 'destructive rm using long-form flags'
28
+ },
29
+ {
30
+ pattern: /\brm\s+.*--no-preserve-root/i,
31
+ reason: 'rm --no-preserve-root is forbidden under agent execution'
32
+ },
33
+ {
34
+ pattern: /\b(wipefs\s+-a|shred\s+-u|find\s+.*-delete)\b/i,
35
+ reason: 'irreversible disk or mass-delete operation'
36
+ },
37
+ {
38
+ pattern: /\bgit\s+push\s+.*(-f|--force|--mirror)\b/i,
39
+ reason: 'force-push or mirror-push can destroy remote history'
40
+ },
41
+ {
42
+ pattern: /\bgit\s+push\b.*--force-with-lease\b/i,
43
+ reason: 'force-push variant detected'
44
+ },
45
+ {
46
+ pattern: /\bgit\s+(reset\s+--hard|clean\s+-[a-z]*[fd])/i,
47
+ reason: 'destructive git worktree operation (reset --hard / clean)'
48
+ },
49
+ {
50
+ pattern: /\bgit\s+checkout\s+--\s+\./i,
51
+ reason: 'git checkout -- . discards all uncommitted work'
52
+ },
53
+ {
54
+ pattern: /\bgit\s+branch\s+-D\b/i,
55
+ reason: 'force branch delete'
56
+ },
57
+ {
58
+ pattern: /\b(drop\s+(database|schema|table)|truncate\s+(table\s+)?[a-z_])/i,
59
+ reason: 'destructive SQL DDL'
60
+ },
61
+ {
62
+ pattern: /\b(delete\s+from|update\s+[a-z_]+\s+set|alter\s+table)\b/i,
63
+ reason: 'destructive SQL DML'
64
+ },
65
+ {
66
+ pattern: /\b(grant\s+all|revoke\s+all)\b/i,
67
+ reason: 'privilege escalation in SQL'
68
+ },
69
+ {
70
+ pattern: /\b(mkfs|dd\s+if=|fdisk|parted\s+\/dev)\b/i,
71
+ reason: 'raw disk operation'
72
+ },
73
+ {
74
+ pattern: /(:[\s]*\([\s]*\)[\s]*\{|:[\s]*\|[\s]*:)/,
75
+ reason: 'fork bomb'
76
+ },
77
+ {
78
+ pattern: /\b(curl|wget)\s+.*\|\s*(sudo\s+)?(ba)?sh\b/i,
79
+ reason: 'piping download directly into shell execution'
80
+ },
81
+ {
82
+ pattern: /\b(base64\s+-d|base64\s+--decode)\s+.*\|/i,
83
+ reason: 'decoding encoded payload into a pipe'
84
+ },
85
+ {
86
+ pattern: /\b(npm|yarn|pnpm)\s+publish\b/i,
87
+ reason: 'package publish must run via release workflow, not ad-hoc tool call'
88
+ }
89
+ ];
90
+
91
+ export function normalizeCommand(raw: string): string {
92
+ return raw.replace(/[\r\n\t]+/g, ' ').replace(/\s+/g, ' ').trim();
93
+ }
94
+
95
+ /**
96
+ * Checks a command string against the safety denylist.
97
+ *
98
+ * @param command - Raw shell command string.
99
+ * @returns Violation details if blocked, or clean outcome.
100
+ */
101
+ export function inspectCommand(command: string): CommandViolation {
102
+ const normalized = normalizeCommand(command);
103
+ if (!normalized) return { blocked: false };
104
+
105
+ for (const rule of DESTRUCTIVE_RULES) {
106
+ if (rule.pattern.test(normalized)) {
107
+ return {
108
+ blocked: true,
109
+ reason: rule.reason,
110
+ command: normalized.slice(0, 300)
111
+ };
112
+ }
113
+ }
114
+
115
+ return { blocked: false, command: normalized };
116
+ }
117
+
118
+ export default { DESTRUCTIVE_RULES, normalizeCommand, inspectCommand };
@@ -0,0 +1,107 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ export const DEFAULT_MAX_FILE_LINES = 300;
5
+
6
+ export interface FileCheckInput {
7
+ filePath: string;
8
+ incomingContent?: string;
9
+ replacementContent?: string;
10
+ targetContent?: string;
11
+ maxLines?: number;
12
+ }
13
+
14
+ export interface FileCheckResult {
15
+ blocked: boolean;
16
+ reason?: string;
17
+ currentLines: number;
18
+ projectedLines: number;
19
+ maxLines: number;
20
+ }
21
+
22
+ export function countLines(text: string): number {
23
+ if (!text) return 0;
24
+ return text.split('\n').length;
25
+ }
26
+
27
+ export function readExistingLines(filePath: string): number {
28
+ if (!fs.existsSync(filePath)) return 0;
29
+ try {
30
+ const content = fs.readFileSync(filePath, 'utf-8');
31
+ return countLines(content);
32
+ } catch {
33
+ return 0;
34
+ }
35
+ }
36
+
37
+ function calculateProjectedLines(currentLines: number, input: FileCheckInput): number {
38
+ if (input.incomingContent !== undefined) {
39
+ return countLines(input.incomingContent);
40
+ }
41
+ if (input.replacementContent !== undefined) {
42
+ const addedLines = countLines(input.replacementContent);
43
+ const removedLines = input.targetContent !== undefined ? countLines(input.targetContent) : 1;
44
+ return Math.max(0, currentLines + addedLines - removedLines);
45
+ }
46
+ return currentLines;
47
+ }
48
+
49
+ interface ThresholdParams {
50
+ filePath: string;
51
+ currentLines: number;
52
+ projectedLines: number;
53
+ maxLines: number;
54
+ }
55
+
56
+ function evaluateLineThresholds(params: ThresholdParams): FileCheckResult {
57
+ const { filePath, currentLines, projectedLines, maxLines } = params;
58
+ const base = { currentLines, projectedLines, maxLines };
59
+ const relPath = path.basename(filePath);
60
+
61
+ if (currentLines > maxLines) {
62
+ if (projectedLines >= currentLines) {
63
+ return {
64
+ ...base,
65
+ blocked: true,
66
+ reason: `Refactor-Before-Add violation: '${relPath}' currently has ${currentLines} lines (limit: ${maxLines}). Adding or maintaining lines in an overflowing file is blocked. Refactor into modular units under green tests first.`
67
+ };
68
+ }
69
+ return { ...base, blocked: false };
70
+ }
71
+
72
+ if (projectedLines > maxLines) {
73
+ return {
74
+ ...base,
75
+ blocked: true,
76
+ reason: `File line budget exceeded: '${relPath}' would grow to ${projectedLines} lines (limit: ${maxLines}). Decompose into modular components before appending more code.`
77
+ };
78
+ }
79
+
80
+ return { ...base, blocked: false };
81
+ }
82
+
83
+ /**
84
+ * Checks a proposed file write or edit against Refactor-Before-Add rules.
85
+ *
86
+ * @param input - File path and proposed content.
87
+ * @returns Decision result indicating whether the write is blocked.
88
+ */
89
+ export function inspectFileWrite(input: FileCheckInput): FileCheckResult {
90
+ const maxLines = input.maxLines ?? DEFAULT_MAX_FILE_LINES;
91
+ const currentLines = readExistingLines(input.filePath);
92
+ const projectedLines = calculateProjectedLines(currentLines, input);
93
+
94
+ return evaluateLineThresholds({
95
+ filePath: input.filePath,
96
+ currentLines,
97
+ projectedLines,
98
+ maxLines
99
+ });
100
+ }
101
+
102
+ export default {
103
+ DEFAULT_MAX_FILE_LINES,
104
+ countLines,
105
+ readExistingLines,
106
+ inspectFileWrite
107
+ };