contextos-agents 1.7.0 → 2.0.0-beta.3
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/.agents/AGENTS.md +16 -50
- package/.agents/adapters/aider/export.js +117 -99
- package/.agents/adapters/claude/export.js +68 -26
- package/.agents/adapters/copilot/export.js +90 -53
- package/.agents/adapters/cursor/export.js +100 -104
- package/.agents/adapters/drift-detector.js +196 -0
- package/.agents/adapters/gemini/export.js +76 -45
- package/.agents/adapters/pure-compiler.js +443 -0
- package/.agents/adapters/zed/export.js +104 -96
- package/.agents/compiled/registry.v2.json +504 -0
- package/.agents/compiled/registry.v2.sha256 +1 -0
- package/.agents/compiler/manifest-compiler.js +963 -0
- package/.agents/compiler/vendor/yaml.LICENSE.txt +13 -0
- package/.agents/compiler/vendor/yaml.SBOM.json +6 -0
- package/.agents/compiler/vendor/yaml.js +139 -0
- package/.agents/core/profiles/init.yaml +25 -0
- package/.agents/core/skills/context-manager/skill.yaml +3 -5
- package/.agents/core/skills/context-os/SKILL.md +3 -6
- package/.agents/core/skills/context-os/skill.yaml +3 -8
- package/.agents/core/skills/engineering-workflow/skill.yaml +1 -7
- package/.agents/core/skills/gemini-precision/skill.yaml +1 -6
- package/.agents/core/skills/gstack-roles/skill.yaml +3 -6
- package/.agents/core/skills/ponytail-mindset/skill.yaml +1 -7
- package/.agents/core/skills/security/skill.yaml +15 -3
- package/.agents/ctx.js +537 -112
- package/.agents/customization-dx.js +282 -0
- package/.agents/doctor.js +855 -66
- package/.agents/filesystem/index.js +71 -0
- package/.agents/filesystem/journaled-transaction.js +451 -0
- package/.agents/filesystem/lockfile-v2.js +275 -0
- package/.agents/filesystem/platform-hardening.js +222 -0
- package/.agents/filesystem/project-lock.js +218 -0
- package/.agents/filesystem/safe-path.js +256 -0
- package/.agents/generated/claude/skills/context-os/SKILL.md +1 -1
- package/.agents/generated/gemini/skills/context-os/SKILL.md +2 -2
- package/.agents/plugins/contextos/plugin.json +1 -1
- package/.agents/plugins.js +278 -64
- package/.agents/profiles.js +486 -51
- package/.agents/resolver/canonical-resolver.js +1348 -0
- package/.agents/resolver.js +50 -534
- package/.agents/rules/rule-catalog.js +525 -0
- package/.agents/schemas/attestation.review.v1.json +111 -0
- package/.agents/schemas/attestation.verification.v1.json +85 -0
- package/.agents/schemas/lockfile.v2.schema.json +134 -0
- package/.agents/schemas/profile.v2.schema.json +114 -0
- package/.agents/schemas/runtime.thread.v1.json +192 -0
- package/.agents/schemas/skill.manifest.v2.json +177 -0
- package/.agents/schemas/verification.spec.v1.json +39 -0
- package/.agents/schemas/workspace.graph.schema.json +106 -0
- package/.agents/skills-index.json +6 -166
- package/.agents/stats.js +9 -9
- package/.agents/transaction-core/event-store.js +288 -0
- package/.agents/transaction-core/idempotency.js +129 -0
- package/.agents/transaction-core/ipc-lock.js +311 -0
- package/.agents/transaction-core/plugin-supply-chain-bundle.js +436 -0
- package/.agents/validate.js +44 -1
- package/.agents/watch.js +354 -102
- package/.agents/workspace/workspace-graph.js +778 -0
- package/README.md +59 -387
- package/benchmarks/v2/analysis/statistics.js +140 -0
- package/benchmarks/v2/analysis/stats.js +69 -0
- package/benchmarks/v2/arms/arm-definitions.js +79 -0
- package/benchmarks/v2/dataset.schema.json +34 -0
- package/benchmarks/v2/evaluators/index.js +25 -0
- package/benchmarks/v2/evaluators/verified-success.js +116 -0
- package/benchmarks/v2/harness/runner.js +88 -0
- package/benchmarks/v2/pilot-tasks.json +392 -0
- package/bin/commands/recover.js +88 -0
- package/bin/commands/update.js +80 -17
- package/bin/commands.js +62 -25
- package/bin/index.js +138 -81
- package/bin/lib/lockfile.js +5 -3
- package/bin/lib/safe-writer.js +34 -3
- package/package.json +87 -72
- package/registry.json +2 -2
- package/registry.v2.schema.json +86 -0
- package/.agents/core/profiles/backend.yaml +0 -47
- package/.agents/core/profiles/enterprise.yaml +0 -46
- package/.agents/core/profiles/frontend.yaml +0 -46
- package/.agents/core/profiles/hackathon.yaml +0 -45
- package/.agents/core/profiles/mvp.yaml +0 -44
- package/.agents/core/profiles/startup.yaml +0 -48
- package/.agents/core/skills/adapters/EXAMPLES.md +0 -19
- package/.agents/core/skills/adapters/SKILL.md +0 -105
- package/.agents/core/skills/adapters/TROUBLESHOOTING.md +0 -7
- package/.agents/core/skills/adapters/VALIDATION.json +0 -12
- package/.agents/core/skills/adapters/skill.yaml +0 -16
- package/.agents/core/skills/architecture-diagrams/SKILL.md +0 -108
- package/.agents/core/skills/architecture-diagrams/VALIDATION.json +0 -12
- package/.agents/core/skills/architecture-diagrams/skill.yaml +0 -12
- package/.agents/core/skills/brutalist-design/SKILL.md +0 -150
- package/.agents/core/skills/brutalist-design/VALIDATION.json +0 -12
- package/.agents/core/skills/brutalist-design/skill.yaml +0 -12
- package/.agents/core/skills/database/EXAMPLES.md +0 -74
- package/.agents/core/skills/database/SKILL.md +0 -101
- package/.agents/core/skills/database/TROUBLESHOOTING.md +0 -18
- package/.agents/core/skills/database/VALIDATION.json +0 -11
- package/.agents/core/skills/database/skill.yaml +0 -31
- package/.agents/core/skills/ddd/EXAMPLES.md +0 -42
- package/.agents/core/skills/ddd/SKILL.md +0 -247
- package/.agents/core/skills/ddd/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/ddd/VALIDATION.json +0 -12
- package/.agents/core/skills/ddd/ddd.md +0 -178
- package/.agents/core/skills/ddd/skill.yaml +0 -17
- package/.agents/core/skills/decisions/EXAMPLES.md +0 -35
- package/.agents/core/skills/decisions/SKILL.md +0 -90
- package/.agents/core/skills/decisions/TROUBLESHOOTING.md +0 -13
- package/.agents/core/skills/decisions/VALIDATION.json +0 -12
- package/.agents/core/skills/decisions/skill.yaml +0 -16
- package/.agents/core/skills/docker/EXAMPLES.md +0 -56
- package/.agents/core/skills/docker/SKILL.md +0 -63
- package/.agents/core/skills/docker/TROUBLESHOOTING.md +0 -18
- package/.agents/core/skills/docker/VALIDATION.json +0 -11
- package/.agents/core/skills/docker/skill.yaml +0 -29
- package/.agents/core/skills/fastapi/EXAMPLES.md +0 -36
- package/.agents/core/skills/fastapi/SKILL.md +0 -148
- package/.agents/core/skills/fastapi/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/fastapi/VALIDATION.json +0 -12
- package/.agents/core/skills/fastapi/fastapi.md +0 -112
- package/.agents/core/skills/fastapi/skill.yaml +0 -17
- package/.agents/core/skills/generators/EXAMPLES.md +0 -19
- package/.agents/core/skills/generators/SKILL.md +0 -112
- package/.agents/core/skills/generators/TROUBLESHOOTING.md +0 -7
- package/.agents/core/skills/generators/VALIDATION.json +0 -12
- package/.agents/core/skills/generators/skill.yaml +0 -25
- package/.agents/core/skills/generators/templates/API.md +0 -77
- package/.agents/core/skills/generators/templates/ARCHITECTURE.md +0 -70
- package/.agents/core/skills/generators/templates/DATABASE.md +0 -42
- package/.agents/core/skills/generators/templates/DECISION.md +0 -46
- package/.agents/core/skills/generators/templates/PRD.md +0 -67
- package/.agents/core/skills/generators/templates/PROJECT_GRAPH.md +0 -56
- package/.agents/core/skills/generators/templates/ROADMAP.md +0 -51
- package/.agents/core/skills/generators/templates/TASKS.md +0 -43
- package/.agents/core/skills/generators/templates/UI.md +0 -73
- package/.agents/core/skills/graphify/EXAMPLES.md +0 -73
- package/.agents/core/skills/graphify/SKILL.md +0 -130
- package/.agents/core/skills/graphify/VALIDATION.json +0 -12
- package/.agents/core/skills/graphify/skill.yaml +0 -18
- package/.agents/core/skills/impeccable-design/EXAMPLES.md +0 -26
- package/.agents/core/skills/impeccable-design/SKILL.md +0 -201
- package/.agents/core/skills/impeccable-design/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/impeccable-design/VALIDATION.json +0 -12
- package/.agents/core/skills/impeccable-design/skill.yaml +0 -20
- package/.agents/core/skills/interview-me/SKILL.md +0 -97
- package/.agents/core/skills/interview-me/VALIDATION.json +0 -12
- package/.agents/core/skills/interview-me/skill.yaml +0 -12
- package/.agents/core/skills/microservices/EXAMPLES.md +0 -38
- package/.agents/core/skills/microservices/SKILL.md +0 -164
- package/.agents/core/skills/microservices/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/microservices/VALIDATION.json +0 -12
- package/.agents/core/skills/microservices/microservices.md +0 -119
- package/.agents/core/skills/microservices/skill.yaml +0 -17
- package/.agents/core/skills/minimalist-design/SKILL.md +0 -113
- package/.agents/core/skills/minimalist-design/VALIDATION.json +0 -12
- package/.agents/core/skills/minimalist-design/skill.yaml +0 -12
- package/.agents/core/skills/nestjs/EXAMPLES.md +0 -40
- package/.agents/core/skills/nestjs/SKILL.md +0 -139
- package/.agents/core/skills/nestjs/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/nestjs/VALIDATION.json +0 -12
- package/.agents/core/skills/nestjs/nestjs.md +0 -103
- package/.agents/core/skills/nestjs/skill.yaml +0 -17
- package/.agents/core/skills/nextjs/EXAMPLES.md +0 -40
- package/.agents/core/skills/nextjs/SKILL.md +0 -163
- package/.agents/core/skills/nextjs/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/nextjs/VALIDATION.json +0 -12
- package/.agents/core/skills/nextjs/nextjs.md +0 -67
- package/.agents/core/skills/nextjs/skill.yaml +0 -17
- package/.agents/core/skills/node/EXAMPLES.md +0 -80
- package/.agents/core/skills/node/SKILL.md +0 -128
- package/.agents/core/skills/node/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/node/VALIDATION.json +0 -12
- package/.agents/core/skills/node/node.md +0 -87
- package/.agents/core/skills/node/skill.yaml +0 -17
- package/.agents/core/skills/performance/EXAMPLES.md +0 -30
- package/.agents/core/skills/performance/SKILL.md +0 -75
- package/.agents/core/skills/performance/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/performance/VALIDATION.json +0 -12
- package/.agents/core/skills/performance/performance.md +0 -52
- package/.agents/core/skills/performance/skill.yaml +0 -17
- package/.agents/core/skills/react/EXAMPLES.md +0 -79
- package/.agents/core/skills/react/SKILL.md +0 -132
- package/.agents/core/skills/react/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/react/VALIDATION.json +0 -12
- package/.agents/core/skills/react/react.md +0 -93
- package/.agents/core/skills/react/skill.yaml +0 -17
- package/.agents/core/skills/react-best-practices/SKILL.md +0 -155
- package/.agents/core/skills/react-best-practices/VALIDATION.json +0 -12
- package/.agents/core/skills/react-best-practices/skill.yaml +0 -14
- package/.agents/core/skills/redesign-audit/SKILL.md +0 -117
- package/.agents/core/skills/redesign-audit/VALIDATION.json +0 -12
- package/.agents/core/skills/redesign-audit/skill.yaml +0 -12
- package/.agents/core/skills/soft-design/SKILL.md +0 -108
- package/.agents/core/skills/soft-design/VALIDATION.json +0 -12
- package/.agents/core/skills/soft-design/skill.yaml +0 -12
- package/.agents/core/skills/state-management/EXAMPLES.md +0 -56
- package/.agents/core/skills/state-management/SKILL.md +0 -48
- package/.agents/core/skills/state-management/TROUBLESHOOTING.md +0 -18
- package/.agents/core/skills/state-management/VALIDATION.json +0 -11
- package/.agents/core/skills/state-management/skill.yaml +0 -28
- package/.agents/core/skills/subagent-orchestrator/SKILL.md +0 -117
- package/.agents/core/skills/subagent-orchestrator/VALIDATION.json +0 -12
- package/.agents/core/skills/subagent-orchestrator/skill.yaml +0 -12
- package/.agents/core/skills/system-design/EXAMPLES.md +0 -75
- package/.agents/core/skills/system-design/SKILL.md +0 -419
- package/.agents/core/skills/system-design/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/system-design/VALIDATION.json +0 -12
- package/.agents/core/skills/system-design/skill.yaml +0 -20
- package/.agents/core/skills/system-design/system-design.md +0 -112
- package/.agents/core/skills/testing/EXAMPLES.md +0 -71
- package/.agents/core/skills/testing/SKILL.md +0 -70
- package/.agents/core/skills/testing/TROUBLESHOOTING.md +0 -18
- package/.agents/core/skills/testing/VALIDATION.json +0 -11
- package/.agents/core/skills/testing/skill.yaml +0 -32
- package/.agents/core/skills/typescript/EXAMPLES.md +0 -64
- package/.agents/core/skills/typescript/SKILL.md +0 -112
- package/.agents/core/skills/typescript/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/typescript/VALIDATION.json +0 -12
- package/.agents/core/skills/typescript/skill.yaml +0 -17
- package/.agents/core/skills/typescript/typescript.md +0 -71
- package/.agents/core/skills/ui-design/EXAMPLES.md +0 -21
- package/.agents/core/skills/ui-design/SKILL.md +0 -124
- package/.agents/core/skills/ui-design/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/ui-design/VALIDATION.json +0 -12
- package/.agents/core/skills/ui-design/skill.yaml +0 -17
- package/.agents/core/skills/ui-design/ui.md +0 -88
- package/.agents/core/skills/ui-ux-pro/EXAMPLES.md +0 -62
- package/.agents/core/skills/ui-ux-pro/SKILL.md +0 -375
- package/.agents/core/skills/ui-ux-pro/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/ui-ux-pro/VALIDATION.json +0 -12
- package/.agents/core/skills/ui-ux-pro/skill.yaml +0 -19
- package/.agents/core/skills/ux-design/EXAMPLES.md +0 -36
- package/.agents/core/skills/ux-design/SKILL.md +0 -116
- package/.agents/core/skills/ux-design/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/ux-design/VALIDATION.json +0 -12
- package/.agents/core/skills/ux-design/skill.yaml +0 -17
- package/.agents/core/skills/ux-design/ux.md +0 -80
- package/.agents/core/skills/vercel-optimize/SKILL.md +0 -83
- package/.agents/core/skills/vercel-optimize/VALIDATION.json +0 -12
- package/.agents/core/skills/vercel-optimize/scripts/collect-signals.mjs +0 -131
- package/.agents/core/skills/vercel-optimize/scripts/gate-investigations.mjs +0 -142
- package/.agents/core/skills/vercel-optimize/scripts/merge-signals.mjs +0 -143
- package/.agents/core/skills/vercel-optimize/scripts/scan-codebase.mjs +0 -174
- package/.agents/core/skills/vercel-optimize/skill.yaml +0 -18
- package/.agents/core/skills/web-accessibility/EXAMPLES.md +0 -39
- package/.agents/core/skills/web-accessibility/SKILL.md +0 -170
- package/.agents/core/skills/web-accessibility/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/web-accessibility/VALIDATION.json +0 -12
- package/.agents/core/skills/web-accessibility/accessibility.md +0 -63
- package/.agents/core/skills/web-accessibility/skill.yaml +0 -17
- package/.agents/generated/claude/skills/adapters/SKILL.md +0 -126
- package/.agents/generated/claude/skills/architecture-diagrams/SKILL.md +0 -101
- package/.agents/generated/claude/skills/brutalist-design/SKILL.md +0 -145
- package/.agents/generated/claude/skills/database/SKILL.md +0 -191
- package/.agents/generated/claude/skills/ddd/SKILL.md +0 -305
- package/.agents/generated/claude/skills/decisions/SKILL.md +0 -134
- package/.agents/generated/claude/skills/docker/SKILL.md +0 -135
- package/.agents/generated/claude/skills/fastapi/SKILL.md +0 -200
- package/.agents/generated/claude/skills/generators/SKILL.md +0 -133
- package/.agents/generated/claude/skills/graphify/SKILL.md +0 -198
- package/.agents/generated/claude/skills/impeccable-design/SKILL.md +0 -241
- package/.agents/generated/claude/skills/interview-me/SKILL.md +0 -90
- package/.agents/generated/claude/skills/microservices/SKILL.md +0 -218
- package/.agents/generated/claude/skills/minimalist-design/SKILL.md +0 -108
- package/.agents/generated/claude/skills/nestjs/SKILL.md +0 -195
- package/.agents/generated/claude/skills/nextjs/SKILL.md +0 -219
- package/.agents/generated/claude/skills/node/SKILL.md +0 -224
- package/.agents/generated/claude/skills/performance/SKILL.md +0 -121
- package/.agents/generated/claude/skills/react/SKILL.md +0 -227
- package/.agents/generated/claude/skills/react-best-practices/SKILL.md +0 -146
- package/.agents/generated/claude/skills/redesign-audit/SKILL.md +0 -112
- package/.agents/generated/claude/skills/soft-design/SKILL.md +0 -103
- package/.agents/generated/claude/skills/state-management/SKILL.md +0 -120
- package/.agents/generated/claude/skills/subagent-orchestrator/SKILL.md +0 -110
- package/.agents/generated/claude/skills/system-design/SKILL.md +0 -507
- package/.agents/generated/claude/skills/testing/SKILL.md +0 -157
- package/.agents/generated/claude/skills/typescript/SKILL.md +0 -192
- package/.agents/generated/claude/skills/ui-design/SKILL.md +0 -161
- package/.agents/generated/claude/skills/ui-ux-pro/SKILL.md +0 -451
- package/.agents/generated/claude/skills/ux-design/SKILL.md +0 -168
- package/.agents/generated/claude/skills/vercel-optimize/SKILL.md +0 -76
- package/.agents/generated/claude/skills/web-accessibility/SKILL.md +0 -225
- package/.agents/generated/gemini/skills/adapters/SKILL.md +0 -135
- package/.agents/generated/gemini/skills/architecture-diagrams/SKILL.md +0 -107
- package/.agents/generated/gemini/skills/brutalist-design/SKILL.md +0 -151
- package/.agents/generated/gemini/skills/database/SKILL.md +0 -200
- package/.agents/generated/gemini/skills/ddd/SKILL.md +0 -314
- package/.agents/generated/gemini/skills/decisions/SKILL.md +0 -143
- package/.agents/generated/gemini/skills/docker/SKILL.md +0 -144
- package/.agents/generated/gemini/skills/fastapi/SKILL.md +0 -209
- package/.agents/generated/gemini/skills/generators/SKILL.md +0 -142
- package/.agents/generated/gemini/skills/graphify/SKILL.md +0 -205
- package/.agents/generated/gemini/skills/impeccable-design/SKILL.md +0 -250
- package/.agents/generated/gemini/skills/interview-me/SKILL.md +0 -96
- package/.agents/generated/gemini/skills/microservices/SKILL.md +0 -227
- package/.agents/generated/gemini/skills/minimalist-design/SKILL.md +0 -114
- package/.agents/generated/gemini/skills/nestjs/SKILL.md +0 -204
- package/.agents/generated/gemini/skills/nextjs/SKILL.md +0 -298
- package/.agents/generated/gemini/skills/node/SKILL.md +0 -323
- package/.agents/generated/gemini/skills/performance/SKILL.md +0 -185
- package/.agents/generated/gemini/skills/react/SKILL.md +0 -332
- package/.agents/generated/gemini/skills/react-best-practices/SKILL.md +0 -152
- package/.agents/generated/gemini/skills/redesign-audit/SKILL.md +0 -118
- package/.agents/generated/gemini/skills/soft-design/SKILL.md +0 -109
- package/.agents/generated/gemini/skills/state-management/SKILL.md +0 -129
- package/.agents/generated/gemini/skills/subagent-orchestrator/SKILL.md +0 -116
- package/.agents/generated/gemini/skills/system-design/SKILL.md +0 -631
- package/.agents/generated/gemini/skills/testing/SKILL.md +0 -166
- package/.agents/generated/gemini/skills/typescript/SKILL.md +0 -275
- package/.agents/generated/gemini/skills/ui-design/SKILL.md +0 -170
- package/.agents/generated/gemini/skills/ui-ux-pro/SKILL.md +0 -460
- package/.agents/generated/gemini/skills/ux-design/SKILL.md +0 -177
- package/.agents/generated/gemini/skills/vercel-optimize/SKILL.md +0 -82
- package/.agents/generated/gemini/skills/web-accessibility/SKILL.md +0 -300
package/.agents/resolver.js
CHANGED
|
@@ -2,564 +2,80 @@
|
|
|
2
2
|
* .agents/resolver.js
|
|
3
3
|
* ContextOS — Dynamic Skill Resolver & Progressive Index Engine
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Unified facade wrapping CanonicalResolver for 100% CLI and MCP parity.
|
|
6
|
+
* Implements evidence-based scoring, transitive closures, token budget planning,
|
|
7
|
+
* and transparent explainability.
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
10
|
'use strict';
|
|
10
11
|
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Keyword & Regex matching rules for dynamic resolution.
|
|
19
|
-
*/
|
|
20
|
-
const SKILL_RULES = [
|
|
21
|
-
{
|
|
22
|
-
skill: 'nextjs',
|
|
23
|
-
category: 'stack',
|
|
24
|
-
strong: [/\bnext(?:\.js)?\b/i, /\bapp\s*router\b/i, /\bserver\s*actions?\b/i, /\brsc\b/i, /некст/i],
|
|
25
|
-
medium: [/\bpage\.tsx\b/i, /\blayout\.tsx\b/i],
|
|
26
|
-
weak: [],
|
|
27
|
-
fileGlobs: [/app\/.*\.(tsx|jsx|ts|js)$/, /next\.config\./],
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
skill: 'react',
|
|
31
|
-
category: 'stack',
|
|
32
|
-
strong: [/\breact\b/i, /\buseOptimistic\b/i, /компонент/i, /хук/i],
|
|
33
|
-
medium: [/\bcomponent\b/i, /\bhooks?\b/i, /\buseState\b/i, /\buseEffect\b/i, /\buseMemo\b/i, /\bprops\b/i, /модал\w*/i],
|
|
34
|
-
weak: [],
|
|
35
|
-
fileGlobs: [/\.(tsx|jsx)$/],
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
skill: 'typescript',
|
|
39
|
-
category: 'stack',
|
|
40
|
-
strong: [/\btypescript\b/i, /\btype-?safe\b/i, /\bgenerics?\b/i, /\binterface\b/i, /\btsconfig\b/i, /тайпскрипт/i, /типизац/i],
|
|
41
|
-
medium: [],
|
|
42
|
-
weak: [/\btypes?\b/i],
|
|
43
|
-
fileGlobs: [/\.tsx?$/, /tsconfig\.json$/],
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
skill: 'ui-ux-pro',
|
|
47
|
-
category: 'ui',
|
|
48
|
-
strong: [/\bui\b/i, /\bux\b/i, /\btailwind\b/i, /\bstyling\b/i, /дизайн/i, /верстк/i, /макет/i, /интерфейс/i],
|
|
49
|
-
medium: [/\bcss\b/i, /\btheme\b/i, /\bmodal\b/i, /\bbutton\b/i, /модал\w*/i, /кнопк/i],
|
|
50
|
-
weak: [/\bdesign\b/i],
|
|
51
|
-
fileGlobs: [/\.(css|scss|sass)$/, /tailwind\.config\./],
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
skill: 'web-accessibility',
|
|
55
|
-
category: 'ui',
|
|
56
|
-
strong: [/\baccessib\w*\b/i, /\ba11y\b/i, /\baria\b/i, /\bfocus\s*trap\b/i, /\bkeyboard\s*nav/i, /\bwcag\b/i, /\bscreen\s*reader\b/i, /доступност/i, /скринридер/i],
|
|
57
|
-
medium: [],
|
|
58
|
-
weak: [],
|
|
59
|
-
fileGlobs: [],
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
skill: 'impeccable-design',
|
|
63
|
-
category: 'ui',
|
|
64
|
-
strong: [/\bvisual\s*qa\b/i, /\bmicro-?animation\b/i, /\bglassmorphism\b/i, /\btypography\b/i, /анимац/i, /полировк/i],
|
|
65
|
-
medium: [/\bpolish\b/i],
|
|
66
|
-
weak: [],
|
|
67
|
-
fileGlobs: [],
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
skill: 'database',
|
|
71
|
-
category: 'intent',
|
|
72
|
-
strong: [/\bdatabase\b/i, /\bsql\b/i, /\bpostgres(?:ql)?\b/i, /\bprisma\b/i, /\bdrizzle\b/i, /\bmigration\b/i, /\borm\b/i, /баз.*данн/i, /миграц/i, /таблиц/i],
|
|
73
|
-
medium: [/\bschema\b/i],
|
|
74
|
-
weak: [/\bquery\b/i, /\bindex(?:ing)?\b/i],
|
|
75
|
-
fileGlobs: [/\.prisma$/, /drizzle\.config\./, /\bmigrations?\/.*\.sql$/],
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
skill: 'security',
|
|
79
|
-
category: 'intent',
|
|
80
|
-
strong: [/\bauth\b/i, /\bjwt\b/i, /\blogin\b/i, /\bcsrf\b/i, /\bxss\b/i, /\brate\s*limit\b/i, /авториз/i, /аутентифик/i, /парол/i, /безопасност/i],
|
|
81
|
-
medium: [/\bpermission\b/i, /\bsession\b/i, /\btoken\b/i, /токен/i],
|
|
82
|
-
weak: [],
|
|
83
|
-
fileGlobs: [/\bauth\b/, /\bsecurity\b/],
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
skill: 'performance',
|
|
87
|
-
category: 'intent',
|
|
88
|
-
strong: [/\bperformance\b/i, /\blatency\b/i, /\blcp\b/i, /\bcls\b/i, /\binp\b/i, /\bcore\s*web\s*vitals\b/i, /\bwaterfall\b/i, /\bbundle\s*size\b/i, /производительн/i, /ускор/i],
|
|
89
|
-
medium: [/\boptimize\b/i, /\bslow\b/i, /оптимиз/i, /медленн/i],
|
|
90
|
-
weak: [],
|
|
91
|
-
fileGlobs: [],
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
skill: 'testing',
|
|
95
|
-
category: 'intent',
|
|
96
|
-
strong: [/\bvitest\b/i, /\bjest\b/i, /\bplaywright\b/i, /\btdd\b/i, /\bbdd\b/i, /\be2e\b/i, /тестирован/i, /покрыти/i, /юнит/i],
|
|
97
|
-
medium: [/\btest(?:s|ing)?\b/i, /\bmock\b/i, /тест/i],
|
|
98
|
-
weak: [],
|
|
99
|
-
fileGlobs: [/\.(test|spec)\.(ts|js|tsx|jsx|py)$/, /vitest\.config\./, /playwright\.config\./],
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
skill: 'docker',
|
|
103
|
-
category: 'intent',
|
|
104
|
-
strong: [/\bdocker\b/i, /\bdockerfile\b/i, /\bcompose\b/i, /\bkubernetes\b/i, /\bk8s\b/i, /докер/i],
|
|
105
|
-
medium: [],
|
|
106
|
-
weak: [/\bcontainer\b/i, /контейнер/i],
|
|
107
|
-
fileGlobs: [/Dockerfile/, /docker-compose\./],
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
skill: 'fastapi',
|
|
111
|
-
category: 'stack',
|
|
112
|
-
strong: [/\bfastapi\b/i, /\bpydantic\b/i, /\buvicorn\b/i, /\bpytest\b/i, /питон/i],
|
|
113
|
-
medium: [/\bpython\b/i],
|
|
114
|
-
weak: [],
|
|
115
|
-
fileGlobs: [/\.py$/, /requirements\.txt$/, /pyproject\.toml$/],
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
skill: 'nestjs',
|
|
119
|
-
category: 'stack',
|
|
120
|
-
strong: [/\bnestjs\b/i, /\b@nestjs\b/i, /нест/i],
|
|
121
|
-
medium: [],
|
|
122
|
-
weak: [/\bmodule\b/i, /\bcontroller\b/i, /\binjectable\b/i],
|
|
123
|
-
fileGlobs: [/nest-cli\.json$/],
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
skill: 'node',
|
|
127
|
-
category: 'stack',
|
|
128
|
-
strong: [/\bnode(?:\.js)?\b/i, /\bexpress\b/i, /\bfastify\b/i],
|
|
129
|
-
medium: [/\bbackend\b/i, /\bapi\s*route\b/i, /бэкенд/i, /эндпоинт/i],
|
|
130
|
-
weak: [],
|
|
131
|
-
fileGlobs: [],
|
|
132
|
-
},
|
|
133
|
-
{
|
|
134
|
-
skill: 'ddd',
|
|
135
|
-
category: 'intent',
|
|
136
|
-
strong: [/\bddd\b/i, /\bdomain-?driven\b/i, /\baggregate\b/i, /\bvalue\s*object\b/i, /\bbounded\s*context\b/i],
|
|
137
|
-
medium: [/\bentity\b/i, /домен/i, /агрегат/i],
|
|
138
|
-
weak: [],
|
|
139
|
-
fileGlobs: [],
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
skill: 'microservices',
|
|
143
|
-
category: 'intent',
|
|
144
|
-
strong: [/\bmicroservices?\b/i, /\bevent-?driven\b/i, /\brabbitmq\b/i, /\bkafka\b/i, /\bgrpc\b/i, /микросервис/i],
|
|
145
|
-
medium: [/\bpub\/?sub\b/i, /очеред/i],
|
|
146
|
-
weak: [],
|
|
147
|
-
fileGlobs: [],
|
|
148
|
-
},
|
|
149
|
-
{
|
|
150
|
-
skill: 'system-design',
|
|
151
|
-
category: 'intent',
|
|
152
|
-
strong: [/\bsystem\s*design\b/i, /\bhigh\s*concurrency\b/i, /\bcircuit\s*breaker\b/i, /масштабируем/i],
|
|
153
|
-
medium: [/\barchitecture\b/i, /\bscalab(?:le|ility)\b/i, /архитектур/i],
|
|
154
|
-
weak: [],
|
|
155
|
-
fileGlobs: [],
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
skill: 'graphify',
|
|
159
|
-
category: 'intent',
|
|
160
|
-
strong: [/\bgraphify\b/i, /\bknowledge\s*graph\b/i, /\bcodebase\s*graph\b/i, /\bproject\s*graph\b/i, /\bblast\s*radius\b/i, /\bmap\s*(?:the\s*)?codebase\b/i, /граф\s*проект/i, /граф\s*зависимост/i],
|
|
161
|
-
medium: [],
|
|
162
|
-
weak: [],
|
|
163
|
-
fileGlobs: [/graph\.json$/, /GRAPH_REPORT\.md$/],
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
skill: 'architecture-diagrams',
|
|
167
|
-
category: 'intent',
|
|
168
|
-
strong: [/\bflowchart\b/i, /\bsequence\s*diagram\b/i],
|
|
169
|
-
medium: [/\bdiagrams?\b/i, /диаграмм/i, /схем/i, /нарисуй/i],
|
|
170
|
-
weak: [],
|
|
171
|
-
fileGlobs: [],
|
|
172
|
-
},
|
|
173
|
-
{
|
|
174
|
-
skill: 'subagent-orchestrator',
|
|
175
|
-
category: 'intent',
|
|
176
|
-
strong: [/\bsubagent\b/i, /\bparallel\s*tasks\b/i, /субагент/i, /распараллел/i],
|
|
177
|
-
medium: [/\bdelegate\b/i, /делегируй/i],
|
|
178
|
-
weak: [],
|
|
179
|
-
fileGlobs: [],
|
|
180
|
-
},
|
|
181
|
-
{
|
|
182
|
-
skill: 'interview-me',
|
|
183
|
-
category: 'intent',
|
|
184
|
-
strong: [/\binterview\b/i, /интервью/i, /расспроси/i],
|
|
185
|
-
medium: [/\bclarify\b/i, /\bquestions\b/i, /уточни\b/i],
|
|
186
|
-
weak: [],
|
|
187
|
-
fileGlobs: [],
|
|
188
|
-
},
|
|
189
|
-
];
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* @typedef {Object} SkillIndexItem
|
|
193
|
-
* @property {string} name - Skill unique identifier
|
|
194
|
-
* @property {string} description - Brief summary of the skill
|
|
195
|
-
* @property {string} path - Relative path to the skill markdown document
|
|
196
|
-
*/
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* @typedef {Object} ResolveSkillsOptions
|
|
200
|
-
* @property {string} [prompt] - Free-form prompt text describing the current task
|
|
201
|
-
* @property {string[]} [files] - List of file paths currently touched or opened
|
|
202
|
-
* @property {string} [phase] - Active lifecycle phase (Define, Plan, Build, Verify, Review, Ship)
|
|
203
|
-
* @property {string} [domain] - Engineering domain override (Frontend, Backend, Architecture, Full-Stack, DevOps)
|
|
204
|
-
*/
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* @typedef {Object} ResolvedSkillsResult
|
|
208
|
-
* @property {string} domain - Identified technical domain
|
|
209
|
-
* @property {string} phase - Current pipeline phase
|
|
210
|
-
* @property {string} role - Specialized GStack agent role
|
|
211
|
-
* @property {string[]} skills - Resolved list of minimal skill identifiers
|
|
212
|
-
*/
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Builds a compact, progressive index of all available skills.
|
|
216
|
-
*
|
|
217
|
-
* @param {string} [projectDir=process.cwd()] - Target root directory of the project
|
|
218
|
-
* @returns {SkillIndexItem[]} Array of indexed skill metadata objects
|
|
219
|
-
*/
|
|
220
|
-
function buildSkillIndex(projectDir = process.cwd()) {
|
|
221
|
-
const shared = require(path.join(AGENTS_DIR, 'adapters', 'shared.js'));
|
|
222
|
-
const skillDirs = shared.collectSkillDirectories();
|
|
223
|
-
const index = [];
|
|
224
|
-
|
|
225
|
-
for (const dir of skillDirs) {
|
|
226
|
-
const skillName = path.basename(dir);
|
|
227
|
-
const skillMdPath = path.join(dir, 'SKILL.md');
|
|
228
|
-
if (!fs.existsSync(skillMdPath)) continue;
|
|
229
|
-
|
|
230
|
-
const raw = fs.readFileSync(skillMdPath, 'utf8');
|
|
231
|
-
let description = '';
|
|
232
|
-
const descMatch = raw.match(/description:\s*(?:>)?\s*([^\n\r]+)/);
|
|
233
|
-
if (descMatch) {
|
|
234
|
-
description = descMatch[1].trim().replace(/^['"]|['"]$/g, '');
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const relPath = path.relative(projectDir, skillMdPath).replace(/\\/g, '/');
|
|
238
|
-
|
|
239
|
-
index.push({
|
|
240
|
-
name: skillName,
|
|
241
|
-
description: description || `ContextOS skill for ${skillName}`,
|
|
242
|
-
path: relPath,
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
return index;
|
|
247
|
-
}
|
|
12
|
+
const {
|
|
13
|
+
CanonicalResolver,
|
|
14
|
+
DEFAULT_CONTEXT_BUDGET_TOKENS,
|
|
15
|
+
WEIGHTS,
|
|
16
|
+
analyzeImportGraph,
|
|
17
|
+
} = require('./resolver/canonical-resolver.js');
|
|
248
18
|
|
|
249
19
|
/**
|
|
250
|
-
*
|
|
251
|
-
* Scans project manifests and configs to detect active technologies
|
|
252
|
-
* that keyword or regex matching in prompts might omit.
|
|
20
|
+
* Resolves the minimal set of skills for a given prompt, file list, and phase.
|
|
253
21
|
*
|
|
254
|
-
* @param {
|
|
255
|
-
* @returns {
|
|
22
|
+
* @param {Object} options - Context options
|
|
23
|
+
* @returns {Object} Resolution result
|
|
256
24
|
*/
|
|
257
|
-
function
|
|
258
|
-
const
|
|
259
|
-
|
|
25
|
+
function resolveSkills({ prompt = '', files = [], phase = 'Build', domain = '', projectDir = process.cwd(), maxSkills, contextBudgetTokens = DEFAULT_CONTEXT_BUDGET_TOKENS } = {}) {
|
|
26
|
+
const resolver = new CanonicalResolver({ rootDir: projectDir });
|
|
27
|
+
const result = resolver.resolve({
|
|
28
|
+
task: prompt,
|
|
29
|
+
files,
|
|
30
|
+
explicitPhase: phase,
|
|
31
|
+
domain,
|
|
32
|
+
projectDir,
|
|
33
|
+
maxSkills,
|
|
34
|
+
contextBudgetTokens,
|
|
35
|
+
});
|
|
260
36
|
|
|
261
|
-
|
|
262
|
-
|
|
37
|
+
return {
|
|
38
|
+
domain: result.domain,
|
|
39
|
+
phase: result.phase.value,
|
|
40
|
+
role: result.role,
|
|
41
|
+
skills: result.skills,
|
|
42
|
+
risk: result.risk,
|
|
43
|
+
selected: result.selected,
|
|
44
|
+
excluded: result.excluded,
|
|
45
|
+
conflicts: result.conflicts,
|
|
46
|
+
warnings: result.warnings,
|
|
47
|
+
totalEstimatedTokens: result.totalEstimatedTokens,
|
|
48
|
+
registryFingerprint: result.registryFingerprint,
|
|
49
|
+
workspaceFingerprint: result.workspaceFingerprint,
|
|
263
50
|
};
|
|
264
|
-
|
|
265
|
-
// 1. Scan package.json dependencies and devDependencies
|
|
266
|
-
const pkgPath = path.join(projectDir, 'package.json');
|
|
267
|
-
if (fs.existsSync(pkgPath)) {
|
|
268
|
-
try {
|
|
269
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
270
|
-
const allDeps = {
|
|
271
|
-
...(pkg.dependencies || {}),
|
|
272
|
-
...(pkg.devDependencies || {}),
|
|
273
|
-
...(pkg.peerDependencies || {}),
|
|
274
|
-
};
|
|
275
|
-
|
|
276
|
-
const DEP_SKILL_MAP = {
|
|
277
|
-
'react': 'react',
|
|
278
|
-
'react-dom': 'react',
|
|
279
|
-
'next': 'nextjs',
|
|
280
|
-
'prisma': 'database',
|
|
281
|
-
'@prisma/client': 'database',
|
|
282
|
-
'drizzle-orm': 'database',
|
|
283
|
-
'drizzle-kit': 'database',
|
|
284
|
-
'typeorm': 'database',
|
|
285
|
-
'mongoose': 'database',
|
|
286
|
-
'pg': 'database',
|
|
287
|
-
'mysql2': 'database',
|
|
288
|
-
'vitest': 'testing',
|
|
289
|
-
'jest': 'testing',
|
|
290
|
-
'playwright': 'testing',
|
|
291
|
-
'@playwright/test': 'testing',
|
|
292
|
-
'cypress': 'testing',
|
|
293
|
-
'express': 'node',
|
|
294
|
-
'fastify': 'node',
|
|
295
|
-
'hono': 'node',
|
|
296
|
-
'@nestjs/core': 'nestjs',
|
|
297
|
-
'typescript': 'typescript',
|
|
298
|
-
'zod': 'typescript',
|
|
299
|
-
'tailwindcss': 'ui-ux-pro',
|
|
300
|
-
'lucide-react': 'ui-ux-pro',
|
|
301
|
-
'@radix-ui/react-dialog': 'web-accessibility',
|
|
302
|
-
'framer-motion': 'impeccable-design',
|
|
303
|
-
'dockerode': 'docker',
|
|
304
|
-
'ioredis': 'system-design',
|
|
305
|
-
'kafkajs': 'microservices',
|
|
306
|
-
'amqplib': 'microservices',
|
|
307
|
-
};
|
|
308
|
-
|
|
309
|
-
for (const [dep, skill] of Object.entries(DEP_SKILL_MAP)) {
|
|
310
|
-
if (allDeps[dep]) {
|
|
311
|
-
addSignal(skill, 15);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
} catch {
|
|
315
|
-
// ignore malformed package.json
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
// 2. Scan framework & tooling configuration files
|
|
320
|
-
const CONFIG_FILE_MAP = [
|
|
321
|
-
{ file: 'tsconfig.json', skill: 'typescript', weight: 10 },
|
|
322
|
-
{ file: 'next.config.js', skill: 'nextjs', weight: 15 },
|
|
323
|
-
{ file: 'next.config.mjs', skill: 'nextjs', weight: 15 },
|
|
324
|
-
{ file: 'next.config.ts', skill: 'nextjs', weight: 15 },
|
|
325
|
-
{ file: 'tailwind.config.js', skill: 'ui-ux-pro', weight: 10 },
|
|
326
|
-
{ file: 'tailwind.config.ts', skill: 'ui-ux-pro', weight: 10 },
|
|
327
|
-
{ file: 'nest-cli.json', skill: 'nestjs', weight: 15 },
|
|
328
|
-
{ file: 'prisma/schema.prisma', skill: 'database', weight: 15 },
|
|
329
|
-
{ file: 'drizzle.config.ts', skill: 'database', weight: 15 },
|
|
330
|
-
{ file: 'drizzle.config.js', skill: 'database', weight: 15 },
|
|
331
|
-
{ file: 'Dockerfile', skill: 'docker', weight: 15 },
|
|
332
|
-
{ file: 'docker-compose.yml', skill: 'docker', weight: 15 },
|
|
333
|
-
{ file: 'docker-compose.yaml', skill: 'docker', weight: 15 },
|
|
334
|
-
{ file: 'requirements.txt', skill: 'fastapi', weight: 15 },
|
|
335
|
-
{ file: 'pyproject.toml', skill: 'fastapi', weight: 15 },
|
|
336
|
-
{ file: 'vitest.config.ts', skill: 'testing', weight: 15 },
|
|
337
|
-
{ file: 'vitest.config.js', skill: 'testing', weight: 15 },
|
|
338
|
-
{ file: 'playwright.config.ts', skill: 'testing', weight: 15 },
|
|
339
|
-
{ file: 'playwright.config.js', skill: 'testing', weight: 15 },
|
|
340
|
-
];
|
|
341
|
-
|
|
342
|
-
for (const { file, skill, weight } of CONFIG_FILE_MAP) {
|
|
343
|
-
if (fs.existsSync(path.join(projectDir, file))) {
|
|
344
|
-
addSignal(skill, weight);
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
return techSignals;
|
|
349
51
|
}
|
|
350
52
|
|
|
351
53
|
/**
|
|
352
|
-
*
|
|
54
|
+
* Builds a progressive index of installed skills.
|
|
353
55
|
*
|
|
354
|
-
* @param {
|
|
355
|
-
* @returns {
|
|
56
|
+
* @param {string} [projectDir=process.cwd()]
|
|
57
|
+
* @returns {Array<{name: string, description: string, path: string}>}
|
|
356
58
|
*/
|
|
357
|
-
function
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
-
const promptScores = new Map();
|
|
361
|
-
const fileScores = new Map();
|
|
362
|
-
|
|
363
|
-
for (const rule of SKILL_RULES) {
|
|
364
|
-
ruleMap.set(rule.skill, rule);
|
|
365
|
-
let pScore = 0;
|
|
366
|
-
let fScore = 0;
|
|
367
|
-
|
|
368
|
-
// Strong triggers (10 points each match)
|
|
369
|
-
for (const pat of rule.strong || []) {
|
|
370
|
-
if (pat.test(promptText)) pScore += 10;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
// Medium triggers (5 points each match)
|
|
374
|
-
for (const pat of rule.medium || []) {
|
|
375
|
-
if (pat.test(promptText)) pScore += 5;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
// Weak triggers (2 points each match)
|
|
379
|
-
for (const pat of rule.weak || []) {
|
|
380
|
-
if (pat.test(promptText)) pScore += 2;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
// File matches (10 points per matching file)
|
|
384
|
-
for (const file of files) {
|
|
385
|
-
const normalized = file.replace(/\\/g, '/');
|
|
386
|
-
for (const pat of rule.fileGlobs || []) {
|
|
387
|
-
if (pat.test(normalized)) fScore += 10;
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
if (pScore > 0) promptScores.set(rule.skill, pScore);
|
|
392
|
-
if (fScore > 0) fileScores.set(rule.skill, fScore);
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
// Phase 2: Merge AST & Project Dependency Graph Signals
|
|
396
|
-
const astSignals = projectDir ? analyzeImportGraph(projectDir) : new Map();
|
|
397
|
-
|
|
398
|
-
// Active Profile Resolution Enforcement
|
|
399
|
-
const profiles = require('./profiles.js');
|
|
400
|
-
const activeProfile = projectDir ? profiles.getActiveProfile(projectDir) : null;
|
|
401
|
-
const profileExcluded = new Set(activeProfile?.exclude_skills || []);
|
|
402
|
-
const profilePreferred = new Set(activeProfile?.prefer_skills || []);
|
|
403
|
-
const profileEnforce = activeProfile?.enforce || {};
|
|
404
|
-
const profileDefaults = activeProfile?.defaults || {};
|
|
405
|
-
|
|
406
|
-
const MAX_DOMAIN_SKILLS = 4;
|
|
407
|
-
const selectedSkills = [];
|
|
408
|
-
|
|
409
|
-
// 1. INTENT SLOTS & INTENT PRECEDENCE (Immunity against eviction)
|
|
410
|
-
// Direct user intent in prompt MUST NOT be evicted by ambient stack/file signals.
|
|
411
|
-
// Profile-excluded skills are strictly omitted from candidate intents.
|
|
412
|
-
const candidateIntents = [];
|
|
413
|
-
for (const rule of SKILL_RULES) {
|
|
414
|
-
const s = rule.skill;
|
|
415
|
-
if (profileExcluded.has(s)) continue;
|
|
416
|
-
|
|
417
|
-
const p = promptScores.get(s) || 0;
|
|
418
|
-
const f = fileScores.get(s) || 0;
|
|
419
|
-
if (rule.category === 'intent' && (p >= 5 || (p > 0 && f >= 10))) {
|
|
420
|
-
candidateIntents.push({ skill: s, score: p * 2 + f, priority: 2 });
|
|
421
|
-
} else if (p >= 10) {
|
|
422
|
-
candidateIntents.push({ skill: s, score: p, priority: 1 });
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
candidateIntents.sort((a, b) => b.priority - a.priority || b.score - a.score);
|
|
427
|
-
|
|
428
|
-
// Reserve up to 2 guaranteed intent slots for directly requested capabilities
|
|
429
|
-
for (const item of candidateIntents) {
|
|
430
|
-
if (selectedSkills.length < 2 && !selectedSkills.includes(item.skill)) {
|
|
431
|
-
selectedSkills.push(item.skill);
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
// 2. CONTEXT SUPPRESSION
|
|
436
|
-
// If task is purely infrastructure (e.g. docker) or pure backend/architecture,
|
|
437
|
-
// suppress ambient UI skills from AST to avoid polluting non-UI tasks.
|
|
438
|
-
const hasPureInfraIntent = selectedSkills.includes('docker');
|
|
439
|
-
const hasBackendOnlyIntent = selectedSkills.some(s => ['database', 'fastapi', 'nestjs', 'ddd'].includes(s)) &&
|
|
440
|
-
!files.some(f => /\.(tsx|jsx|css|scss|html)$/.test(f)) &&
|
|
441
|
-
!/\b(ui|react|css|tailwind|frontend|макет|дизайн|кнопк|стил|компонент)/i.test(promptText);
|
|
442
|
-
|
|
443
|
-
const suppressAmbientUI = hasPureInfraIntent || hasBackendOnlyIntent;
|
|
444
|
-
|
|
445
|
-
// 3. REMAINING SLOTS: Rank candidate skills with user-intent weighting and profile preferences
|
|
446
|
-
const candidateScores = new Map();
|
|
447
|
-
for (const rule of SKILL_RULES) {
|
|
448
|
-
const s = rule.skill;
|
|
449
|
-
if (selectedSkills.includes(s) || profileExcluded.has(s)) continue;
|
|
450
|
-
|
|
451
|
-
const p = promptScores.get(s) || 0;
|
|
452
|
-
const f = fileScores.get(s) || 0;
|
|
453
|
-
const a = astSignals.get(s) || 0;
|
|
454
|
-
|
|
455
|
-
// If ambient UI is suppressed, skip UI skills unless explicitly requested in prompt
|
|
456
|
-
if (suppressAmbientUI && (rule.category === 'ui' || s === 'react') && p < 5 && f === 0) {
|
|
457
|
-
continue;
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
// Require minimum unweighted threshold of 5 points to filter casual weak mentions,
|
|
461
|
-
// then apply multiplier for strong/medium prompt matches to prioritize user intent over ambient signals.
|
|
462
|
-
const rawSum = p + f + a;
|
|
463
|
-
if (rawSum >= 5 || profilePreferred.has(s)) {
|
|
464
|
-
let weightedScore = (p >= 5 ? p * 3 : p) + f + a;
|
|
465
|
-
if (profilePreferred.has(s)) {
|
|
466
|
-
weightedScore += 20; // Profile prefer boost
|
|
467
|
-
}
|
|
468
|
-
candidateScores.set(s, weightedScore);
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
const remainingSorted = Array.from(candidateScores.entries())
|
|
473
|
-
.sort((a, b) => b[1] - a[1])
|
|
474
|
-
.map(([skill]) => skill);
|
|
475
|
-
|
|
476
|
-
for (const s of remainingSorted) {
|
|
477
|
-
if (selectedSkills.length >= MAX_DOMAIN_SKILLS) break;
|
|
478
|
-
if (!selectedSkills.includes(s)) {
|
|
479
|
-
selectedSkills.push(s);
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
// 4. Synergy rules (from AGENTS.md matrix)
|
|
484
|
-
const hasSynergyPrereq = selectedSkills.includes('database') ||
|
|
485
|
-
selectedSkills.includes('microservices') ||
|
|
486
|
-
selectedSkills.includes('ddd') ||
|
|
487
|
-
selectedSkills.includes('graphify');
|
|
488
|
-
|
|
489
|
-
if (hasSynergyPrereq && !selectedSkills.includes('system-design') && !profileExcluded.has('system-design')) {
|
|
490
|
-
if (selectedSkills.length < MAX_DOMAIN_SKILLS + 1) {
|
|
491
|
-
selectedSkills.push('system-design');
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
// 5. Enforce profile invariants (e.g. enterprise or startup compliance)
|
|
496
|
-
const normPhase = (phase || '').toLowerCase();
|
|
497
|
-
if (profileEnforce.testing === true && ['build', 'verify', 'test'].includes(normPhase)) {
|
|
498
|
-
if (!selectedSkills.includes('testing') && !profileExcluded.has('testing')) {
|
|
499
|
-
selectedSkills.push('testing');
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
if (profileEnforce.security_audit === true && (selectedSkills.includes('database') || selectedSkills.includes('node') || selectedSkills.includes('fastapi') || selectedSkills.includes('nestjs'))) {
|
|
504
|
-
if (!selectedSkills.includes('security') && !profileExcluded.has('security')) {
|
|
505
|
-
selectedSkills.push('security');
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
if (profileEnforce.adr === true && (normPhase === 'plan' || selectedSkills.includes('system-design') || selectedSkills.includes('microservices'))) {
|
|
510
|
-
if (!selectedSkills.includes('decisions') && !profileExcluded.has('decisions')) {
|
|
511
|
-
selectedSkills.push('decisions');
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
if (profileEnforce.accessibility_audit === true && (selectedSkills.includes('react') || selectedSkills.includes('ui-ux-pro'))) {
|
|
516
|
-
if (!selectedSkills.includes('web-accessibility') && !profileExcluded.has('web-accessibility')) {
|
|
517
|
-
selectedSkills.push('web-accessibility');
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
// Foundational skills (always active unless explicitly excluded)
|
|
522
|
-
const allSkills = ['ponytail-mindset', 'engineering-workflow', ...selectedSkills];
|
|
523
|
-
const finalSkills = Array.from(new Set(allSkills)).filter(s => !profileExcluded.has(s));
|
|
524
|
-
|
|
525
|
-
// Infer Domain if not specified
|
|
526
|
-
let inferredDomain = domain;
|
|
527
|
-
if (!inferredDomain) {
|
|
528
|
-
const isFrontend = finalSkills.includes('react') || finalSkills.includes('nextjs') || finalSkills.includes('ui-ux-pro');
|
|
529
|
-
const isBackend = finalSkills.includes('database') || finalSkills.includes('fastapi') || finalSkills.includes('nestjs') || finalSkills.includes('node') || finalSkills.includes('system-design');
|
|
530
|
-
if (isFrontend && isBackend) inferredDomain = 'Full-Stack';
|
|
531
|
-
else if (isFrontend) inferredDomain = 'Frontend';
|
|
532
|
-
else if (isBackend) inferredDomain = 'Backend';
|
|
533
|
-
else inferredDomain = 'Architecture';
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
// Infer Role
|
|
537
|
-
let inferredRole = 'Senior Developer';
|
|
538
|
-
if (phase.toLowerCase() === 'define') inferredRole = 'Product Manager';
|
|
539
|
-
else if (phase.toLowerCase() === 'plan') inferredRole = 'Architect';
|
|
540
|
-
else if (phase.toLowerCase() === 'review') inferredRole = inferredDomain === 'Frontend' ? 'Staff Engineer + Senior Designer' : 'Staff Engineer';
|
|
541
|
-
else if (phase.toLowerCase() === 'test') inferredRole = 'QA Lead';
|
|
542
|
-
else if (phase.toLowerCase() === 'ship') inferredRole = 'Release Engineer';
|
|
543
|
-
|
|
544
|
-
return {
|
|
545
|
-
domain: inferredDomain,
|
|
546
|
-
phase: phase,
|
|
547
|
-
role: inferredRole,
|
|
548
|
-
skills: finalSkills,
|
|
549
|
-
};
|
|
59
|
+
function buildSkillIndex(projectDir = process.cwd()) {
|
|
60
|
+
const resolver = new CanonicalResolver({ rootDir: projectDir });
|
|
61
|
+
return resolver.buildSkillIndex(projectDir);
|
|
550
62
|
}
|
|
551
63
|
|
|
552
64
|
/**
|
|
553
|
-
* Formats resolved skills into a clean ContextOS declaration string.
|
|
65
|
+
* Formats resolved skills into a clean ContextOS declaration string matching AGENTS.md.
|
|
554
66
|
*
|
|
555
|
-
* @param {
|
|
556
|
-
* @returns {string}
|
|
67
|
+
* @param {Object} resolution
|
|
68
|
+
* @returns {string}
|
|
557
69
|
*/
|
|
558
70
|
function formatDeclaration(resolution) {
|
|
559
|
-
|
|
71
|
+
const resolver = new CanonicalResolver();
|
|
72
|
+
return resolver.formatDeclaration(resolution);
|
|
560
73
|
}
|
|
561
74
|
|
|
562
75
|
module.exports = {
|
|
76
|
+
CanonicalResolver,
|
|
77
|
+
DEFAULT_CONTEXT_BUDGET_TOKENS,
|
|
78
|
+
WEIGHTS,
|
|
563
79
|
buildSkillIndex,
|
|
564
80
|
resolveSkills,
|
|
565
81
|
analyzeImportGraph,
|