@ryuenn3123/agentic-senior-core 2.5.22 → 3.0.2
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/.agent-context/prompts/bootstrap-design.md +22 -0
- package/.agent-context/prompts/init-project.md +55 -39
- package/.agent-context/prompts/refactor.md +2 -1
- package/.agent-context/prompts/review-code.md +3 -2
- package/.agent-context/review-checklists/pr-checklist.md +8 -1
- package/.agent-context/rules/architecture.md +11 -0
- package/.agent-context/rules/frontend-architecture.md +2 -2
- package/.agent-context/state/architecture-map.md +1 -1
- package/.agent-context/state/memory-continuity-benchmark.json +1 -1
- package/.agents/workflows/init-project.md +3 -3
- package/.agents/workflows/refactor.md +1 -1
- package/.agents/workflows/review-code.md +4 -5
- package/.cursorrules +27 -71
- package/.gemini/instructions.md +6 -7
- package/.github/copilot-instructions.md +5 -6
- package/.windsurfrules +27 -71
- package/AGENTS.md +7 -9
- package/CONTRIBUTING.md +18 -31
- package/README.md +17 -43
- package/bin/agentic-senior-core.js +0 -6
- package/lib/cli/commands/init.mjs +113 -650
- package/lib/cli/commands/launch.mjs +1 -23
- package/lib/cli/commands/rollback.mjs +1 -1
- package/lib/cli/commands/upgrade.mjs +47 -28
- package/lib/cli/compiler.mjs +77 -72
- package/lib/cli/constants.mjs +84 -26
- package/lib/cli/init-architecture-flow.mjs +231 -0
- package/lib/cli/init-detection-flow.mjs +123 -0
- package/lib/cli/init-options.mjs +344 -0
- package/lib/cli/init-selection.mjs +100 -0
- package/lib/cli/preflight.mjs +1 -1
- package/lib/cli/profile-packs.mjs +15 -1
- package/lib/cli/project-scaffolder.mjs +18 -154
- package/lib/cli/utils.mjs +224 -13
- package/mcp.json +19 -19
- package/package.json +5 -2
- package/scripts/context-triggered-audit.mjs +18 -18
- package/scripts/documentation-boundary-audit.mjs +92 -5
- package/scripts/forbidden-content-check.mjs +1 -1
- package/scripts/frontend-usability-audit.mjs +21 -28
- package/scripts/governance-weekly-report.mjs +29 -15
- package/scripts/llm-judge.mjs +2 -5
- package/scripts/mcp-server.mjs +389 -5
- package/scripts/release-gate.mjs +121 -145
- package/scripts/sync-thin-adapters.mjs +161 -0
- package/scripts/v3-purge-audit.mjs +231 -0
- package/scripts/validate-evidence-bundle.mjs +1 -1
- package/scripts/validate.mjs +224 -272
- package/.agent-context/blueprints/api-nextjs.md +0 -184
- package/.agent-context/blueprints/aspnet-api.md +0 -247
- package/.agent-context/blueprints/ci-github-actions.md +0 -226
- package/.agent-context/blueprints/ci-gitlab.md +0 -200
- package/.agent-context/blueprints/fastapi-service.md +0 -210
- package/.agent-context/blueprints/go-service.md +0 -217
- package/.agent-context/blueprints/graphql-grpc-api.md +0 -51
- package/.agent-context/blueprints/infrastructure-as-code.md +0 -62
- package/.agent-context/blueprints/kubernetes-manifests.md +0 -76
- package/.agent-context/blueprints/laravel-api.md +0 -233
- package/.agent-context/blueprints/mobile-app.md +0 -91
- package/.agent-context/blueprints/nestjs-logic.md +0 -247
- package/.agent-context/blueprints/observability.md +0 -227
- package/.agent-context/blueprints/spring-boot-api.md +0 -218
- package/.agent-context/profiles/platform.md +0 -13
- package/.agent-context/profiles/regulated.md +0 -13
- package/.agent-context/profiles/startup.md +0 -13
- package/.agent-context/review-checklists/frontend-excellence-rubric.md +0 -73
- package/.agent-context/review-checklists/frontend-skill-parity.md +0 -29
- package/.agent-context/review-checklists/frontend-usability.md +0 -35
- package/.agent-context/review-checklists/marketplace-acceptance.md +0 -60
- package/.agent-context/review-checklists/performance-audit.md +0 -71
- package/.agent-context/review-checklists/release-operations.md +0 -33
- package/.agent-context/review-checklists/security-audit.md +0 -119
- package/.agent-context/skills/README.md +0 -63
- package/.agent-context/skills/backend/README.md +0 -68
- package/.agent-context/skills/backend/architecture.md +0 -361
- package/.agent-context/skills/backend/compatibility-manifest.json +0 -8
- package/.agent-context/skills/backend/data-access.md +0 -231
- package/.agent-context/skills/backend/errors.md +0 -138
- package/.agent-context/skills/backend/validation.md +0 -117
- package/.agent-context/skills/backend.md +0 -29
- package/.agent-context/skills/cli/.evidence/compatibility-manifest.json +0 -5
- package/.agent-context/skills/cli/.evidence/sbom-excerpt.json +0 -10
- package/.agent-context/skills/cli/.evidence/test-report.json +0 -8
- package/.agent-context/skills/cli/CHANGELOG.md +0 -6
- package/.agent-context/skills/cli/README.md +0 -56
- package/.agent-context/skills/cli/compatibility-manifest.json +0 -8
- package/.agent-context/skills/cli/init.md +0 -38
- package/.agent-context/skills/cli/output.md +0 -36
- package/.agent-context/skills/cli/package.json +0 -5
- package/.agent-context/skills/cli/safety-telemetry.md +0 -39
- package/.agent-context/skills/cli/tests/.gitkeep +0 -1
- package/.agent-context/skills/cli/upgrade.md +0 -38
- package/.agent-context/skills/cli.md +0 -32
- package/.agent-context/skills/distribution/.evidence/compatibility-manifest.json +0 -9
- package/.agent-context/skills/distribution/.evidence/sbom-excerpt.json +0 -6
- package/.agent-context/skills/distribution/.evidence/test-report.json +0 -8
- package/.agent-context/skills/distribution/CHANGELOG.md +0 -7
- package/.agent-context/skills/distribution/README.md +0 -27
- package/.agent-context/skills/distribution/compatibility-manifest.json +0 -8
- package/.agent-context/skills/distribution/compatibility.md +0 -32
- package/.agent-context/skills/distribution/package.json +0 -5
- package/.agent-context/skills/distribution/provenance-attestation.md +0 -47
- package/.agent-context/skills/distribution/publish.md +0 -37
- package/.agent-context/skills/distribution/rollback.md +0 -32
- package/.agent-context/skills/distribution/tests/.gitkeep +0 -1
- package/.agent-context/skills/distribution.md +0 -32
- package/.agent-context/skills/frontend/.evidence/compatibility-manifest.json +0 -9
- package/.agent-context/skills/frontend/.evidence/sbom-excerpt.json +0 -6
- package/.agent-context/skills/frontend/.evidence/test-report.json +0 -8
- package/.agent-context/skills/frontend/CHANGELOG.md +0 -7
- package/.agent-context/skills/frontend/README.md +0 -50
- package/.agent-context/skills/frontend/accessibility.md +0 -107
- package/.agent-context/skills/frontend/compatibility-manifest.json +0 -8
- package/.agent-context/skills/frontend/conversion-clarity.md +0 -51
- package/.agent-context/skills/frontend/motion.md +0 -67
- package/.agent-context/skills/frontend/package.json +0 -5
- package/.agent-context/skills/frontend/performance.md +0 -63
- package/.agent-context/skills/frontend/responsive-delivery.md +0 -41
- package/.agent-context/skills/frontend/tests/.gitkeep +0 -1
- package/.agent-context/skills/frontend/ui-architecture.md +0 -128
- package/.agent-context/skills/frontend.md +0 -40
- package/.agent-context/skills/fullstack/.evidence/compatibility-manifest.json +0 -9
- package/.agent-context/skills/fullstack/.evidence/sbom-excerpt.json +0 -6
- package/.agent-context/skills/fullstack/.evidence/test-report.json +0 -8
- package/.agent-context/skills/fullstack/CHANGELOG.md +0 -7
- package/.agent-context/skills/fullstack/README.md +0 -27
- package/.agent-context/skills/fullstack/compatibility-manifest.json +0 -8
- package/.agent-context/skills/fullstack/contracts.md +0 -53
- package/.agent-context/skills/fullstack/end-to-end.md +0 -42
- package/.agent-context/skills/fullstack/feature-slicing.md +0 -65
- package/.agent-context/skills/fullstack/package.json +0 -5
- package/.agent-context/skills/fullstack/release-coordination.md +0 -51
- package/.agent-context/skills/fullstack/tests/.gitkeep +0 -1
- package/.agent-context/skills/fullstack.md +0 -30
- package/.agent-context/skills/index.json +0 -107
- package/.agent-context/skills/review-quality/.evidence/compatibility-manifest.json +0 -9
- package/.agent-context/skills/review-quality/.evidence/sbom-excerpt.json +0 -6
- package/.agent-context/skills/review-quality/.evidence/test-report.json +0 -8
- package/.agent-context/skills/review-quality/CHANGELOG.md +0 -7
- package/.agent-context/skills/review-quality/README.md +0 -27
- package/.agent-context/skills/review-quality/benchmark.md +0 -30
- package/.agent-context/skills/review-quality/compatibility-manifest.json +0 -8
- package/.agent-context/skills/review-quality/package.json +0 -5
- package/.agent-context/skills/review-quality/planning.md +0 -38
- package/.agent-context/skills/review-quality/release-decision.md +0 -49
- package/.agent-context/skills/review-quality/security.md +0 -34
- package/.agent-context/skills/review-quality/tests/.gitkeep +0 -1
- package/.agent-context/skills/review-quality.md +0 -34
- package/.agent-context/stacks/csharp.md +0 -149
- package/.agent-context/stacks/flutter.md +0 -16
- package/.agent-context/stacks/go.md +0 -181
- package/.agent-context/stacks/java.md +0 -135
- package/.agent-context/stacks/php.md +0 -192
- package/.agent-context/stacks/python.md +0 -153
- package/.agent-context/stacks/react-native.md +0 -16
- package/.agent-context/stacks/ruby.md +0 -80
- package/.agent-context/stacks/rust.md +0 -86
- package/.agent-context/stacks/typescript.md +0 -317
- package/.agent-context/state/skill-platform.json +0 -38
- package/lib/cli/skill-selector.mjs +0 -232
- package/lib/cli/templates/api-contract.md.id.tmpl +0 -143
- package/lib/cli/templates/api-contract.md.tmpl +0 -143
- package/lib/cli/templates/architecture-decision-record.md.id.tmpl +0 -106
- package/lib/cli/templates/architecture-decision-record.md.tmpl +0 -145
- package/lib/cli/templates/database-schema.md.id.tmpl +0 -74
- package/lib/cli/templates/database-schema.md.tmpl +0 -74
- package/lib/cli/templates/flow-overview.md.id.tmpl +0 -118
- package/lib/cli/templates/flow-overview.md.tmpl +0 -131
- package/lib/cli/templates/project-brief.md.id.tmpl +0 -55
- package/lib/cli/templates/project-brief.md.tmpl +0 -79
- package/scripts/init-project.ps1 +0 -105
- package/scripts/init-project.sh +0 -131
- package/scripts/skill-tier-policy.mjs +0 -76
- package/scripts/trust-scorer.mjs +0 -119
package/lib/cli/utils.mjs
CHANGED
|
@@ -25,16 +25,14 @@ export function printUsage() {
|
|
|
25
25
|
console.log(' npx @ryuenn3123/agentic-senior-core init');
|
|
26
26
|
console.log(' npm install -g @ryuenn3123/agentic-senior-core && agentic-senior-core init');
|
|
27
27
|
console.log(' bunx @ryuenn3123/agentic-senior-core init # optional Bun path');
|
|
28
|
-
console.log(' open GitHub template: https://github.com/fatidaprilian/Agentic-Senior-Core/generate');
|
|
29
28
|
console.log('');
|
|
30
29
|
console.log('Usage:');
|
|
31
30
|
console.log(' agentic-senior-core launch');
|
|
32
31
|
console.log(' agentic-senior-core init [target-directory] [--preset <name>] [--profile <beginner|balanced|strict>] [--profile-pack <name>] [--stack <name>] [--blueprint <name>] [--project-description <text>] [--architect-token-budget <number>] [--architect-timeout-ms <number>] [--architect-research-mode <snapshot|realtime>] [--enable-realtime-research] [--architect-realtime-signal-file <path>] [--ci <true|false>] [--newbie] [--token-optimize] [--no-token-optimize] [--token-agent <name>] [--memory-continuity] [--no-memory-continuity] [--scaffold-docs] [--no-scaffold-docs] [--docs-lang <en|id>] [--project-config <path>] [--runtime-env <auto|linux-wsl|linux|windows|macos>]');
|
|
33
|
-
console.log(' agentic-senior-core upgrade [target-directory] [--dry-run] [--yes] [--mcp-template]');
|
|
32
|
+
console.log(' agentic-senior-core upgrade [target-directory] [--dry-run] [--yes] [--mcp-template] [--no-mcp-template] [--prune] [--no-prune]');
|
|
34
33
|
console.log(' agentic-senior-core optimize [target-directory] [--agent <copilot|claude|cursor|windsurf|gemini|codex|cline>] [--enable|--disable] [--show]');
|
|
35
34
|
console.log(' agentic-senior-core mcp');
|
|
36
35
|
console.log(' agentic-senior-core rollback [target-directory]');
|
|
37
|
-
console.log(' agentic-senior-core skill [domain] [--tier <standard|advance|expert|above>] [--json]');
|
|
38
36
|
console.log(' agentic-senior-core --version');
|
|
39
37
|
console.log('');
|
|
40
38
|
console.log('Options:');
|
|
@@ -68,12 +66,12 @@ export function printUsage() {
|
|
|
68
66
|
console.log(' --runtime-env Override runtime environment hint (auto, linux-wsl, linux, windows, macos)');
|
|
69
67
|
console.log(' --dry-run Preview upgrade without writing files');
|
|
70
68
|
console.log(' --yes Skip confirmation prompts for upgrade');
|
|
69
|
+
console.log(' --prune Keep managed governance files synchronized 1:1 (default in upgrade)');
|
|
70
|
+
console.log(' --no-prune Do not remove stale managed governance files during upgrade');
|
|
71
71
|
console.log(' --agent Target agent integration for token optimization mode');
|
|
72
72
|
console.log(' --enable Enable token optimization policy and rebuild compiled rules');
|
|
73
73
|
console.log(' --disable Disable token optimization policy and rebuild compiled rules');
|
|
74
74
|
console.log(' --show Print current token optimization state as JSON');
|
|
75
|
-
console.log(' --tier Choose a skill tier for the skill selector');
|
|
76
|
-
console.log(' --json Emit machine-readable skill selection output');
|
|
77
75
|
}
|
|
78
76
|
|
|
79
77
|
export async function pathExists(targetPath) {
|
|
@@ -114,11 +112,188 @@ export async function copyDirectory(sourceDirectoryPath, targetDirectoryPath) {
|
|
|
114
112
|
}
|
|
115
113
|
}
|
|
116
114
|
|
|
115
|
+
function toPosixRelativePath(relativePath) {
|
|
116
|
+
return relativePath.split(path.sep).join('/');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function isPathWithinPrefix(relativePath, prefixPath) {
|
|
120
|
+
const normalizedRelativePath = toPosixRelativePath(relativePath).replace(/\/+$/g, '');
|
|
121
|
+
const normalizedPrefixPath = toPosixRelativePath(prefixPath).replace(/\/+$/g, '');
|
|
122
|
+
|
|
123
|
+
if (!normalizedPrefixPath) {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return normalizedRelativePath === normalizedPrefixPath
|
|
128
|
+
|| normalizedRelativePath.startsWith(`${normalizedPrefixPath}/`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async function collectRelativeTreeEntries(baseDirectoryPath, relativeRootPath) {
|
|
132
|
+
const files = [];
|
|
133
|
+
const directories = [];
|
|
134
|
+
|
|
135
|
+
if (!(await pathExists(baseDirectoryPath))) {
|
|
136
|
+
return { files, directories };
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const normalizedRootPath = toPosixRelativePath(relativeRootPath);
|
|
140
|
+
directories.push(normalizedRootPath);
|
|
141
|
+
|
|
142
|
+
async function walkDirectory(currentDirectoryPath, currentRelativePath) {
|
|
143
|
+
const directoryEntries = await fs.readdir(currentDirectoryPath, { withFileTypes: true });
|
|
144
|
+
|
|
145
|
+
for (const directoryEntry of directoryEntries) {
|
|
146
|
+
const sourceEntryPath = path.join(currentDirectoryPath, directoryEntry.name);
|
|
147
|
+
const relativeEntryPath = toPosixRelativePath(path.join(currentRelativePath, directoryEntry.name));
|
|
148
|
+
|
|
149
|
+
if (directoryEntry.isDirectory()) {
|
|
150
|
+
directories.push(relativeEntryPath);
|
|
151
|
+
await walkDirectory(sourceEntryPath, relativeEntryPath);
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
files.push(relativeEntryPath);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
await walkDirectory(baseDirectoryPath, normalizedRootPath);
|
|
160
|
+
return { files, directories };
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
async function buildManagedSourceManifest() {
|
|
164
|
+
const sourceFiles = new Set();
|
|
165
|
+
const sourceDirectories = new Set();
|
|
166
|
+
|
|
167
|
+
for (const sourceDirectoryName of directoryCopies) {
|
|
168
|
+
const sourceDirectoryPath = path.join(REPO_ROOT, sourceDirectoryName);
|
|
169
|
+
const sourceTreeEntries = await collectRelativeTreeEntries(sourceDirectoryPath, sourceDirectoryName);
|
|
170
|
+
|
|
171
|
+
for (const sourceFilePath of sourceTreeEntries.files) {
|
|
172
|
+
sourceFiles.add(sourceFilePath);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
for (const sourceDirectoryPathRelative of sourceTreeEntries.directories) {
|
|
176
|
+
sourceDirectories.add(sourceDirectoryPathRelative);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
for (const entryPointFileName of entryPointFiles) {
|
|
181
|
+
const sourceFilePath = path.join(REPO_ROOT, entryPointFileName);
|
|
182
|
+
if (!(await pathExists(sourceFilePath))) {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
sourceFiles.add(toPosixRelativePath(entryPointFileName));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return {
|
|
190
|
+
files: sourceFiles,
|
|
191
|
+
directories: sourceDirectories,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
async function collectManagedTargetManifest(resolvedTargetDirectoryPath) {
|
|
196
|
+
const targetFiles = new Set();
|
|
197
|
+
const targetDirectories = new Set();
|
|
198
|
+
|
|
199
|
+
for (const sourceDirectoryName of directoryCopies) {
|
|
200
|
+
const targetDirectoryPath = path.join(resolvedTargetDirectoryPath, sourceDirectoryName);
|
|
201
|
+
const targetTreeEntries = await collectRelativeTreeEntries(targetDirectoryPath, sourceDirectoryName);
|
|
202
|
+
|
|
203
|
+
for (const targetFilePath of targetTreeEntries.files) {
|
|
204
|
+
targetFiles.add(targetFilePath);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
for (const targetDirectoryPathRelative of targetTreeEntries.directories) {
|
|
208
|
+
targetDirectories.add(targetDirectoryPathRelative);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
for (const entryPointFileName of entryPointFiles) {
|
|
213
|
+
const targetFilePath = path.join(resolvedTargetDirectoryPath, entryPointFileName);
|
|
214
|
+
if (!(await pathExists(targetFilePath))) {
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
targetFiles.add(toPosixRelativePath(entryPointFileName));
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
files: targetFiles,
|
|
223
|
+
directories: targetDirectories,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export async function analyzeManagedGovernanceSurface(
|
|
228
|
+
resolvedTargetDirectoryPath,
|
|
229
|
+
options = {}
|
|
230
|
+
) {
|
|
231
|
+
const preservePathPrefixes = Array.isArray(options.preservePathPrefixes)
|
|
232
|
+
? options.preservePathPrefixes
|
|
233
|
+
: ['.agent-context/state'];
|
|
234
|
+
|
|
235
|
+
const sourceManifest = await buildManagedSourceManifest();
|
|
236
|
+
const targetManifest = await collectManagedTargetManifest(resolvedTargetDirectoryPath);
|
|
237
|
+
|
|
238
|
+
const staleFiles = [];
|
|
239
|
+
const staleDirectories = [];
|
|
240
|
+
const preservedFiles = [];
|
|
241
|
+
const preservedDirectories = [];
|
|
242
|
+
|
|
243
|
+
const sortedTargetFiles = [...targetManifest.files].sort((leftPath, rightPath) => leftPath.localeCompare(rightPath));
|
|
244
|
+
const sortedTargetDirectories = [...targetManifest.directories].sort(
|
|
245
|
+
(leftPath, rightPath) => rightPath.length - leftPath.length || leftPath.localeCompare(rightPath)
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
for (const targetFilePath of sortedTargetFiles) {
|
|
249
|
+
if (sourceManifest.files.has(targetFilePath)) {
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (preservePathPrefixes.some((prefixPath) => isPathWithinPrefix(targetFilePath, prefixPath))) {
|
|
254
|
+
preservedFiles.push(targetFilePath);
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
staleFiles.push(targetFilePath);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
for (const targetDirectoryPathRelative of sortedTargetDirectories) {
|
|
262
|
+
if (sourceManifest.directories.has(targetDirectoryPathRelative)) {
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (preservePathPrefixes.some((prefixPath) => isPathWithinPrefix(targetDirectoryPathRelative, prefixPath))) {
|
|
267
|
+
preservedDirectories.push(targetDirectoryPathRelative);
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
staleDirectories.push(targetDirectoryPathRelative);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return {
|
|
275
|
+
staleFiles,
|
|
276
|
+
staleDirectories,
|
|
277
|
+
preservedFiles,
|
|
278
|
+
preservedDirectories,
|
|
279
|
+
managedSourceFileCount: sourceManifest.files.size,
|
|
280
|
+
managedSourceDirectoryCount: sourceManifest.directories.size,
|
|
281
|
+
managedTargetFileCount: targetManifest.files.size,
|
|
282
|
+
managedTargetDirectoryCount: targetManifest.directories.size,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
|
|
117
286
|
export async function copyGovernanceAssetsToTarget(
|
|
118
287
|
resolvedTargetDirectoryPath,
|
|
119
288
|
options = {}
|
|
120
289
|
) {
|
|
121
290
|
const shouldIncludeMcpTemplate = options.includeMcpTemplate === true;
|
|
291
|
+
const shouldPruneManagedSurface = options.pruneManagedSurface === true;
|
|
292
|
+
const managedSurfacePlan = shouldPruneManagedSurface
|
|
293
|
+
? options.managedSurfacePlan || await analyzeManagedGovernanceSurface(resolvedTargetDirectoryPath)
|
|
294
|
+
: null;
|
|
295
|
+
const deletedManagedFiles = [];
|
|
296
|
+
const deletedManagedDirectories = [];
|
|
122
297
|
|
|
123
298
|
for (const sourceDirectoryName of directoryCopies) {
|
|
124
299
|
const sourceDirectoryPath = path.join(REPO_ROOT, sourceDirectoryName);
|
|
@@ -145,6 +320,28 @@ export async function copyGovernanceAssetsToTarget(
|
|
|
145
320
|
await fs.copyFile(sourceFilePath, targetFilePath);
|
|
146
321
|
}
|
|
147
322
|
|
|
323
|
+
if (shouldPruneManagedSurface && managedSurfacePlan) {
|
|
324
|
+
for (const staleFileRelativePath of managedSurfacePlan.staleFiles) {
|
|
325
|
+
const staleFilePath = path.join(resolvedTargetDirectoryPath, ...staleFileRelativePath.split('/'));
|
|
326
|
+
if (!(await pathExists(staleFilePath))) {
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
await fs.unlink(staleFilePath);
|
|
331
|
+
deletedManagedFiles.push(staleFileRelativePath);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
for (const staleDirectoryRelativePath of managedSurfacePlan.staleDirectories) {
|
|
335
|
+
const staleDirectoryPath = path.join(resolvedTargetDirectoryPath, ...staleDirectoryRelativePath.split('/'));
|
|
336
|
+
if (!(await pathExists(staleDirectoryPath))) {
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
await fs.rm(staleDirectoryPath, { recursive: true, force: true });
|
|
341
|
+
deletedManagedDirectories.push(staleDirectoryRelativePath);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
148
345
|
if (shouldIncludeMcpTemplate) {
|
|
149
346
|
const projectName = path.basename(resolvedTargetDirectoryPath);
|
|
150
347
|
const mcpArgs = ['./scripts/mcp-server.mjs'];
|
|
@@ -199,7 +396,7 @@ export async function copyGovernanceAssetsToTarget(
|
|
|
199
396
|
parsedZedSettings.context_servers['agentic-senior-core'] = zedMcpConfig.context_servers['agentic-senior-core'];
|
|
200
397
|
await fs.writeFile(zedSettingsPath, JSON.stringify(parsedZedSettings, null, 2) + '\n', 'utf8');
|
|
201
398
|
}
|
|
202
|
-
} catch
|
|
399
|
+
} catch {
|
|
203
400
|
// Fallback or ignore if user has broken JSON
|
|
204
401
|
}
|
|
205
402
|
}
|
|
@@ -216,7 +413,7 @@ export async function copyGovernanceAssetsToTarget(
|
|
|
216
413
|
if (await pathExists(globalGeminiMcpPath)) {
|
|
217
414
|
const content = await fs.readFile(globalGeminiMcpPath, 'utf8');
|
|
218
415
|
if (content.trim()) {
|
|
219
|
-
try { geminiConfig = JSON.parse(content); } catch
|
|
416
|
+
try { geminiConfig = JSON.parse(content); } catch {}
|
|
220
417
|
}
|
|
221
418
|
}
|
|
222
419
|
if (!geminiConfig.mcpServers) geminiConfig.mcpServers = {};
|
|
@@ -233,12 +430,18 @@ export async function copyGovernanceAssetsToTarget(
|
|
|
233
430
|
|
|
234
431
|
await fs.writeFile(globalGeminiMcpPath, JSON.stringify(geminiConfig, null, 2) + '\n', 'utf8');
|
|
235
432
|
}
|
|
236
|
-
} catch
|
|
433
|
+
} catch {
|
|
237
434
|
// Ignore global injection errors
|
|
238
435
|
}
|
|
239
436
|
}
|
|
240
437
|
}
|
|
241
438
|
|
|
439
|
+
return {
|
|
440
|
+
deletedManagedFiles,
|
|
441
|
+
deletedManagedDirectories,
|
|
442
|
+
managedSurfacePlan,
|
|
443
|
+
};
|
|
444
|
+
|
|
242
445
|
}
|
|
243
446
|
|
|
244
447
|
export async function askChoice(promptMessage, options, userInterface) {
|
|
@@ -346,11 +549,19 @@ export function parseBlockingSeverities(rawSeverityValues, fileName) {
|
|
|
346
549
|
}
|
|
347
550
|
|
|
348
551
|
export async function collectFileNames(folderPath) {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
552
|
+
try {
|
|
553
|
+
const fileNames = await fs.readdir(folderPath, { withFileTypes: true });
|
|
554
|
+
return fileNames
|
|
555
|
+
.filter((entry) => entry.isFile() && entry.name.endsWith('.md'))
|
|
556
|
+
.map((entry) => entry.name)
|
|
557
|
+
.sort((leftName, rightName) => leftName.localeCompare(rightName));
|
|
558
|
+
} catch (error) {
|
|
559
|
+
if (error?.code === 'ENOENT') {
|
|
560
|
+
return [];
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
throw error;
|
|
564
|
+
}
|
|
354
565
|
}
|
|
355
566
|
|
|
356
567
|
export function formatBlockingSeverities(blockingSeverities) {
|
package/mcp.json
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "1.0",
|
|
3
3
|
"name": "agentic-senior-core",
|
|
4
|
-
"description": "MCP configuration for governance-aware diagnostics and self-healing workflows with
|
|
4
|
+
"description": "MCP configuration for governance-aware diagnostics and self-healing workflows with dynamic knowledge injection.",
|
|
5
5
|
"knowledgeLayers": {
|
|
6
6
|
"enabled": true,
|
|
7
|
-
"description": "8-layer
|
|
7
|
+
"description": "8-layer dynamic knowledge injection for AI agents",
|
|
8
8
|
"layers": {
|
|
9
9
|
"rules": {
|
|
10
10
|
"path": ".agent-context/rules",
|
|
11
11
|
"count": 14,
|
|
12
12
|
"autoLoad": true
|
|
13
13
|
},
|
|
14
|
-
"
|
|
15
|
-
"path": "
|
|
16
|
-
"count":
|
|
14
|
+
"stack-strategies": {
|
|
15
|
+
"path": "dynamic",
|
|
16
|
+
"count": 0,
|
|
17
17
|
"autoLoad": true
|
|
18
18
|
},
|
|
19
|
-
"
|
|
20
|
-
"path": "
|
|
21
|
-
"count":
|
|
19
|
+
"architecture-playbooks": {
|
|
20
|
+
"path": "dynamic",
|
|
21
|
+
"count": 0,
|
|
22
22
|
"autoLoad": true
|
|
23
23
|
},
|
|
24
|
-
"
|
|
25
|
-
"path": "
|
|
26
|
-
"count":
|
|
24
|
+
"execution-contracts": {
|
|
25
|
+
"path": "dynamic",
|
|
26
|
+
"count": 0,
|
|
27
27
|
"autoLoad": true,
|
|
28
|
-
"
|
|
28
|
+
"sources": ["prompts", "review-checklists", "policies"]
|
|
29
29
|
},
|
|
30
30
|
"prompts": {
|
|
31
31
|
"path": ".agent-context/prompts",
|
|
@@ -33,9 +33,9 @@
|
|
|
33
33
|
"autoLoad": true,
|
|
34
34
|
"templates": ["init-project", "refactor", "review-code"]
|
|
35
35
|
},
|
|
36
|
-
"
|
|
37
|
-
"path": "
|
|
38
|
-
"count":
|
|
36
|
+
"governance-modes": {
|
|
37
|
+
"path": "dynamic",
|
|
38
|
+
"count": 0,
|
|
39
39
|
"autoLoad": true,
|
|
40
40
|
"governance": ["platform", "regulated", "startup"]
|
|
41
41
|
},
|
|
@@ -78,11 +78,11 @@
|
|
|
78
78
|
"steps": [
|
|
79
79
|
"load_all_knowledge_layers",
|
|
80
80
|
"inject_rules",
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
"
|
|
81
|
+
"inject_stack_strategies",
|
|
82
|
+
"inject_architecture_playbooks",
|
|
83
|
+
"inject_execution_contracts",
|
|
84
84
|
"inject_prompts",
|
|
85
|
-
"
|
|
85
|
+
"inject_governance_modes",
|
|
86
86
|
"inject_state",
|
|
87
87
|
"inject_policies"
|
|
88
88
|
]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ryuenn3123/agentic-senior-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Force your AI Agent to code like a Staff Engineer, not a Junior.",
|
|
6
6
|
"bin": {
|
|
@@ -48,6 +48,9 @@
|
|
|
48
48
|
"audit:rules-guardian": "node ./scripts/rules-guardian-audit.mjs",
|
|
49
49
|
"audit:explain-on-demand": "node ./scripts/explain-on-demand-audit.mjs",
|
|
50
50
|
"audit:single-source-lazy-loading": "node ./scripts/single-source-lazy-loading-audit.mjs",
|
|
51
|
+
"audit:v3-purge": "node ./scripts/v3-purge-audit.mjs",
|
|
52
|
+
"sync:adapters": "node ./scripts/sync-thin-adapters.mjs",
|
|
53
|
+
"check:adapters": "node ./scripts/sync-thin-adapters.mjs --check",
|
|
51
54
|
"gate:release": "node ./scripts/release-gate.mjs && node ./scripts/forbidden-content-check.mjs",
|
|
52
55
|
"prepublishOnly": "npm run gate:release",
|
|
53
56
|
"sbom:generate": "node ./scripts/generate-sbom.mjs",
|
|
@@ -62,6 +65,6 @@
|
|
|
62
65
|
"report:docs-quality-drift": "node ./scripts/docs-quality-drift-report.mjs",
|
|
63
66
|
"report:governance-weekly": "node ./scripts/governance-weekly-report.mjs",
|
|
64
67
|
"validate": "node ./scripts/validate.mjs",
|
|
65
|
-
"test": "node --test ./tests/cli-smoke.test.mjs ./tests/mcp-server.test.mjs ./tests/llm-judge.test.mjs ./tests/enterprise-ops.test.mjs
|
|
68
|
+
"test": "node --test ./tests/cli-smoke.test.mjs ./tests/mcp-server.test.mjs ./tests/llm-judge.test.mjs ./tests/enterprise-ops.test.mjs"
|
|
66
69
|
}
|
|
67
70
|
}
|
|
@@ -16,8 +16,8 @@ const __filename = fileURLToPath(import.meta.url);
|
|
|
16
16
|
const __dirname = dirname(__filename);
|
|
17
17
|
const REPOSITORY_ROOT = resolve(__dirname, '..');
|
|
18
18
|
|
|
19
|
-
const
|
|
20
|
-
const
|
|
19
|
+
const PR_CHECKLIST_PATH = '.agent-context/review-checklists/pr-checklist.md';
|
|
20
|
+
const ARCHITECTURE_CHECKLIST_PATH = '.agent-context/review-checklists/architecture-review.md';
|
|
21
21
|
const DEFAULT_WORKFLOW = 'auto';
|
|
22
22
|
const SMALL_EDIT_MAX_FILES = 3;
|
|
23
23
|
const MAJOR_FEATURE_MIN_SIGNIFICANT_FILES = 4;
|
|
@@ -36,18 +36,18 @@ const SUPPORTED_WORKFLOWS = new Set([
|
|
|
36
36
|
'standard',
|
|
37
37
|
]);
|
|
38
38
|
|
|
39
|
-
const
|
|
40
|
-
'
|
|
41
|
-
'Strict
|
|
42
|
-
'Small edits
|
|
43
|
-
'User can force strict mode manually
|
|
39
|
+
const REQUIRED_PR_CHECKLIST_SNIPPETS = [
|
|
40
|
+
'### 11. Context-Triggered Audit Mode',
|
|
41
|
+
'Strict audit mode activates automatically on review and PR-intent workflows',
|
|
42
|
+
'Small edits avoid heavy checks by default unless strict mode is explicitly requested',
|
|
43
|
+
'User can always force strict audit mode manually',
|
|
44
44
|
];
|
|
45
45
|
|
|
46
|
-
const
|
|
47
|
-
'##
|
|
48
|
-
'
|
|
49
|
-
'
|
|
50
|
-
'
|
|
46
|
+
const REQUIRED_ARCHITECTURE_CHECKLIST_SNIPPETS = [
|
|
47
|
+
'## Backend Universal Principles',
|
|
48
|
+
'No clever hacks in backend and shared core modules',
|
|
49
|
+
'No premature abstraction',
|
|
50
|
+
'Readability over brevity',
|
|
51
51
|
];
|
|
52
52
|
|
|
53
53
|
function pushResult(results, isPassed, checkName, details) {
|
|
@@ -348,16 +348,16 @@ function runAudit() {
|
|
|
348
348
|
pushResult(results, true, 'strict-audit-activation', `Strict audit mode activated (${auditMode.triggerReason})`);
|
|
349
349
|
|
|
350
350
|
assertChecklist(
|
|
351
|
-
'
|
|
352
|
-
|
|
353
|
-
|
|
351
|
+
'pr',
|
|
352
|
+
PR_CHECKLIST_PATH,
|
|
353
|
+
REQUIRED_PR_CHECKLIST_SNIPPETS,
|
|
354
354
|
failures,
|
|
355
355
|
results
|
|
356
356
|
);
|
|
357
357
|
assertChecklist(
|
|
358
|
-
'
|
|
359
|
-
|
|
360
|
-
|
|
358
|
+
'architecture',
|
|
359
|
+
ARCHITECTURE_CHECKLIST_PATH,
|
|
360
|
+
REQUIRED_ARCHITECTURE_CHECKLIST_SNIPPETS,
|
|
361
361
|
failures,
|
|
362
362
|
results
|
|
363
363
|
);
|
|
@@ -15,6 +15,13 @@ import { fileURLToPath } from 'node:url';
|
|
|
15
15
|
const __filename = fileURLToPath(import.meta.url);
|
|
16
16
|
const __dirname = dirname(__filename);
|
|
17
17
|
const REPOSITORY_ROOT = resolve(__dirname, '..');
|
|
18
|
+
const DOCUMENTATION_BOUNDARY_AUDIT_REPORT_VERSION = '2.1.0';
|
|
19
|
+
const AUTO_DOCS_SYNC_SCOPE_PHASE = 'phase-1';
|
|
20
|
+
const AUTO_DOCS_SYNC_SCOPE_BOUNDARIES = [
|
|
21
|
+
'public-surface',
|
|
22
|
+
'api-contract',
|
|
23
|
+
'database-structure',
|
|
24
|
+
];
|
|
18
25
|
|
|
19
26
|
const CORE_DOCUMENTATION_FILES = new Set(['README.md', 'CHANGELOG.md']);
|
|
20
27
|
|
|
@@ -22,6 +29,12 @@ const BOUNDARY_RULES = [
|
|
|
22
29
|
{
|
|
23
30
|
boundaryName: 'public-surface',
|
|
24
31
|
requirement: 'Public surface changes must update README.md, CHANGELOG.md, or docs/* in the same scope.',
|
|
32
|
+
suggestedDocumentationUpdates: [
|
|
33
|
+
'README.md',
|
|
34
|
+
'CHANGELOG.md',
|
|
35
|
+
'docs/architecture-decision-record.md',
|
|
36
|
+
'docs/flow-overview.md',
|
|
37
|
+
],
|
|
25
38
|
trigger(filePath) {
|
|
26
39
|
return /^(bin\/|lib\/|scripts\/)/.test(filePath) && !isDocumentationFilePath(filePath);
|
|
27
40
|
},
|
|
@@ -32,6 +45,12 @@ const BOUNDARY_RULES = [
|
|
|
32
45
|
{
|
|
33
46
|
boundaryName: 'api-contract',
|
|
34
47
|
requirement: 'API endpoint or contract changes must update API/OpenAPI documentation in the same scope.',
|
|
48
|
+
suggestedDocumentationUpdates: [
|
|
49
|
+
'docs/api-contract.md',
|
|
50
|
+
'docs/flow-overview.md',
|
|
51
|
+
'.agent-context/rules/api-docs.md',
|
|
52
|
+
'README.md',
|
|
53
|
+
],
|
|
35
54
|
trigger(filePath) {
|
|
36
55
|
return !isDocumentationFilePath(filePath)
|
|
37
56
|
&& /(api|openapi|contract|controller|route|endpoint)/i.test(filePath);
|
|
@@ -45,6 +64,12 @@ const BOUNDARY_RULES = [
|
|
|
45
64
|
{
|
|
46
65
|
boundaryName: 'database-structure',
|
|
47
66
|
requirement: 'Database structure changes must update schema or migration documentation in the same scope.',
|
|
67
|
+
suggestedDocumentationUpdates: [
|
|
68
|
+
'docs/database-schema.md',
|
|
69
|
+
'docs/flow-overview.md',
|
|
70
|
+
'.agent-context/rules/database-design.md',
|
|
71
|
+
'README.md',
|
|
72
|
+
],
|
|
48
73
|
trigger(filePath) {
|
|
49
74
|
return !isDocumentationFilePath(filePath)
|
|
50
75
|
&& /(database|schema|migration|repository|sql|prisma|typeorm|knex)/i.test(filePath);
|
|
@@ -135,6 +160,9 @@ function isDocumentationFilePath(filePath) {
|
|
|
135
160
|
|
|
136
161
|
function evaluateBoundary(boundaryRule, changedFiles, changedDocumentationFiles) {
|
|
137
162
|
const boundaryChangedFiles = changedFiles.filter((filePath) => boundaryRule.trigger(filePath));
|
|
163
|
+
const expectedDocumentationPaths = Array.isArray(boundaryRule.suggestedDocumentationUpdates)
|
|
164
|
+
? boundaryRule.suggestedDocumentationUpdates
|
|
165
|
+
: [];
|
|
138
166
|
|
|
139
167
|
if (boundaryChangedFiles.length === 0) {
|
|
140
168
|
return {
|
|
@@ -144,12 +172,21 @@ function evaluateBoundary(boundaryRule, changedFiles, changedDocumentationFiles)
|
|
|
144
172
|
passed: true,
|
|
145
173
|
changedFiles: [],
|
|
146
174
|
documentationFiles: [],
|
|
175
|
+
expectedDocumentationPaths,
|
|
176
|
+
missingDocumentationUpdates: false,
|
|
177
|
+
suggestedActions: [],
|
|
147
178
|
details: 'Boundary not triggered by changed scope.',
|
|
148
179
|
};
|
|
149
180
|
}
|
|
150
181
|
|
|
151
182
|
const matchingDocumentationFiles = changedDocumentationFiles.filter((filePath) => boundaryRule.docsMatcher(filePath));
|
|
152
183
|
const boundaryPassed = matchingDocumentationFiles.length > 0;
|
|
184
|
+
const suggestedActions = boundaryPassed
|
|
185
|
+
? []
|
|
186
|
+
: [
|
|
187
|
+
`Update one or more boundary docs: ${expectedDocumentationPaths.join(', ')}`,
|
|
188
|
+
'Re-run scripts/documentation-boundary-audit.mjs before merge.',
|
|
189
|
+
];
|
|
153
190
|
|
|
154
191
|
const details = boundaryPassed
|
|
155
192
|
? `Boundary triggered and synchronized with documentation updates: ${matchingDocumentationFiles.join(', ')}`
|
|
@@ -162,6 +199,9 @@ function evaluateBoundary(boundaryRule, changedFiles, changedDocumentationFiles)
|
|
|
162
199
|
passed: boundaryPassed,
|
|
163
200
|
changedFiles: boundaryChangedFiles,
|
|
164
201
|
documentationFiles: matchingDocumentationFiles,
|
|
202
|
+
expectedDocumentationPaths,
|
|
203
|
+
missingDocumentationUpdates: !boundaryPassed,
|
|
204
|
+
suggestedActions,
|
|
165
205
|
details,
|
|
166
206
|
};
|
|
167
207
|
}
|
|
@@ -175,25 +215,72 @@ function runDocumentationBoundaryAudit() {
|
|
|
175
215
|
evaluateBoundary(boundaryRule, changedFiles, changedDocumentationFiles)
|
|
176
216
|
));
|
|
177
217
|
|
|
178
|
-
const
|
|
218
|
+
const violations = boundaryResults
|
|
179
219
|
.filter((boundaryResult) => boundaryResult.triggered && !boundaryResult.passed)
|
|
180
|
-
.map((boundaryResult) => {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
220
|
+
.map((boundaryResult) => ({
|
|
221
|
+
boundaryName: boundaryResult.boundaryName,
|
|
222
|
+
requirement: boundaryResult.requirement,
|
|
223
|
+
changedFiles: boundaryResult.changedFiles,
|
|
224
|
+
expectedDocumentationPaths: boundaryResult.expectedDocumentationPaths,
|
|
225
|
+
suggestedActions: boundaryResult.suggestedActions,
|
|
226
|
+
diagnosticCode: `BOUNDARY_${boundaryResult.boundaryName.toUpperCase().replace(/-/g, '_')}_DOCS_SYNC_REQUIRED`,
|
|
227
|
+
}));
|
|
228
|
+
|
|
229
|
+
const failures = violations.map((violation) => {
|
|
230
|
+
const affectedFiles = violation.changedFiles.join(', ');
|
|
231
|
+
return `${violation.boundaryName}: ${violation.requirement} Changed files: ${affectedFiles}`;
|
|
232
|
+
});
|
|
184
233
|
|
|
185
234
|
const reportPayload = {
|
|
186
235
|
generatedAt: new Date().toISOString(),
|
|
236
|
+
reportVersion: DOCUMENTATION_BOUNDARY_AUDIT_REPORT_VERSION,
|
|
187
237
|
auditName: 'documentation-boundary-audit',
|
|
188
238
|
source: changedScope.source,
|
|
189
239
|
changedFileCount: changedFiles.length,
|
|
190
240
|
changedFiles,
|
|
191
241
|
boundaryResults,
|
|
242
|
+
violations,
|
|
192
243
|
passed: failures.length === 0,
|
|
193
244
|
failureCount: failures.length,
|
|
194
245
|
failures,
|
|
195
246
|
};
|
|
196
247
|
|
|
248
|
+
const triggeredBoundaryResults = boundaryResults.filter((boundaryResult) => boundaryResult.triggered);
|
|
249
|
+
const passedTriggeredBoundaryResults = triggeredBoundaryResults.filter((boundaryResult) => boundaryResult.passed);
|
|
250
|
+
const scopeMatchedDocumentationFiles = uniqueSorted(
|
|
251
|
+
triggeredBoundaryResults.flatMap((boundaryResult) => boundaryResult.documentationFiles),
|
|
252
|
+
);
|
|
253
|
+
const scopeMatchedDocumentationFileSet = new Set(scopeMatchedDocumentationFiles);
|
|
254
|
+
const outOfScopeDocumentationFiles = changedDocumentationFiles.filter(
|
|
255
|
+
(filePath) => !scopeMatchedDocumentationFileSet.has(filePath),
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
const precisionNumerator = scopeMatchedDocumentationFiles.length;
|
|
259
|
+
const precisionDenominator = changedDocumentationFiles.length;
|
|
260
|
+
const recallNumerator = passedTriggeredBoundaryResults.length;
|
|
261
|
+
const recallDenominator = triggeredBoundaryResults.length;
|
|
262
|
+
|
|
263
|
+
const precision = precisionDenominator > 0 ? precisionNumerator / precisionDenominator : 1;
|
|
264
|
+
const recall = recallDenominator > 0 ? recallNumerator / recallDenominator : 1;
|
|
265
|
+
|
|
266
|
+
reportPayload.autoDocsSyncScope = {
|
|
267
|
+
phase: AUTO_DOCS_SYNC_SCOPE_PHASE,
|
|
268
|
+
bounded: true,
|
|
269
|
+
explicitBoundaries: AUTO_DOCS_SYNC_SCOPE_BOUNDARIES,
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
reportPayload.rolloutMetrics = {
|
|
273
|
+
measuredAt: reportPayload.generatedAt,
|
|
274
|
+
precision,
|
|
275
|
+
recall,
|
|
276
|
+
precisionNumerator,
|
|
277
|
+
precisionDenominator,
|
|
278
|
+
recallNumerator,
|
|
279
|
+
recallDenominator,
|
|
280
|
+
scopeMatchedDocumentationFiles,
|
|
281
|
+
outOfScopeDocumentationFiles,
|
|
282
|
+
};
|
|
283
|
+
|
|
197
284
|
console.log(JSON.stringify(reportPayload, null, 2));
|
|
198
285
|
process.exit(reportPayload.passed ? 0 : 1);
|
|
199
286
|
}
|