...
This commit is contained in:
@@ -32,8 +32,8 @@ bash /tmp/install_v.sh --analyzer --herolib
|
||||
Alternatively, you can manually set up the environment:
|
||||
|
||||
```bash
|
||||
mkdir -p ~/code/github/freeflowuniverse
|
||||
cd ~/code/github/freeflowuniverse
|
||||
mkdir -p ~/code/github/incubaid
|
||||
cd ~/code/github/incubaid
|
||||
git clone git@github.com:freeflowuniverse/herolib.git
|
||||
cd herolib
|
||||
# checkout development branch for most recent changes
|
||||
@@ -87,10 +87,10 @@ Before submitting a pull request, ensure all tests pass:
|
||||
./test_basic.vsh
|
||||
|
||||
# Run tests for a specific module
|
||||
vtest ~/code/github/freeflowuniverse/herolib/lib/osal/package_test.v
|
||||
vtest ~/code/github/incubaid/herolib/lib/osal/package_test.v
|
||||
|
||||
# Run tests for an entire directory
|
||||
vtest ~/code/github/freeflowuniverse/herolib/lib/osal
|
||||
vtest ~/code/github/incubaid/herolib/lib/osal
|
||||
```
|
||||
|
||||
The test script (`test_basic.vsh`) manages test execution and caching to optimize performance. It automatically skips tests listed in the ignore or error sections of the script.
|
||||
@@ -148,7 +148,7 @@ This workflow automatically updates the documentation on GitHub Pages when chang
|
||||
To generate documentation locally:
|
||||
|
||||
```bash
|
||||
cd ~/code/github/freeflowuniverse/herolib
|
||||
cd ~/code/github/incubaid/herolib
|
||||
bash doc.sh
|
||||
```
|
||||
|
||||
|
||||
24
README.md
24
README.md
@@ -38,7 +38,7 @@ curl 'https://raw.githubusercontent.com/freeflowuniverse/herolib/refs/heads/deve
|
||||
bash /tmp/install_v.sh --analyzer --herolib
|
||||
|
||||
#do not forget to do the following this makes sure vtest and vrun exists
|
||||
cd ~/code/github/freeflowuniverse/herolib
|
||||
cd ~/code/github/incubaid/herolib
|
||||
v install_herolib.vsh
|
||||
|
||||
# IMPORTANT: Start a new shell after installation for paths to be set correctly
|
||||
@@ -50,7 +50,7 @@ v install_herolib.vsh
|
||||
```
|
||||
V & HeroLib Installer Script
|
||||
|
||||
Usage: ~/code/github/freeflowuniverse/herolib/install_v.sh [options]
|
||||
Usage: ~/code/github/incubaid/herolib/install_v.sh [options]
|
||||
|
||||
Options:
|
||||
-h, --help Show this help message
|
||||
@@ -60,12 +60,12 @@ Options:
|
||||
--herolib Install our herolib
|
||||
|
||||
Examples:
|
||||
~/code/github/freeflowuniverse/herolib/install_v.sh
|
||||
~/code/github/freeflowuniverse/herolib/install_v.sh --reset
|
||||
~/code/github/freeflowuniverse/herolib/install_v.sh --remove
|
||||
~/code/github/freeflowuniverse/herolib/install_v.sh --analyzer
|
||||
~/code/github/freeflowuniverse/herolib/install_v.sh --herolib
|
||||
~/code/github/freeflowuniverse/herolib/install_v.sh --reset --analyzer # Fresh install of both
|
||||
~/code/github/incubaid/herolib/install_v.sh
|
||||
~/code/github/incubaid/herolib/install_v.sh --reset
|
||||
~/code/github/incubaid/herolib/install_v.sh --remove
|
||||
~/code/github/incubaid/herolib/install_v.sh --analyzer
|
||||
~/code/github/incubaid/herolib/install_v.sh --herolib
|
||||
~/code/github/incubaid/herolib/install_v.sh --reset --analyzer # Fresh install of both
|
||||
```
|
||||
|
||||
## Features
|
||||
@@ -98,13 +98,13 @@ Running tests is an essential part of development. To run the basic tests:
|
||||
|
||||
```bash
|
||||
# Run all basic tests
|
||||
~/code/github/freeflowuniverse/herolib/test_basic.vsh
|
||||
~/code/github/incubaid/herolib/test_basic.vsh
|
||||
|
||||
# Run tests for a specific module
|
||||
vtest ~/code/github/freeflowuniverse/herolib/lib/osal/package_test.v
|
||||
vtest ~/code/github/incubaid/herolib/lib/osal/package_test.v
|
||||
|
||||
# Run tests for an entire directory
|
||||
vtest ~/code/github/freeflowuniverse/herolib/lib/osal
|
||||
vtest ~/code/github/incubaid/herolib/lib/osal
|
||||
```
|
||||
|
||||
The `vtest` command is an alias for testing functionality.
|
||||
@@ -168,7 +168,7 @@ This is caused by incompatibility between TCC and the half precision math functi
|
||||
To generate documentation locally:
|
||||
|
||||
```bash
|
||||
cd ~/code/github/freeflowuniverse/herolib
|
||||
cd ~/code/github/incubaid/herolib
|
||||
bash doc.sh
|
||||
```
|
||||
|
||||
|
||||
@@ -19,6 +19,6 @@ travelcost is 3% of revenue
|
||||
|
||||
create me the full heroscript which gives me this biz model
|
||||
|
||||
create bizmodel.heroscript in ~/code/github/freeflowuniverse/herolib/examples/biztools/generated_ai
|
||||
create bizmodel.heroscript in ~/code/github/incubaid/herolib/examples/biztools/generated_ai
|
||||
|
||||
as well as a do.vsh file which executes the heroscript and does a pprint, in do.vsh , call play with heroscript_path arg
|
||||
|
||||
@@ -27,7 +27,7 @@ when I generate vlang scripts I will always use .vsh extension and use following
|
||||
As AI agent I should also execute .v or .vsh scripts with vrun
|
||||
|
||||
```bash
|
||||
vrun ~/code/github/freeflowuniverse/herolib/examples/biztools/bizmodel.vsh
|
||||
vrun ~/code/github/incubaid/herolib/examples/biztools/bizmodel.vsh
|
||||
```
|
||||
|
||||
## executing test scripts
|
||||
@@ -35,7 +35,7 @@ vrun ~/code/github/freeflowuniverse/herolib/examples/biztools/bizmodel.vsh
|
||||
instruct user to test as follows (vtest is an alias which gets installed when herolib gets installed), can be done for a dir and for a file
|
||||
|
||||
```bash
|
||||
vtest ~/code/github/freeflowuniverse/herolib/lib/osal/package_test.v
|
||||
vtest ~/code/github/incubaid/herolib/lib/osal/package_test.v
|
||||
```
|
||||
|
||||
- use ~ so it works over all machines
|
||||
|
||||
@@ -9,7 +9,7 @@ import freeflowuniverse.herolib...
|
||||
|
||||
```
|
||||
|
||||
the files are in ~/code/github/freeflowuniverse/herolib/examples for herolib
|
||||
the files are in ~/code/github/incubaid/herolib/examples for herolib
|
||||
|
||||
## important instructions
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ when I generate vlang scripts I will always use .vsh extension and use following
|
||||
As AI agent I should also execute v or .vsh scripts with vrun
|
||||
|
||||
```bash
|
||||
vrun ~/code/github/freeflowuniverse/herolib/examples/biztools/bizmodel.vsh
|
||||
vrun ~/code/github/incubaid/herolib/examples/biztools/bizmodel.vsh
|
||||
```
|
||||
|
||||
## executing test scripts
|
||||
@@ -31,7 +31,7 @@ vrun ~/code/github/freeflowuniverse/herolib/examples/biztools/bizmodel.vsh
|
||||
instruct user to test as follows (vtest is an alias which gets installed when herolib gets installed), can be done for a dir and for a file
|
||||
|
||||
```bash
|
||||
vtest ~/code/github/freeflowuniverse/herolib/lib/osal/package_test.v
|
||||
vtest ~/code/github/incubaid/herolib/lib/osal/package_test.v
|
||||
```
|
||||
|
||||
- use ~ so it works over all machines
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
params:
|
||||
|
||||
- filepath: /Users/despiegk/code/github/freeflowuniverse/herolib/lib/clients/openai
|
||||
- filepath: /Users/despiegk/code/github/incubaid/herolib/lib/clients/openai
|
||||
|
||||
make a dense overview of the code above, easy to understand for AI
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<file_map>
|
||||
/Users/despiegk/code/github/freeflowuniverse/herolib
|
||||
/Users/despiegk/code/github/incubaid/herolib
|
||||
└── aiprompts
|
||||
└── herolib_core
|
||||
├── core_curdir_example.md
|
||||
@@ -467,7 +467,7 @@
|
||||
</file_map>
|
||||
|
||||
<file_contents>
|
||||
File: /Users/despiegk/code/github/freeflowuniverse/herolib/aiprompts/herolib_core/core_curdir_example.md
|
||||
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_curdir_example.md
|
||||
```md
|
||||
# Getting the Current Script's Path in Herolib/V Shell
|
||||
|
||||
@@ -483,7 +483,7 @@ echo "Current scripts directory: ${script_directory}"
|
||||
|
||||
```
|
||||
|
||||
File: /Users/despiegk/code/github/freeflowuniverse/herolib/aiprompts/herolib_core/core_globals.md
|
||||
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_globals.md
|
||||
```md
|
||||
## how to remember clients, installers as a global
|
||||
|
||||
@@ -531,7 +531,7 @@ pub fn default() !&SiteConfig {
|
||||
```
|
||||
```
|
||||
|
||||
File: /Users/despiegk/code/github/freeflowuniverse/herolib/aiprompts/herolib_core/core_heroscript_basics.md
|
||||
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_heroscript_basics.md
|
||||
```md
|
||||
# HeroScript: Vlang Integration
|
||||
|
||||
@@ -590,7 +590,7 @@ For detailed information on parameter retrieval methods (e.g., `p.get()`, `p.get
|
||||
|
||||
```
|
||||
|
||||
File: /Users/despiegk/code/github/freeflowuniverse/herolib/aiprompts/herolib_core/core_heroscript_playbook.md
|
||||
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_heroscript_playbook.md
|
||||
```md
|
||||
# PlayBook
|
||||
|
||||
@@ -620,7 +620,7 @@ playcmds.run(mut plbook)!
|
||||
|
||||
```
|
||||
|
||||
File: /Users/despiegk/code/github/freeflowuniverse/herolib/aiprompts/herolib_core/core_http_client.md
|
||||
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_http_client.md
|
||||
```md
|
||||
# HTTPConnection Module
|
||||
|
||||
@@ -732,7 +732,7 @@ user := conn.get_json_generic[User](
|
||||
|
||||
```
|
||||
|
||||
File: /Users/despiegk/code/github/freeflowuniverse/herolib/aiprompts/herolib_core/core_osal.md
|
||||
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_osal.md
|
||||
```md
|
||||
# OSAL Core Module - Key Capabilities (freeflowuniverse.herolib.osal.core)
|
||||
|
||||
@@ -798,7 +798,7 @@ this document has info about the most core functions, more detailed info can be
|
||||
|
||||
```
|
||||
|
||||
File: /Users/despiegk/code/github/freeflowuniverse/herolib/aiprompts/herolib_core/core_ourtime.md
|
||||
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_ourtime.md
|
||||
```md
|
||||
# OurTime Module
|
||||
|
||||
@@ -895,7 +895,7 @@ t_invalid := ourtime.new('bad-date') or {
|
||||
|
||||
```
|
||||
|
||||
File: /Users/despiegk/code/github/freeflowuniverse/herolib/aiprompts/herolib_core/core_params.md
|
||||
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_params.md
|
||||
```md
|
||||
# Parameter Parsing in Vlang
|
||||
|
||||
@@ -1009,7 +1009,7 @@ Lists are typically comma-separated strings (e.g., `users: "john,jane,bob"`).
|
||||
|
||||
```
|
||||
|
||||
File: /Users/despiegk/code/github/freeflowuniverse/herolib/aiprompts/herolib_core/core_paths.md
|
||||
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_paths.md
|
||||
```md
|
||||
# Pathlib Usage Guide
|
||||
|
||||
@@ -1164,7 +1164,7 @@ if file_path.exists() {
|
||||
|
||||
```
|
||||
|
||||
File: /Users/despiegk/code/github/freeflowuniverse/herolib/aiprompts/herolib_core/core_text.md
|
||||
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_text.md
|
||||
```md
|
||||
# TextTools Module
|
||||
|
||||
@@ -1268,7 +1268,7 @@ assert hello_world == texttools.name_fix("Hello World!")
|
||||
|
||||
```
|
||||
|
||||
File: /Users/despiegk/code/github/freeflowuniverse/herolib/aiprompts/herolib_core/core_ui_console.md
|
||||
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_ui_console.md
|
||||
```md
|
||||
# module ui.console
|
||||
|
||||
@@ -1473,7 +1473,7 @@ enum Style {
|
||||
|
||||
```
|
||||
|
||||
File: /Users/despiegk/code/github/freeflowuniverse/herolib/aiprompts/herolib_core/core_vshell.md
|
||||
File: /Users/despiegk/code/github/incubaid/herolib/aiprompts/herolib_core/core_vshell.md
|
||||
```md
|
||||
# how to run the vshell example scripts
|
||||
|
||||
@@ -1486,7 +1486,7 @@ import freeflowuniverse.herolib...
|
||||
|
||||
```
|
||||
|
||||
the files are in ~/code/github/freeflowuniverse/herolib/examples for herolib
|
||||
the files are in ~/code/github/incubaid/herolib/examples for herolib
|
||||
|
||||
## important instructions
|
||||
|
||||
@@ -2456,7 +2456,7 @@ $NAME = finance
|
||||
walk over all models from biz: db/heromodels/src/models/$NAME in the rust repo
|
||||
create nice structured public models in Vlang (V) see instructions in herlolib
|
||||
|
||||
put the results in /Users/despiegk/code/github/freeflowuniverse/herolib/lib/hero/models/$NAME
|
||||
put the results in /Users/despiegk/code/github/incubaid/herolib/lib/hero/models/$NAME
|
||||
|
||||
put decorator on fields which need to be indexed: use @[index] for that at end of line of the property of the struct
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ $NAME = calendar
|
||||
walk over all models from biz: db/heromodels/src/models/$NAME in the rust repo
|
||||
create nice structured public models in Vlang (V) see instructions in herlolib
|
||||
|
||||
put the results in /Users/despiegk/code/github/freeflowuniverse/herolib/lib/hero/models/$NAME
|
||||
put the results in /Users/despiegk/code/github/incubaid/herolib/lib/hero/models/$NAME
|
||||
|
||||
put decorator on fields which need to be indexed: use @[index] for that at end of line of the property of the struct
|
||||
|
||||
|
||||
@@ -207,7 +207,7 @@ function os_update {
|
||||
|
||||
|
||||
function hero_lib_pull {
|
||||
pushd $DIR_CODE/github/freeflowuniverse/herolib 2>&1 >> /dev/null
|
||||
pushd $DIR_CODE/github/incubaid/herolib 2>&1 >> /dev/null
|
||||
if [[ $(git status -s) ]]; then
|
||||
echo "There are uncommitted changes in the Git repository herolib."
|
||||
return 1
|
||||
@@ -218,12 +218,12 @@ function hero_lib_pull {
|
||||
|
||||
function hero_lib_get {
|
||||
|
||||
mkdir -p $DIR_CODE/github/freeflowuniverse
|
||||
if [[ -d "$DIR_CODE/github/freeflowuniverse/herolib" ]]
|
||||
mkdir -p $DIR_CODE/github/incubaid
|
||||
if [[ -d "$DIR_CODE/github/incubaid/herolib" ]]
|
||||
then
|
||||
hero_lib_pull
|
||||
else
|
||||
pushd $DIR_CODE/github/freeflowuniverse 2>&1 >> /dev/null
|
||||
pushd $DIR_CODE/github/incubaid 2>&1 >> /dev/null
|
||||
git clone --depth 1 --no-single-branch https://github.com/freeflowuniverse/herolib.git
|
||||
popd 2>&1 >> /dev/null
|
||||
fi
|
||||
@@ -461,7 +461,7 @@ check_and_start_redis
|
||||
|
||||
if [ "$HEROLIB" = true ]; then
|
||||
hero_lib_get
|
||||
~/code/github/freeflowuniverse/herolib/install_herolib.vsh
|
||||
~/code/github/incubaid/herolib/install_herolib.vsh
|
||||
fi
|
||||
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
# SSH and rsync configuration
|
||||
SSH_HOST="verse.tf"
|
||||
SSH_USER="root"
|
||||
SOURCE_DIR="${HOME}/code/github/freeflowuniverse/herolib/"
|
||||
DEST_DIR="/root/code/github/freeflowuniverse/herolib/"
|
||||
FINAL_DIR="/root/code/github/freeflowuniverse/herolib/examples/hero"
|
||||
SOURCE_DIR="${HOME}/code/github/incubaid/herolib/"
|
||||
DEST_DIR="/root/code/github/incubaid/herolib/"
|
||||
FINAL_DIR="/root/code/github/incubaid/herolib/examples/hero"
|
||||
|
||||
# Check if the source directory exists, if not stop
|
||||
if [ ! -d "$SOURCE_DIR" ]; then
|
||||
|
||||
10
install_v.sh
10
install_v.sh
@@ -297,7 +297,7 @@ function os_update {
|
||||
|
||||
|
||||
function hero_lib_pull {
|
||||
pushd $DIR_CODE/github/freeflowuniverse/herolib 2>&1 >> /dev/null
|
||||
pushd $DIR_CODE/github/incubaid/herolib 2>&1 >> /dev/null
|
||||
if [[ $(git status -s) ]]; then
|
||||
echo "There are uncommitted changes in the Git repository herolib."
|
||||
return 1
|
||||
@@ -308,12 +308,12 @@ function hero_lib_pull {
|
||||
|
||||
function hero_lib_get {
|
||||
|
||||
mkdir -p $DIR_CODE/github/freeflowuniverse
|
||||
if [[ -d "$DIR_CODE/github/freeflowuniverse/herolib" ]]
|
||||
mkdir -p $DIR_CODE/github/incubaid
|
||||
if [[ -d "$DIR_CODE/github/incubaid/herolib" ]]
|
||||
then
|
||||
hero_lib_pull
|
||||
else
|
||||
pushd $DIR_CODE/github/freeflowuniverse 2>&1 >> /dev/null
|
||||
pushd $DIR_CODE/github/incubaid 2>&1 >> /dev/null
|
||||
git clone --depth 1 --no-single-branch https://github.com/freeflowuniverse/herolib.git
|
||||
popd 2>&1 >> /dev/null
|
||||
fi
|
||||
@@ -632,7 +632,7 @@ check_and_start_redis
|
||||
|
||||
if [ "$HEROLIB" = true ]; then
|
||||
hero_lib_get
|
||||
~/code/github/freeflowuniverse/herolib/install_herolib.vsh
|
||||
~/code/github/incubaid/herolib/install_herolib.vsh
|
||||
fi
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ The server supports the following operations:
|
||||
### Building the Server
|
||||
|
||||
```bash
|
||||
v -gc none -stats -enable-globals -n -w -cg -g -cc tcc /Users/despiegk/code/github/freeflowuniverse/herolib/lib/mcp/v_do
|
||||
v -gc none -stats -enable-globals -n -w -cg -g -cc tcc /Users/despiegk/code/github/incubaid/herolib/lib/mcp/v_do
|
||||
```
|
||||
|
||||
### Using the Server
|
||||
|
||||
@@ -16,7 +16,7 @@ The server supports the following operations:
|
||||
### Building the Server
|
||||
|
||||
```bash
|
||||
v -gc none -stats -enable-globals -n -w -cg -g -cc tcc /Users/despiegk/code/github/freeflowuniverse/herolib/lib/mcp/v_do
|
||||
v -gc none -stats -enable-globals -n -w -cg -g -cc tcc /Users/despiegk/code/github/incubaid/herolib/lib/mcp/v_do
|
||||
```
|
||||
|
||||
### Using the Server
|
||||
|
||||
@@ -163,7 +163,7 @@ search_result := client.search(
|
||||
Qdrant server can be installed using the provided installer script:
|
||||
|
||||
```bash
|
||||
~/code/github/freeflowuniverse/herolib/examples/installers/db/qdrant.vsh
|
||||
~/code/github/incubaid/herolib/examples/installers/db/qdrant.vsh
|
||||
```
|
||||
|
||||
This will install and start a Qdrant server locally.
|
||||
|
||||
@@ -62,7 +62,7 @@ The configuration will be automatically loaded and applied when creating a new R
|
||||
To run the tests:
|
||||
|
||||
```bash
|
||||
vtest ~/code/github/freeflowuniverse/herolib/lib/osal/rclone/rclone_test.v
|
||||
vtest ~/code/github/incubaid/herolib/lib/osal/rclone/rclone_test.v
|
||||
```
|
||||
|
||||
Note: Some tests are commented out as they require an actual rclone configuration and remote to work with. They serve as examples of how to use the RCloneClient module.
|
||||
|
||||
@@ -73,7 +73,7 @@ to call in code
|
||||
|
||||
import freeflowuniverse.herolib.core.generator.generic
|
||||
|
||||
generic.scan(path:"~/code/github/freeflowuniverse/herolib/herolib/installers",force:true)!
|
||||
generic.scan(path:"~/code/github/incubaid/herolib/herolib/installers",force:true)!
|
||||
|
||||
|
||||
```
|
||||
@@ -81,6 +81,6 @@ generic.scan(path:"~/code/github/freeflowuniverse/herolib/herolib/installers",fo
|
||||
to run from bash
|
||||
|
||||
```bash
|
||||
~/code/github/freeflowuniverse/herolib/scripts/fix_installers.vsh
|
||||
~/code/github/incubaid/herolib/scripts/fix_installers.vsh
|
||||
```
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
name:col1 src:'/Users/timurgordon/code/github/freeflowuniverse/herolib/lib/data/doctree/collection/testdata/export_test/mytree/dir1'
|
||||
name:col1 src:'/Users/timurgordon/code/github/incubaid/herolib/lib/data/doctree/collection/testdata/export_test/mytree/dir1'
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
## page_not_found
|
||||
|
||||
path: /Users/timurgordon/code/github/freeflowuniverse/herolib/herolib/data/doctree/collection/testdata/export_test/mytree/dir1/dir2/file1.md
|
||||
path: /Users/timurgordon/code/github/incubaid/herolib/herolib/data/doctree/collection/testdata/export_test/mytree/dir1/dir2/file1.md
|
||||
|
||||
msg: page col3:file5.md not found
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
name:col1 src:'/Users/timurgordon/code/github/freeflowuniverse/herolib/herolib/data/doctree/testdata/export_test/mytree/dir1'
|
||||
name:col1 src:'/Users/timurgordon/code/github/incubaid/herolib/herolib/data/doctree/testdata/export_test/mytree/dir1'
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
## page_not_found
|
||||
|
||||
path: /Users/timurgordon/code/github/freeflowuniverse/herolib/herolib/data/doctree/testdata/export_test/mytree/dir1/dir2/file1.md
|
||||
path: /Users/timurgordon/code/github/incubaid/herolib/herolib/data/doctree/testdata/export_test/mytree/dir1/dir2/file1.md
|
||||
|
||||
msg: page col3:file5.md not found
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
name:col2 src:'/Users/timurgordon/code/github/freeflowuniverse/herolib/herolib/data/doctree/testdata/export_test/mytree/dir3'
|
||||
name:col2 src:'/Users/timurgordon/code/github/incubaid/herolib/herolib/data/doctree/testdata/export_test/mytree/dir3'
|
||||
0
lib/develop/codetools/vtest.v
Normal file
0
lib/develop/codetools/vtest.v
Normal file
269
lib/develop/codetools/vvet.v
Normal file
269
lib/develop/codetools/vvet.v
Normal file
@@ -0,0 +1,269 @@
|
||||
module code
|
||||
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import os
|
||||
|
||||
// ===== FILE AND DIRECTORY OPERATIONS =====
|
||||
|
||||
// list_v_files returns all .v files in a directory (non-recursive), excluding generated files ending with _.v
|
||||
// ARGS:
|
||||
// dir string - directory path to search
|
||||
// RETURNS:
|
||||
// []string - list of absolute paths to V files
|
||||
pub fn list_v_files(dir string) ![]string {
|
||||
files := os.ls(dir) or { return error('Error listing directory: ${err}') }
|
||||
|
||||
mut v_files := []string{}
|
||||
for file in files {
|
||||
if file.ends_with('.v') && !file.ends_with('_.v') {
|
||||
filepath := os.join_path(dir, file)
|
||||
v_files << filepath
|
||||
}
|
||||
}
|
||||
|
||||
return v_files
|
||||
}
|
||||
|
||||
// get_module_dir converts a V module path to a directory path
|
||||
// ARGS:
|
||||
// mod string - module name (e.g., 'freeflowuniverse.herolib.mcp')
|
||||
// RETURNS:
|
||||
// string - absolute path to the module directory
|
||||
pub fn get_module_dir(mod string) string {
|
||||
module_parts := mod.trim_string_left('freeflowuniverse.herolib').split('.')
|
||||
return '${os.home_dir()}/code/github/freeflowuniverse/herolib/lib/${module_parts.join('/')}'
|
||||
}
|
||||
|
||||
// ===== CODE PARSING UTILITIES =====
|
||||
|
||||
// find_closing_brace finds the position of the closing brace that matches an opening brace
|
||||
// ARGS:
|
||||
// content string - the string to search in
|
||||
// start_i int - the position after the opening brace
|
||||
// RETURNS:
|
||||
// ?int - position of the matching closing brace, or none if not found
|
||||
fn find_closing_brace(content string, start_i int) ?int {
|
||||
mut brace_count := 1
|
||||
for i := start_i; i < content.len; i++ {
|
||||
if content[i] == `{` {
|
||||
brace_count++
|
||||
} else if content[i] == `}` {
|
||||
brace_count--
|
||||
if brace_count == 0 {
|
||||
return i
|
||||
}
|
||||
}
|
||||
}
|
||||
return none
|
||||
}
|
||||
|
||||
// get_function_from_file parses a V file and extracts a specific function block including its comments
|
||||
// ARGS:
|
||||
// file_path string - path to the V file
|
||||
// function_name string - name of the function to extract
|
||||
// RETURNS:
|
||||
// string - the function block including comments, or error if not found
|
||||
pub fn get_function_from_file(file_path string, function_name string) !Function {
|
||||
content := os.read_file(file_path) or {
|
||||
return error('Failed to read file ${file_path}: ${err}')
|
||||
}
|
||||
|
||||
vfile := parse_vfile(content) or { return error('Failed to parse file ${file_path}: ${err}') }
|
||||
|
||||
if fn_obj := vfile.get_function(function_name) {
|
||||
return fn_obj
|
||||
}
|
||||
|
||||
return error('function ${function_name} not found in file ${file_path}')
|
||||
}
|
||||
|
||||
// get_function_from_module searches for a function in all V files within a module
|
||||
// ARGS:
|
||||
// module_path string - path to the module directory
|
||||
// function_name string - name of the function to find
|
||||
// RETURNS:
|
||||
// string - the function definition if found, or error if not found
|
||||
pub fn get_function_from_module(module_path string, function_name string) !Function {
|
||||
v_files := list_v_files(module_path) or {
|
||||
return error('Failed to list V files in ${module_path}: ${err}')
|
||||
}
|
||||
|
||||
console.print_stderr('Found ${v_files} V files in ${module_path}')
|
||||
for v_file in v_files {
|
||||
// Read the file content
|
||||
content := os.read_file(v_file) or { continue }
|
||||
|
||||
// Parse the file
|
||||
vfile := parse_vfile(content) or { continue }
|
||||
|
||||
// Look for the function
|
||||
if fn_obj := vfile.get_function(function_name) {
|
||||
return fn_obj
|
||||
}
|
||||
}
|
||||
|
||||
return error('function ${function_name} not found in module ${module_path}')
|
||||
}
|
||||
|
||||
// get_type_from_module searches for a type definition in all V files within a module
|
||||
// ARGS:
|
||||
// module_path string - path to the module directory
|
||||
// type_name string - name of the type to find
|
||||
// RETURNS:
|
||||
// string - the type definition if found, or error if not found
|
||||
pub fn get_type_from_module(module_path string, type_name string) !string {
|
||||
console.print_debug('Looking for type ${type_name} in module ${module_path}')
|
||||
v_files := list_v_files(module_path) or {
|
||||
return error('Failed to list V files in ${module_path}: ${err}')
|
||||
}
|
||||
|
||||
for v_file in v_files {
|
||||
console.print_debug('Checking file: ${v_file}')
|
||||
content := os.read_file(v_file) or { return error('Failed to read file ${v_file}: ${err}') }
|
||||
|
||||
// Look for both regular and pub struct declarations
|
||||
mut type_str := 'struct ${type_name} {'
|
||||
mut i := content.index(type_str) or { -1 }
|
||||
mut is_pub := false
|
||||
|
||||
if i == -1 {
|
||||
// Try with pub struct
|
||||
type_str = 'pub struct ${type_name} {'
|
||||
i = content.index(type_str) or { -1 }
|
||||
is_pub = true
|
||||
}
|
||||
|
||||
if i == -1 {
|
||||
type_import := content.split_into_lines().filter(it.contains('import')
|
||||
&& it.contains(type_name))
|
||||
if type_import.len > 0 {
|
||||
mod := type_import[0].trim_space().trim_string_left('import ').all_before(' ')
|
||||
return get_type_from_module(get_module_dir(mod), type_name)
|
||||
}
|
||||
continue
|
||||
}
|
||||
console.print_debug('Found type ${type_name} in ${v_file} at position ${i}')
|
||||
|
||||
// Find the start of the struct definition including comments
|
||||
mut comment_start := i
|
||||
mut line_start := i
|
||||
|
||||
// Find the start of the line containing the struct definition
|
||||
for j := i; j >= 0; j-- {
|
||||
if j == 0 || content[j - 1] == `\n` {
|
||||
line_start = j
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Find the start of the comment block (if any)
|
||||
for j := line_start - 1; j >= 0; j-- {
|
||||
if j == 0 {
|
||||
comment_start = 0
|
||||
break
|
||||
}
|
||||
|
||||
// If we hit a blank line or a non-comment line, stop
|
||||
if content[j] == `\n` {
|
||||
if j > 0 && j < content.len - 1 {
|
||||
// Check if the next line starts with a comment
|
||||
next_line_start := j + 1
|
||||
if next_line_start < content.len && content[next_line_start] != `/` {
|
||||
comment_start = j + 1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find the end of the struct definition
|
||||
closing_i := find_closing_brace(content, i + type_str.len) or {
|
||||
return error('could not find where declaration for type ${type_name} ends')
|
||||
}
|
||||
|
||||
// Get the full struct definition including the struct declaration line
|
||||
full_struct := content.substr(line_start, closing_i + 1)
|
||||
console.print_debug('Found struct definition:\n${full_struct}')
|
||||
|
||||
// Return the full struct definition
|
||||
return full_struct
|
||||
}
|
||||
|
||||
return error('type ${type_name} not found in module ${module_path}')
|
||||
}
|
||||
|
||||
// ===== V LANGUAGE TOOLS =====
|
||||
|
||||
// vtest runs v test on the specified file or directory
|
||||
// ARGS:
|
||||
// fullpath string - path to the file or directory to test
|
||||
// RETURNS:
|
||||
// string - test results output, or error if test fails
|
||||
pub fn vtest(fullpath string) !string {
|
||||
console.print_item('test ${fullpath}')
|
||||
if !os.exists(fullpath) {
|
||||
return error('File or directory does not exist: ${fullpath}')
|
||||
}
|
||||
if os.is_dir(fullpath) {
|
||||
mut results := ''
|
||||
for item in list_v_files(fullpath)! {
|
||||
results += vtest(item)!
|
||||
results += '\n-----------------------\n'
|
||||
}
|
||||
return results
|
||||
} else {
|
||||
cmd := 'v -gc none -stats -enable-globals -show-c-output -keepc -n -w -cg -o /tmp/tester.c -g -cc tcc test ${fullpath}'
|
||||
console.print_debug('Executing command: ${cmd}')
|
||||
result := os.execute(cmd)
|
||||
if result.exit_code != 0 {
|
||||
return error('Test failed for ${fullpath} with exit code ${result.exit_code}\n${result.output}')
|
||||
} else {
|
||||
console.print_item('Test completed for ${fullpath}')
|
||||
}
|
||||
return 'Command: ${cmd}\nExit code: ${result.exit_code}\nOutput:\n${result.output}'
|
||||
}
|
||||
}
|
||||
|
||||
// vet_file runs v vet on a single file
|
||||
// ARGS:
|
||||
// file string - path to the file to vet
|
||||
// RETURNS:
|
||||
// string - vet results output, or error if vet fails
|
||||
fn vet_file(file string) !string {
|
||||
cmd := 'v vet -v -w ${file}'
|
||||
console.print_debug('Executing command: ${cmd}')
|
||||
result := os.execute(cmd)
|
||||
if result.exit_code != 0 {
|
||||
return error('Vet failed for ${file} with exit code ${result.exit_code}\n${result.output}')
|
||||
} else {
|
||||
console.print_item('Vet completed for ${file}')
|
||||
}
|
||||
return 'Command: ${cmd}\nExit code: ${result.exit_code}\nOutput:\n${result.output}'
|
||||
}
|
||||
|
||||
// vvet runs v vet on the specified file or directory
|
||||
// ARGS:
|
||||
// fullpath string - path to the file or directory to vet
|
||||
// RETURNS:
|
||||
// string - vet results output, or error if vet fails
|
||||
pub fn vvet(fullpath string) !string {
|
||||
console.print_item('vet ${fullpath}')
|
||||
if !os.exists(fullpath) {
|
||||
return error('File or directory does not exist: ${fullpath}')
|
||||
}
|
||||
|
||||
if os.is_dir(fullpath) {
|
||||
mut results := ''
|
||||
files := list_v_files(fullpath) or { return error('Error listing V files: ${err}') }
|
||||
for file in files {
|
||||
results += vet_file(file) or {
|
||||
console.print_stderr('Failed to vet ${file}: ${err}')
|
||||
return error('Failed to vet ${file}: ${err}')
|
||||
}
|
||||
results += '\n-----------------------\n'
|
||||
}
|
||||
return results
|
||||
} else {
|
||||
return vet_file(fullpath)
|
||||
}
|
||||
}
|
||||
@@ -63,4 +63,4 @@ screen -r test
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
vtest ~/code/github/freeflowuniverse/herolib/lib/osal/screen/screen_test.v
|
||||
vtest ~/code/github/incubaid/herolib/lib/osal/screen/screen_test.v
|
||||
|
||||
@@ -251,4 +251,4 @@ mut web_service := systemd.new(
|
||||
|
||||
```v
|
||||
// Test module
|
||||
vtest ~/code/github/freeflowuniverse/herolib/lib/osal/systemd/systemd_process_test.v
|
||||
vtest ~/code/github/incubaid/herolib/lib/osal/systemd/systemd_process_test.v
|
||||
@@ -32,8 +32,8 @@ requirements
|
||||
- ssh key loaded for access to github
|
||||
|
||||
```bash
|
||||
mkdir -p ~/code/github/freeflowuniverse
|
||||
cd ~/code/github/freeflowuniverse
|
||||
mkdir -p ~/code/github/incubaid
|
||||
cd ~/code/github/incubaid
|
||||
git clone git@github.com:freeflowuniverse/herolib.git
|
||||
cd herolib
|
||||
# checkout a branch with most recent changes
|
||||
@@ -72,7 +72,7 @@ requirements
|
||||
|
||||
```bash
|
||||
#cd in this directory
|
||||
cd ~/code/github/freeflowuniverse/herolib
|
||||
cd ~/code/github/incubaid/herolib
|
||||
bash doc.sh
|
||||
```
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ The server supports the following operations:
|
||||
### Building the Server
|
||||
|
||||
```bash
|
||||
v -gc none -stats -enable-globals -n -w -cg -g -cc tcc /Users/despiegk/code/github/freeflowuniverse/herolib/lib/mcp/v_do
|
||||
v -gc none -stats -enable-globals -n -w -cg -g -cc tcc /Users/despiegk/code/github/incubaid/herolib/lib/mcp/v_do
|
||||
```
|
||||
|
||||
### Using the Server
|
||||
|
||||
@@ -16,7 +16,7 @@ The server supports the following operations:
|
||||
### Building the Server
|
||||
|
||||
```bash
|
||||
v -gc none -stats -enable-globals -n -w -cg -g -cc tcc /Users/despiegk/code/github/freeflowuniverse/herolib/lib/mcp/v_do
|
||||
v -gc none -stats -enable-globals -n -w -cg -g -cc tcc /Users/despiegk/code/github/incubaid/herolib/lib/mcp/v_do
|
||||
```
|
||||
|
||||
### Using the Server
|
||||
|
||||
@@ -1,131 +1,131 @@
|
||||
{
|
||||
"Sidebar": [
|
||||
{
|
||||
"Title": "General",
|
||||
"Items": [
|
||||
{
|
||||
"Title": "Create Tag",
|
||||
"Href": "/create_tag",
|
||||
"IsDir": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "Best Practices",
|
||||
"Items": [
|
||||
{
|
||||
"Title": "Osal",
|
||||
"Href": "/best_practices/osal",
|
||||
"IsDir": true,
|
||||
"Children": [
|
||||
{
|
||||
"Title": "Silence",
|
||||
"Href": "/best_practices/osal/silence",
|
||||
"IsDir": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "Scripts",
|
||||
"Href": "/best_practices/scripts",
|
||||
"IsDir": true,
|
||||
"Children": [
|
||||
{
|
||||
"Title": "Scripts",
|
||||
"Href": "/best_practices/scripts/scripts",
|
||||
"IsDir": false
|
||||
},
|
||||
{
|
||||
"Title": "Shebang",
|
||||
"Href": "/best_practices/scripts/shebang",
|
||||
"IsDir": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "Using Args In Function",
|
||||
"Href": "/best_practices/using_args_in_function",
|
||||
"IsDir": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "Model Context Providers",
|
||||
"Items": [
|
||||
{
|
||||
"Title": "Baobab MCP",
|
||||
"Href": "/Users/timurgordon/code/github/freeflowuniverse/herolib/lib/mcp/baobab/README.md",
|
||||
"IsDir": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "Core",
|
||||
"Items": [
|
||||
{
|
||||
"Title": "Base",
|
||||
"Href": "/core/base",
|
||||
"IsDir": false
|
||||
},
|
||||
{
|
||||
"Title": "Concepts",
|
||||
"Href": "/core/concepts",
|
||||
"IsDir": true,
|
||||
"Children": [
|
||||
{
|
||||
"Title": "Global Ids",
|
||||
"Href": "/core/concepts/global_ids",
|
||||
"IsDir": false
|
||||
},
|
||||
{
|
||||
"Title": "Name Registry",
|
||||
"Href": "/core/concepts/name_registry",
|
||||
"IsDir": false
|
||||
},
|
||||
{
|
||||
"Title": "Objects",
|
||||
"Href": "/core/concepts/objects",
|
||||
"IsDir": false
|
||||
},
|
||||
{
|
||||
"Title": "Sid",
|
||||
"Href": "/core/concepts/sid",
|
||||
"IsDir": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "Context",
|
||||
"Href": "/core/context",
|
||||
"IsDir": false
|
||||
},
|
||||
{
|
||||
"Title": "Context Session Job",
|
||||
"Href": "/core/context_session_job",
|
||||
"IsDir": false
|
||||
},
|
||||
{
|
||||
"Title": "Play",
|
||||
"Href": "/core/play",
|
||||
"IsDir": false
|
||||
},
|
||||
{
|
||||
"Title": "Session",
|
||||
"Href": "/core/session",
|
||||
"IsDir": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "Documentation",
|
||||
"Items": [
|
||||
{
|
||||
"Title": "Docextractor",
|
||||
"Href": "/documentation/docextractor",
|
||||
"IsDir": false
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Title": "HeroLib Manual"
|
||||
}
|
||||
"Sidebar": [
|
||||
{
|
||||
"Title": "General",
|
||||
"Items": [
|
||||
{
|
||||
"Title": "Create Tag",
|
||||
"Href": "/create_tag",
|
||||
"IsDir": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "Best Practices",
|
||||
"Items": [
|
||||
{
|
||||
"Title": "Osal",
|
||||
"Href": "/best_practices/osal",
|
||||
"IsDir": true,
|
||||
"Children": [
|
||||
{
|
||||
"Title": "Silence",
|
||||
"Href": "/best_practices/osal/silence",
|
||||
"IsDir": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "Scripts",
|
||||
"Href": "/best_practices/scripts",
|
||||
"IsDir": true,
|
||||
"Children": [
|
||||
{
|
||||
"Title": "Scripts",
|
||||
"Href": "/best_practices/scripts/scripts",
|
||||
"IsDir": false
|
||||
},
|
||||
{
|
||||
"Title": "Shebang",
|
||||
"Href": "/best_practices/scripts/shebang",
|
||||
"IsDir": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "Using Args In Function",
|
||||
"Href": "/best_practices/using_args_in_function",
|
||||
"IsDir": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "Model Context Providers",
|
||||
"Items": [
|
||||
{
|
||||
"Title": "Baobab MCP",
|
||||
"Href": "/Users/timurgordon/code/github/incubaid/herolib/lib/mcp/baobab/README.md",
|
||||
"IsDir": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "Core",
|
||||
"Items": [
|
||||
{
|
||||
"Title": "Base",
|
||||
"Href": "/core/base",
|
||||
"IsDir": false
|
||||
},
|
||||
{
|
||||
"Title": "Concepts",
|
||||
"Href": "/core/concepts",
|
||||
"IsDir": true,
|
||||
"Children": [
|
||||
{
|
||||
"Title": "Global Ids",
|
||||
"Href": "/core/concepts/global_ids",
|
||||
"IsDir": false
|
||||
},
|
||||
{
|
||||
"Title": "Name Registry",
|
||||
"Href": "/core/concepts/name_registry",
|
||||
"IsDir": false
|
||||
},
|
||||
{
|
||||
"Title": "Objects",
|
||||
"Href": "/core/concepts/objects",
|
||||
"IsDir": false
|
||||
},
|
||||
{
|
||||
"Title": "Sid",
|
||||
"Href": "/core/concepts/sid",
|
||||
"IsDir": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "Context",
|
||||
"Href": "/core/context",
|
||||
"IsDir": false
|
||||
},
|
||||
{
|
||||
"Title": "Context Session Job",
|
||||
"Href": "/core/context_session_job",
|
||||
"IsDir": false
|
||||
},
|
||||
{
|
||||
"Title": "Play",
|
||||
"Href": "/core/play",
|
||||
"IsDir": false
|
||||
},
|
||||
{
|
||||
"Title": "Session",
|
||||
"Href": "/core/session",
|
||||
"IsDir": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "Documentation",
|
||||
"Items": [
|
||||
{
|
||||
"Title": "Docextractor",
|
||||
"Href": "/documentation/docextractor",
|
||||
"IsDir": false
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Title": "HeroLib Manual"
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
## how to tag a version and push
|
||||
|
||||
```bash
|
||||
cd ~/Users/despiegk~/code/github/freeflowuniverse/herolib
|
||||
cd ~/Users/despiegk~/code/github/incubaid/herolib
|
||||
git tag -a v1.0.4 -m "all CI is now working"
|
||||
git add . -A ; git commit -m ... ; git pull ; git push origin v1.0.4
|
||||
```
|
||||
@@ -12,6 +12,6 @@ this allows us to make manual and to copy information from the readme's which ar
|
||||
to run
|
||||
|
||||
```bash
|
||||
~/code/github/freeflowuniverse/herolib/tools/doc_extractor/extractor.sh
|
||||
~/code/github/incubaid/herolib/tools/doc_extractor/extractor.sh
|
||||
```
|
||||
|
||||
|
||||
@@ -12,10 +12,10 @@ MANUAL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CONFIG_FILE="$MANUAL_DIR/config.json"
|
||||
|
||||
# Path to the wiki package
|
||||
WIKI_DIR="/Users/timurgordon/code/github/freeflowuniverse/herolauncher/pkg/ui/wiki"
|
||||
WIKI_DIR="/Users/timurgordon/code/github/incubaid/herolauncher/pkg/ui/wiki"
|
||||
|
||||
# Path to the herolib directory
|
||||
HEROLIB_DIR="/Users/timurgordon/code/github/freeflowuniverse/herolib"
|
||||
HEROLIB_DIR="/Users/timurgordon/code/github/incubaid/herolib"
|
||||
|
||||
cd "$WIKI_DIR"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
cd ~/code/github/freeflowuniverse/herolib/vscodeplugin/heroscrypt-syntax
|
||||
cd ~/code/github/incubaid/herolib/vscodeplugin/heroscrypt-syntax
|
||||
npx @vscode/vsce package
|
||||
|
||||
code --install-extension ~/code/github/freeflowuniverse/herolib/vscodeplugin/heroscrypt-syntax/heroscript-syntax-0.0.1.vsix
|
||||
code --install-extension ~/code/github/incubaid/herolib/vscodeplugin/heroscrypt-syntax/heroscript-syntax-0.0.1.vsix
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
you can go to extensions and install the vsx
|
||||
|
||||
/root/code/github/freeflowuniverse/crystallib/vscodeplugin/heroscrypt-syntax/heroscript-syntax-0.0.1.vsix
|
||||
/root/code/github/incubaid/crystallib/vscodeplugin/heroscrypt-syntax/heroscript-syntax-0.0.1.vsix
|
||||
|
||||
also in vscode go on right mouse and see how to install (starting from .vsix file)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user