@ryuenn3123/agentic-senior-core 2.0.25 → 2.0.26
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/review-checklists/frontend-excellence-rubric.md +54 -0
- package/.agent-context/review-checklists/frontend-skill-parity.md +1 -0
- package/.agent-context/review-checklists/frontend-usability.md +1 -0
- package/.agent-context/rules/docker-runtime.md +29 -0
- package/.agent-context/skills/frontend/README.md +1 -0
- package/.agent-context/skills/frontend.md +4 -0
- package/.cursorrules +1 -1
- package/.windsurfrules +1 -1
- package/README.md +7 -0
- package/lib/cli/commands/init.mjs +358 -16
- package/lib/cli/commands/optimize.mjs +12 -0
- package/lib/cli/commands/upgrade.mjs +30 -1
- package/lib/cli/compiler.mjs +55 -1
- package/lib/cli/constants.mjs +83 -0
- package/lib/cli/detector.mjs +11 -1
- package/lib/cli/project-scaffolder.mjs +174 -1
- package/lib/cli/skill-selector.mjs +60 -38
- package/lib/cli/templates/architecture-decision-record.md.tmpl +39 -0
- package/lib/cli/templates/flow-overview.md.tmpl +12 -0
- package/lib/cli/templates/project-brief.md.id.tmpl +2 -0
- package/lib/cli/templates/project-brief.md.tmpl +26 -0
- package/lib/cli/utils.mjs +2 -1
- package/package.json +1 -1
- package/scripts/frontend-usability-audit.mjs +21 -0
- package/scripts/release-gate.mjs +30 -0
- package/scripts/validate.mjs +2 -0
|
@@ -43,55 +43,77 @@ export function formatSkillTierList(skillPlatformIndex) {
|
|
|
43
43
|
return skillPlatformIndex.tiers.map((tierDefinition) => `${tierDefinition.name} (${tierDefinition.description})`).join('\n');
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
export function inferSkillDomainNamesFromSelection(
|
|
46
|
+
export function inferSkillDomainNamesFromSelection(
|
|
47
|
+
selectedStackFileName,
|
|
48
|
+
selectedBlueprintFileName,
|
|
49
|
+
additionalStackFileNames = [],
|
|
50
|
+
additionalBlueprintFileNames = []
|
|
51
|
+
) {
|
|
47
52
|
const inferredDomainNames = new Set();
|
|
48
53
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
function applyStackSignals(stackFileName) {
|
|
55
|
+
if (stackFileName === 'typescript.md') {
|
|
56
|
+
inferredDomainNames.add('frontend');
|
|
57
|
+
inferredDomainNames.add('cli');
|
|
58
|
+
}
|
|
54
59
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
if (stackFileName === 'go.md'
|
|
61
|
+
|| stackFileName === 'java.md'
|
|
62
|
+
|| stackFileName === 'php.md'
|
|
63
|
+
|| stackFileName === 'csharp.md'
|
|
64
|
+
|| stackFileName === 'python.md'
|
|
65
|
+
|| stackFileName === 'ruby.md'
|
|
66
|
+
|| stackFileName === 'rust.md') {
|
|
67
|
+
inferredDomainNames.add('backend');
|
|
68
|
+
}
|
|
63
69
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
70
|
+
if (stackFileName === 'react-native.md' || stackFileName === 'flutter.md') {
|
|
71
|
+
inferredDomainNames.add('frontend');
|
|
72
|
+
inferredDomainNames.add('fullstack');
|
|
73
|
+
inferredDomainNames.add('cli');
|
|
74
|
+
}
|
|
67
75
|
}
|
|
68
76
|
|
|
69
|
-
|
|
70
|
-
||
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|| selectedStackFileName === 'rust.md') {
|
|
76
|
-
inferredDomainNames.add('backend');
|
|
77
|
-
}
|
|
77
|
+
function applyBlueprintSignals(blueprintFileName) {
|
|
78
|
+
if (blueprintFileName === 'api-nextjs.md' || blueprintFileName === 'fastapi-service.md') {
|
|
79
|
+
inferredDomainNames.add('frontend');
|
|
80
|
+
inferredDomainNames.add('fullstack');
|
|
81
|
+
inferredDomainNames.add('cli');
|
|
82
|
+
}
|
|
78
83
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
84
|
+
if (blueprintFileName === 'go-service.md'
|
|
85
|
+
|| blueprintFileName === 'spring-boot-api.md'
|
|
86
|
+
|| blueprintFileName === 'laravel-api.md'
|
|
87
|
+
|| blueprintFileName === 'aspnet-api.md'
|
|
88
|
+
|| blueprintFileName === 'nestjs-logic.md'
|
|
89
|
+
|| blueprintFileName === 'graphql-grpc-api.md') {
|
|
90
|
+
inferredDomainNames.add('backend');
|
|
91
|
+
inferredDomainNames.add('fullstack');
|
|
92
|
+
inferredDomainNames.add('cli');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (blueprintFileName === 'mobile-app.md') {
|
|
96
|
+
inferredDomainNames.add('frontend');
|
|
97
|
+
inferredDomainNames.add('fullstack');
|
|
98
|
+
inferredDomainNames.add('cli');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (blueprintFileName === 'observability.md') {
|
|
102
|
+
inferredDomainNames.add('backend');
|
|
103
|
+
inferredDomainNames.add('fullstack');
|
|
104
|
+
inferredDomainNames.add('cli');
|
|
105
|
+
}
|
|
83
106
|
}
|
|
84
107
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
108
|
+
applyBlueprintSignals(selectedBlueprintFileName);
|
|
109
|
+
|
|
110
|
+
applyStackSignals(selectedStackFileName);
|
|
111
|
+
for (const additionalStackFileName of additionalStackFileNames) {
|
|
112
|
+
applyStackSignals(additionalStackFileName);
|
|
89
113
|
}
|
|
90
114
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
inferredDomainNames.add('fullstack');
|
|
94
|
-
inferredDomainNames.add('cli');
|
|
115
|
+
for (const additionalBlueprintFileName of additionalBlueprintFileNames) {
|
|
116
|
+
applyBlueprintSignals(additionalBlueprintFileName);
|
|
95
117
|
}
|
|
96
118
|
|
|
97
119
|
if (inferredDomainNames.size === 0) {
|
|
@@ -18,9 +18,23 @@ This project requires a {{primaryDomain}} solution. The team evaluated available
|
|
|
18
18
|
### Decision
|
|
19
19
|
|
|
20
20
|
- **Language/Runtime**: {{stackDisplayName}} (source: `.agent-context/stacks/{{stackFileName}}`)
|
|
21
|
+
{{#if additionalStackDisplayNames}}
|
|
22
|
+
- **Additional runtime context**:
|
|
23
|
+
{{#each additionalStackDisplayNames}}
|
|
24
|
+
- {{this}}
|
|
25
|
+
{{/each}}
|
|
26
|
+
{{/if}}
|
|
21
27
|
- **Architecture blueprint**: {{blueprintDisplayName}} (source: `.agent-context/blueprints/{{blueprintFileName}}`)
|
|
28
|
+
{{#if additionalBlueprintDisplayNames}}
|
|
29
|
+
- **Additional architecture blueprints**:
|
|
30
|
+
{{#each additionalBlueprintDisplayNames}}
|
|
31
|
+
- {{this}}
|
|
32
|
+
{{/each}}
|
|
33
|
+
{{/if}}
|
|
22
34
|
- **Database**: {{databaseChoice}}
|
|
23
35
|
- **Auth**: {{authStrategy}}
|
|
36
|
+
- **Runtime environment target**: {{runtimeEnvironmentLabel}}
|
|
37
|
+
- **Containerization strategy**: {{dockerStrategy}}
|
|
24
38
|
|
|
25
39
|
### Rationale
|
|
26
40
|
|
|
@@ -36,6 +50,31 @@ The {{stackDisplayName}} stack was selected because:
|
|
|
36
50
|
- Database access must follow `.agent-context/rules/database-design.md`.
|
|
37
51
|
- API contracts must follow `.agent-context/rules/api-docs.md`.
|
|
38
52
|
|
|
53
|
+
{{#if hasDocker}}
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## ADR-004: Containerization Strategy (Dynamic)
|
|
57
|
+
|
|
58
|
+
**Status**: Accepted
|
|
59
|
+
**Date**: {{generatedDate}}
|
|
60
|
+
|
|
61
|
+
### Context
|
|
62
|
+
|
|
63
|
+
This project requires container support with separated development and production concerns.
|
|
64
|
+
|
|
65
|
+
### Decision
|
|
66
|
+
|
|
67
|
+
- Follow dynamic container generation based on real project dependencies and runtime profile.
|
|
68
|
+
- Do not rely on static Docker templates copied from unrelated repositories.
|
|
69
|
+
{{dockerDevelopmentGuidance}}
|
|
70
|
+
{{dockerProductionGuidance}}
|
|
71
|
+
|
|
72
|
+
### Consequences
|
|
73
|
+
|
|
74
|
+
- Development and production Docker artifacts are treated as separate deliverables.
|
|
75
|
+
- Changes in package/runtime dependencies must regenerate container setup instructions in the same change.
|
|
76
|
+
{{/if}}
|
|
77
|
+
|
|
39
78
|
---
|
|
40
79
|
|
|
41
80
|
## ADR-002: Architecture Pattern
|
|
@@ -12,6 +12,18 @@ Template version: {{templateVersion}}
|
|
|
12
12
|
**Domain**: {{primaryDomain}}
|
|
13
13
|
**Stack**: {{stackDisplayName}}
|
|
14
14
|
**Blueprint**: {{blueprintDisplayName}}
|
|
15
|
+
**Runtime target**: {{runtimeEnvironmentLabel}}
|
|
16
|
+
**Containerization**: {{dockerStrategy}}
|
|
17
|
+
|
|
18
|
+
{{#if hasDocker}}
|
|
19
|
+
## Container Flow (Dynamic Dev and Prod)
|
|
20
|
+
|
|
21
|
+
- Container setup is generated dynamically by AI from current dependencies, not from static canned templates.
|
|
22
|
+
{{dockerDevelopmentGuidance}}
|
|
23
|
+
{{dockerProductionGuidance}}
|
|
24
|
+
- Keep dev and prod container concerns explicitly separated.
|
|
25
|
+
|
|
26
|
+
{{/if}}
|
|
15
27
|
|
|
16
28
|
## High-Level Architecture
|
|
17
29
|
|
|
@@ -18,6 +18,8 @@ Versi template: {{templateVersion}}
|
|
|
18
18
|
**Blueprint**: {{blueprintDisplayName}}
|
|
19
19
|
**Database**: {{databaseChoice}}
|
|
20
20
|
**Strategi autentikasi**: {{authStrategy}}
|
|
21
|
+
**Target environment runtime**: {{runtimeEnvironmentLabel}}
|
|
22
|
+
**Strategi containerisasi**: {{dockerStrategy}}
|
|
21
23
|
|
|
22
24
|
## Fitur Kunci
|
|
23
25
|
|
|
@@ -15,9 +15,35 @@ Template version: {{templateVersion}}
|
|
|
15
15
|
## Technology Decisions
|
|
16
16
|
|
|
17
17
|
**Stack**: {{stackDisplayName}}
|
|
18
|
+
{{#if additionalStackDisplayNames}}
|
|
19
|
+
**Additional stacks**:
|
|
20
|
+
{{#each additionalStackDisplayNames}}
|
|
21
|
+
- {{this}}
|
|
22
|
+
{{/each}}
|
|
23
|
+
{{/if}}
|
|
18
24
|
**Blueprint**: {{blueprintDisplayName}}
|
|
25
|
+
{{#if additionalBlueprintDisplayNames}}
|
|
26
|
+
**Additional blueprints**:
|
|
27
|
+
{{#each additionalBlueprintDisplayNames}}
|
|
28
|
+
- {{this}}
|
|
29
|
+
{{/each}}
|
|
30
|
+
{{/if}}
|
|
19
31
|
**Database**: {{databaseChoice}}
|
|
20
32
|
**Auth strategy**: {{authStrategy}}
|
|
33
|
+
**Runtime environment target**: {{runtimeEnvironmentLabel}}
|
|
34
|
+
**Containerization strategy**: {{dockerStrategy}}
|
|
35
|
+
|
|
36
|
+
{{#if hasDocker}}
|
|
37
|
+
## Containerization Workflow (Dynamic)
|
|
38
|
+
|
|
39
|
+
- Docker is enabled for this project: **{{dockerStrategy}}**.
|
|
40
|
+
- Docker setup must be generated dynamically by AI based on current dependencies and runtime constraints.
|
|
41
|
+
- Do not use fixed boilerplate templates that ignore actual project structure.
|
|
42
|
+
{{dockerDevelopmentGuidance}}
|
|
43
|
+
{{dockerProductionGuidance}}
|
|
44
|
+
|
|
45
|
+
- Keep development and production container strategy separated to avoid environment drift.
|
|
46
|
+
{{/if}}
|
|
21
47
|
|
|
22
48
|
## Key Features
|
|
23
49
|
|
package/lib/cli/utils.mjs
CHANGED
|
@@ -28,7 +28,7 @@ export function printUsage() {
|
|
|
28
28
|
console.log('');
|
|
29
29
|
console.log('Usage:');
|
|
30
30
|
console.log(' agentic-senior-core launch');
|
|
31
|
-
console.log(' agentic-senior-core init [target-directory] [--preset <name>] [--profile <beginner|balanced|strict>] [--profile-pack <name>] [--stack <name>] [--blueprint <name>] [--ci <true|false>] [--newbie] [--token-optimize] [--no-token-optimize] [--token-agent <name>] [--scaffold-docs] [--no-scaffold-docs] [--docs-lang <en|id>] [--project-config <path>]');
|
|
31
|
+
console.log(' agentic-senior-core init [target-directory] [--preset <name>] [--profile <beginner|balanced|strict>] [--profile-pack <name>] [--stack <name>] [--blueprint <name>] [--ci <true|false>] [--newbie] [--token-optimize] [--no-token-optimize] [--token-agent <name>] [--scaffold-docs] [--no-scaffold-docs] [--docs-lang <en|id>] [--project-config <path>] [--runtime-env <auto|linux-wsl|linux|windows|macos>]');
|
|
32
32
|
console.log(' agentic-senior-core upgrade [target-directory] [--dry-run] [--yes] [--mcp-template]');
|
|
33
33
|
console.log(' agentic-senior-core optimize [target-directory] [--agent <copilot|claude|cursor|windsurf|gemini|codex|cline>] [--enable|--disable] [--show]');
|
|
34
34
|
console.log(' agentic-senior-core mcp');
|
|
@@ -54,6 +54,7 @@ export function printUsage() {
|
|
|
54
54
|
console.log(' --no-scaffold-docs Skip project documentation scaffolding');
|
|
55
55
|
console.log(' --docs-lang Optional override for generated project docs language (default: en)');
|
|
56
56
|
console.log(' --project-config Path to a project config file for non-interactive doc scaffolding');
|
|
57
|
+
console.log(' --runtime-env Override runtime environment hint (auto, linux-wsl, linux, windows, macos)');
|
|
57
58
|
console.log(' --dry-run Preview upgrade without writing files');
|
|
58
59
|
console.log(' --yes Skip confirmation prompts for upgrade');
|
|
59
60
|
console.log(' --agent Target agent integration for token optimization mode');
|
package/package.json
CHANGED
|
@@ -21,6 +21,7 @@ const REQUIRED_FILES = [
|
|
|
21
21
|
'docs/v1.7-issue-breakdown.md',
|
|
22
22
|
'docs/v1.7-execution-playbook.md',
|
|
23
23
|
'.agent-context/review-checklists/frontend-usability.md',
|
|
24
|
+
'.agent-context/review-checklists/frontend-excellence-rubric.md',
|
|
24
25
|
];
|
|
25
26
|
|
|
26
27
|
const REQUIRED_ROADMAP_SNIPPETS = [
|
|
@@ -37,6 +38,14 @@ const REQUIRED_CHECKLIST_SNIPPETS = [
|
|
|
37
38
|
'Documentation and Release Evidence',
|
|
38
39
|
];
|
|
39
40
|
|
|
41
|
+
const REQUIRED_EXCELLENCE_RUBRIC_SNIPPETS = [
|
|
42
|
+
'Visual Direction and Identity',
|
|
43
|
+
'Typography Quality',
|
|
44
|
+
'Color System Diversity and Contrast',
|
|
45
|
+
'Interaction Choreography',
|
|
46
|
+
'Awwwards-level reference quality',
|
|
47
|
+
];
|
|
48
|
+
|
|
40
49
|
function assertFileExists(relativeFilePath, failures) {
|
|
41
50
|
const absoluteFilePath = resolve(REPOSITORY_ROOT, relativeFilePath);
|
|
42
51
|
if (!existsSync(absoluteFilePath)) {
|
|
@@ -61,6 +70,7 @@ function runAudit() {
|
|
|
61
70
|
|
|
62
71
|
const roadmapPath = 'docs/roadmap.md';
|
|
63
72
|
const checklistPath = '.agent-context/review-checklists/frontend-usability.md';
|
|
73
|
+
const excellenceRubricPath = '.agent-context/review-checklists/frontend-excellence-rubric.md';
|
|
64
74
|
|
|
65
75
|
if (existsSync(resolve(REPOSITORY_ROOT, roadmapPath))) {
|
|
66
76
|
const roadmapContent = readFileSync(resolve(REPOSITORY_ROOT, roadmapPath), 'utf8');
|
|
@@ -72,6 +82,17 @@ function runAudit() {
|
|
|
72
82
|
assertContains('Checklist', checklistPath, checklistContent, REQUIRED_CHECKLIST_SNIPPETS, failures);
|
|
73
83
|
}
|
|
74
84
|
|
|
85
|
+
if (existsSync(resolve(REPOSITORY_ROOT, excellenceRubricPath))) {
|
|
86
|
+
const excellenceRubricContent = readFileSync(resolve(REPOSITORY_ROOT, excellenceRubricPath), 'utf8');
|
|
87
|
+
assertContains(
|
|
88
|
+
'Frontend excellence rubric',
|
|
89
|
+
excellenceRubricPath,
|
|
90
|
+
excellenceRubricContent,
|
|
91
|
+
REQUIRED_EXCELLENCE_RUBRIC_SNIPPETS,
|
|
92
|
+
failures
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
75
96
|
const reportPayload = {
|
|
76
97
|
generatedAt: new Date().toISOString(),
|
|
77
98
|
auditName: 'frontend-usability-audit',
|
package/scripts/release-gate.mjs
CHANGED
|
@@ -28,6 +28,7 @@ const REQUIRED_SKILL_DOMAINS = [
|
|
|
28
28
|
'review-quality',
|
|
29
29
|
];
|
|
30
30
|
const FRONTEND_PARITY_CHECKLIST_PATH = '.agent-context/review-checklists/frontend-skill-parity.md';
|
|
31
|
+
const FRONTEND_EXCELLENCE_RUBRIC_PATH = '.agent-context/review-checklists/frontend-excellence-rubric.md';
|
|
31
32
|
const FRONTEND_AUDIT_SCRIPT_PATH = 'scripts/frontend-usability-audit.mjs';
|
|
32
33
|
const REQUIRED_FRONTEND_PARITY_SNIPPETS = [
|
|
33
34
|
'Architecture and Composition',
|
|
@@ -36,6 +37,13 @@ const REQUIRED_FRONTEND_PARITY_SNIPPETS = [
|
|
|
36
37
|
'UX Narrative and Conversion Clarity',
|
|
37
38
|
'Release Evidence',
|
|
38
39
|
];
|
|
40
|
+
const REQUIRED_FRONTEND_EXCELLENCE_RUBRIC_SNIPPETS = [
|
|
41
|
+
'Visual Direction and Identity',
|
|
42
|
+
'Typography Quality',
|
|
43
|
+
'Color System Diversity and Contrast',
|
|
44
|
+
'Interaction Choreography',
|
|
45
|
+
'Awwwards-level reference quality',
|
|
46
|
+
];
|
|
39
47
|
const BENCHMARK_GATE_SCRIPT_PATH = 'scripts/benchmark-gate.mjs';
|
|
40
48
|
|
|
41
49
|
function readText(relativeFilePath) {
|
|
@@ -264,6 +272,28 @@ function runReleaseGate() {
|
|
|
264
272
|
}
|
|
265
273
|
}
|
|
266
274
|
|
|
275
|
+
const frontendExcellenceRubricContent = readText(FRONTEND_EXCELLENCE_RUBRIC_PATH);
|
|
276
|
+
if (!frontendExcellenceRubricContent) {
|
|
277
|
+
pushResult(results, false, 'frontend-excellence-rubric-exists', `Missing ${FRONTEND_EXCELLENCE_RUBRIC_PATH}`);
|
|
278
|
+
} else {
|
|
279
|
+
pushResult(results, true, 'frontend-excellence-rubric-exists', `${FRONTEND_EXCELLENCE_RUBRIC_PATH} is present`);
|
|
280
|
+
|
|
281
|
+
const missingFrontendExcellenceSnippets = REQUIRED_FRONTEND_EXCELLENCE_RUBRIC_SNIPPETS.filter(
|
|
282
|
+
(requiredSnippet) => !frontendExcellenceRubricContent.includes(requiredSnippet)
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
if (missingFrontendExcellenceSnippets.length === 0) {
|
|
286
|
+
pushResult(results, true, 'frontend-excellence-rubric-coverage', 'Frontend excellence rubric sections are complete');
|
|
287
|
+
} else {
|
|
288
|
+
pushResult(
|
|
289
|
+
results,
|
|
290
|
+
false,
|
|
291
|
+
'frontend-excellence-rubric-coverage',
|
|
292
|
+
`Missing frontend excellence rubric sections: ${missingFrontendExcellenceSnippets.join(', ')}`
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
267
297
|
try {
|
|
268
298
|
const frontendAuditRawOutput = execFileSync('node', [FRONTEND_AUDIT_SCRIPT_PATH], {
|
|
269
299
|
cwd: REPOSITORY_ROOT,
|
package/scripts/validate.mjs
CHANGED
|
@@ -258,6 +258,7 @@ async function validateRuleFiles() {
|
|
|
258
258
|
'rules/database-design.md',
|
|
259
259
|
'rules/realtime.md',
|
|
260
260
|
'rules/frontend-architecture.md',
|
|
261
|
+
'rules/docker-runtime.md',
|
|
261
262
|
'stacks/typescript.md',
|
|
262
263
|
'stacks/python.md',
|
|
263
264
|
'stacks/java.md',
|
|
@@ -285,6 +286,7 @@ async function validateRuleFiles() {
|
|
|
285
286
|
'review-checklists/pr-checklist.md',
|
|
286
287
|
'review-checklists/frontend-usability.md',
|
|
287
288
|
'review-checklists/frontend-skill-parity.md',
|
|
289
|
+
'review-checklists/frontend-excellence-rubric.md',
|
|
288
290
|
'review-checklists/release-operations.md',
|
|
289
291
|
'review-checklists/security-audit.md',
|
|
290
292
|
'review-checklists/performance-audit.md',
|