Introducing @knitpkg:wired: Real MQL #include for Composite Packages in KnitPkg

Introducing @knitpkg:wired: Real MQL #include for Composite Packages in KnitPkg

24 March 2026, 19:12
Douglas Nascimento Rechia
0
29

If you’ve played with KnitPkg composite packages, you’ve probably hit this classic problem:

  • During development, you want MetaEditor to resolve all your  #include s so that IntelliSense and unit tests work.
  • But when your package is installed as a dependency, those  #include s must point to the real installed headers under  knitpkg/include/ , not to some dev‑only helper.

Until now, the “classic” solution was:

  • Include a big  autocomplete.mqh  file to make symbols from dependencies visible;
  • Declare the real external dependencies via  /* @knitpkg:include "..." */  directives, which KnitPkg rewrites into real  #include  statements during  kp install .

This works, but it has two downsides:

  1. autocomplete.mqh  pulls in everything from your dependencies, polluting IntelliSense with lots of unrelated names.
  2. Your real dependencies are hidden inside comments instead of being visible as normal MQL includes.

KnitPkg v1.1.0 introduces a better approach.


What Is  @knitpkg:wired ?

@knitpkg:wired  is a new directive for composite packages that lets you write real MQL  #include  paths to dependency headers, while still letting KnitPkg “rewire” those includes when your package is installed somewhere else.

Instead of doing this (classic approach):

#include "../../../autocomplete/autocomplete.mqh"
/* @knitpkg:include "douglasrechia/bar/TimeSeries.mqh" */

you can now write this:

#include "../../../autocomplete/knitpkg/include/douglasrechia/bar/TimeSeries.mqh" /* @knitpkg:wired */
A few key points:
  • The  #include  is real MQL, pointing to the header under  knitpkg/autocomplete/knitpkg/include/… .
  • MetaEditor resolves it directly, so IntelliSense and unit tests just work.
  • The  /* @knitpkg:wired */  annotation sits on the same line as the  #include .
  • During  kp install , KnitPkg detects this annotation and rewrites the path from the  autocomplete  structure to the real installed header under  knitpkg/include/… .

So inside your dev repo, your file might look like this:

//+------------------------------------------------------------------+
//| Cross.mqh                                                        |
//| Package barhelper                                                |
//| Organization: douglasrechia                                      |
//+------------------------------------------------------------------+
#include "../../../autocomplete/knitpkg/include/douglasrechia/bar/TimeSeries.mqh" /* @knitpkg:wired */

namespace douglasrechia
{
  bool CrossUp(ITimeSeries<double> &series1,
               ITimeSeries<double> &series2,
               int shift = 0)
  {
    if(shift < 0) return false;
    if(shift >= series1.Size() - 1) return false;
    if(shift >= series2.Size() - 1) return false;

    return series1.ValueAtShift(shift + 1) < series2.ValueAtShift(shift + 1) &&
           series1.ValueAtShift(shift)     > series2.ValueAtShift(shift);
  }
}
//+------------------------------------------------------------------+

When  barhelper  is installed as a dependency in another project, KnitPkg rewrites that include so it points at the installed  TimeSeries.mqh  under  knitpkg/include/douglasrechia/bar/…  instead of the autocomplete copy.

For another example, see this repository.


Why This Is Better for Composite Packages

From the MQL developer’s point of view,  @knitpkg:wired  is much more natural than the old  autocomplete.mqh + @knitpkg:include  combo:

  1. The includes are honest MQL.
    You see exactly which headers you are including, as normal  #include  statements. There is no “magic” hidden inside comments.

  2. No more namespace pollution.
    You include only the specific headers you need from each dependency, instead of pulling everything into the current translation unit via  autocomplete.mqh .

  3. MetaEditor just works.
    Because the  #include  references the header under  knitpkg/autocomplete/knitpkg/include/… , MetaEditor resolves it normally. IntelliSense and unit tests see the same code you see.

  4. Install-time wiring is automatic.
    kp install  simply detects  /* @knitpkg:wired */  and overwrites the include path to target the installed package header. You don’t have to maintain a separate list of  @knitpkg:include  directives.

The result: your composite packages read like idiomatic MQL code, while still behaving correctly when installed as dependencies.


How To Use  @knitpkg:wired  in Your Package

Here’s the workflow in practice:

1. Declare the dependency. 

In your composite package (for example  barhelper ), add the dependency with the CLI:

    kp add @douglasrechia/bar

    This updates your  knitpkg.yaml  with something like:

    dependencies: '@douglasrechia/bar': ^1.0.0

    2. Generate autocomplete headers. 

    Run:

      kp autocomplete

      This populates  knitpkg/autocomplete/knitpkg/include/...  with headers for your dependencies, preserving their structure. These are the headers your dev-time includes should target when you write  @knitpkg:wired  includes.

      3. Write wired includes in your public headers. 

      In a header under  knitpkg/include/<org>/<package>/ , include dependency headers from the  autocomplete  tree and annotate them:

        #include "../../../autocomplete/knitpkg/include/douglasrechia/bar/TimeSeries.mqh" /* @knitpkg:wired */
        A few rules:

        • The path must point somewhere under  knitpkg/autocomplete/knitpkg/include/ .
        • The path should be relative to the header that’s including it.
        • The  /* @knitpkg:wired */  annotation must be on the same line as the  #include .

        4. Validate with kp checkinstall. Before publishing your package, run:

        kp checkinstall
        This simulates installation and verifies that all wired includes will resolve correctly when your package is consumed as a dependency.

        Comparison With the Classic  @knitpkg:include  Approach

        For context, here is what the classic approach looked like in a composite package header:

        #include "../../../autocomplete/autocomplete.mqh"
        /* @knitpkg:include "douglasrechia/bar/TimeSeries.mqh" */
        

        During development:

        • autocomplete.mqh  brings all dependency headers into a local structure so MetaEditor can resolve symbols for IntelliSense and compilation.
        • The  @knitpkg:include  directive lives inside a comment and is only interpreted by KnitPkg at install time.

        When the package is installed as a dependency, KnitPkg:

        • Comments out the  #include "../../../autocomplete/autocomplete.mqh"  line so it doesn’t leak into the consumer’s code;
        • Converts each  @knitpkg:include  directive into a real MQL  #include  pointing at the installed dependency headers under  knitpkg/include/… .

        This still works and is fully supported, but in practice it has some drawbacks:

        • You have two sources of truth for dependencies (the dev-time  autocomplete.mqh  and the install-time  @knitpkg:include  comments).
        • autocomplete pulls in a lot of stuff you may not need.
        • The real dependency edges are hidden in comments rather than expressed as normal  #include s.

        @knitpkg:wired  was designed specifically to remove these wrinkles and make composite packages feel like straightforward MQL projects that just happen to be wired up by KnitPkg at install time.


        Recommended Usage

        Going forward:

        • For composite packages,  @knitpkg:wired  is the recommended pattern to express dependencies between packages in public headers.
        • For single packages (those with no dependencies), you don’t need  kp autocomplete ,  @knitpkg:wired , or  @knitpkg:include  at all; your headers compile as regular  .mqh  files.
        • For internal includes within the same package, you still use normal relative  #include  statements with no KnitPkg directives.

        If you already have packages using  autocomplete.mqh + @knitpkg:include , they will continue to work. You can migrate gradually: as you touch existing headers, you can swap them to  @knitpkg:wired  if you want the cleaner, more explicit style.


        Wrap-Up

        @knitpkg:wired  is a small directive, but it significantly simplifies how composite packages are written:

        • Real MQL includes instead of comment‑based indirection.
        • Cleaner IntelliSense, less namespace clutter.
        • Automatic path rewiring at install time, validated by  kp checkinstall .

        If you’re maintaining packages that depend on others, I strongly recommend trying the wired approach in your next refactor or new package.

        Read the KnitPkg docs for more information.

        If you’d like, I can help you convert one of your existing KnitPkg packages step-by-step from  @knitpkg:include  to  @knitpkg:wired —do you have a specific repo in mind?