@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.
Files changed (173) hide show
  1. package/.agent-context/prompts/init-project.md +5 -5
  2. package/.agent-context/prompts/refactor.md +2 -1
  3. package/.agent-context/prompts/review-code.md +3 -2
  4. package/.agent-context/review-checklists/pr-checklist.md +8 -1
  5. package/.agent-context/rules/architecture.md +11 -0
  6. package/.agent-context/rules/frontend-architecture.md +2 -2
  7. package/.agent-context/state/architecture-map.md +1 -1
  8. package/.agent-context/state/memory-continuity-benchmark.json +1 -1
  9. package/.agents/workflows/init-project.md +3 -3
  10. package/.agents/workflows/refactor.md +1 -1
  11. package/.agents/workflows/review-code.md +4 -5
  12. package/.cursorrules +27 -71
  13. package/.gemini/instructions.md +6 -7
  14. package/.github/copilot-instructions.md +5 -6
  15. package/.windsurfrules +27 -71
  16. package/AGENTS.md +7 -9
  17. package/CONTRIBUTING.md +18 -31
  18. package/README.md +21 -4
  19. package/bin/agentic-senior-core.js +0 -6
  20. package/lib/cli/commands/init.mjs +113 -650
  21. package/lib/cli/commands/launch.mjs +1 -23
  22. package/lib/cli/commands/rollback.mjs +1 -1
  23. package/lib/cli/commands/upgrade.mjs +1 -23
  24. package/lib/cli/compiler.mjs +77 -72
  25. package/lib/cli/constants.mjs +84 -26
  26. package/lib/cli/init-architecture-flow.mjs +231 -0
  27. package/lib/cli/init-detection-flow.mjs +123 -0
  28. package/lib/cli/init-options.mjs +344 -0
  29. package/lib/cli/init-selection.mjs +100 -0
  30. package/lib/cli/preflight.mjs +1 -1
  31. package/lib/cli/profile-packs.mjs +15 -1
  32. package/lib/cli/project-scaffolder.mjs +18 -154
  33. package/lib/cli/utils.mjs +16 -12
  34. package/mcp.json +19 -19
  35. package/package.json +5 -2
  36. package/scripts/context-triggered-audit.mjs +18 -18
  37. package/scripts/documentation-boundary-audit.mjs +92 -5
  38. package/scripts/forbidden-content-check.mjs +1 -1
  39. package/scripts/frontend-usability-audit.mjs +21 -28
  40. package/scripts/governance-weekly-report.mjs +29 -15
  41. package/scripts/llm-judge.mjs +2 -5
  42. package/scripts/mcp-server.mjs +389 -5
  43. package/scripts/release-gate.mjs +121 -145
  44. package/scripts/sync-thin-adapters.mjs +161 -0
  45. package/scripts/v3-purge-audit.mjs +231 -0
  46. package/scripts/validate-evidence-bundle.mjs +1 -1
  47. package/scripts/validate.mjs +224 -272
  48. package/.agent-context/blueprints/api-nextjs.md +0 -184
  49. package/.agent-context/blueprints/aspnet-api.md +0 -247
  50. package/.agent-context/blueprints/ci-github-actions.md +0 -226
  51. package/.agent-context/blueprints/ci-gitlab.md +0 -200
  52. package/.agent-context/blueprints/fastapi-service.md +0 -210
  53. package/.agent-context/blueprints/go-service.md +0 -217
  54. package/.agent-context/blueprints/graphql-grpc-api.md +0 -51
  55. package/.agent-context/blueprints/infrastructure-as-code.md +0 -62
  56. package/.agent-context/blueprints/kubernetes-manifests.md +0 -76
  57. package/.agent-context/blueprints/laravel-api.md +0 -233
  58. package/.agent-context/blueprints/mobile-app.md +0 -91
  59. package/.agent-context/blueprints/nestjs-logic.md +0 -247
  60. package/.agent-context/blueprints/observability.md +0 -227
  61. package/.agent-context/blueprints/spring-boot-api.md +0 -218
  62. package/.agent-context/profiles/platform.md +0 -13
  63. package/.agent-context/profiles/regulated.md +0 -13
  64. package/.agent-context/profiles/startup.md +0 -13
  65. package/.agent-context/review-checklists/frontend-excellence-rubric.md +0 -73
  66. package/.agent-context/review-checklists/frontend-skill-parity.md +0 -29
  67. package/.agent-context/review-checklists/frontend-usability.md +0 -35
  68. package/.agent-context/review-checklists/marketplace-acceptance.md +0 -60
  69. package/.agent-context/review-checklists/performance-audit.md +0 -71
  70. package/.agent-context/review-checklists/release-operations.md +0 -33
  71. package/.agent-context/review-checklists/security-audit.md +0 -119
  72. package/.agent-context/skills/README.md +0 -63
  73. package/.agent-context/skills/backend/README.md +0 -68
  74. package/.agent-context/skills/backend/architecture.md +0 -361
  75. package/.agent-context/skills/backend/compatibility-manifest.json +0 -8
  76. package/.agent-context/skills/backend/data-access.md +0 -231
  77. package/.agent-context/skills/backend/errors.md +0 -138
  78. package/.agent-context/skills/backend/validation.md +0 -117
  79. package/.agent-context/skills/backend.md +0 -29
  80. package/.agent-context/skills/cli/.evidence/compatibility-manifest.json +0 -5
  81. package/.agent-context/skills/cli/.evidence/sbom-excerpt.json +0 -10
  82. package/.agent-context/skills/cli/.evidence/test-report.json +0 -8
  83. package/.agent-context/skills/cli/CHANGELOG.md +0 -6
  84. package/.agent-context/skills/cli/README.md +0 -56
  85. package/.agent-context/skills/cli/compatibility-manifest.json +0 -8
  86. package/.agent-context/skills/cli/init.md +0 -38
  87. package/.agent-context/skills/cli/output.md +0 -36
  88. package/.agent-context/skills/cli/package.json +0 -5
  89. package/.agent-context/skills/cli/safety-telemetry.md +0 -39
  90. package/.agent-context/skills/cli/tests/.gitkeep +0 -1
  91. package/.agent-context/skills/cli/upgrade.md +0 -38
  92. package/.agent-context/skills/cli.md +0 -32
  93. package/.agent-context/skills/distribution/.evidence/compatibility-manifest.json +0 -9
  94. package/.agent-context/skills/distribution/.evidence/sbom-excerpt.json +0 -6
  95. package/.agent-context/skills/distribution/.evidence/test-report.json +0 -8
  96. package/.agent-context/skills/distribution/CHANGELOG.md +0 -7
  97. package/.agent-context/skills/distribution/README.md +0 -27
  98. package/.agent-context/skills/distribution/compatibility-manifest.json +0 -8
  99. package/.agent-context/skills/distribution/compatibility.md +0 -32
  100. package/.agent-context/skills/distribution/package.json +0 -5
  101. package/.agent-context/skills/distribution/provenance-attestation.md +0 -47
  102. package/.agent-context/skills/distribution/publish.md +0 -37
  103. package/.agent-context/skills/distribution/rollback.md +0 -32
  104. package/.agent-context/skills/distribution/tests/.gitkeep +0 -1
  105. package/.agent-context/skills/distribution.md +0 -32
  106. package/.agent-context/skills/frontend/.evidence/compatibility-manifest.json +0 -9
  107. package/.agent-context/skills/frontend/.evidence/sbom-excerpt.json +0 -6
  108. package/.agent-context/skills/frontend/.evidence/test-report.json +0 -8
  109. package/.agent-context/skills/frontend/CHANGELOG.md +0 -7
  110. package/.agent-context/skills/frontend/README.md +0 -50
  111. package/.agent-context/skills/frontend/accessibility.md +0 -107
  112. package/.agent-context/skills/frontend/compatibility-manifest.json +0 -8
  113. package/.agent-context/skills/frontend/conversion-clarity.md +0 -51
  114. package/.agent-context/skills/frontend/motion.md +0 -67
  115. package/.agent-context/skills/frontend/package.json +0 -5
  116. package/.agent-context/skills/frontend/performance.md +0 -63
  117. package/.agent-context/skills/frontend/responsive-delivery.md +0 -41
  118. package/.agent-context/skills/frontend/tests/.gitkeep +0 -1
  119. package/.agent-context/skills/frontend/ui-architecture.md +0 -128
  120. package/.agent-context/skills/frontend.md +0 -40
  121. package/.agent-context/skills/fullstack/.evidence/compatibility-manifest.json +0 -9
  122. package/.agent-context/skills/fullstack/.evidence/sbom-excerpt.json +0 -6
  123. package/.agent-context/skills/fullstack/.evidence/test-report.json +0 -8
  124. package/.agent-context/skills/fullstack/CHANGELOG.md +0 -7
  125. package/.agent-context/skills/fullstack/README.md +0 -27
  126. package/.agent-context/skills/fullstack/compatibility-manifest.json +0 -8
  127. package/.agent-context/skills/fullstack/contracts.md +0 -53
  128. package/.agent-context/skills/fullstack/end-to-end.md +0 -42
  129. package/.agent-context/skills/fullstack/feature-slicing.md +0 -65
  130. package/.agent-context/skills/fullstack/package.json +0 -5
  131. package/.agent-context/skills/fullstack/release-coordination.md +0 -51
  132. package/.agent-context/skills/fullstack/tests/.gitkeep +0 -1
  133. package/.agent-context/skills/fullstack.md +0 -30
  134. package/.agent-context/skills/index.json +0 -107
  135. package/.agent-context/skills/review-quality/.evidence/compatibility-manifest.json +0 -9
  136. package/.agent-context/skills/review-quality/.evidence/sbom-excerpt.json +0 -6
  137. package/.agent-context/skills/review-quality/.evidence/test-report.json +0 -8
  138. package/.agent-context/skills/review-quality/CHANGELOG.md +0 -7
  139. package/.agent-context/skills/review-quality/README.md +0 -27
  140. package/.agent-context/skills/review-quality/benchmark.md +0 -30
  141. package/.agent-context/skills/review-quality/compatibility-manifest.json +0 -8
  142. package/.agent-context/skills/review-quality/package.json +0 -5
  143. package/.agent-context/skills/review-quality/planning.md +0 -38
  144. package/.agent-context/skills/review-quality/release-decision.md +0 -49
  145. package/.agent-context/skills/review-quality/security.md +0 -34
  146. package/.agent-context/skills/review-quality/tests/.gitkeep +0 -1
  147. package/.agent-context/skills/review-quality.md +0 -34
  148. package/.agent-context/stacks/csharp.md +0 -149
  149. package/.agent-context/stacks/flutter.md +0 -16
  150. package/.agent-context/stacks/go.md +0 -181
  151. package/.agent-context/stacks/java.md +0 -135
  152. package/.agent-context/stacks/php.md +0 -192
  153. package/.agent-context/stacks/python.md +0 -153
  154. package/.agent-context/stacks/react-native.md +0 -16
  155. package/.agent-context/stacks/ruby.md +0 -80
  156. package/.agent-context/stacks/rust.md +0 -86
  157. package/.agent-context/stacks/typescript.md +0 -317
  158. package/.agent-context/state/skill-platform.json +0 -38
  159. package/lib/cli/skill-selector.mjs +0 -232
  160. package/lib/cli/templates/api-contract.md.id.tmpl +0 -143
  161. package/lib/cli/templates/api-contract.md.tmpl +0 -143
  162. package/lib/cli/templates/architecture-decision-record.md.id.tmpl +0 -106
  163. package/lib/cli/templates/architecture-decision-record.md.tmpl +0 -145
  164. package/lib/cli/templates/database-schema.md.id.tmpl +0 -74
  165. package/lib/cli/templates/database-schema.md.tmpl +0 -74
  166. package/lib/cli/templates/flow-overview.md.id.tmpl +0 -118
  167. package/lib/cli/templates/flow-overview.md.tmpl +0 -131
  168. package/lib/cli/templates/project-brief.md.id.tmpl +0 -55
  169. package/lib/cli/templates/project-brief.md.tmpl +0 -79
  170. package/scripts/init-project.ps1 +0 -105
  171. package/scripts/init-project.sh +0 -131
  172. package/scripts/skill-tier-policy.mjs +0 -76
  173. package/scripts/trust-scorer.mjs +0 -119
@@ -1,317 +0,0 @@
1
- # TypeScript Stack Profile — The "Galak" Standard
2
-
3
- > TypeScript is not JavaScript with optional types.
4
- > It is a contract system. Use it like one.
5
-
6
- ## Compiler Configuration (Non-Negotiable)
7
-
8
- ### tsconfig.json Strict Settings
9
- ```json
10
- {
11
- "compilerOptions": {
12
- "strict": true,
13
- "noUncheckedIndexedAccess": true,
14
- "noImplicitReturns": true,
15
- "noFallthroughCasesInSwitch": true,
16
- "noUnusedLocals": true,
17
- "noUnusedParameters": true,
18
- "exactOptionalPropertyTypes": true,
19
- "forceConsistentCasingInFileNames": true,
20
- "isolatedModules": true,
21
- "esModuleInterop": true,
22
- "resolveJsonModule": true,
23
- "moduleResolution": "bundler",
24
- "module": "ESNext",
25
- "target": "ES2022",
26
- "skipLibCheck": true,
27
- "paths": {
28
- "@/*": ["./src/*"]
29
- }
30
- }
31
- }
32
- ```
33
-
34
- **Rule:** `"strict": true` is mandatory. If a project has `"strict": false`, fix it before writing any new code.
35
-
36
- ---
37
-
38
- ## The `any` Ban (Zero Tolerance)
39
-
40
- ### Rule: `any` is BANNED. No exceptions.
41
-
42
- ```typescript
43
- // ❌ INSTANT REJECTION
44
- function processData(data: any) { ... }
45
- const result = response.json() as any;
46
- // @ts-ignore
47
- // @ts-expect-error — only allowed with a comment explaining WHY and a linked issue
48
-
49
- // ✅ REQUIRED: Use `unknown` with type narrowing
50
- function processData(data: unknown) {
51
- const parsed = DataSchema.parse(data); // Zod validates and narrows
52
- // `parsed` is now fully typed
53
- }
54
-
55
- // ✅ REQUIRED: Use generics when the type varies
56
- function getFirstItem<T>(items: T[]): T | undefined {
57
- return items[0];
58
- }
59
- ```
60
-
61
- ### What to Use Instead of `any`
62
- | Situation | Instead of `any`, Use |
63
- |-----------|----------------------|
64
- | Unknown external data | `unknown` + Zod parsing |
65
- | Generic container | `T` (generic type parameter) |
66
- | Object with unknown keys | `Record<string, unknown>` |
67
- | Function argument you'll refine | `unknown` + type guard |
68
- | Library with bad types | Write a `.d.ts` override or `unknown` wrapper |
69
- | Event handlers | The specific event type (`MouseEvent`, `ChangeEvent<HTMLInputElement>`) |
70
-
71
- ---
72
-
73
- ## Zod at Boundaries (Mandatory)
74
-
75
- ### Rule: ALL External Data MUST Pass Through Zod
76
-
77
- ```typescript
78
- // ❌ BANNED: Trusting external data
79
- app.post('/users', async (req, res) => {
80
- const { name, email, age } = req.body; // Could be anything!
81
- await userService.create({ name, email, age });
82
- });
83
-
84
- // ✅ REQUIRED: Validate with Zod at the boundary
85
- import { z } from 'zod';
86
-
87
- const CreateUserSchema = z.object({
88
- name: z.string().min(1).max(100).trim(),
89
- email: z.string().email().toLowerCase(),
90
- age: z.number().int().min(13).max(150),
91
- });
92
-
93
- type CreateUserDto = z.infer<typeof CreateUserSchema>;
94
-
95
- app.post('/users', async (req, res) => {
96
- const parsed = CreateUserSchema.safeParse(req.body);
97
- if (!parsed.success) {
98
- return res.status(400).json({ errors: parsed.error.flatten() });
99
- }
100
- // `parsed.data` is fully typed and validated
101
- await userService.create(parsed.data);
102
- });
103
- ```
104
-
105
- ### Where Zod is MANDATORY
106
- - API request bodies (POST, PUT, PATCH)
107
- - Query parameters and path parameters
108
- - WebSocket incoming messages
109
- - Queue/event payloads from external systems
110
- - Environment variables at startup
111
- - Third-party API responses (trust but verify)
112
- - File upload metadata
113
-
114
- ### Zod Best Practices
115
- ```typescript
116
- // ✅ Reuse schemas — define once, use everywhere
117
- // src/modules/user/user.schema.ts
118
- export const UserSchema = z.object({
119
- id: z.string().uuid(),
120
- email: z.string().email(),
121
- name: z.string().min(1).max(100),
122
- role: z.enum(['user', 'admin', 'moderator']),
123
- createdAt: z.coerce.date(),
124
- });
125
-
126
- export const CreateUserSchema = UserSchema.omit({ id: true, createdAt: true });
127
- export const UpdateUserSchema = CreateUserSchema.partial();
128
-
129
- // Types derived from schemas — single source of truth
130
- export type User = z.infer<typeof UserSchema>;
131
- export type CreateUserDto = z.infer<typeof CreateUserSchema>;
132
- export type UpdateUserDto = z.infer<typeof UpdateUserSchema>;
133
- ```
134
-
135
- ---
136
-
137
- ## API Documentation (Mandatory)
138
-
139
- ### Rule: No API Endpoint Exists Without Documentation
140
-
141
- Every API endpoint MUST have corresponding documentation. When creating or modifying an endpoint, you MUST simultaneously update the API documentation.
142
-
143
- ### Preferred Approach: OpenAPI (Swagger)
144
-
145
- ```typescript
146
- // Option 1: Code-first with decorators (NestJS)
147
- @ApiOperation({ summary: 'Create a new user' })
148
- @ApiBody({ type: CreateUserDto })
149
- @ApiResponse({ status: 201, description: 'User created', type: UserResponseDto })
150
- @ApiResponse({ status: 400, description: 'Validation error' })
151
- @ApiResponse({ status: 409, description: 'Email already exists' })
152
- @Post()
153
- async createUser(@Body() dto: CreateUserDto): Promise<UserResponseDto> { ... }
154
-
155
- // Option 2: Schema-first with Zod + zod-to-openapi
156
- import { extendZodWithOpenApi } from '@asteasolutions/zod-to-openapi';
157
- extendZodWithOpenApi(z);
158
-
159
- const CreateUserSchema = z.object({
160
- name: z.string().min(1).openapi({ example: 'John Doe' }),
161
- email: z.string().email().openapi({ example: 'john@example.com' }),
162
- }).openapi('CreateUserRequest');
163
- ```
164
-
165
- ### Documentation Checklist (Per Endpoint)
166
- - [ ] HTTP method and path
167
- - [ ] Request body schema (with examples)
168
- - [ ] Query/path parameter descriptions
169
- - [ ] All possible response codes with schemas
170
- - [ ] Authentication requirements
171
- - [ ] Rate limiting information (if applicable)
172
-
173
- ### Documentation Must Stay in Sync
174
- ```
175
- ❌ BANNED:
176
- // Endpoint accepts `role` field but docs don't mention it
177
- // Endpoint returns 422 but docs only show 400
178
-
179
- ✅ REQUIRED:
180
- // When you change an endpoint → update the schema/docs in the SAME commit
181
- // Use code-first tools so docs are generated from the actual types
182
- ```
183
-
184
- ---
185
-
186
- ## Import Style
187
-
188
- ### Path Aliases (Required)
189
- ```typescript
190
- // ❌ BANNED: Deep relative imports
191
- import { UserService } from '../../../modules/user/user.service';
192
- import { AppError } from '../../../../shared/errors/app-error';
193
-
194
- // ✅ REQUIRED: Path aliases
195
- import { UserService } from '@/modules/user/user.service';
196
- import { AppError } from '@/shared/errors/app-error';
197
- ```
198
-
199
- ### Import Order (Enforced by ESLint)
200
- ```typescript
201
- // 1. Node built-ins
202
- import { readFile } from 'node:fs/promises';
203
- import { join } from 'node:path';
204
-
205
- // 2. External packages
206
- import { z } from 'zod';
207
- import { PrismaClient } from '@prisma/client';
208
-
209
- // 3. Internal modules (path aliases)
210
- import { UserService } from '@/modules/user/user.service';
211
- import { AppError } from '@/shared/errors/app-error';
212
-
213
- // 4. Relative imports (same module only)
214
- import { CreateUserDto } from './user.dto';
215
- import { UserRepository } from './user.repository';
216
- ```
217
-
218
- ---
219
-
220
- ## Async Patterns
221
-
222
- ### Rule: Prefer async/await Over Raw Promises
223
- ```typescript
224
- // ❌ BANNED: Promise chain hell
225
- function getUser(id: string) {
226
- return userRepo.findById(id)
227
- .then(user => {
228
- if (!user) throw new NotFoundError('User', id);
229
- return orderRepo.findByUserId(user.id);
230
- })
231
- .then(orders => ({ ...user, orders }))
232
- .catch(err => { throw err; });
233
- }
234
-
235
- // ✅ REQUIRED: Clean async/await
236
- async function getUser(id: string): Promise<UserWithOrders> {
237
- const user = await userRepo.findById(id);
238
- if (!user) throw new NotFoundError('User', id);
239
-
240
- const orders = await orderRepo.findByUserId(user.id);
241
- return { ...user, orders };
242
- }
243
- ```
244
-
245
- ### Parallel Execution
246
- ```typescript
247
- // ❌ SLOW: Sequential when operations are independent
248
- const user = await getUser(id);
249
- const orders = await getOrders(id);
250
- const preferences = await getPreferences(id);
251
-
252
- // ✅ FAST: Parallel independent operations
253
- const [user, orders, preferences] = await Promise.all([
254
- getUser(id),
255
- getOrders(id),
256
- getPreferences(id),
257
- ]);
258
- ```
259
-
260
- ---
261
-
262
- ## Enum and Union Types
263
-
264
- ### Prefer `as const` Unions Over Enums
265
- ```typescript
266
- // ⚠️ ACCEPTABLE but verbose:
267
- enum OrderStatus {
268
- PENDING = 'pending',
269
- CONFIRMED = 'confirmed',
270
- SHIPPED = 'shipped',
271
- DELIVERED = 'delivered',
272
- }
273
-
274
- // ✅ PREFERRED: const assertion + union type
275
- const ORDER_STATUSES = ['pending', 'confirmed', 'shipped', 'delivered'] as const;
276
- type OrderStatus = (typeof ORDER_STATUSES)[number];
277
- // OrderStatus = 'pending' | 'confirmed' | 'shipped' | 'delivered'
278
-
279
- // Works perfectly with Zod:
280
- const OrderStatusSchema = z.enum(ORDER_STATUSES);
281
- ```
282
-
283
- ---
284
-
285
- ## Preferred Libraries (V1.0 — 2025)
286
-
287
- | Need | Library | Why |
288
- |------|---------|-----|
289
- | Runtime | Bun / Node 20+ | ESM native, fast, batteries-included |
290
- | Validation | `zod` | 0 deps, type inference, composable |
291
- | ORM | `prisma` or `drizzle-orm` | Type-safe queries, migration support |
292
- | HTTP framework | `hono` / `fastify` / Next.js | Lightweight, modern, tree-shakeable |
293
- | Testing | `vitest` | Vite-native, Jest-compatible API, fast |
294
- | Linting | `eslint` + `@typescript-eslint` | Community standard |
295
- | Formatting | `prettier` | Community standard |
296
- | Date | `date-fns` or `Temporal` (when stable) | Tree-shakeable, immutable |
297
- | HTTP client | `ky` / `ofetch` / built-in `fetch` | Lightweight, modern |
298
- | Password | `bcrypt` / `argon2` | Proven, secure |
299
- | Logger | `pino` | Fastest JSON logger for Node.js |
300
- | Env | `@t3-oss/env-core` + Zod | Type-safe env validation |
301
-
302
- ---
303
-
304
- ## Banned Patterns
305
-
306
- | Pattern | Why | Alternative |
307
- |---------|-----|-------------|
308
- | `any` type | Defeats TypeScript's purpose | `unknown` + narrowing |
309
- | `// @ts-ignore` | Hides real type errors | Fix the type or `@ts-expect-error` with comment |
310
- | `var` keyword | Function scoping bugs | `const` (default) or `let` |
311
- | `==` loose equality | Type coercion surprises | `===` always |
312
- | `console.log` in production | Not structured, not configurable | Use `pino` or structured logger |
313
- | `new Date()` without timezone | Timezone bugs | Explicit UTC or use date-fns |
314
- | Default exports | Naming inconsistency across imports | Named exports only |
315
- | Barrel re-exports (`index.ts`) | Circular dependency magnets | Direct imports or module public API only |
316
- | `moment.js` | Deprecated, massive bundle | `date-fns` or `dayjs` |
317
- | `class` with inheritance (deep chains) | Fragile hierarchies | Composition + interfaces |
@@ -1,38 +0,0 @@
1
- {
2
- "defaultTier": "advance",
3
- "tiers": [
4
- {
5
- "name": "standard",
6
- "role": "compatibility",
7
- "description": "Minimal fallback mode for legacy support"
8
- },
9
- {
10
- "name": "advance",
11
- "role": "default",
12
- "description": "Efficient, opinionated, production-aware baseline"
13
- },
14
- {
15
- "name": "expert",
16
- "role": "complexity",
17
- "description": "For advanced integration, architecture, and critical refactors"
18
- },
19
- {
20
- "name": "above",
21
- "role": "governance",
22
- "description": "For release-critical and enterprise control-plane work"
23
- }
24
- ],
25
- "domains": [
26
- "frontend",
27
- "backend",
28
- "fullstack",
29
- "cli",
30
- "distribution",
31
- "review-quality"
32
- ],
33
- "benchmarkSources": [
34
- "sickn33/antigravity-awesome-skills",
35
- "github/awesome-copilot",
36
- "MiniMax-AI/skills"
37
- ]
38
- }
@@ -1,232 +0,0 @@
1
- /**
2
- * Skill Selector — Skill platform interaction and domain inference.
3
- * Depends on: constants.mjs, utils.mjs
4
- */
5
- import fs from 'node:fs/promises';
6
- import path from 'node:path';
7
-
8
- import {
9
- SKILL_PLATFORM_DIRECTORY,
10
- SKILL_PLATFORM_INDEX_PATH,
11
- } from './constants.mjs';
12
-
13
- import { normalizeChoiceInput } from './utils.mjs';
14
-
15
- export async function loadSkillPlatformIndex() {
16
- const skillPlatformIndexContent = await fs.readFile(SKILL_PLATFORM_INDEX_PATH, 'utf8');
17
- return JSON.parse(skillPlatformIndexContent);
18
- }
19
-
20
- export function normalizeSkillTierInput(rawTierInput) {
21
- const normalizedTierInput = normalizeChoiceInput(rawTierInput);
22
- const allowedTierNames = new Set(['standard', 'advance', 'expert', 'above']);
23
-
24
- if (!allowedTierNames.has(normalizedTierInput)) {
25
- return null;
26
- }
27
-
28
- return normalizedTierInput;
29
- }
30
-
31
- export function findSkillDomainByInput(skillDomainInput, skillDomainEntries) {
32
- const normalizedSkillDomainInput = normalizeChoiceInput(skillDomainInput);
33
-
34
- return skillDomainEntries.find((skillDomainEntry) => {
35
- const normalizedDomainName = normalizeChoiceInput(skillDomainEntry.name);
36
- const normalizedDisplayName = normalizeChoiceInput(skillDomainEntry.displayName);
37
-
38
- return normalizedSkillDomainInput === normalizedDomainName || normalizedSkillDomainInput === normalizedDisplayName;
39
- }) || null;
40
- }
41
-
42
- export function formatSkillTierList(skillPlatformIndex) {
43
- return skillPlatformIndex.tiers.map((tierDefinition) => `${tierDefinition.name} (${tierDefinition.description})`).join('\n');
44
- }
45
-
46
- export function inferSkillDomainNamesFromSelection(
47
- selectedStackFileName,
48
- selectedBlueprintFileName,
49
- additionalStackFileNames = [],
50
- additionalBlueprintFileNames = []
51
- ) {
52
- const inferredDomainNames = new Set();
53
-
54
- function applyStackSignals(stackFileName) {
55
- if (stackFileName === 'typescript.md') {
56
- inferredDomainNames.add('frontend');
57
- inferredDomainNames.add('cli');
58
- }
59
-
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
- }
69
-
70
- if (stackFileName === 'react-native.md' || stackFileName === 'flutter.md') {
71
- inferredDomainNames.add('frontend');
72
- inferredDomainNames.add('fullstack');
73
- inferredDomainNames.add('cli');
74
- }
75
- }
76
-
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
- }
83
-
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
- }
106
- }
107
-
108
- applyBlueprintSignals(selectedBlueprintFileName);
109
-
110
- applyStackSignals(selectedStackFileName);
111
- for (const additionalStackFileName of additionalStackFileNames) {
112
- applyStackSignals(additionalStackFileName);
113
- }
114
-
115
- for (const additionalBlueprintFileName of additionalBlueprintFileNames) {
116
- applyBlueprintSignals(additionalBlueprintFileName);
117
- }
118
-
119
- if (inferredDomainNames.size === 0) {
120
- inferredDomainNames.add('fullstack');
121
- inferredDomainNames.add('cli');
122
- }
123
-
124
- return Array.from(inferredDomainNames);
125
- }
126
-
127
- export async function buildSkillPackSection(skillDomainEntry, selectedTierName) {
128
- const resolvedPackFileName = skillDomainEntry.tierToPackFileNames?.[selectedTierName]
129
- || skillDomainEntry.tierToPackFileNames?.[skillDomainEntry.defaultTier]
130
- || skillDomainEntry.defaultPackFileName;
131
- const skillPackFilePath = path.join(SKILL_PLATFORM_DIRECTORY, resolvedPackFileName);
132
- const skillPackContent = await fs.readFile(skillPackFilePath, 'utf8');
133
-
134
- return [
135
- `## SKILL PACK: ${skillDomainEntry.displayName}`,
136
- `Source: .agent-context/skills/${resolvedPackFileName}`,
137
- `Default tier: ${skillDomainEntry.defaultTier}`,
138
- `Selected tier: ${selectedTierName}`,
139
- `Evidence: ${skillDomainEntry.evidence}`,
140
- '',
141
- skillPackContent.trim(),
142
- '',
143
- ].join('\n');
144
- }
145
-
146
- export async function runSkillCommand(commandArguments) {
147
- const parsedSkillOptions = {
148
- domain: null,
149
- tier: null,
150
- tierProvided: false,
151
- json: false,
152
- };
153
-
154
- for (let argumentIndex = 0; argumentIndex < commandArguments.length; argumentIndex++) {
155
- const currentArgument = commandArguments[argumentIndex];
156
-
157
- if (!currentArgument.startsWith('--')) {
158
- parsedSkillOptions.domain = currentArgument;
159
- continue;
160
- }
161
-
162
- if (currentArgument === '--tier') {
163
- parsedSkillOptions.tier = normalizeSkillTierInput(commandArguments[argumentIndex + 1] || '');
164
- parsedSkillOptions.tierProvided = true;
165
- argumentIndex += 1;
166
- continue;
167
- }
168
-
169
- if (currentArgument.startsWith('--tier=')) {
170
- parsedSkillOptions.tier = normalizeSkillTierInput(currentArgument.split('=')[1]);
171
- parsedSkillOptions.tierProvided = true;
172
- continue;
173
- }
174
-
175
- if (currentArgument === '--json') {
176
- parsedSkillOptions.json = true;
177
- continue;
178
- }
179
-
180
- throw new Error(`Unknown option: ${currentArgument}`);
181
- }
182
-
183
- const skillPlatformIndex = await loadSkillPlatformIndex();
184
- const skillDomainEntries = Object.values(skillPlatformIndex.domains || {});
185
- const selectedSkillDomain = parsedSkillOptions.domain
186
- ? findSkillDomainByInput(parsedSkillOptions.domain, skillDomainEntries)
187
- : null;
188
-
189
- if (parsedSkillOptions.domain && !selectedSkillDomain) {
190
- throw new Error(`Unknown skill domain: ${parsedSkillOptions.domain}`);
191
- }
192
-
193
- if (parsedSkillOptions.tierProvided && !parsedSkillOptions.tier) {
194
- throw new Error(`Unknown skill tier: ${commandArguments.join(' ')}`);
195
- }
196
-
197
- const selectedTierName = parsedSkillOptions.tier || skillPlatformIndex.defaultTier || 'advance';
198
- const recommendedPackFileName = selectedSkillDomain
199
- ? selectedSkillDomain.tierToPackFileNames?.[selectedTierName]
200
- || selectedSkillDomain.tierToPackFileNames?.[selectedSkillDomain.defaultTier]
201
- || selectedSkillDomain.defaultPackFileName
202
- || null
203
- : null;
204
-
205
- if (parsedSkillOptions.json) {
206
- console.log(JSON.stringify({
207
- defaultTier: skillPlatformIndex.defaultTier,
208
- selectedTier: selectedTierName,
209
- selectedDomain: selectedSkillDomain,
210
- recommendedPackFileName,
211
- }, null, 2));
212
- return;
213
- }
214
-
215
- console.log('Skill platform selector');
216
- console.log(`Default tier: ${skillPlatformIndex.defaultTier}`);
217
- console.log(`Available tiers:\n${formatSkillTierList(skillPlatformIndex)}`);
218
-
219
- if (!selectedSkillDomain) {
220
- console.log('\nAvailable domains:');
221
- for (const skillDomainEntry of skillDomainEntries) {
222
- console.log(`- ${skillDomainEntry.name}: ${skillDomainEntry.description}`);
223
- }
224
- return;
225
- }
226
-
227
- console.log(`\nSelected domain: ${selectedSkillDomain.displayName}`);
228
- console.log(`Selected tier: ${selectedTierName}`);
229
- console.log(`Recommended pack: ${recommendedPackFileName}`);
230
- console.log(`Purpose: ${selectedSkillDomain.description}`);
231
- console.log(`Evidence: ${selectedSkillDomain.evidence}`);
232
- }