From sdcorejs-agent
Use when initializing a brand-new Angular portal repo using `@sd-angular/core` baseline template. Generates project skeleton (app shell, environments, sample module, configurations). Triggers - "khởi tạo portal", "init portal", "create portal-X", "new portal repo", "tạo dự án portal mới". Bilingual (VI/EN).
How this skill is triggered — by the user, by Claude, or both
Slash command
/sdcorejs-agent:angular-portal-init-portalThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Generates production-ready Angular portal starter from internal baseline template (`core/templates/angular-portal-starter/`).
Generates production-ready Angular portal starter from internal baseline template (core/templates/angular-portal-starter/).
Output: Complete portal with sample lib (1 module, 2 entities), dev tools, ready for npm start.
This skill uses two placeholders wherever the Core UI package appears:
| Placeholder | Resolved from _refs/core-version.md field |
|---|---|
<CORE_UI_PACKAGE_NAME> | packageName |
<CORE_VERSION> | currentVersion |
The actual values live ONLY in
_refs/core-version.md. Do not duplicate them here — the drift-check hook will block any literal version or any import statement that hardcodes the Core UI package name in this file.
BEFORE generating any file, the agent MUST:
_refs/core-version.md and extract packageName + currentVersion<CORE_UI_PACKAGE_NAME> / <CORE_VERSION> token in this skill's output with those values@sd-angular/core → @sdcorejs/angular)package.json / commit message / verification textSingle-file bump: change _refs/core-version.md and every future portal picks it up. Do NOT find-replace placeholders inside this skill file itself — they are intentional.
If _refs/core-version.md is missing or malformed, STOP and ask the user — never guess the version or package name.
Before generating, clarify with user:
hr-portal, sales-portaldev, qc, uat, prod)Portal)order, customer — Order uses <customer-select> so the sample also demos the base-select / entity-select pattern)11-init-module skill after generation"Port is fixed at
4200(Angular default). Do not ask.
Source: core/templates/angular-portal-starter/
Render Exclusion Rule (MANDATORY):
.claude, .github, .git, .vscode-test.gitkeep placeholders in generated output, especially under src/libs/**Result: Fresh portal project with:
portal-new/
├── package.json # <CORE_UI_PACKAGE_NAME>: <CORE_VERSION> (npm)
├── tsconfig.json # baseUrl + @sample paths
├── angular.json # build/serve configs
├── src/
│ ├── main.ts # Bootstrap with config providers
│ ├── app/
│ │ ├── app.component.ts # RouterOutlet
│ │ ├── app.routes.ts # Lazy-load layout + sample
│ │ └── configurations/ # Auth, Layout, Permission
│ └── libs/
│ └── sample/ # ONE sample lib only
│ ├── sample.configuration.ts
│ ├── sample.module.ts
│ ├── routes.ts
│ ├── configurations/ # API interceptor, upload config
│ ├── services/base/ # BaseService with CRUD
│ ├── components/ # MODULE-level reusables
│ │ ├── base-select/ # generic dropdown
│ │ └── customer-select/ # per-entity dropdown (reused by Order)
│ └── features/
│ ├── order/ # AdaptiveSplitDetail — Order form uses <customer-select>
│ └── customer/ # UnifiedCompact full-page detail
├── .prettierrc.json
├── .vscode/
└── plopfile.js # Optional generators
Run npm install. See package.json template below — pins <CORE_UI_PACKAGE_NAME>@<CORE_VERSION>.
npm run build-dev
# Expect: exit code 0, dist/ folder produced
npm start
# Expect: server at http://localhost:4200/
# Unit/integration
npm run test -- --watch=false
# E2E (only when project has e2e script/config)
npm run e2e
Report pass/fail summary and failing spec names. If E2E missing, report blocker.
_refs/core-version.md and substitute placeholders BEFORE writing any filecore/templates/angular-portal-starter onlyorder + customer (Order's create/update form uses <customer-select> — demonstrates the reusable dropdown pattern from 11-init-module)features/ (NOT modules/) at the lib level — src/libs/<lib>/features/<entity>/modules/, still generate new code under features/ and recommend renaming the existing modules/ directorysrc/libs/sample/components/base-select/ + src/libs/sample/components/customer-select/loadChildren: () => import('<CORE_UI_PACKAGE_NAME>/modules/layout').then(m => m.SdLayoutModule)<MODULE>_<ENTITY>_<ACTION> (e.g. SAMPLE_ORDER_LIST)<MODULE>_C_<ENTITY>_<ACTION> (e.g. SAMPLE_C_ORDER_LIST), <MODULE>_<ENTITY>:<ACTION>, etc.disabled = true so the portal boots without a permission backendsrc/app/pages/home and wire LayoutConfiguration.homeUrlsrc/libs/sample in starter generationorder, customer)file:sd-angular-core-*.tgz)tsconfig.json<CORE_UI_PACKAGE_NAME> with ad-hoc local componentsSD_PERMISSION_CONFIGURATION / SD_UPLOAD_FILE_CONFIGURATION in module or route providers with multi: true and expect root services to consume themdisabled = true) when permission backend/data source is not readyRequired before applying this skill:
- internal baseline templates exist in `core/templates/angular-portal-starter`
- developer confirmed project name
- developer confirmed environment names
- developer confirmed starter should include sample scaffold under `src/libs/sample`
- _refs/core-version.md is present (packageName + currentVersion)
Ask the developer:
1. Tên project portal mới là gì? (vd: portal-ops)
2. Cần các môi trường nào? Mặc định: dev, qc, uat, prod
3. Tiêu đề portal/sidebar mặc định là gì?
4. Giữ 2 entity mẫu mặc định (`order`, `customer`) hay đổi tên?
[project-name]/
├── angular.json
├── package.json
├── tsconfig.json
├── tsconfig.app.json
├── tsconfig.spec.json
├── eslint.config.js
├── plopfile.js
├── public/
│ └── silent-renew.html
├── src/
│ ├── index.html
│ ├── main.ts
│ ├── styles.scss
│ ├── app/
│ │ ├── app.component.ts
│ │ ├── app.routes.ts
│ │ ├── components/
│ │ │ └── main/
│ │ │ ├── main.component.ts
│ │ │ └── main.component.html
│ │ └── configurations/
│ │ ├── auth.configuration.ts
│ │ ├── layout.configuration.ts
│ │ ├── permission.configuration.ts
│ │ └── index.ts
│ └── environments/
│ ├── environment.model.ts
│ ├── environment.ts
│ ├── environment.dev.ts
│ ├── environment.qc.ts
│ ├── environment.uat.ts
│ └── environment.prod.ts
└── src/libs/
└── sample/
├── sample.configuration.ts
├── sample.module.ts
├── routes.ts
├── index.ts
├── configurations/
│ ├── api.configuration.ts
│ └── upload-file.configuration.ts
├── services/
│ └── base/
│ └── base.service.ts
├── components/
│ ├── base-select/
│ │ ├── base-select.component.ts
│ │ └── base-select.component.html
│ └── customer-select/
│ └── customer-select.component.ts
└── features/
├── order/
│ ├── routes.ts
│ ├── services/
│ │ ├── order.model.ts
│ │ └── order.service.ts
│ └── pages/
│ ├── list/list.component.ts
│ └── detail/detail.component.ts
└── customer/
├── routes.ts
├── services/
│ ├── customer.model.ts
│ └── customer.service.ts
└── pages/
├── list/list.component.ts
└── detail/detail.component.ts
All file-content templates referenced by the Generation Steps above live in _refs/templates/init-portal-templates.md. Read it when writing the corresponding files:
| File to generate | Section in templates ref |
|---|---|
package.json | #packagejson |
src/app/app.routes.ts | #approutests |
src/main.ts | #maints — most rationale-heavy; preserve the inline // Why ... comments verbatim |
src/app/configurations/permission.configuration.ts | #permissionconfigurationts-starter-default--disabled |
src/libs/sample/routes.ts | #sampleroutests |
Resolve <CORE_UI_PACKAGE_NAME> and <CORE_VERSION> from _refs/core-version.md before materializing any of these files (see §"Source of truth — Core UI package" at the top of this skill).
After generation:
1. Confirm package name, Angular project name, and output path match developer request
2. Confirm starter is generated from `core/templates/angular-portal-starter` without workspace-external dependencies
3. Confirm `tsconfig.json` has no unnecessary `compilerOptions.baseUrl` (or document why it is needed)
4. Run npm install
5. Run npm start
6. Open /sample/order and /sample/customer routes
7. Open Order detail and verify the <customer-select> dropdown lists customers
8. If build config exists, run npm run build-dev
9. Run starter unit tests (at minimum route/bootstrap smoke specs)
_refs/core-version.md read; placeholders substituted (no literal version/package string left in generated files)package.json pins <CORE_UI_PACKAGE_NAME>@<CORE_VERSION> (npm, not tgz)tsconfig.json has "baseUrl": "./" + "@sample": ["./src/libs/sample"] + "@sample/*": ["./src/libs/sample/*"]app.routes.ts lazy-loads sample lib + Core UI layoutSampleModule.useValue({ host: environment.sampleBackendUrl }) wired at root in main.ts (no route-level providers)src/libs/sample/features/:
order/ — Order list + detail; detail form contains <customer-select> referencing the customer entitycustomer/ — Customer list + detailsrc/libs/sample/components/base-select/src/libs/sample/components/customer-select/PermissionConfiguration.disabled = true in starternpm install succeedsnpm run build-dev exits 0npm start serves at http://localhost:4200/<customer-select> populated.vscode extensions recommendedKhoi tao du an portal-starter-moi co cac moi truong dev, qc, uat va prod.
Can include sample scaffold de demo module + entity-select pattern.
Tich hop san <CORE_UI_PACKAGE_NAME>.
Tao src/libs/sample va seed 2 entity order, customer (Order su dung customer-select).
Use internal baseline under core/templates/angular-portal-starter as source.
Create project portal-starter-moi.
Keep app shell, core configuration, environments, and plop generator files.
Generate src/libs/sample scaffold with:
- components/base-select (generic dropdown)
- components/customer-select (per-entity dropdown)
- features/order (uses <customer-select> in detail form)
- features/customer
Pin <CORE_UI_PACKAGE_NAME> to npm version <CORE_VERSION> via _refs/core-version.md (no local tgz).
Ship PermissionConfiguration with disabled=true so the portal boots without a permission backend.
Then run npm install and npm start to verify the starter boots.
[project-name]/package.json
[project-name]/angular.json
[project-name]/tsconfig.json
[project-name]/src/main.ts
[project-name]/src/app/app.routes.ts
[project-name]/src/app/components/main/main.component.ts
[project-name]/src/app/components/main/main.component.html
[project-name]/src/app/configurations/auth.configuration.ts
[project-name]/src/app/configurations/layout.configuration.ts
[project-name]/src/app/configurations/permission.configuration.ts
[project-name]/src/libs/sample/sample.configuration.ts
[project-name]/src/libs/sample/sample.module.ts
[project-name]/src/libs/sample/routes.ts
[project-name]/src/libs/sample/components/base-select/base-select.component.ts
[project-name]/src/libs/sample/components/base-select/base-select.component.html
[project-name]/src/libs/sample/components/customer-select/customer-select.component.ts
[project-name]/src/libs/sample/features/order/routes.ts
[project-name]/src/libs/sample/features/order/services/order.service.ts
[project-name]/src/libs/sample/features/order/services/order.model.ts
[project-name]/src/libs/sample/features/customer/routes.ts
[project-name]/src/libs/sample/features/customer/services/customer.service.ts
[project-name]/src/libs/sample/features/customer/services/customer.model.ts
[project-name]/src/environments/environment.dev.ts
[project-name]/src/environments/environment.qc.ts
[project-name]/src/environments/environment.uat.ts
[project-name]/src/environments/environment.prod.ts
npx claudepluginhub sdcorejs/sdcorejs-agent --plugin sdcorejs-agentCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.