Skip to content

CLI TypeScript migration (re) - #2830

Merged
gerteck merged 17 commits into
MarkBind:masterfrom
Harjun751:cli-typescript-migration-redux
Feb 10, 2026
Merged

CLI TypeScript migration (re)#2830
gerteck merged 17 commits into
MarkBind:masterfrom
Harjun751:cli-typescript-migration-redux

Conversation

@Harjun751

@Harjun751Harjun751 commented Feb 7, 2026

Copy link
Copy Markdown
Contributor

What is the purpose of this pull request?

  • Documentation update
  • Bug fix
  • Feature addition or enhancement
  • Code maintenance
  • DevOps
  • Improve developer experience
  • Others, please explain:

Overview of changes:

Resolves#2754

  • Migrate functional code in CLI package to typescript

    • index.js and all util files converted to typescript
    • live-server patch is still JavaScript - added type definitions for now.
    • Test files migrated to typescript
    • Add typescript configs in the cli package - generated files go to cli/dist/
  • Package changes

    • Modified cli/package.json to properly prepare and publish the markbind-cli package.
    • Modified root package.json to use the built CLI module in cli/dist/
    • Updated selected packages to get built-in type definitions
    • Installed some type definitions
  • Developer-facing changes

    • Added a build/dev script in cli/package.json
    • Updated root build/dev scripts to utilize Project References (running the build/dev scripts are functionally the same as a developer)
    • Added tsx as a dev dependency - run TypeScript files directly using the bundled runner
    • Update dev docs on modified setup instructions & on how to use tsx to directly run files

Anything you'd like to highlight/discuss:
The migrated code is TypeScript, but it's not good TypeScript. There's liberal use of any, so it could definitely be improved. I think we could do refactoring as a separate PR, as I didn't want to clutter this PR any further. LMK, though.

Suggested things to refactor:
  1. Refactor core Site constructor. The CLI was using the constructor without properly specifying all the arguments - create an overloaded constructor for this?

  2. TypeScript 4.4 set the error type of catch variable to unknown. This means that to extract the error message, type narrowing was required. This introduces an extra branch and decision - what to log when the type of error is unknown? Currently, it simply logs "unknown error". Suggest: extract a variable/function that can be re-used in these cases, instead of hard-coding a message.

  3. Create an interface/type that can be used for the option parameter of the commander package callbacks

  4. Generally improve logger re-use in the cmd/ files - a lot of code duplication.

  5. Create an interface/type that can be used for the ServerConfig object in serve.ts

  6. Decrease the high level of coupling between the CLI and Core package

I chose tsx over ts-node since tsx seems more actively-maintained (the last release for ts-node was 3 years ago). Furthermore, tsx seems generally faster, and I had a good experience using tsx with Webstorm with zero configuration or issues. If there's another option worth considering, feel free to raise it up.

In terms of documentation, I did not add an entry on how to configure VSCode with tsx to run TypeScript code directly with, as I don't use VSC. If you think it's valuable, please do add it in!

Testing instructions:

Above running normal tests, you can check if your IDE/setup can correctly run individual test cases/suites in the cli/test/unit directory, since they use TypeScript now.

Proposed commit message: (wrap lines at 72 characters)

Migrate functional code in CLI package to TypeScript


Checklist: ☑️

  • Updated the documentation for feature additions and enhancements
  • Added tests for bug fixes or features
  • Linked all related issues
  • No unrelated changes

Reviewer checklist:

Indicate the SEMVER impact of the PR:

  • Major (when you make incompatible API changes)
  • Minor (when you add functionality in a backward compatible manner)
  • Patch (when you make backward compatible bug fixes)

At the end of the review, please label the PR with the appropriate label: r.Major, r.Minor, r.Patch.

Breaking change release note preparation (if applicable):

  • To be included in the release note for any feature that is made obsolete/breaking

Give a brief explanation note about:

  • what was the old feature that was made obsolete
  • any replacement feature (if any), and
  • how the author should modify his website to migrate from the old feature to the replacement feature (if possible).

With migrated test files, eslint does not detect that
functional test files are tests, resulting in
raising "no-extraneous-dependencies" error.
This error suggests that dependencies used in the actual
application and not test harnesses/files should be in
the main dependencies section.
However, since these are test files, the dependencies
should rightfully be in `devDependencies`.
Hence, let's add an rule exclusion for
import/no-extraneous-dependencies for the functional
tests.
To facilitate TypeScript migration, update `diff`
package to get in-built type declarations.
No breaking changes related to current usage
introduced.
istextorbinary developer dependency uses an old version
without typescript type definitions.
As part of migration of tests to typescript, the files
requiring istextorbinary now need type definitions.
Let's update istextorbinary to the latest version.
No breaking changes were introduced that affected the
usage of istextorbinary in the code.
To configure adapted tests and files to run
properly, scripts need to be updated.
Additionally, project references should
be enabled to ensure that subpackages
referring to each other are built
in the correct order and correctly.
Let's
* Update root package.json to use `tsc --build`
to build the backend
* Update scripts that require CLI to use built
output (.js files)
* Update cli jest.config.ts to use ts-jest to
be able to run test files with jest directly
* Update root tsconfig to point to cli/ and
core/ packages
* Update core/ tsconfig to set `composite` to
true to utilize incremental builds
* Add cli/ tsconfig with references to
core/ package, along with basic config
* Update packages in package-lock
Due to update TypeScript configurations,
update the developer docs to remain
up-to-date on setting up the project
and developing.
@codecov

codecovBot commented Feb 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.50000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.20%. Comparing base (2f6cb37) to head (b7ed620).
⚠️ Report is 17 commits behind head on master.

Files with missing linesPatch %Lines
packages/cli/src/util/cliUtil.ts91.66%3 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #2830 +/- ##
==========================================
- Coverage 72.20% 72.20% -0.01% 
==========================================
Files 134 134 Lines 7454 7461 +7 Branches 1528 1531 +3 ==========================================
+ Hits 5382 5387 +5 - Misses 2026 2028 +2 
Partials 46 46 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Harjun751
Harjun751 requested a review from a teamFebruary 7, 2026 03:51
Comment threadtsconfig.json
@Harjun751Harjun751 mentioned this pull request Feb 8, 2026
14 tasks
Comment threadtsconfig_base.json
Comment threadpackages/cli/test/functional/.eslintrc.js

@gerteckgerteck left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, good job on this

Note to self:

  • --build for tsc is for project references, which builds each package in dependency order.

Other stuff

  1. CLI snapshot test fails on my local after checking out to this branch. (EDIT: Due to .DS_Store due to dev on MacOS, unrelated to this PR. Tests pass on CI.)

  2. I got a permission denied as in, had to run chmod to add execute perms. i wonder if it is just a local dev env thing? Have not faced this before.
    Generated js file does not have executable flag enabled.

Edit: The markbind CLI command fails with "permission denied" because the generated packages/cli/dist/index.js
file loses its executable flag during the build process. tsc does not preserve permissions from source files.

@Harjun751
Harjun751force-pushed the cli-typescript-migration-redux branch 2 times, most recently from 268221f to b7ed620CompareFebruary 10, 2026 01:36
TypeScript compiler outputs all generated files
with `644` permissions, meaning that by default
generated files are not executable. Additionally,
the compiler does not preserve permissions of
source files when generating output, see:
github.com/microsoft/TypeScript/issues/37583
This particularly causes a problem with
`npm link`, since the entrypoint file
does not have execute permissions after
rebuilding, making the linked project
unable to be ran.
To workaround this, let's
* Add a script to ensure that the entrypoint
file is executable
* Make the script run before `dev` and
`build:backend` workflows
* Add a disclaimer in documentation
on what to do if the permission
error occurs
Comment threadscripts/prepCliOutput.js

@gerteckgerteck left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the great work on this @Harjun751

Merging this in, @MarkBind/active-3281-members do remember to update your forks and pull the latest after merging!

@gerteck
gerteck merged commit fe1bcba into MarkBind:masterFeb 10, 2026
16 of 21 checks passed
@github-actionsgithub-actionsBot added the r.Minor Version resolver: increment by 0.1.0 label Feb 10, 2026
This was referenced Feb 19, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

r.MinorVersion resolver: increment by 0.1.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate cli package to Typescript

2 participants

@Harjun751@gerteck
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
CLI TypeScript migration (re) by Harjun751 · Pull Request #2830 · MarkBind/markbind · GitHub
Skip to content

CLI TypeScript migration (re) - #2830

Merged
gerteck merged 17 commits into
MarkBind:masterfrom
Harjun751:cli-typescript-migration-redux
Feb 10, 2026
Merged

CLI TypeScript migration (re)#2830
gerteck merged 17 commits into
MarkBind:masterfrom
Harjun751:cli-typescript-migration-redux

Conversation

@Harjun751

@Harjun751Harjun751 commented Feb 7, 2026

Copy link
Copy Markdown
Contributor

What is the purpose of this pull request?

  • Documentation update
  • Bug fix
  • Feature addition or enhancement
  • Code maintenance
  • DevOps
  • Improve developer experience
  • Others, please explain:

Overview of changes:

Resolves#2754

  • Migrate functional code in CLI package to typescript

    • index.js and all util files converted to typescript
    • live-server patch is still JavaScript - added type definitions for now.
    • Test files migrated to typescript
    • Add typescript configs in the cli package - generated files go to cli/dist/
  • Package changes

    • Modified cli/package.json to properly prepare and publish the markbind-cli package.
    • Modified root package.json to use the built CLI module in cli/dist/
    • Updated selected packages to get built-in type definitions
    • Installed some type definitions
  • Developer-facing changes

    • Added a build/dev script in cli/package.json
    • Updated root build/dev scripts to utilize Project References (running the build/dev scripts are functionally the same as a developer)
    • Added tsx as a dev dependency - run TypeScript files directly using the bundled runner
    • Update dev docs on modified setup instructions & on how to use tsx to directly run files

Anything you'd like to highlight/discuss:
The migrated code is TypeScript, but it's not good TypeScript. There's liberal use of any, so it could definitely be improved. I think we could do refactoring as a separate PR, as I didn't want to clutter this PR any further. LMK, though.

Suggested things to refactor:
  1. Refactor core Site constructor. The CLI was using the constructor without properly specifying all the arguments - create an overloaded constructor for this?

  2. TypeScript 4.4 set the error type of catch variable to unknown. This means that to extract the error message, type narrowing was required. This introduces an extra branch and decision - what to log when the type of error is unknown? Currently, it simply logs "unknown error". Suggest: extract a variable/function that can be re-used in these cases, instead of hard-coding a message.

  3. Create an interface/type that can be used for the option parameter of the commander package callbacks

  4. Generally improve logger re-use in the cmd/ files - a lot of code duplication.

  5. Create an interface/type that can be used for the ServerConfig object in serve.ts

  6. Decrease the high level of coupling between the CLI and Core package

I chose tsx over ts-node since tsx seems more actively-maintained (the last release for ts-node was 3 years ago). Furthermore, tsx seems generally faster, and I had a good experience using tsx with Webstorm with zero configuration or issues. If there's another option worth considering, feel free to raise it up.

In terms of documentation, I did not add an entry on how to configure VSCode with tsx to run TypeScript code directly with, as I don't use VSC. If you think it's valuable, please do add it in!

Testing instructions:

Above running normal tests, you can check if your IDE/setup can correctly run individual test cases/suites in the cli/test/unit directory, since they use TypeScript now.

Proposed commit message: (wrap lines at 72 characters)

Migrate functional code in CLI package to TypeScript


Checklist: ☑️

  • Updated the documentation for feature additions and enhancements
  • Added tests for bug fixes or features
  • Linked all related issues
  • No unrelated changes

Reviewer checklist:

Indicate the SEMVER impact of the PR:

  • Major (when you make incompatible API changes)
  • Minor (when you add functionality in a backward compatible manner)
  • Patch (when you make backward compatible bug fixes)

At the end of the review, please label the PR with the appropriate label: r.Major, r.Minor, r.Patch.

Breaking change release note preparation (if applicable):

  • To be included in the release note for any feature that is made obsolete/breaking

Give a brief explanation note about:

  • what was the old feature that was made obsolete
  • any replacement feature (if any), and
  • how the author should modify his website to migrate from the old feature to the replacement feature (if possible).

With migrated test files, eslint does not detect that
functional test files are tests, resulting in
raising "no-extraneous-dependencies" error.
This error suggests that dependencies used in the actual
application and not test harnesses/files should be in
the main dependencies section.
However, since these are test files, the dependencies
should rightfully be in `devDependencies`.
Hence, let's add an rule exclusion for
import/no-extraneous-dependencies for the functional
tests.
To facilitate TypeScript migration, update `diff`
package to get in-built type declarations.
No breaking changes related to current usage
introduced.
istextorbinary developer dependency uses an old version
without typescript type definitions.
As part of migration of tests to typescript, the files
requiring istextorbinary now need type definitions.
Let's update istextorbinary to the latest version.
No breaking changes were introduced that affected the
usage of istextorbinary in the code.
To configure adapted tests and files to run
properly, scripts need to be updated.
Additionally, project references should
be enabled to ensure that subpackages
referring to each other are built
in the correct order and correctly.
Let's
* Update root package.json to use `tsc --build`
to build the backend
* Update scripts that require CLI to use built
output (.js files)
* Update cli jest.config.ts to use ts-jest to
be able to run test files with jest directly
* Update root tsconfig to point to cli/ and
core/ packages
* Update core/ tsconfig to set `composite` to
true to utilize incremental builds
* Add cli/ tsconfig with references to
core/ package, along with basic config
* Update packages in package-lock
Due to update TypeScript configurations,
update the developer docs to remain
up-to-date on setting up the project
and developing.
@codecov

codecovBot commented Feb 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.50000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.20%. Comparing base (2f6cb37) to head (b7ed620).
⚠️ Report is 17 commits behind head on master.

Files with missing linesPatch %Lines
packages/cli/src/util/cliUtil.ts91.66%3 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #2830 +/- ##
==========================================
- Coverage 72.20% 72.20% -0.01% 
==========================================
Files 134 134 Lines 7454 7461 +7 Branches 1528 1531 +3 ==========================================
+ Hits 5382 5387 +5 - Misses 2026 2028 +2 
Partials 46 46 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Harjun751
Harjun751 requested a review from a teamFebruary 7, 2026 03:51
Comment threadtsconfig.json
@Harjun751Harjun751 mentioned this pull request Feb 8, 2026
14 tasks
Comment threadtsconfig_base.json
Comment threadpackages/cli/test/functional/.eslintrc.js

@gerteckgerteck left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, good job on this

Note to self:

  • --build for tsc is for project references, which builds each package in dependency order.

Other stuff

  1. CLI snapshot test fails on my local after checking out to this branch. (EDIT: Due to .DS_Store due to dev on MacOS, unrelated to this PR. Tests pass on CI.)

  2. I got a permission denied as in, had to run chmod to add execute perms. i wonder if it is just a local dev env thing? Have not faced this before.
    Generated js file does not have executable flag enabled.

Edit: The markbind CLI command fails with "permission denied" because the generated packages/cli/dist/index.js
file loses its executable flag during the build process. tsc does not preserve permissions from source files.

@Harjun751
Harjun751force-pushed the cli-typescript-migration-redux branch 2 times, most recently from 268221f to b7ed620CompareFebruary 10, 2026 01:36
TypeScript compiler outputs all generated files
with `644` permissions, meaning that by default
generated files are not executable. Additionally,
the compiler does not preserve permissions of
source files when generating output, see:
github.com/microsoft/TypeScript/issues/37583
This particularly causes a problem with
`npm link`, since the entrypoint file
does not have execute permissions after
rebuilding, making the linked project
unable to be ran.
To workaround this, let's
* Add a script to ensure that the entrypoint
file is executable
* Make the script run before `dev` and
`build:backend` workflows
* Add a disclaimer in documentation
on what to do if the permission
error occurs
Comment threadscripts/prepCliOutput.js

@gerteckgerteck left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the great work on this @Harjun751

Merging this in, @MarkBind/active-3281-members do remember to update your forks and pull the latest after merging!

@gerteck
gerteck merged commit fe1bcba into MarkBind:masterFeb 10, 2026
16 of 21 checks passed
@github-actionsgithub-actionsBot added the r.Minor Version resolver: increment by 0.1.0 label Feb 10, 2026
This was referenced Feb 19, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

r.MinorVersion resolver: increment by 0.1.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate cli package to Typescript

2 participants

@Harjun751@gerteck
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' CLI TypeScript migration (re) by Harjun751 · Pull Request #2830 · MarkBind/markbind · GitHub
Skip to content

CLI TypeScript migration (re) - #2830

Merged
gerteck merged 17 commits into
MarkBind:masterfrom
Harjun751:cli-typescript-migration-redux
Feb 10, 2026
Merged

CLI TypeScript migration (re)#2830
gerteck merged 17 commits into
MarkBind:masterfrom
Harjun751:cli-typescript-migration-redux

Conversation

@Harjun751

@Harjun751Harjun751 commented Feb 7, 2026

Copy link
Copy Markdown
Contributor

What is the purpose of this pull request?

  • Documentation update
  • Bug fix
  • Feature addition or enhancement
  • Code maintenance
  • DevOps
  • Improve developer experience
  • Others, please explain:

Overview of changes:

Resolves#2754

  • Migrate functional code in CLI package to typescript

    • index.js and all util files converted to typescript
    • live-server patch is still JavaScript - added type definitions for now.
    • Test files migrated to typescript
    • Add typescript configs in the cli package - generated files go to cli/dist/
  • Package changes

    • Modified cli/package.json to properly prepare and publish the markbind-cli package.
    • Modified root package.json to use the built CLI module in cli/dist/
    • Updated selected packages to get built-in type definitions
    • Installed some type definitions
  • Developer-facing changes

    • Added a build/dev script in cli/package.json
    • Updated root build/dev scripts to utilize Project References (running the build/dev scripts are functionally the same as a developer)
    • Added tsx as a dev dependency - run TypeScript files directly using the bundled runner
    • Update dev docs on modified setup instructions & on how to use tsx to directly run files

Anything you'd like to highlight/discuss:
The migrated code is TypeScript, but it's not good TypeScript. There's liberal use of any, so it could definitely be improved. I think we could do refactoring as a separate PR, as I didn't want to clutter this PR any further. LMK, though.

Suggested things to refactor:
  1. Refactor core Site constructor. The CLI was using the constructor without properly specifying all the arguments - create an overloaded constructor for this?

  2. TypeScript 4.4 set the error type of catch variable to unknown. This means that to extract the error message, type narrowing was required. This introduces an extra branch and decision - what to log when the type of error is unknown? Currently, it simply logs "unknown error". Suggest: extract a variable/function that can be re-used in these cases, instead of hard-coding a message.

  3. Create an interface/type that can be used for the option parameter of the commander package callbacks

  4. Generally improve logger re-use in the cmd/ files - a lot of code duplication.

  5. Create an interface/type that can be used for the ServerConfig object in serve.ts

  6. Decrease the high level of coupling between the CLI and Core package

I chose tsx over ts-node since tsx seems more actively-maintained (the last release for ts-node was 3 years ago). Furthermore, tsx seems generally faster, and I had a good experience using tsx with Webstorm with zero configuration or issues. If there's another option worth considering, feel free to raise it up.

In terms of documentation, I did not add an entry on how to configure VSCode with tsx to run TypeScript code directly with, as I don't use VSC. If you think it's valuable, please do add it in!

Testing instructions:

Above running normal tests, you can check if your IDE/setup can correctly run individual test cases/suites in the cli/test/unit directory, since they use TypeScript now.

Proposed commit message: (wrap lines at 72 characters)

Migrate functional code in CLI package to TypeScript


Checklist: ☑️

  • Updated the documentation for feature additions and enhancements
  • Added tests for bug fixes or features
  • Linked all related issues
  • No unrelated changes

Reviewer checklist:

Indicate the SEMVER impact of the PR:

  • Major (when you make incompatible API changes)
  • Minor (when you add functionality in a backward compatible manner)
  • Patch (when you make backward compatible bug fixes)

At the end of the review, please label the PR with the appropriate label: r.Major, r.Minor, r.Patch.

Breaking change release note preparation (if applicable):

  • To be included in the release note for any feature that is made obsolete/breaking

Give a brief explanation note about:

  • what was the old feature that was made obsolete
  • any replacement feature (if any), and
  • how the author should modify his website to migrate from the old feature to the replacement feature (if possible).

With migrated test files, eslint does not detect that
functional test files are tests, resulting in
raising "no-extraneous-dependencies" error.
This error suggests that dependencies used in the actual
application and not test harnesses/files should be in
the main dependencies section.
However, since these are test files, the dependencies
should rightfully be in `devDependencies`.
Hence, let's add an rule exclusion for
import/no-extraneous-dependencies for the functional
tests.
To facilitate TypeScript migration, update `diff`
package to get in-built type declarations.
No breaking changes related to current usage
introduced.
istextorbinary developer dependency uses an old version
without typescript type definitions.
As part of migration of tests to typescript, the files
requiring istextorbinary now need type definitions.
Let's update istextorbinary to the latest version.
No breaking changes were introduced that affected the
usage of istextorbinary in the code.
To configure adapted tests and files to run
properly, scripts need to be updated.
Additionally, project references should
be enabled to ensure that subpackages
referring to each other are built
in the correct order and correctly.
Let's
* Update root package.json to use `tsc --build`
to build the backend
* Update scripts that require CLI to use built
output (.js files)
* Update cli jest.config.ts to use ts-jest to
be able to run test files with jest directly
* Update root tsconfig to point to cli/ and
core/ packages
* Update core/ tsconfig to set `composite` to
true to utilize incremental builds
* Add cli/ tsconfig with references to
core/ package, along with basic config
* Update packages in package-lock
Due to update TypeScript configurations,
update the developer docs to remain
up-to-date on setting up the project
and developing.
@codecov

codecovBot commented Feb 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.50000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.20%. Comparing base (2f6cb37) to head (b7ed620).
⚠️ Report is 17 commits behind head on master.

Files with missing linesPatch %Lines
packages/cli/src/util/cliUtil.ts91.66%3 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #2830 +/- ##
==========================================
- Coverage 72.20% 72.20% -0.01% 
==========================================
Files 134 134 Lines 7454 7461 +7 Branches 1528 1531 +3 ==========================================
+ Hits 5382 5387 +5 - Misses 2026 2028 +2 
Partials 46 46 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Harjun751
Harjun751 requested a review from a teamFebruary 7, 2026 03:51
Comment threadtsconfig.json
@Harjun751Harjun751 mentioned this pull request Feb 8, 2026
14 tasks
Comment threadtsconfig_base.json
Comment threadpackages/cli/test/functional/.eslintrc.js

@gerteckgerteck left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, good job on this

Note to self:

  • --build for tsc is for project references, which builds each package in dependency order.

Other stuff

  1. CLI snapshot test fails on my local after checking out to this branch. (EDIT: Due to .DS_Store due to dev on MacOS, unrelated to this PR. Tests pass on CI.)

  2. I got a permission denied as in, had to run chmod to add execute perms. i wonder if it is just a local dev env thing? Have not faced this before.
    Generated js file does not have executable flag enabled.

Edit: The markbind CLI command fails with "permission denied" because the generated packages/cli/dist/index.js
file loses its executable flag during the build process. tsc does not preserve permissions from source files.

@Harjun751
Harjun751force-pushed the cli-typescript-migration-redux branch 2 times, most recently from 268221f to b7ed620CompareFebruary 10, 2026 01:36
TypeScript compiler outputs all generated files
with `644` permissions, meaning that by default
generated files are not executable. Additionally,
the compiler does not preserve permissions of
source files when generating output, see:
github.com/microsoft/TypeScript/issues/37583
This particularly causes a problem with
`npm link`, since the entrypoint file
does not have execute permissions after
rebuilding, making the linked project
unable to be ran.
To workaround this, let's
* Add a script to ensure that the entrypoint
file is executable
* Make the script run before `dev` and
`build:backend` workflows
* Add a disclaimer in documentation
on what to do if the permission
error occurs
Comment threadscripts/prepCliOutput.js

@gerteckgerteck left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the great work on this @Harjun751

Merging this in, @MarkBind/active-3281-members do remember to update your forks and pull the latest after merging!

@gerteck
gerteck merged commit fe1bcba into MarkBind:masterFeb 10, 2026
16 of 21 checks passed
@github-actionsgithub-actionsBot added the r.Minor Version resolver: increment by 0.1.0 label Feb 10, 2026
This was referenced Feb 19, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

r.MinorVersion resolver: increment by 0.1.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate cli package to Typescript

2 participants

@Harjun751@gerteck
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' CLI TypeScript migration (re) by Harjun751 · Pull Request #2830 · MarkBind/markbind · GitHub
Skip to content

CLI TypeScript migration (re) - #2830

Merged
gerteck merged 17 commits into
MarkBind:masterfrom
Harjun751:cli-typescript-migration-redux
Feb 10, 2026
Merged

CLI TypeScript migration (re)#2830
gerteck merged 17 commits into
MarkBind:masterfrom
Harjun751:cli-typescript-migration-redux

Conversation

@Harjun751

@Harjun751Harjun751 commented Feb 7, 2026

Copy link
Copy Markdown
Contributor

What is the purpose of this pull request?

  • Documentation update
  • Bug fix
  • Feature addition or enhancement
  • Code maintenance
  • DevOps
  • Improve developer experience
  • Others, please explain:

Overview of changes:

Resolves#2754

  • Migrate functional code in CLI package to typescript

    • index.js and all util files converted to typescript
    • live-server patch is still JavaScript - added type definitions for now.
    • Test files migrated to typescript
    • Add typescript configs in the cli package - generated files go to cli/dist/
  • Package changes

    • Modified cli/package.json to properly prepare and publish the markbind-cli package.
    • Modified root package.json to use the built CLI module in cli/dist/
    • Updated selected packages to get built-in type definitions
    • Installed some type definitions
  • Developer-facing changes

    • Added a build/dev script in cli/package.json
    • Updated root build/dev scripts to utilize Project References (running the build/dev scripts are functionally the same as a developer)
    • Added tsx as a dev dependency - run TypeScript files directly using the bundled runner
    • Update dev docs on modified setup instructions & on how to use tsx to directly run files

Anything you'd like to highlight/discuss:
The migrated code is TypeScript, but it's not good TypeScript. There's liberal use of any, so it could definitely be improved. I think we could do refactoring as a separate PR, as I didn't want to clutter this PR any further. LMK, though.

Suggested things to refactor:
  1. Refactor core Site constructor. The CLI was using the constructor without properly specifying all the arguments - create an overloaded constructor for this?

  2. TypeScript 4.4 set the error type of catch variable to unknown. This means that to extract the error message, type narrowing was required. This introduces an extra branch and decision - what to log when the type of error is unknown? Currently, it simply logs "unknown error". Suggest: extract a variable/function that can be re-used in these cases, instead of hard-coding a message.

  3. Create an interface/type that can be used for the option parameter of the commander package callbacks

  4. Generally improve logger re-use in the cmd/ files - a lot of code duplication.

  5. Create an interface/type that can be used for the ServerConfig object in serve.ts

  6. Decrease the high level of coupling between the CLI and Core package

I chose tsx over ts-node since tsx seems more actively-maintained (the last release for ts-node was 3 years ago). Furthermore, tsx seems generally faster, and I had a good experience using tsx with Webstorm with zero configuration or issues. If there's another option worth considering, feel free to raise it up.

In terms of documentation, I did not add an entry on how to configure VSCode with tsx to run TypeScript code directly with, as I don't use VSC. If you think it's valuable, please do add it in!

Testing instructions:

Above running normal tests, you can check if your IDE/setup can correctly run individual test cases/suites in the cli/test/unit directory, since they use TypeScript now.

Proposed commit message: (wrap lines at 72 characters)

Migrate functional code in CLI package to TypeScript


Checklist: ☑️

  • Updated the documentation for feature additions and enhancements
  • Added tests for bug fixes or features
  • Linked all related issues
  • No unrelated changes

Reviewer checklist:

Indicate the SEMVER impact of the PR:

  • Major (when you make incompatible API changes)
  • Minor (when you add functionality in a backward compatible manner)
  • Patch (when you make backward compatible bug fixes)

At the end of the review, please label the PR with the appropriate label: r.Major, r.Minor, r.Patch.

Breaking change release note preparation (if applicable):

  • To be included in the release note for any feature that is made obsolete/breaking

Give a brief explanation note about:

  • what was the old feature that was made obsolete
  • any replacement feature (if any), and
  • how the author should modify his website to migrate from the old feature to the replacement feature (if possible).

With migrated test files, eslint does not detect that
functional test files are tests, resulting in
raising "no-extraneous-dependencies" error.
This error suggests that dependencies used in the actual
application and not test harnesses/files should be in
the main dependencies section.
However, since these are test files, the dependencies
should rightfully be in `devDependencies`.
Hence, let's add an rule exclusion for
import/no-extraneous-dependencies for the functional
tests.
To facilitate TypeScript migration, update `diff`
package to get in-built type declarations.
No breaking changes related to current usage
introduced.
istextorbinary developer dependency uses an old version
without typescript type definitions.
As part of migration of tests to typescript, the files
requiring istextorbinary now need type definitions.
Let's update istextorbinary to the latest version.
No breaking changes were introduced that affected the
usage of istextorbinary in the code.
To configure adapted tests and files to run
properly, scripts need to be updated.
Additionally, project references should
be enabled to ensure that subpackages
referring to each other are built
in the correct order and correctly.
Let's
* Update root package.json to use `tsc --build`
to build the backend
* Update scripts that require CLI to use built
output (.js files)
* Update cli jest.config.ts to use ts-jest to
be able to run test files with jest directly
* Update root tsconfig to point to cli/ and
core/ packages
* Update core/ tsconfig to set `composite` to
true to utilize incremental builds
* Add cli/ tsconfig with references to
core/ package, along with basic config
* Update packages in package-lock
Due to update TypeScript configurations,
update the developer docs to remain
up-to-date on setting up the project
and developing.
@codecov

codecovBot commented Feb 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.50000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.20%. Comparing base (2f6cb37) to head (b7ed620).
⚠️ Report is 17 commits behind head on master.

Files with missing linesPatch %Lines
packages/cli/src/util/cliUtil.ts91.66%3 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #2830 +/- ##
==========================================
- Coverage 72.20% 72.20% -0.01% 
==========================================
Files 134 134 Lines 7454 7461 +7 Branches 1528 1531 +3 ==========================================
+ Hits 5382 5387 +5 - Misses 2026 2028 +2 
Partials 46 46 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Harjun751
Harjun751 requested a review from a teamFebruary 7, 2026 03:51
Comment threadtsconfig.json
@Harjun751Harjun751 mentioned this pull request Feb 8, 2026
14 tasks
Comment threadtsconfig_base.json
Comment threadpackages/cli/test/functional/.eslintrc.js

@gerteckgerteck left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, good job on this

Note to self:

  • --build for tsc is for project references, which builds each package in dependency order.

Other stuff

  1. CLI snapshot test fails on my local after checking out to this branch. (EDIT: Due to .DS_Store due to dev on MacOS, unrelated to this PR. Tests pass on CI.)

  2. I got a permission denied as in, had to run chmod to add execute perms. i wonder if it is just a local dev env thing? Have not faced this before.
    Generated js file does not have executable flag enabled.

Edit: The markbind CLI command fails with "permission denied" because the generated packages/cli/dist/index.js
file loses its executable flag during the build process. tsc does not preserve permissions from source files.

@Harjun751
Harjun751force-pushed the cli-typescript-migration-redux branch 2 times, most recently from 268221f to b7ed620CompareFebruary 10, 2026 01:36
TypeScript compiler outputs all generated files
with `644` permissions, meaning that by default
generated files are not executable. Additionally,
the compiler does not preserve permissions of
source files when generating output, see:
github.com/microsoft/TypeScript/issues/37583
This particularly causes a problem with
`npm link`, since the entrypoint file
does not have execute permissions after
rebuilding, making the linked project
unable to be ran.
To workaround this, let's
* Add a script to ensure that the entrypoint
file is executable
* Make the script run before `dev` and
`build:backend` workflows
* Add a disclaimer in documentation
on what to do if the permission
error occurs
Comment threadscripts/prepCliOutput.js

@gerteckgerteck left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the great work on this @Harjun751

Merging this in, @MarkBind/active-3281-members do remember to update your forks and pull the latest after merging!

@gerteck
gerteck merged commit fe1bcba into MarkBind:masterFeb 10, 2026
16 of 21 checks passed
@github-actionsgithub-actionsBot added the r.Minor Version resolver: increment by 0.1.0 label Feb 10, 2026
This was referenced Feb 19, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

r.MinorVersion resolver: increment by 0.1.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate cli package to Typescript

2 participants

@Harjun751@gerteck
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' CLI TypeScript migration (re) by Harjun751 · Pull Request #2830 · MarkBind/markbind · GitHub
Skip to content

CLI TypeScript migration (re) - #2830

Merged
gerteck merged 17 commits into
MarkBind:masterfrom
Harjun751:cli-typescript-migration-redux
Feb 10, 2026
Merged

CLI TypeScript migration (re)#2830
gerteck merged 17 commits into
MarkBind:masterfrom
Harjun751:cli-typescript-migration-redux

Conversation

@Harjun751

@Harjun751Harjun751 commented Feb 7, 2026

Copy link
Copy Markdown
Contributor

What is the purpose of this pull request?

  • Documentation update
  • Bug fix
  • Feature addition or enhancement
  • Code maintenance
  • DevOps
  • Improve developer experience
  • Others, please explain:

Overview of changes:

Resolves#2754

  • Migrate functional code in CLI package to typescript

    • index.js and all util files converted to typescript
    • live-server patch is still JavaScript - added type definitions for now.
    • Test files migrated to typescript
    • Add typescript configs in the cli package - generated files go to cli/dist/
  • Package changes

    • Modified cli/package.json to properly prepare and publish the markbind-cli package.
    • Modified root package.json to use the built CLI module in cli/dist/
    • Updated selected packages to get built-in type definitions
    • Installed some type definitions
  • Developer-facing changes

    • Added a build/dev script in cli/package.json
    • Updated root build/dev scripts to utilize Project References (running the build/dev scripts are functionally the same as a developer)
    • Added tsx as a dev dependency - run TypeScript files directly using the bundled runner
    • Update dev docs on modified setup instructions & on how to use tsx to directly run files

Anything you'd like to highlight/discuss:
The migrated code is TypeScript, but it's not good TypeScript. There's liberal use of any, so it could definitely be improved. I think we could do refactoring as a separate PR, as I didn't want to clutter this PR any further. LMK, though.

Suggested things to refactor:
  1. Refactor core Site constructor. The CLI was using the constructor without properly specifying all the arguments - create an overloaded constructor for this?

  2. TypeScript 4.4 set the error type of catch variable to unknown. This means that to extract the error message, type narrowing was required. This introduces an extra branch and decision - what to log when the type of error is unknown? Currently, it simply logs "unknown error". Suggest: extract a variable/function that can be re-used in these cases, instead of hard-coding a message.

  3. Create an interface/type that can be used for the option parameter of the commander package callbacks

  4. Generally improve logger re-use in the cmd/ files - a lot of code duplication.

  5. Create an interface/type that can be used for the ServerConfig object in serve.ts

  6. Decrease the high level of coupling between the CLI and Core package

I chose tsx over ts-node since tsx seems more actively-maintained (the last release for ts-node was 3 years ago). Furthermore, tsx seems generally faster, and I had a good experience using tsx with Webstorm with zero configuration or issues. If there's another option worth considering, feel free to raise it up.

In terms of documentation, I did not add an entry on how to configure VSCode with tsx to run TypeScript code directly with, as I don't use VSC. If you think it's valuable, please do add it in!

Testing instructions:

Above running normal tests, you can check if your IDE/setup can correctly run individual test cases/suites in the cli/test/unit directory, since they use TypeScript now.

Proposed commit message: (wrap lines at 72 characters)

Migrate functional code in CLI package to TypeScript


Checklist: ☑️

  • Updated the documentation for feature additions and enhancements
  • Added tests for bug fixes or features
  • Linked all related issues
  • No unrelated changes

Reviewer checklist:

Indicate the SEMVER impact of the PR:

  • Major (when you make incompatible API changes)
  • Minor (when you add functionality in a backward compatible manner)
  • Patch (when you make backward compatible bug fixes)

At the end of the review, please label the PR with the appropriate label: r.Major, r.Minor, r.Patch.

Breaking change release note preparation (if applicable):

  • To be included in the release note for any feature that is made obsolete/breaking

Give a brief explanation note about:

  • what was the old feature that was made obsolete
  • any replacement feature (if any), and
  • how the author should modify his website to migrate from the old feature to the replacement feature (if possible).

With migrated test files, eslint does not detect that
functional test files are tests, resulting in
raising "no-extraneous-dependencies" error.
This error suggests that dependencies used in the actual
application and not test harnesses/files should be in
the main dependencies section.
However, since these are test files, the dependencies
should rightfully be in `devDependencies`.
Hence, let's add an rule exclusion for
import/no-extraneous-dependencies for the functional
tests.
To facilitate TypeScript migration, update `diff`
package to get in-built type declarations.
No breaking changes related to current usage
introduced.
istextorbinary developer dependency uses an old version
without typescript type definitions.
As part of migration of tests to typescript, the files
requiring istextorbinary now need type definitions.
Let's update istextorbinary to the latest version.
No breaking changes were introduced that affected the
usage of istextorbinary in the code.
To configure adapted tests and files to run
properly, scripts need to be updated.
Additionally, project references should
be enabled to ensure that subpackages
referring to each other are built
in the correct order and correctly.
Let's
* Update root package.json to use `tsc --build`
to build the backend
* Update scripts that require CLI to use built
output (.js files)
* Update cli jest.config.ts to use ts-jest to
be able to run test files with jest directly
* Update root tsconfig to point to cli/ and
core/ packages
* Update core/ tsconfig to set `composite` to
true to utilize incremental builds
* Add cli/ tsconfig with references to
core/ package, along with basic config
* Update packages in package-lock
Due to update TypeScript configurations,
update the developer docs to remain
up-to-date on setting up the project
and developing.
@codecov

codecovBot commented Feb 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.50000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.20%. Comparing base (2f6cb37) to head (b7ed620).
⚠️ Report is 17 commits behind head on master.

Files with missing linesPatch %Lines
packages/cli/src/util/cliUtil.ts91.66%3 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #2830 +/- ##
==========================================
- Coverage 72.20% 72.20% -0.01% 
==========================================
Files 134 134 Lines 7454 7461 +7 Branches 1528 1531 +3 ==========================================
+ Hits 5382 5387 +5 - Misses 2026 2028 +2 
Partials 46 46 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Harjun751
Harjun751 requested a review from a teamFebruary 7, 2026 03:51
Comment threadtsconfig.json
@Harjun751Harjun751 mentioned this pull request Feb 8, 2026
14 tasks
Comment threadtsconfig_base.json
Comment threadpackages/cli/test/functional/.eslintrc.js

@gerteckgerteck left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, good job on this

Note to self:

  • --build for tsc is for project references, which builds each package in dependency order.

Other stuff

  1. CLI snapshot test fails on my local after checking out to this branch. (EDIT: Due to .DS_Store due to dev on MacOS, unrelated to this PR. Tests pass on CI.)

  2. I got a permission denied as in, had to run chmod to add execute perms. i wonder if it is just a local dev env thing? Have not faced this before.
    Generated js file does not have executable flag enabled.

Edit: The markbind CLI command fails with "permission denied" because the generated packages/cli/dist/index.js
file loses its executable flag during the build process. tsc does not preserve permissions from source files.

@Harjun751
Harjun751force-pushed the cli-typescript-migration-redux branch 2 times, most recently from 268221f to b7ed620CompareFebruary 10, 2026 01:36
TypeScript compiler outputs all generated files
with `644` permissions, meaning that by default
generated files are not executable. Additionally,
the compiler does not preserve permissions of
source files when generating output, see:
github.com/microsoft/TypeScript/issues/37583
This particularly causes a problem with
`npm link`, since the entrypoint file
does not have execute permissions after
rebuilding, making the linked project
unable to be ran.
To workaround this, let's
* Add a script to ensure that the entrypoint
file is executable
* Make the script run before `dev` and
`build:backend` workflows
* Add a disclaimer in documentation
on what to do if the permission
error occurs
Comment threadscripts/prepCliOutput.js

@gerteckgerteck left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the great work on this @Harjun751

Merging this in, @MarkBind/active-3281-members do remember to update your forks and pull the latest after merging!

@gerteck
gerteck merged commit fe1bcba into MarkBind:masterFeb 10, 2026
16 of 21 checks passed
@github-actionsgithub-actionsBot added the r.Minor Version resolver: increment by 0.1.0 label Feb 10, 2026
This was referenced Feb 19, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

r.MinorVersion resolver: increment by 0.1.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate cli package to Typescript

2 participants

@Harjun751@gerteck
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' CLI TypeScript migration (re) by Harjun751 · Pull Request #2830 · MarkBind/markbind · GitHub
Skip to content

CLI TypeScript migration (re) - #2830

Merged
gerteck merged 17 commits into
MarkBind:masterfrom
Harjun751:cli-typescript-migration-redux
Feb 10, 2026
Merged

CLI TypeScript migration (re)#2830
gerteck merged 17 commits into
MarkBind:masterfrom
Harjun751:cli-typescript-migration-redux

Conversation

@Harjun751

@Harjun751Harjun751 commented Feb 7, 2026

Copy link
Copy Markdown
Contributor

What is the purpose of this pull request?

  • Documentation update
  • Bug fix
  • Feature addition or enhancement
  • Code maintenance
  • DevOps
  • Improve developer experience
  • Others, please explain:

Overview of changes:

Resolves#2754

  • Migrate functional code in CLI package to typescript

    • index.js and all util files converted to typescript
    • live-server patch is still JavaScript - added type definitions for now.
    • Test files migrated to typescript
    • Add typescript configs in the cli package - generated files go to cli/dist/
  • Package changes

    • Modified cli/package.json to properly prepare and publish the markbind-cli package.
    • Modified root package.json to use the built CLI module in cli/dist/
    • Updated selected packages to get built-in type definitions
    • Installed some type definitions
  • Developer-facing changes

    • Added a build/dev script in cli/package.json
    • Updated root build/dev scripts to utilize Project References (running the build/dev scripts are functionally the same as a developer)
    • Added tsx as a dev dependency - run TypeScript files directly using the bundled runner
    • Update dev docs on modified setup instructions & on how to use tsx to directly run files

Anything you'd like to highlight/discuss:
The migrated code is TypeScript, but it's not good TypeScript. There's liberal use of any, so it could definitely be improved. I think we could do refactoring as a separate PR, as I didn't want to clutter this PR any further. LMK, though.

Suggested things to refactor:
  1. Refactor core Site constructor. The CLI was using the constructor without properly specifying all the arguments - create an overloaded constructor for this?

  2. TypeScript 4.4 set the error type of catch variable to unknown. This means that to extract the error message, type narrowing was required. This introduces an extra branch and decision - what to log when the type of error is unknown? Currently, it simply logs "unknown error". Suggest: extract a variable/function that can be re-used in these cases, instead of hard-coding a message.

  3. Create an interface/type that can be used for the option parameter of the commander package callbacks

  4. Generally improve logger re-use in the cmd/ files - a lot of code duplication.

  5. Create an interface/type that can be used for the ServerConfig object in serve.ts

  6. Decrease the high level of coupling between the CLI and Core package

I chose tsx over ts-node since tsx seems more actively-maintained (the last release for ts-node was 3 years ago). Furthermore, tsx seems generally faster, and I had a good experience using tsx with Webstorm with zero configuration or issues. If there's another option worth considering, feel free to raise it up.

In terms of documentation, I did not add an entry on how to configure VSCode with tsx to run TypeScript code directly with, as I don't use VSC. If you think it's valuable, please do add it in!

Testing instructions:

Above running normal tests, you can check if your IDE/setup can correctly run individual test cases/suites in the cli/test/unit directory, since they use TypeScript now.

Proposed commit message: (wrap lines at 72 characters)

Migrate functional code in CLI package to TypeScript


Checklist: ☑️

  • Updated the documentation for feature additions and enhancements
  • Added tests for bug fixes or features
  • Linked all related issues
  • No unrelated changes

Reviewer checklist:

Indicate the SEMVER impact of the PR:

  • Major (when you make incompatible API changes)
  • Minor (when you add functionality in a backward compatible manner)
  • Patch (when you make backward compatible bug fixes)

At the end of the review, please label the PR with the appropriate label: r.Major, r.Minor, r.Patch.

Breaking change release note preparation (if applicable):

  • To be included in the release note for any feature that is made obsolete/breaking

Give a brief explanation note about:

  • what was the old feature that was made obsolete
  • any replacement feature (if any), and
  • how the author should modify his website to migrate from the old feature to the replacement feature (if possible).

With migrated test files, eslint does not detect that
functional test files are tests, resulting in
raising "no-extraneous-dependencies" error.
This error suggests that dependencies used in the actual
application and not test harnesses/files should be in
the main dependencies section.
However, since these are test files, the dependencies
should rightfully be in `devDependencies`.
Hence, let's add an rule exclusion for
import/no-extraneous-dependencies for the functional
tests.
To facilitate TypeScript migration, update `diff`
package to get in-built type declarations.
No breaking changes related to current usage
introduced.
istextorbinary developer dependency uses an old version
without typescript type definitions.
As part of migration of tests to typescript, the files
requiring istextorbinary now need type definitions.
Let's update istextorbinary to the latest version.
No breaking changes were introduced that affected the
usage of istextorbinary in the code.
To configure adapted tests and files to run
properly, scripts need to be updated.
Additionally, project references should
be enabled to ensure that subpackages
referring to each other are built
in the correct order and correctly.
Let's
* Update root package.json to use `tsc --build`
to build the backend
* Update scripts that require CLI to use built
output (.js files)
* Update cli jest.config.ts to use ts-jest to
be able to run test files with jest directly
* Update root tsconfig to point to cli/ and
core/ packages
* Update core/ tsconfig to set `composite` to
true to utilize incremental builds
* Add cli/ tsconfig with references to
core/ package, along with basic config
* Update packages in package-lock
Due to update TypeScript configurations,
update the developer docs to remain
up-to-date on setting up the project
and developing.
@codecov

codecovBot commented Feb 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.50000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.20%. Comparing base (2f6cb37) to head (b7ed620).
⚠️ Report is 17 commits behind head on master.

Files with missing linesPatch %Lines
packages/cli/src/util/cliUtil.ts91.66%3 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #2830 +/- ##
==========================================
- Coverage 72.20% 72.20% -0.01% 
==========================================
Files 134 134 Lines 7454 7461 +7 Branches 1528 1531 +3 ==========================================
+ Hits 5382 5387 +5 - Misses 2026 2028 +2 
Partials 46 46 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Harjun751
Harjun751 requested a review from a teamFebruary 7, 2026 03:51
Comment threadtsconfig.json
@Harjun751Harjun751 mentioned this pull request Feb 8, 2026
14 tasks
Comment threadtsconfig_base.json
Comment threadpackages/cli/test/functional/.eslintrc.js

@gerteckgerteck left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, good job on this

Note to self:

  • --build for tsc is for project references, which builds each package in dependency order.

Other stuff

  1. CLI snapshot test fails on my local after checking out to this branch. (EDIT: Due to .DS_Store due to dev on MacOS, unrelated to this PR. Tests pass on CI.)

  2. I got a permission denied as in, had to run chmod to add execute perms. i wonder if it is just a local dev env thing? Have not faced this before.
    Generated js file does not have executable flag enabled.

Edit: The markbind CLI command fails with "permission denied" because the generated packages/cli/dist/index.js
file loses its executable flag during the build process. tsc does not preserve permissions from source files.

@Harjun751
Harjun751force-pushed the cli-typescript-migration-redux branch 2 times, most recently from 268221f to b7ed620CompareFebruary 10, 2026 01:36
TypeScript compiler outputs all generated files
with `644` permissions, meaning that by default
generated files are not executable. Additionally,
the compiler does not preserve permissions of
source files when generating output, see:
github.com/microsoft/TypeScript/issues/37583
This particularly causes a problem with
`npm link`, since the entrypoint file
does not have execute permissions after
rebuilding, making the linked project
unable to be ran.
To workaround this, let's
* Add a script to ensure that the entrypoint
file is executable
* Make the script run before `dev` and
`build:backend` workflows
* Add a disclaimer in documentation
on what to do if the permission
error occurs
Comment threadscripts/prepCliOutput.js

@gerteckgerteck left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the great work on this @Harjun751

Merging this in, @MarkBind/active-3281-members do remember to update your forks and pull the latest after merging!

@gerteck
gerteck merged commit fe1bcba into MarkBind:masterFeb 10, 2026
16 of 21 checks passed
@github-actionsgithub-actionsBot added the r.Minor Version resolver: increment by 0.1.0 label Feb 10, 2026
This was referenced Feb 19, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

r.MinorVersion resolver: increment by 0.1.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate cli package to Typescript

2 participants

@Harjun751@gerteck
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' CLI TypeScript migration (re) by Harjun751 · Pull Request #2830 · MarkBind/markbind · GitHub
Skip to content

CLI TypeScript migration (re) - #2830

Merged
gerteck merged 17 commits into
MarkBind:masterfrom
Harjun751:cli-typescript-migration-redux
Feb 10, 2026
Merged

CLI TypeScript migration (re)#2830
gerteck merged 17 commits into
MarkBind:masterfrom
Harjun751:cli-typescript-migration-redux

Conversation

@Harjun751

@Harjun751Harjun751 commented Feb 7, 2026

Copy link
Copy Markdown
Contributor

What is the purpose of this pull request?

  • Documentation update
  • Bug fix
  • Feature addition or enhancement
  • Code maintenance
  • DevOps
  • Improve developer experience
  • Others, please explain:

Overview of changes:

Resolves#2754

  • Migrate functional code in CLI package to typescript

    • index.js and all util files converted to typescript
    • live-server patch is still JavaScript - added type definitions for now.
    • Test files migrated to typescript
    • Add typescript configs in the cli package - generated files go to cli/dist/
  • Package changes

    • Modified cli/package.json to properly prepare and publish the markbind-cli package.
    • Modified root package.json to use the built CLI module in cli/dist/
    • Updated selected packages to get built-in type definitions
    • Installed some type definitions
  • Developer-facing changes

    • Added a build/dev script in cli/package.json
    • Updated root build/dev scripts to utilize Project References (running the build/dev scripts are functionally the same as a developer)
    • Added tsx as a dev dependency - run TypeScript files directly using the bundled runner
    • Update dev docs on modified setup instructions & on how to use tsx to directly run files

Anything you'd like to highlight/discuss:
The migrated code is TypeScript, but it's not good TypeScript. There's liberal use of any, so it could definitely be improved. I think we could do refactoring as a separate PR, as I didn't want to clutter this PR any further. LMK, though.

Suggested things to refactor:
  1. Refactor core Site constructor. The CLI was using the constructor without properly specifying all the arguments - create an overloaded constructor for this?

  2. TypeScript 4.4 set the error type of catch variable to unknown. This means that to extract the error message, type narrowing was required. This introduces an extra branch and decision - what to log when the type of error is unknown? Currently, it simply logs "unknown error". Suggest: extract a variable/function that can be re-used in these cases, instead of hard-coding a message.

  3. Create an interface/type that can be used for the option parameter of the commander package callbacks

  4. Generally improve logger re-use in the cmd/ files - a lot of code duplication.

  5. Create an interface/type that can be used for the ServerConfig object in serve.ts

  6. Decrease the high level of coupling between the CLI and Core package

I chose tsx over ts-node since tsx seems more actively-maintained (the last release for ts-node was 3 years ago). Furthermore, tsx seems generally faster, and I had a good experience using tsx with Webstorm with zero configuration or issues. If there's another option worth considering, feel free to raise it up.

In terms of documentation, I did not add an entry on how to configure VSCode with tsx to run TypeScript code directly with, as I don't use VSC. If you think it's valuable, please do add it in!

Testing instructions:

Above running normal tests, you can check if your IDE/setup can correctly run individual test cases/suites in the cli/test/unit directory, since they use TypeScript now.

Proposed commit message: (wrap lines at 72 characters)

Migrate functional code in CLI package to TypeScript


Checklist: ☑️

  • Updated the documentation for feature additions and enhancements
  • Added tests for bug fixes or features
  • Linked all related issues
  • No unrelated changes

Reviewer checklist:

Indicate the SEMVER impact of the PR:

  • Major (when you make incompatible API changes)
  • Minor (when you add functionality in a backward compatible manner)
  • Patch (when you make backward compatible bug fixes)

At the end of the review, please label the PR with the appropriate label: r.Major, r.Minor, r.Patch.

Breaking change release note preparation (if applicable):

  • To be included in the release note for any feature that is made obsolete/breaking

Give a brief explanation note about:

  • what was the old feature that was made obsolete
  • any replacement feature (if any), and
  • how the author should modify his website to migrate from the old feature to the replacement feature (if possible).

With migrated test files, eslint does not detect that
functional test files are tests, resulting in
raising "no-extraneous-dependencies" error.
This error suggests that dependencies used in the actual
application and not test harnesses/files should be in
the main dependencies section.
However, since these are test files, the dependencies
should rightfully be in `devDependencies`.
Hence, let's add an rule exclusion for
import/no-extraneous-dependencies for the functional
tests.
To facilitate TypeScript migration, update `diff`
package to get in-built type declarations.
No breaking changes related to current usage
introduced.
istextorbinary developer dependency uses an old version
without typescript type definitions.
As part of migration of tests to typescript, the files
requiring istextorbinary now need type definitions.
Let's update istextorbinary to the latest version.
No breaking changes were introduced that affected the
usage of istextorbinary in the code.
To configure adapted tests and files to run
properly, scripts need to be updated.
Additionally, project references should
be enabled to ensure that subpackages
referring to each other are built
in the correct order and correctly.
Let's
* Update root package.json to use `tsc --build`
to build the backend
* Update scripts that require CLI to use built
output (.js files)
* Update cli jest.config.ts to use ts-jest to
be able to run test files with jest directly
* Update root tsconfig to point to cli/ and
core/ packages
* Update core/ tsconfig to set `composite` to
true to utilize incremental builds
* Add cli/ tsconfig with references to
core/ package, along with basic config
* Update packages in package-lock
Due to update TypeScript configurations,
update the developer docs to remain
up-to-date on setting up the project
and developing.
@codecov

codecovBot commented Feb 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.50000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.20%. Comparing base (2f6cb37) to head (b7ed620).
⚠️ Report is 17 commits behind head on master.

Files with missing linesPatch %Lines
packages/cli/src/util/cliUtil.ts91.66%3 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #2830 +/- ##
==========================================
- Coverage 72.20% 72.20% -0.01% 
==========================================
Files 134 134 Lines 7454 7461 +7 Branches 1528 1531 +3 ==========================================
+ Hits 5382 5387 +5 - Misses 2026 2028 +2 
Partials 46 46 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Harjun751
Harjun751 requested a review from a teamFebruary 7, 2026 03:51
Comment threadtsconfig.json
@Harjun751Harjun751 mentioned this pull request Feb 8, 2026
14 tasks
Comment threadtsconfig_base.json
Comment threadpackages/cli/test/functional/.eslintrc.js

@gerteckgerteck left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, good job on this

Note to self:

  • --build for tsc is for project references, which builds each package in dependency order.

Other stuff

  1. CLI snapshot test fails on my local after checking out to this branch. (EDIT: Due to .DS_Store due to dev on MacOS, unrelated to this PR. Tests pass on CI.)

  2. I got a permission denied as in, had to run chmod to add execute perms. i wonder if it is just a local dev env thing? Have not faced this before.
    Generated js file does not have executable flag enabled.

Edit: The markbind CLI command fails with "permission denied" because the generated packages/cli/dist/index.js
file loses its executable flag during the build process. tsc does not preserve permissions from source files.

@Harjun751
Harjun751force-pushed the cli-typescript-migration-redux branch 2 times, most recently from 268221f to b7ed620CompareFebruary 10, 2026 01:36
TypeScript compiler outputs all generated files
with `644` permissions, meaning that by default
generated files are not executable. Additionally,
the compiler does not preserve permissions of
source files when generating output, see:
github.com/microsoft/TypeScript/issues/37583
This particularly causes a problem with
`npm link`, since the entrypoint file
does not have execute permissions after
rebuilding, making the linked project
unable to be ran.
To workaround this, let's
* Add a script to ensure that the entrypoint
file is executable
* Make the script run before `dev` and
`build:backend` workflows
* Add a disclaimer in documentation
on what to do if the permission
error occurs
Comment threadscripts/prepCliOutput.js

@gerteckgerteck left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the great work on this @Harjun751

Merging this in, @MarkBind/active-3281-members do remember to update your forks and pull the latest after merging!

@gerteck
gerteck merged commit fe1bcba into MarkBind:masterFeb 10, 2026
16 of 21 checks passed
@github-actionsgithub-actionsBot added the r.Minor Version resolver: increment by 0.1.0 label Feb 10, 2026
This was referenced Feb 19, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

r.MinorVersion resolver: increment by 0.1.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate cli package to Typescript

2 participants

@Harjun751@gerteck
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); CLI TypeScript migration (re) by Harjun751 · Pull Request #2830 · MarkBind/markbind · GitHub
Skip to content

CLI TypeScript migration (re) - #2830

Merged
gerteck merged 17 commits into
MarkBind:masterfrom
Harjun751:cli-typescript-migration-redux
Feb 10, 2026
Merged

CLI TypeScript migration (re)#2830
gerteck merged 17 commits into
MarkBind:masterfrom
Harjun751:cli-typescript-migration-redux

Conversation

@Harjun751

@Harjun751Harjun751 commented Feb 7, 2026

Copy link
Copy Markdown
Contributor

What is the purpose of this pull request?

  • Documentation update
  • Bug fix
  • Feature addition or enhancement
  • Code maintenance
  • DevOps
  • Improve developer experience
  • Others, please explain:

Overview of changes:

Resolves#2754

  • Migrate functional code in CLI package to typescript

    • index.js and all util files converted to typescript
    • live-server patch is still JavaScript - added type definitions for now.
    • Test files migrated to typescript
    • Add typescript configs in the cli package - generated files go to cli/dist/
  • Package changes

    • Modified cli/package.json to properly prepare and publish the markbind-cli package.
    • Modified root package.json to use the built CLI module in cli/dist/
    • Updated selected packages to get built-in type definitions
    • Installed some type definitions
  • Developer-facing changes

    • Added a build/dev script in cli/package.json
    • Updated root build/dev scripts to utilize Project References (running the build/dev scripts are functionally the same as a developer)
    • Added tsx as a dev dependency - run TypeScript files directly using the bundled runner
    • Update dev docs on modified setup instructions & on how to use tsx to directly run files

Anything you'd like to highlight/discuss:
The migrated code is TypeScript, but it's not good TypeScript. There's liberal use of any, so it could definitely be improved. I think we could do refactoring as a separate PR, as I didn't want to clutter this PR any further. LMK, though.

Suggested things to refactor:
  1. Refactor core Site constructor. The CLI was using the constructor without properly specifying all the arguments - create an overloaded constructor for this?

  2. TypeScript 4.4 set the error type of catch variable to unknown. This means that to extract the error message, type narrowing was required. This introduces an extra branch and decision - what to log when the type of error is unknown? Currently, it simply logs "unknown error". Suggest: extract a variable/function that can be re-used in these cases, instead of hard-coding a message.

  3. Create an interface/type that can be used for the option parameter of the commander package callbacks

  4. Generally improve logger re-use in the cmd/ files - a lot of code duplication.

  5. Create an interface/type that can be used for the ServerConfig object in serve.ts

  6. Decrease the high level of coupling between the CLI and Core package

I chose tsx over ts-node since tsx seems more actively-maintained (the last release for ts-node was 3 years ago). Furthermore, tsx seems generally faster, and I had a good experience using tsx with Webstorm with zero configuration or issues. If there's another option worth considering, feel free to raise it up.

In terms of documentation, I did not add an entry on how to configure VSCode with tsx to run TypeScript code directly with, as I don't use VSC. If you think it's valuable, please do add it in!

Testing instructions:

Above running normal tests, you can check if your IDE/setup can correctly run individual test cases/suites in the cli/test/unit directory, since they use TypeScript now.

Proposed commit message: (wrap lines at 72 characters)

Migrate functional code in CLI package to TypeScript


Checklist: ☑️

  • Updated the documentation for feature additions and enhancements
  • Added tests for bug fixes or features
  • Linked all related issues
  • No unrelated changes

Reviewer checklist:

Indicate the SEMVER impact of the PR:

  • Major (when you make incompatible API changes)
  • Minor (when you add functionality in a backward compatible manner)
  • Patch (when you make backward compatible bug fixes)

At the end of the review, please label the PR with the appropriate label: r.Major, r.Minor, r.Patch.

Breaking change release note preparation (if applicable):

  • To be included in the release note for any feature that is made obsolete/breaking

Give a brief explanation note about:

  • what was the old feature that was made obsolete
  • any replacement feature (if any), and
  • how the author should modify his website to migrate from the old feature to the replacement feature (if possible).

With migrated test files, eslint does not detect that
functional test files are tests, resulting in
raising "no-extraneous-dependencies" error.
This error suggests that dependencies used in the actual
application and not test harnesses/files should be in
the main dependencies section.
However, since these are test files, the dependencies
should rightfully be in `devDependencies`.
Hence, let's add an rule exclusion for
import/no-extraneous-dependencies for the functional
tests.
To facilitate TypeScript migration, update `diff`
package to get in-built type declarations.
No breaking changes related to current usage
introduced.
istextorbinary developer dependency uses an old version
without typescript type definitions.
As part of migration of tests to typescript, the files
requiring istextorbinary now need type definitions.
Let's update istextorbinary to the latest version.
No breaking changes were introduced that affected the
usage of istextorbinary in the code.
To configure adapted tests and files to run
properly, scripts need to be updated.
Additionally, project references should
be enabled to ensure that subpackages
referring to each other are built
in the correct order and correctly.
Let's
* Update root package.json to use `tsc --build`
to build the backend
* Update scripts that require CLI to use built
output (.js files)
* Update cli jest.config.ts to use ts-jest to
be able to run test files with jest directly
* Update root tsconfig to point to cli/ and
core/ packages
* Update core/ tsconfig to set `composite` to
true to utilize incremental builds
* Add cli/ tsconfig with references to
core/ package, along with basic config
* Update packages in package-lock
Due to update TypeScript configurations,
update the developer docs to remain
up-to-date on setting up the project
and developing.
@codecov

codecovBot commented Feb 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.50000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.20%. Comparing base (2f6cb37) to head (b7ed620).
⚠️ Report is 17 commits behind head on master.

Files with missing linesPatch %Lines
packages/cli/src/util/cliUtil.ts91.66%3 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #2830 +/- ##
==========================================
- Coverage 72.20% 72.20% -0.01% 
==========================================
Files 134 134 Lines 7454 7461 +7 Branches 1528 1531 +3 ==========================================
+ Hits 5382 5387 +5 - Misses 2026 2028 +2 
Partials 46 46 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Harjun751
Harjun751 requested a review from a teamFebruary 7, 2026 03:51
Comment threadtsconfig.json
@Harjun751Harjun751 mentioned this pull request Feb 8, 2026
14 tasks
Comment threadtsconfig_base.json
Comment threadpackages/cli/test/functional/.eslintrc.js

@gerteckgerteck left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, good job on this

Note to self:

  • --build for tsc is for project references, which builds each package in dependency order.

Other stuff

  1. CLI snapshot test fails on my local after checking out to this branch. (EDIT: Due to .DS_Store due to dev on MacOS, unrelated to this PR. Tests pass on CI.)

  2. I got a permission denied as in, had to run chmod to add execute perms. i wonder if it is just a local dev env thing? Have not faced this before.
    Generated js file does not have executable flag enabled.

Edit: The markbind CLI command fails with "permission denied" because the generated packages/cli/dist/index.js
file loses its executable flag during the build process. tsc does not preserve permissions from source files.

@Harjun751
Harjun751force-pushed the cli-typescript-migration-redux branch 2 times, most recently from 268221f to b7ed620CompareFebruary 10, 2026 01:36
TypeScript compiler outputs all generated files
with `644` permissions, meaning that by default
generated files are not executable. Additionally,
the compiler does not preserve permissions of
source files when generating output, see:
github.com/microsoft/TypeScript/issues/37583
This particularly causes a problem with
`npm link`, since the entrypoint file
does not have execute permissions after
rebuilding, making the linked project
unable to be ran.
To workaround this, let's
* Add a script to ensure that the entrypoint
file is executable
* Make the script run before `dev` and
`build:backend` workflows
* Add a disclaimer in documentation
on what to do if the permission
error occurs
Comment threadscripts/prepCliOutput.js

@gerteckgerteck left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the great work on this @Harjun751

Merging this in, @MarkBind/active-3281-members do remember to update your forks and pull the latest after merging!

@gerteck
gerteck merged commit fe1bcba into MarkBind:masterFeb 10, 2026
16 of 21 checks passed
@github-actionsgithub-actionsBot added the r.Minor Version resolver: increment by 0.1.0 label Feb 10, 2026
This was referenced Feb 19, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

r.MinorVersion resolver: increment by 0.1.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate cli package to Typescript

2 participants

@Harjun751@gerteck