@ryuenn3123/agentic-senior-core 2.5.22 → 3.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/.agent-context/prompts/init-project.md +5 -5
- 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 +21 -4
- 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 +1 -23
- 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 +16 -12
- 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
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Init Selection Helpers — stack/blueprint filtering and scope normalization.
|
|
3
|
+
*/
|
|
4
|
+
import {
|
|
5
|
+
BLUEPRINT_RECOMMENDATIONS,
|
|
6
|
+
PROJECT_SCOPE_CHOICES,
|
|
7
|
+
PROJECT_SCOPE_STACK_FILTERS,
|
|
8
|
+
WEB_FRONTEND_BLUEPRINT_CANDIDATES,
|
|
9
|
+
WEB_BACKEND_BLUEPRINT_CANDIDATES,
|
|
10
|
+
} from './constants.mjs';
|
|
11
|
+
|
|
12
|
+
export function filterStackFileNamesByCandidates(allStackFileNames, preferredStackFileNames) {
|
|
13
|
+
if (!Array.isArray(preferredStackFileNames) || preferredStackFileNames.length === 0) {
|
|
14
|
+
return allStackFileNames;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const filteredStackFileNames = preferredStackFileNames.filter((stackFileName) => allStackFileNames.includes(stackFileName));
|
|
18
|
+
return filteredStackFileNames.length > 0 ? filteredStackFileNames : allStackFileNames;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function filterBlueprintFileNamesByCandidates(allBlueprintFileNames, preferredBlueprintFileNames) {
|
|
22
|
+
if (!Array.isArray(preferredBlueprintFileNames) || preferredBlueprintFileNames.length === 0) {
|
|
23
|
+
return allBlueprintFileNames;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const filteredBlueprintFileNames = preferredBlueprintFileNames.filter(
|
|
27
|
+
(blueprintFileName) => allBlueprintFileNames.includes(blueprintFileName)
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
return filteredBlueprintFileNames.length > 0 ? filteredBlueprintFileNames : allBlueprintFileNames;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function resolveProjectScopeKeyFromLabel(selectedProjectScopeLabel) {
|
|
34
|
+
const projectScopeEntry = PROJECT_SCOPE_CHOICES.find((scopeChoice) => scopeChoice.label === selectedProjectScopeLabel);
|
|
35
|
+
return projectScopeEntry?.key || 'both';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function normalizeAdditionalStackSelection(selectedStackFileName, additionalStackFileNames) {
|
|
39
|
+
if (!Array.isArray(additionalStackFileNames) || additionalStackFileNames.length === 0) {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return Array.from(new Set(additionalStackFileNames.filter((stackFileName) => stackFileName && stackFileName !== selectedStackFileName)));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function normalizeAdditionalBlueprintSelection(selectedBlueprintFileName, additionalBlueprintFileNames) {
|
|
47
|
+
if (!Array.isArray(additionalBlueprintFileNames) || additionalBlueprintFileNames.length === 0) {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return Array.from(new Set(additionalBlueprintFileNames.filter(
|
|
52
|
+
(blueprintFileName) => blueprintFileName && blueprintFileName !== selectedBlueprintFileName
|
|
53
|
+
)));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function deriveAdditionalBlueprintFileNamesFromStacks(
|
|
57
|
+
additionalStackFileNames,
|
|
58
|
+
allBlueprintFileNames,
|
|
59
|
+
selectedBlueprintFileName
|
|
60
|
+
) {
|
|
61
|
+
const derivedBlueprintFileNames = [];
|
|
62
|
+
|
|
63
|
+
for (const additionalStackFileName of additionalStackFileNames || []) {
|
|
64
|
+
const mappedBlueprintFileName = BLUEPRINT_RECOMMENDATIONS[additionalStackFileName];
|
|
65
|
+
if (!mappedBlueprintFileName) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (!allBlueprintFileNames.includes(mappedBlueprintFileName)) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (mappedBlueprintFileName === selectedBlueprintFileName) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
derivedBlueprintFileNames.push(mappedBlueprintFileName);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return Array.from(new Set(derivedBlueprintFileNames));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function resolveScopeStackCandidates(projectScopeKey) {
|
|
84
|
+
return PROJECT_SCOPE_STACK_FILTERS[projectScopeKey] || null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function resolveScopeBlueprintCandidates(projectScopeKey) {
|
|
88
|
+
if (projectScopeKey === 'frontend-only') {
|
|
89
|
+
return WEB_FRONTEND_BLUEPRINT_CANDIDATES;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (projectScopeKey === 'backend-only') {
|
|
93
|
+
return WEB_BACKEND_BLUEPRINT_CANDIDATES;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return Array.from(new Set([
|
|
97
|
+
...WEB_FRONTEND_BLUEPRINT_CANDIDATES,
|
|
98
|
+
...WEB_BACKEND_BLUEPRINT_CANDIDATES,
|
|
99
|
+
]));
|
|
100
|
+
}
|
package/lib/cli/preflight.mjs
CHANGED
|
@@ -34,7 +34,7 @@ export async function runPreflightChecks(targetDirectoryPath, operationMode) {
|
|
|
34
34
|
try {
|
|
35
35
|
await fs.access(parentDir, constants.W_OK);
|
|
36
36
|
result.checks.push(`Target parent directory is writable: ${parentDir}`);
|
|
37
|
-
|
|
37
|
+
} catch {
|
|
38
38
|
result.passed = false;
|
|
39
39
|
result.errors.push(`Target directory does not exist and parent is read-only: ${parentDir}`);
|
|
40
40
|
}
|
|
@@ -8,6 +8,7 @@ import path from 'node:path';
|
|
|
8
8
|
import {
|
|
9
9
|
PROFILE_PACK_REQUIRED_FIELDS,
|
|
10
10
|
PROFILE_PACKS_DIRECTORY_NAME,
|
|
11
|
+
FALLBACK_PROFILE_PACK_DEFINITIONS,
|
|
11
12
|
} from './constants.mjs';
|
|
12
13
|
|
|
13
14
|
import {
|
|
@@ -19,6 +20,15 @@ import {
|
|
|
19
20
|
parseBlockingSeverities,
|
|
20
21
|
} from './utils.mjs';
|
|
21
22
|
|
|
23
|
+
function cloneProfilePackDefinition(profilePackDefinition) {
|
|
24
|
+
return {
|
|
25
|
+
...profilePackDefinition,
|
|
26
|
+
blockingSeverities: Array.isArray(profilePackDefinition.blockingSeverities)
|
|
27
|
+
? [...profilePackDefinition.blockingSeverities]
|
|
28
|
+
: [],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
22
32
|
export function parseProfilePackContent(fileName, profilePackContent) {
|
|
23
33
|
const parsedFields = {};
|
|
24
34
|
const profilePackLines = profilePackContent.split(/\r?\n/);
|
|
@@ -64,10 +74,14 @@ export function parseProfilePackContent(fileName, profilePackContent) {
|
|
|
64
74
|
export async function collectProfilePacks(targetDirectoryPath) {
|
|
65
75
|
const profilePackDirectoryPath = path.join(targetDirectoryPath, '.agent-context', PROFILE_PACKS_DIRECTORY_NAME);
|
|
66
76
|
if (!(await pathExists(profilePackDirectoryPath))) {
|
|
67
|
-
return
|
|
77
|
+
return FALLBACK_PROFILE_PACK_DEFINITIONS.map(cloneProfilePackDefinition);
|
|
68
78
|
}
|
|
69
79
|
|
|
70
80
|
const profilePackFileNames = await collectFileNames(profilePackDirectoryPath);
|
|
81
|
+
if (profilePackFileNames.length === 0) {
|
|
82
|
+
return FALLBACK_PROFILE_PACK_DEFINITIONS.map(cloneProfilePackDefinition);
|
|
83
|
+
}
|
|
84
|
+
|
|
71
85
|
const profilePackDefinitions = [];
|
|
72
86
|
|
|
73
87
|
for (const profilePackFileName of profilePackFileNames) {
|
|
@@ -5,14 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import fs from 'node:fs/promises';
|
|
7
7
|
import path from 'node:path';
|
|
8
|
-
import { fileURLToPath } from 'node:url';
|
|
9
8
|
|
|
10
|
-
import { CLI_VERSION } from './constants.mjs';
|
|
11
9
|
import { ensureDirectory, askChoice, askYesNo, toTitleCase, pathExists } from './utils.mjs';
|
|
12
10
|
|
|
13
|
-
const CURRENT_FILE_PATH = fileURLToPath(import.meta.url);
|
|
14
|
-
const CURRENT_DIRECTORY_PATH = path.dirname(CURRENT_FILE_PATH);
|
|
15
|
-
const TEMPLATES_DIRECTORY_PATH = path.join(CURRENT_DIRECTORY_PATH, 'templates');
|
|
16
11
|
const SUPPORTED_DOC_LANGUAGES = new Set(['en', 'id']);
|
|
17
12
|
const PROJECT_DOC_FILE_NAMES = [
|
|
18
13
|
'project-brief.md',
|
|
@@ -22,6 +17,7 @@ const PROJECT_DOC_FILE_NAMES = [
|
|
|
22
17
|
'flow-overview.md',
|
|
23
18
|
];
|
|
24
19
|
|
|
20
|
+
// Legacy project docs may still carry this version header; keep for upgrade staleness checks.
|
|
25
21
|
export const PROJECT_DOC_TEMPLATE_VERSION = '1.2.0';
|
|
26
22
|
export const PROJECT_DOC_SYNTHESIS_PROMPT_VERSION = '2.0.0';
|
|
27
23
|
|
|
@@ -224,30 +220,6 @@ export function normalizeDocsLanguage(rawDocsLanguage = 'en') {
|
|
|
224
220
|
return SUPPORTED_DOC_LANGUAGES.has(normalizedDocsLanguage) ? normalizedDocsLanguage : null;
|
|
225
221
|
}
|
|
226
222
|
|
|
227
|
-
function resolveLocalizedTemplateFileName(templateFileName, docsLanguage) {
|
|
228
|
-
if (docsLanguage === 'en') {
|
|
229
|
-
return templateFileName;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
return templateFileName.replace(/\.md\.tmpl$/i, `.md.${docsLanguage}.tmpl`);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
async function resolveTemplateFilePath(templateFileName, docsLanguage) {
|
|
236
|
-
const localizedTemplateFileName = resolveLocalizedTemplateFileName(templateFileName, docsLanguage);
|
|
237
|
-
const localizedTemplateFilePath = path.join(TEMPLATES_DIRECTORY_PATH, localizedTemplateFileName);
|
|
238
|
-
|
|
239
|
-
if (await pathExists(localizedTemplateFilePath)) {
|
|
240
|
-
return localizedTemplateFilePath;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
const defaultTemplateFilePath = path.join(TEMPLATES_DIRECTORY_PATH, templateFileName);
|
|
244
|
-
if (await pathExists(defaultTemplateFilePath)) {
|
|
245
|
-
return defaultTemplateFilePath;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
return null;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
223
|
/**
|
|
252
224
|
* Run the project discovery interview.
|
|
253
225
|
* Returns a structured object with all user responses.
|
|
@@ -444,160 +416,52 @@ export async function runProjectDiscovery(userInterface, options = {}) {
|
|
|
444
416
|
}
|
|
445
417
|
|
|
446
418
|
/**
|
|
447
|
-
* Determine
|
|
419
|
+
* Determine required docs based on project discovery answers.
|
|
448
420
|
*/
|
|
449
|
-
export function
|
|
421
|
+
export function resolveProjectDocTargets(discoveryAnswers) {
|
|
450
422
|
const hasDatabase = !discoveryAnswers.databaseChoice.toLowerCase().startsWith('none');
|
|
451
|
-
const hasAuth = !discoveryAnswers.authStrategy.toLowerCase().startsWith('none');
|
|
452
423
|
const isApiOrWebDomain = ['API service', 'Web application'].includes(discoveryAnswers.primaryDomain)
|
|
453
424
|
|| discoveryAnswers.primaryDomain.toLowerCase().includes('api')
|
|
454
425
|
|| discoveryAnswers.primaryDomain.toLowerCase().includes('web');
|
|
455
426
|
|
|
456
|
-
const
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
427
|
+
const requiredDocFileNames = [
|
|
428
|
+
'project-brief.md',
|
|
429
|
+
'architecture-decision-record.md',
|
|
430
|
+
'flow-overview.md',
|
|
460
431
|
];
|
|
461
432
|
|
|
462
433
|
if (hasDatabase) {
|
|
463
|
-
|
|
464
|
-
templateFileName: 'database-schema.md.tmpl',
|
|
465
|
-
outputFileName: 'database-schema.md',
|
|
466
|
-
alwaysInclude: false,
|
|
467
|
-
});
|
|
434
|
+
requiredDocFileNames.push('database-schema.md');
|
|
468
435
|
}
|
|
469
436
|
|
|
470
437
|
if (isApiOrWebDomain) {
|
|
471
|
-
|
|
472
|
-
templateFileName: 'api-contract.md.tmpl',
|
|
473
|
-
outputFileName: 'api-contract.md',
|
|
474
|
-
alwaysInclude: false,
|
|
475
|
-
});
|
|
438
|
+
requiredDocFileNames.push('api-contract.md');
|
|
476
439
|
}
|
|
477
440
|
|
|
478
|
-
return {
|
|
441
|
+
return { requiredDocFileNames };
|
|
479
442
|
}
|
|
480
443
|
|
|
481
444
|
/**
|
|
482
|
-
* Build
|
|
445
|
+
* Build synthesis context from discovery answers and init selections.
|
|
483
446
|
*/
|
|
484
|
-
export function
|
|
485
|
-
const hasDatabase = !discoveryAnswers.databaseChoice.toLowerCase().startsWith('none');
|
|
486
|
-
const hasAuth = !discoveryAnswers.authStrategy.toLowerCase().startsWith('none');
|
|
447
|
+
export function buildSynthesisContext(_discoveryAnswers, initContext) {
|
|
487
448
|
const additionalStackFileNames = Array.isArray(initContext.additionalStackFileNames)
|
|
488
449
|
? initContext.additionalStackFileNames
|
|
489
450
|
: [];
|
|
490
451
|
const additionalBlueprintFileNames = Array.isArray(initContext.additionalBlueprintFileNames)
|
|
491
452
|
? initContext.additionalBlueprintFileNames
|
|
492
453
|
: [];
|
|
493
|
-
const parsedDockerStrategy = parseDockerStrategy(discoveryAnswers.dockerStrategy);
|
|
494
|
-
|
|
495
|
-
const baseUrlMap = {
|
|
496
|
-
'API service': 'http://localhost:3000',
|
|
497
|
-
'Web application': 'http://localhost:3000/api',
|
|
498
|
-
'Mobile app': 'http://localhost:3000/api',
|
|
499
|
-
'CLI tool': 'N/A',
|
|
500
|
-
'Library / SDK': 'N/A',
|
|
501
|
-
};
|
|
502
454
|
|
|
503
455
|
return {
|
|
504
|
-
projectName: discoveryAnswers.projectName,
|
|
505
|
-
projectDescription: discoveryAnswers.projectDescription,
|
|
506
|
-
primaryDomain: discoveryAnswers.primaryDomain,
|
|
507
|
-
databaseChoice: discoveryAnswers.databaseChoice,
|
|
508
|
-
authStrategy: discoveryAnswers.authStrategy,
|
|
509
|
-
features: discoveryAnswers.features,
|
|
510
|
-
additionalContext: discoveryAnswers.additionalContext,
|
|
511
456
|
stackFileName: initContext.stackFileName,
|
|
512
|
-
stackDisplayName: toTitleCase(initContext.stackFileName),
|
|
513
457
|
additionalStackFileNames,
|
|
514
|
-
additionalStackDisplayNames: additionalStackFileNames.length > 0
|
|
515
|
-
? additionalStackFileNames.map((stackFileName) => toTitleCase(stackFileName))
|
|
516
|
-
: null,
|
|
517
458
|
blueprintFileName: initContext.blueprintFileName,
|
|
518
|
-
blueprintDisplayName: toTitleCase(initContext.blueprintFileName),
|
|
519
459
|
additionalBlueprintFileNames,
|
|
520
|
-
additionalBlueprintDisplayNames: additionalBlueprintFileNames.length > 0
|
|
521
|
-
? additionalBlueprintFileNames.map((blueprintFileName) => toTitleCase(blueprintFileName))
|
|
522
|
-
: null,
|
|
523
460
|
runtimeEnvironmentKey: initContext.runtimeEnvironmentKey || 'linux',
|
|
524
461
|
runtimeEnvironmentLabel: initContext.runtimeEnvironmentLabel || 'Linux',
|
|
525
|
-
cliVersion: CLI_VERSION,
|
|
526
|
-
templateVersion: PROJECT_DOC_TEMPLATE_VERSION,
|
|
527
|
-
generatedAt: new Date().toISOString(),
|
|
528
|
-
generatedDate: new Date().toISOString().split('T')[0],
|
|
529
|
-
hasDatabase,
|
|
530
|
-
hasAuth,
|
|
531
|
-
hasDocker: parsedDockerStrategy.hasDocker,
|
|
532
|
-
dockerStrategy: parsedDockerStrategy.dockerStrategy,
|
|
533
|
-
useDockerDevelopment: parsedDockerStrategy.useDockerDevelopment,
|
|
534
|
-
useDockerProduction: parsedDockerStrategy.useDockerProduction,
|
|
535
|
-
dockerDevelopmentGuidance: parsedDockerStrategy.useDockerDevelopment
|
|
536
|
-
? '- Development containers are required: optimize for fast rebuilds, bind mounts, and debug-friendly startup.'
|
|
537
|
-
: '',
|
|
538
|
-
dockerProductionGuidance: parsedDockerStrategy.useDockerProduction
|
|
539
|
-
? '- Production containers are required: use multi-stage builds, non-root runtime, and minimal image footprint.'
|
|
540
|
-
: '',
|
|
541
|
-
baseUrl: baseUrlMap[discoveryAnswers.primaryDomain] || 'http://localhost:3000',
|
|
542
462
|
};
|
|
543
463
|
}
|
|
544
464
|
|
|
545
|
-
/**
|
|
546
|
-
* Render a template string by replacing {{placeholder}} tokens with context values.
|
|
547
|
-
* Supports:
|
|
548
|
-
* - {{key}} for simple values
|
|
549
|
-
* - {{#each key}}...{{this}}...{{/each}} for arrays
|
|
550
|
-
* - {{#if key}}...{{/if}} for conditionals
|
|
551
|
-
*/
|
|
552
|
-
export function renderTemplate(templateContent, templateContext) {
|
|
553
|
-
let renderedContent = templateContent;
|
|
554
|
-
|
|
555
|
-
// Process {{#each key}}...{{/each}} blocks
|
|
556
|
-
renderedContent = renderedContent.replace(
|
|
557
|
-
/\{\{#each\s+(\w+)\}\}([\s\S]*?)\{\{\/each\}\}/g,
|
|
558
|
-
(_fullMatch, iteratorKey, iteratorBody) => {
|
|
559
|
-
const iteratorValues = templateContext[iteratorKey];
|
|
560
|
-
|
|
561
|
-
if (!Array.isArray(iteratorValues) || iteratorValues.length === 0) {
|
|
562
|
-
return '';
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
return iteratorValues
|
|
566
|
-
.map((iteratorValue) => iteratorBody.replace(/\{\{this\}\}/g, iteratorValue))
|
|
567
|
-
.join('');
|
|
568
|
-
}
|
|
569
|
-
);
|
|
570
|
-
|
|
571
|
-
// Process {{#if key}}...{{/if}} blocks
|
|
572
|
-
renderedContent = renderedContent.replace(
|
|
573
|
-
/\{\{#if\s+(\w+)\}\}([\s\S]*?)\{\{\/if\}\}/g,
|
|
574
|
-
(_fullMatch, conditionKey, conditionBody) => {
|
|
575
|
-
const conditionValue = templateContext[conditionKey];
|
|
576
|
-
return conditionValue ? conditionBody : '';
|
|
577
|
-
}
|
|
578
|
-
);
|
|
579
|
-
|
|
580
|
-
// Process simple {{key}} replacements
|
|
581
|
-
renderedContent = renderedContent.replace(
|
|
582
|
-
/\{\{(\w+)\}\}/g,
|
|
583
|
-
(_fullMatch, placeholderKey) => {
|
|
584
|
-
const placeholderValue = templateContext[placeholderKey];
|
|
585
|
-
|
|
586
|
-
if (placeholderValue === undefined || placeholderValue === null) {
|
|
587
|
-
return `{{${placeholderKey}}}`;
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
if (Array.isArray(placeholderValue)) {
|
|
591
|
-
return placeholderValue.join(', ');
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
return String(placeholderValue);
|
|
595
|
-
}
|
|
596
|
-
);
|
|
597
|
-
|
|
598
|
-
return renderedContent;
|
|
599
|
-
}
|
|
600
|
-
|
|
601
465
|
function shouldBootstrapDesignDocument(discoveryAnswers, initContext) {
|
|
602
466
|
const normalizedDomain = String(discoveryAnswers.primaryDomain || '').trim().toLowerCase();
|
|
603
467
|
const normalizedBlueprint = String(initContext.blueprintFileName || '').trim().toLowerCase();
|
|
@@ -670,6 +534,7 @@ function buildProjectContextBootstrapPrompt({
|
|
|
670
534
|
'2. Every major section must explain rationale and tradeoffs.',
|
|
671
535
|
'3. Keep stack, database, and auth aligned with the project constraints below unless user explicitly requests migration.',
|
|
672
536
|
'4. Output must be implementation-ready for engineers, not generic textbook explanation.',
|
|
537
|
+
'5. For any research-backed claim, include citation metadata (source + fetchedAt timestamp) from the Architect Engine Snapshot.',
|
|
673
538
|
'',
|
|
674
539
|
'## Project Inputs',
|
|
675
540
|
`- Project name: ${discoveryAnswers.projectName}`,
|
|
@@ -764,7 +629,6 @@ function buildDesignBootstrapPrompt({
|
|
|
764
629
|
|
|
765
630
|
/**
|
|
766
631
|
* Generate AI-first bootstrap prompts for dynamic project documentation synthesis.
|
|
767
|
-
* Legacy template rendering utilities are retained for backward compatibility checks.
|
|
768
632
|
*/
|
|
769
633
|
export async function generateProjectDocumentation(
|
|
770
634
|
targetDirectoryPath,
|
|
@@ -781,16 +645,16 @@ export async function generateProjectDocumentation(
|
|
|
781
645
|
const promptsDirectoryPath = path.join(targetDirectoryPath, '.agent-context', 'prompts');
|
|
782
646
|
await ensureDirectory(promptsDirectoryPath);
|
|
783
647
|
|
|
784
|
-
const
|
|
785
|
-
const {
|
|
786
|
-
const expectedDocFileNames =
|
|
648
|
+
const synthesisContext = buildSynthesisContext(discoveryAnswers, initContext);
|
|
649
|
+
const { requiredDocFileNames } = resolveProjectDocTargets(discoveryAnswers);
|
|
650
|
+
const expectedDocFileNames = [...requiredDocFileNames];
|
|
787
651
|
const generatedPromptFileNames = [];
|
|
788
652
|
|
|
789
653
|
const projectContextPromptFileName = 'bootstrap-project-context.md';
|
|
790
654
|
const architectureRecommendation = initContext.architectureRecommendation || null;
|
|
791
655
|
const projectContextPromptContent = buildProjectContextBootstrapPrompt({
|
|
792
656
|
discoveryAnswers,
|
|
793
|
-
initContext:
|
|
657
|
+
initContext: synthesisContext,
|
|
794
658
|
expectedDocFileNames,
|
|
795
659
|
docsLanguage: normalizedDocsLanguage,
|
|
796
660
|
architectureRecommendation,
|
|
@@ -806,7 +670,7 @@ export async function generateProjectDocumentation(
|
|
|
806
670
|
const designPromptFileName = 'bootstrap-design.md';
|
|
807
671
|
const designPromptContent = buildDesignBootstrapPrompt({
|
|
808
672
|
discoveryAnswers,
|
|
809
|
-
initContext:
|
|
673
|
+
initContext: synthesisContext,
|
|
810
674
|
docsLanguage: normalizedDocsLanguage,
|
|
811
675
|
architectureRecommendation,
|
|
812
676
|
});
|
package/lib/cli/utils.mjs
CHANGED
|
@@ -25,7 +25,6 @@ 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');
|
|
@@ -34,7 +33,6 @@ export function printUsage() {
|
|
|
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:');
|
|
@@ -72,8 +70,6 @@ export function printUsage() {
|
|
|
72
70
|
console.log(' --enable Enable token optimization policy and rebuild compiled rules');
|
|
73
71
|
console.log(' --disable Disable token optimization policy and rebuild compiled rules');
|
|
74
72
|
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
73
|
}
|
|
78
74
|
|
|
79
75
|
export async function pathExists(targetPath) {
|
|
@@ -199,7 +195,7 @@ export async function copyGovernanceAssetsToTarget(
|
|
|
199
195
|
parsedZedSettings.context_servers['agentic-senior-core'] = zedMcpConfig.context_servers['agentic-senior-core'];
|
|
200
196
|
await fs.writeFile(zedSettingsPath, JSON.stringify(parsedZedSettings, null, 2) + '\n', 'utf8');
|
|
201
197
|
}
|
|
202
|
-
} catch
|
|
198
|
+
} catch {
|
|
203
199
|
// Fallback or ignore if user has broken JSON
|
|
204
200
|
}
|
|
205
201
|
}
|
|
@@ -216,7 +212,7 @@ export async function copyGovernanceAssetsToTarget(
|
|
|
216
212
|
if (await pathExists(globalGeminiMcpPath)) {
|
|
217
213
|
const content = await fs.readFile(globalGeminiMcpPath, 'utf8');
|
|
218
214
|
if (content.trim()) {
|
|
219
|
-
try { geminiConfig = JSON.parse(content); } catch
|
|
215
|
+
try { geminiConfig = JSON.parse(content); } catch {}
|
|
220
216
|
}
|
|
221
217
|
}
|
|
222
218
|
if (!geminiConfig.mcpServers) geminiConfig.mcpServers = {};
|
|
@@ -233,7 +229,7 @@ export async function copyGovernanceAssetsToTarget(
|
|
|
233
229
|
|
|
234
230
|
await fs.writeFile(globalGeminiMcpPath, JSON.stringify(geminiConfig, null, 2) + '\n', 'utf8');
|
|
235
231
|
}
|
|
236
|
-
} catch
|
|
232
|
+
} catch {
|
|
237
233
|
// Ignore global injection errors
|
|
238
234
|
}
|
|
239
235
|
}
|
|
@@ -346,11 +342,19 @@ export function parseBlockingSeverities(rawSeverityValues, fileName) {
|
|
|
346
342
|
}
|
|
347
343
|
|
|
348
344
|
export async function collectFileNames(folderPath) {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
345
|
+
try {
|
|
346
|
+
const fileNames = await fs.readdir(folderPath, { withFileTypes: true });
|
|
347
|
+
return fileNames
|
|
348
|
+
.filter((entry) => entry.isFile() && entry.name.endsWith('.md'))
|
|
349
|
+
.map((entry) => entry.name)
|
|
350
|
+
.sort((leftName, rightName) => leftName.localeCompare(rightName));
|
|
351
|
+
} catch (error) {
|
|
352
|
+
if (error?.code === 'ENOENT') {
|
|
353
|
+
return [];
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
throw error;
|
|
357
|
+
}
|
|
354
358
|
}
|
|
355
359
|
|
|
356
360
|
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.0",
|
|
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
|
);
|